@ -48,8 +48,7 @@ import _ from 'underscore'
import $ from 'jquery'
import OC from './index.js'
import OCA from '../OCA/index.js'
import { isA11yActivation } from '../Util/a11y.js'
import { FilePickerVue , FilePickerType , spawnDialog } from '@nextcloud/dialogs'
/ * *
* this class to ease the usage of jquery dialogs
@ -59,10 +58,15 @@ const Dialogs = {
YES _NO _BUTTONS : 70 ,
OK _BUTTONS : 71 ,
/** @deprecated use FilePickerType from `@nextcloud/dialogs` */
FILEPICKER _TYPE _CHOOSE : 1 ,
/** @deprecated use FilePickerType from `@nextcloud/dialogs` */
FILEPICKER _TYPE _MOVE : 2 ,
/** @deprecated use FilePickerType from `@nextcloud/dialogs` */
FILEPICKER _TYPE _COPY : 3 ,
/** @deprecated use FilePickerType from `@nextcloud/dialogs` */
FILEPICKER _TYPE _COPY _MOVE : 4 ,
/** @deprecated use FilePickerType from `@nextcloud/dialogs` */
FILEPICKER _TYPE _CUSTOM : 5 ,
// used to name each dialog
@ -226,8 +230,11 @@ const Dialogs = {
Dialogs . dialogsCounter ++
} )
} ,
/ * *
* show a file picker to pick a file from
* Legacy wrapper to the new Vue based filepicker from ` @nextcloud/dialogs `
*
* Prefer to use the Vue filepicker directly instead .
*
* In order to pick several types of mime types they need to be passed as an
* array of strings .
@ -237,339 +244,109 @@ const Dialogs = {
* should be used instead .
*
* @ param { string } title dialog title
* @ param { f unction} callback which will be triggered when user presses Choose
* @ param { F unction} callback which will be triggered when user presses Choose
* @ param { boolean } [ multiselect ] whether it should be possible to select multiple files
* @ param { string [ ] } [ mimetype Filter ] mimetype to filter by - directories will always be included
* @ param { boolean } [ modal] make the dialog modal
* @ param { string [ ] } [ mimetype ] mimetype to filter by - directories will always be included
* @ param { boolean } [ _modal] do not use
* @ param { string } [ type ] Type of file picker : Choose , copy , move , copy and move
* @ param { string } [ path ] path to the folder that the the file can be picket from
* @ param { O bject} [ options ] additonal options that need to be set
* @ param { o bject} [ options ] additonal options that need to be set
* @ param { Function } [ options . filter ] filter function for advanced filtering
* @ param { boolean } [ options . allowDirectoryChooser ] Allow to select directories
* @ deprecated since 27.1 . 0 use the filepicker from ` @nextcloud/dialogs ` instead
* /
filepicker : function ( title , callback , multiselect , mimetypeFilter , modal , type , path , options ) {
var self = this
this . filepicker . sortField = 'name'
this . filepicker . sortOrder = 'asc'
// avoid opening the picker twice
if ( this . filepicker . loading ) {
return
}
if ( type === undefined ) {
type = this . FILEPICKER _TYPE _CHOOSE
}
var emptyText = t ( 'core' , 'No files in here' )
var newText = t ( 'files' , 'New folder' )
if ( type === this . FILEPICKER _TYPE _COPY || type === this . FILEPICKER _TYPE _MOVE || type === this . FILEPICKER _TYPE _COPY _MOVE ) {
emptyText = t ( 'core' , 'No more subfolders in here' )
}
this . filepicker . loading = true
this . filepicker . filesClient = ( OCA . Sharing && OCA . Sharing . PublicApp && OCA . Sharing . PublicApp . fileList ) ? OCA . Sharing . PublicApp . fileList . filesClient : OC . Files . getClient ( )
this . filelist = null
path = path || ''
options = Object . assign ( {
allowDirectoryChooser : false
} , options )
$ . when ( this . _getFilePickerTemplate ( ) ) . then ( function ( $tmpl ) {
self . filepicker . loading = false
var dialogName = 'oc-dialog-filepicker-content'
if ( self . $filePicker ) {
self . $filePicker . ocdialog ( 'close' )
}
if ( mimetypeFilter === undefined || mimetypeFilter === null ) {
mimetypeFilter = [ ]
}
if ( typeof ( mimetypeFilter ) === 'string' ) {
mimetypeFilter = [ mimetypeFilter ]
}
self . $filePicker = $tmpl . octemplate ( {
dialog _name : dialogName ,
title : title ,
emptytext : emptyText ,
newtext : newText ,
nameCol : t ( 'core' , 'Name' ) ,
sizeCol : t ( 'core' , 'Size' ) ,
modifiedCol : t ( 'core' , 'Modified' )
} ) . data ( 'path' , path ) . data ( 'multiselect' , multiselect ) . data ( 'mimetype' , mimetypeFilter ) . data ( 'allowDirectoryChooser' , options . allowDirectoryChooser )
if ( typeof ( options . filter ) === 'function' ) {
self . $filePicker . data ( 'filter' , options . filter )
}
if ( modal === undefined ) {
modal = false
}
if ( multiselect === undefined ) {
multiselect = false
}
filepicker ( title , callback , multiselect = false , mimetype = undefined , _modal = undefined , type = FilePickerType . Choose , path = undefined , options = undefined ) {
$ ( options ? . target ? ? 'body' ) . prepend ( self . $filePicker )
self . $showGridView = $ ( 'button#picker-showgridview' )
self . $showGridView . on ( 'click keydown' , function ( event ) {
if ( isA11yActivation ( event ) ) {
self . _onGridviewChange ( )
}
} )
self . _getGridSettings ( )
var newButton = self . $filePicker . find ( '.actions.creatable .button-add' )
if ( type === self . FILEPICKER _TYPE _CHOOSE && ! options . allowDirectoryChooser ) {
self . $filePicker . find ( '.actions.creatable' ) . hide ( )
}
newButton . on ( 'focus' , function ( ) {
self . $filePicker . ocdialog ( 'setEnterCallback' , function ( event ) {
event . stopImmediatePropagation ( )
event . preventDefault ( )
newButton . click ( )
} )
} )
newButton . on ( 'blur' , function ( ) {
self . $filePicker . ocdialog ( 'unsetEnterCallback' )
} )
OC . registerMenu ( newButton , self . $filePicker . find ( '.menu' ) , function ( ) {
$input . tooltip ( 'hide' )
$input . focus ( )
self . $filePicker . ocdialog ( 'setEnterCallback' , function ( event ) {
event . stopImmediatePropagation ( )
event . preventDefault ( )
self . $filePicker . submit ( )
} )
var newName = $input . val ( )
var lastPos = newName . lastIndexOf ( '.' )
if ( lastPos === - 1 ) {
lastPos = newName . length
}
$input . selectRange ( 0 , lastPos )
} )
var $form = self . $filePicker . find ( '.filenameform' )
var $input = $form . find ( 'input[type=\'text\']' )
var $submit = $form . find ( 'input[type=\'submit\']' )
$input . on ( 'keydown' , function ( event ) {
if ( isA11yActivation ( event ) ) {
event . stopImmediatePropagation ( )
event . preventDefault ( )
$form . submit ( )
}
} )
$submit . on ( 'click' , function ( event ) {
event . stopImmediatePropagation ( )
event . preventDefault ( )
$form . submit ( )
} )
/ * *
* Checks whether the given file name is valid .
*
* @ param name file name to check
* @ return true if the file name is valid .
* @ throws a string exception with an error message if
* the file name is not valid
*
* NOTE : This function is duplicated in the files app :
* https : //github.com/nextcloud/server/blob/b9bc2417e7a8dc81feb0abe20359bedaf864f790/apps/files/js/files.js#L127-L148
* /
var isFileNameValid = function ( name ) {
var trimmedName = name . trim ( ) ;
if ( trimmedName === '.' || trimmedName === '..' )
{
throw t ( 'files' , '"{name}" is an invalid file name.' , { name : name } )
} else if ( trimmedName . length === 0 ) {
throw t ( 'files' , 'File name cannot be empty.' )
} else if ( trimmedName . indexOf ( '/' ) !== - 1 ) {
throw t ( 'files' , '"/" is not allowed inside a file name.' )
} else if ( ! ! ( trimmedName . match ( OC . config . blacklist _files _regex ) ) ) {
throw t ( 'files' , '"{name}" is not an allowed filetype' , { name : name } )
/ * *
* Create legacy callback wrapper to support old filepicker syntax
* @ param fn The original callback
* @ param type The file picker type which was used to pick the file ( s )
* /
const legacyCallback = ( fn , type ) => {
const getPath = ( node ) => {
const root = node ? . root || ''
let path = node ? . path || ''
// TODO: Fix this in @nextcloud/files
if ( path . startsWith ( root ) ) {
path = path . slice ( root . length ) || '/'
}
return true
return path
}
var checkInput = function ( ) {
var filename = $input . val ( )
try {
if ( ! isFileNameValid ( filename ) ) {
// isFileNameValid(filename) throws an exception itself
} else if ( self . filelist . find ( function ( file ) {
return file . name === this
} , filename ) ) {
throw t ( 'files' , '{newName} already exists' , { newName : filename } , undefined , {
escape : false
} )
} else {
return true
}
} catch ( error ) {
$input . attr ( 'title' , error )
$input . tooltip ( {
placement : 'right' ,
trigger : 'manual' ,
'container' : '.newFolderMenu'
} )
$input . tooltip ( '_fixTitle' )
$input . tooltip ( 'show' )
$input . addClass ( 'error' )
}
return false
if ( multiselect ) {
return ( nodes ) => fn ( nodes . map ( getPath ) , type )
} else {
return ( nodes ) => fn ( getPath ( nodes [ 0 ] ) , type )
}
}
$form . on ( 'submit' , function ( event ) {
event . stopPropagation ( )
event . preventDefault ( )
/ * *
* Coverting a Node into a legacy file info to support the OC . dialogs . filepicker filter function
* @ param node The node to convert
* /
const nodeToLegacyFile = ( node ) => ( {
id : node . fileid || null ,
path : node . path ,
mimetype : node . mime || null ,
mtime : node . mtime ? . getTime ( ) || null ,
permissions : node . permissions ,
name : node . attributes ? . displayname || node . basename ,
etag : node . attributes ? . etag || null ,
hasPreview : node . attributes ? . hasPreview || null ,
mountType : node . attributes ? . mountType || null ,
quotaAvailableBytes : node . attributes ? . quotaAvailableBytes || null ,
icon : null ,
sharePermissions : null ,
} )
if ( checkInput ( ) ) {
var newname = $input . val ( )
self . filepicker . filesClient . createDirectory ( self . $filePicker . data ( 'path' ) + "/" + newname ) . always ( function ( status ) {
self . _fillFilePicker ( self . $filePicker . data ( 'path' ) + "/" + newname , type )
} )
OC . hideMenus ( )
self . $filePicker . ocdialog ( 'unsetEnterCallback' )
self . $filePicker . click ( )
$input . val ( newText )
}
const buttons = [ ]
if ( type === FilePickerType . Choose ) {
buttons . push ( {
label : t ( 'core' , 'Choose' ) ,
type : 'primary' ,
callback : legacyCallback ( callback , FilePickerType . Choose ) ,
} )
$input . on ( 'input' , function ( event ) {
$input . tooltip ( 'hide' )
} else if ( type === FilePickerType . Copy || type === FilePickerType . CopyMove ) {
buttons . push ( {
label : t ( 'core' , 'Copy' ) ,
callback : legacyCallback ( callback , FilePickerType . Copy ) ,
} )
self . $filePicker . ready ( function ( ) {
self . $fileListHeader = self . $filePicker . find ( '.filelist thead tr' )
self . $filelist = self . $filePicker . find ( '.filelist tbody' )
self . $filelistContainer = self . $filePicker . find ( '.filelist-container' )
self . $dirTree = self . $filePicker . find ( '.dirtree' )
self . $dirTree . on ( 'click keydown' , '.crumb' , self , function ( event ) {
if ( isA11yActivation ( event ) ) {
self . _handleTreeListSelect ( event , type )
}
} )
self . $filelist . on ( 'click keydown' , 'tr' , function ( event ) {
if ( isA11yActivation ( event ) ) {
self . _handlePickerClick ( event , $ ( this ) , type )
}
} )
self . $fileListHeader . on ( 'click keydown' , 'a' , function ( event ) {
if ( isA11yActivation ( event ) ) {
var dir = self . $filePicker . data ( 'path' )
self . filepicker . sortField = $ ( event . currentTarget ) . data ( 'sort' )
self . filepicker . sortOrder = self . filepicker . sortOrder === 'asc' ? 'desc' : 'asc'
self . _fillFilePicker ( dir , type )
}
}
if ( type === FilePickerType . CopyMove || type === FilePickerType . Move ) {
buttons . push ( {
label : t ( 'core' , 'Move' ) ,
type : 'primary' ,
callback : legacyCallback ( callback , FilePickerType . Move ) ,
} )
}
if ( type === FilePickerType . Custom ) {
( options . buttons || [ ] ) . forEach ( ( button ) => {
buttons . push ( {
callback : legacyCallback ( callback , button . type ) ,
label : button . text ,
type : button . defaultButton ? 'primary' : 'secondary' ,
} )
self . _fillFilePicker ( path , type )
} )
}
// build buttons
var functionToCall = function ( returnType ) {
if ( callback !== undefined ) {
var datapath
if ( multiselect === true ) {
datapath = [ ]
self . $filelist . find ( 'tr.filepicker_element_selected' ) . each ( function ( index , element ) {
datapath . push ( self . $filePicker . data ( 'path' ) + '/' + $ ( element ) . data ( 'entryname' ) )
} )
} else {
datapath = self . $filePicker . data ( 'path' )
var selectedName = self . $filelist . find ( 'tr.filepicker_element_selected' ) . data ( 'entryname' )
if ( selectedName ) {
datapath += '/' + selectedName
}
}
callback ( datapath , returnType )
self . $filePicker . ocdialog ( 'close' )
}
}
var chooseCallback = function ( ) {
functionToCall ( Dialogs . FILEPICKER _TYPE _CHOOSE )
}
var copyCallback = function ( ) {
functionToCall ( Dialogs . FILEPICKER _TYPE _COPY )
}
var moveCallback = function ( ) {
functionToCall ( Dialogs . FILEPICKER _TYPE _MOVE )
}
var buttonlist = [ ]
if ( type === Dialogs . FILEPICKER _TYPE _CHOOSE ) {
buttonlist . push ( {
text : t ( 'core' , 'Choose' ) ,
click : chooseCallback ,
defaultButton : true
} )
} else if ( type === Dialogs . FILEPICKER _TYPE _CUSTOM ) {
options . buttons . forEach ( function ( button ) {
buttonlist . push ( {
text : button . text ,
click : function ( ) {
functionToCall ( button . type )
} ,
defaultButton : button . defaultButton
} )
} )
} else {
if ( type === Dialogs . FILEPICKER _TYPE _COPY || type === Dialogs . FILEPICKER _TYPE _COPY _MOVE ) {
buttonlist . push ( {
text : t ( 'core' , 'Copy' ) ,
click : copyCallback ,
defaultButton : false
} )
}
if ( type === Dialogs . FILEPICKER _TYPE _MOVE || type === Dialogs . FILEPICKER _TYPE _COPY _MOVE ) {
buttonlist . push ( {
text : t ( 'core' , 'Move' ) ,
click : moveCallback ,
defaultButton : true
} )
}
}
const filter = { }
if ( typeof options ? . filter === 'function' ) {
filter . filterFn = ( node ) => options . filter ( nodeToLegacyFile ( node ) )
}
self . $filePicker . ocdialog ( {
closeOnEscape : true ,
// max-width of 600
width : 600 ,
height : 500 ,
modal : modal ,
buttons : buttonlist ,
style : {
buttons : 'aside'
} ,
close : function ( ) {
try {
$ ( this ) . ocdialog ( 'destroy' ) . remove ( )
} catch ( e ) {
}
self . $filePicker = null
}
} )
const mimetypeFilter = typeof mimetype === 'string' ? [ mimetype ] : ( mimetype || [ ] )
// We can access primary class only from oc-dialog.
// Hence this is one of the approach to get the choose button.
var getOcDialog = self . $filePicker . closest ( '.oc-dialog' )
var buttonEnableDisable = getOcDialog . find ( '.primary' )
if ( self . $filePicker . data ( 'mimetype' ) . indexOf ( 'httpd/unix-directory' ) !== - 1 || self . $filePicker . data ( 'allowDirectoryChooser' ) ) {
buttonEnableDisable . prop ( 'disabled' , false )
} else {
buttonEnableDisable . prop ( 'disabled' , true )
}
spawnDialog ( FilePickerVue , {
... filter ,
name : title ,
buttons ,
multiselect ,
path ,
mimetypeFilter ,
allowPickDirectory : options ? . allowDirectoryChooser === true || mimetypeFilter . includes ( 'httpd/unix-directory' ) ,
} )
. fail ( function ( status , error ) {
// If the method is called while navigating away
// from the page, it is probably not needed ;)
self . filepicker . loading = false
if ( status !== 0 ) {
alert ( t ( 'core' , 'Error loading file picker template: {error}' , { error : error } ) )
}
} )
} ,
/ * *
* Displays raw dialog
* You better use a wrapper instead ...
@ -1038,52 +815,7 @@ const Dialogs = {
// }
return dialogDeferred . promise ( )
} ,
// get the gridview setting and set the input accordingly
_getGridSettings : function ( ) {
const self = this
$ . get ( OC . generateUrl ( '/apps/files/api/v1/showgridview' ) , function ( response ) {
self . $showGridView
. removeClass ( 'icon-toggle-filelist icon-toggle-pictures' )
. addClass ( response . gridview ? 'icon-toggle-filelist' : 'icon-toggle-pictures' )
self . $showGridView . attr (
'aria-label' ,
response . gridview ? t ( 'files' , 'Show list view' ) : t ( 'files' , 'Show grid view' ) ,
)
$ ( '.list-container' ) . toggleClass ( 'view-grid' , response . gridview )
} )
} ,
_onGridviewChange : function ( ) {
const isGridView = this . $showGridView . hasClass ( 'icon-toggle-filelist' )
// only save state if user is logged in
if ( OC . currentUser ) {
$ . post ( OC . generateUrl ( '/apps/files/api/v1/showgridview' ) , { show : ! isGridView } )
}
this . $showGridView
. removeClass ( 'icon-toggle-filelist icon-toggle-pictures' )
. addClass ( isGridView ? 'icon-toggle-pictures' : 'icon-toggle-filelist' )
this . $showGridView . attr (
'aria-label' ,
isGridView ? t ( 'files' , 'Show grid view' ) : t ( 'files' , 'Show list view' ) ,
)
this . $filePicker . find ( '.list-container' ) . toggleClass ( 'view-grid' , ! isGridView )
} ,
_getFilePickerTemplate : function ( ) {
var defer = $ . Deferred ( )
if ( ! this . $filePickerTemplate ) {
var self = this
$ . get ( OC . filePath ( 'core' , 'templates' , 'filepicker.html' ) , function ( tmpl ) {
self . $filePickerTemplate = $ ( tmpl )
self . $listTmpl = self . $filePickerTemplate . find ( '.filelist tbody tr:first-child' ) . detach ( )
defer . resolve ( self . $filePickerTemplate )
} )
. fail ( function ( jqXHR , textStatus , errorThrown ) {
defer . reject ( jqXHR . status , errorThrown )
} )
} else {
defer . resolve ( this . $filePickerTemplate )
}
return defer . promise ( )
} ,
_getMessageTemplate : function ( ) {
var defer = $ . Deferred ( )
if ( ! this . $messageTemplate ) {
@ -1116,274 +848,6 @@ const Dialogs = {
}
return defer . promise ( )
} ,
/ * *
* fills the filepicker with files
* /
_fillFilePicker : async function ( dir , type ) {
var self = this
this . $filelist . empty ( )
this . $filePicker . find ( '.emptycontent' ) . hide ( )
this . $filelistContainer . addClass ( 'icon-loading' )
this . $filePicker . data ( 'path' , dir )
var filter = this . $filePicker . data ( 'mimetype' )
var advancedFilter = this . $filePicker . data ( 'filter' )
if ( typeof ( filter ) === 'string' ) {
filter = [ filter ]
}
self . $fileListHeader . find ( '.sort-indicator' ) . addClass ( 'hidden' ) . removeClass ( 'icon-triangle-n' ) . removeClass ( 'icon-triangle-s' )
self . $fileListHeader . find ( '[data-sort=' + self . filepicker . sortField + '] .sort-indicator' ) . removeClass ( 'hidden' )
if ( self . filepicker . sortOrder === 'asc' ) {
self . $fileListHeader . find ( '[data-sort=' + self . filepicker . sortField + '] .sort-indicator' ) . addClass ( 'icon-triangle-n' )
} else {
self . $fileListHeader . find ( '[data-sort=' + self . filepicker . sortField + '] .sort-indicator' ) . addClass ( 'icon-triangle-s' )
}
// Wrap within a method because a promise cannot return multiple values
// But the client impleemntation still does it...
var getFolderContents = async function ( dir ) {
return self . filepicker . filesClient . getFolderContents ( dir )
. then ( ( status , files ) => {
return files
} )
}
try {
var files = await getFolderContents ( dir )
} catch ( error ) {
// fallback to root if requested dir is non-existent
console . error ( 'Requested path does not exists, falling back to root' )
var files = await getFolderContents ( '/' )
this . $filePicker . data ( 'path' , '/' )
this . _changeButtonsText ( type , '' )
}
self . filelist = files
if ( filter && filter . length > 0 && filter . indexOf ( '*' ) === - 1 ) {
files = files . filter ( function ( file ) {
return file . type === 'dir' || filter . indexOf ( file . mimetype ) !== - 1
} )
}
if ( advancedFilter ) {
files = files . filter ( advancedFilter )
}
// Check if the showHidden input field exist and if it exist follow it
// Otherwise just show the hidden files
const showHiddenInput = document . getElementById ( 'showHiddenFiles' )
if ( showHiddenInput ? . value !== "1" ) {
files = files . filter ( function ( file ) {
return ! file . name . startsWith ( '.' )
} )
}
var Comparators = {
name : function ( fileInfo1 , fileInfo2 ) {
if ( fileInfo1 . type === 'dir' && fileInfo2 . type !== 'dir' ) {
return - 1
}
if ( fileInfo1 . type !== 'dir' && fileInfo2 . type === 'dir' ) {
return 1
}
return OC . Util . naturalSortCompare ( fileInfo1 . name , fileInfo2 . name )
} ,
size : function ( fileInfo1 , fileInfo2 ) {
return fileInfo1 . size - fileInfo2 . size
} ,
mtime : function ( fileInfo1 , fileInfo2 ) {
return fileInfo1 . mtime - fileInfo2 . mtime
}
}
var comparator = Comparators [ self . filepicker . sortField ] || Comparators . name
files = files . sort ( function ( file1 , file2 ) {
var isFavorite = function ( fileInfo ) {
return fileInfo . tags && fileInfo . tags . indexOf ( OC . TAG _FAVORITE ) >= 0
}
if ( isFavorite ( file1 ) && ! isFavorite ( file2 ) ) {
return - 1
} else if ( ! isFavorite ( file1 ) && isFavorite ( file2 ) ) {
return 1
}
return self . filepicker . sortOrder === 'asc' ? comparator ( file1 , file2 ) : - comparator ( file1 , file2 )
} )
self . _fillSlug ( )
if ( files . length === 0 ) {
self . $filePicker . find ( '.emptycontent' ) . show ( )
self . $fileListHeader . hide ( )
} else {
self . $filePicker . find ( '.emptycontent' ) . hide ( )
self . $fileListHeader . show ( )
}
self . $filelist . empty ( ) ;
$ . each ( files , function ( idx , entry ) {
if ( entry . isEncrypted && entry . mimetype === 'httpd/unix-directory' ) {
entry . icon = OC . MimeType . getIconUrl ( 'dir-encrypted' )
} else {
entry . icon = OC . MimeType . getIconUrl ( entry . mimetype )
}
var simpleSize , sizeColor
if ( typeof ( entry . size ) !== 'undefined' && entry . size >= 0 ) {
simpleSize = OC . Util . humanFileSize ( parseInt ( entry . size , 10 ) , true )
sizeColor = Math . round ( 160 - Math . pow ( ( entry . size / ( 1024 * 1024 ) ) , 2 ) )
} else {
simpleSize = t ( 'files' , 'Pending' )
sizeColor = 80
}
// split the filename in half if the size is bigger than 20 char
// for ellipsis
if ( entry . name . length >= 10 ) {
// leave maximum 10 letters
var split = Math . min ( Math . floor ( entry . name . length / 2 ) , 10 )
var filename1 = entry . name . substr ( 0 , entry . name . length - split )
var filename2 = entry . name . substr ( entry . name . length - split )
} else {
var filename1 = entry . name
var filename2 = ''
}
var $row = self . $listTmpl . octemplate ( {
type : entry . type ,
dir : dir ,
filename : entry . name ,
filename1 : filename1 ,
filename2 : filename2 ,
date : OC . Util . relativeModifiedDate ( entry . mtime ) ,
size : simpleSize ,
sizeColor : sizeColor ,
icon : entry . icon
} )
if ( entry . type === 'file' ) {
var urlSpec = {
file : dir + '/' + entry . name ,
x : 100 ,
y : 100
}
var img = new Image ( )
var previewUrl = OC . generateUrl ( '/core/preview.png?' ) + $ . param ( urlSpec )
img . onload = function ( ) {
if ( img . width > 5 ) {
$row . find ( 'td.filename' ) . attr ( 'style' , 'background-image:url(' + previewUrl + ')' )
}
}
img . src = previewUrl
}
self . $filelist . append ( $row )
} )
self . $filelistContainer . removeClass ( 'icon-loading' )
} ,
/ * *
* fills the tree list with directories
* /
_fillSlug : function ( ) {
var addButton = this . $dirTree . find ( '.actions.creatable' ) . detach ( )
this . $dirTree . empty ( )
var self = this
self . $dirTree . append ( '<nav></nav>' )
self . $dirTree . append ( addButton )
var dir
var path = this . $filePicker . data ( 'path' )
var $template = $ ( '<li data-dir="{dir}" tabindex="0"><a class="{classList}">{name}</a></li>' ) . addClass ( 'crumb' )
var $breadcrumbs = $ ( '<ul class="breadcrumb"></ul>' )
if ( path ) {
var paths = path . split ( '/' )
$ . each ( paths , function ( index , dir ) {
dir = paths . pop ( )
if ( dir === '' ) {
return false
}
$breadcrumbs . prepend ( $template . octemplate ( {
dir : paths . join ( '/' ) + '/' + dir ,
name : dir
} ) )
} )
}
$template . octemplate ( {
dir : '' ,
name : t ( 'core' , 'Home' ) ,
classList : 'icon-home'
} , { escapeFunction : null } ) . addClass ( 'crumb svg crumbhome' ) . prependTo ( $breadcrumbs )
this . $dirTree . find ( '> nav' ) . prepend ( $breadcrumbs )
} ,
/ * *
* handle selection made in the tree list
* /
_handleTreeListSelect : function ( event , type ) {
var self = event . data
var dir = $ ( event . target ) . closest ( '.crumb' ) . data ( 'dir' )
self . _fillFilePicker ( dir , type )
var getOcDialog = ( event . target ) . closest ( '.oc-dialog' )
var buttonEnableDisable = $ ( '.primary' , getOcDialog )
this . _changeButtonsText ( type , dir . split ( /[/]+/ ) . pop ( ) )
if ( this . $filePicker . data ( 'mimetype' ) . indexOf ( 'httpd/unix-directory' ) !== - 1 || this . $filePicker . data ( 'allowDirectoryChooser' ) ) {
buttonEnableDisable . prop ( 'disabled' , false )
} else {
buttonEnableDisable . prop ( 'disabled' , true )
}
} ,
/ * *
* handle clicks made in the filepicker
* /
_handlePickerClick : function ( event , $element , type ) {
var getOcDialog = this . $filePicker . closest ( '.oc-dialog' )
var buttonEnableDisable = getOcDialog . find ( '.primary' )
if ( $element . data ( 'type' ) === 'file' ) {
if ( this . $filePicker . data ( 'multiselect' ) !== true || ! event . ctrlKey ) {
this . $filelist . find ( '.filepicker_element_selected' ) . removeClass ( 'filepicker_element_selected' )
}
$element . toggleClass ( 'filepicker_element_selected' )
buttonEnableDisable . prop ( 'disabled' , false )
} else if ( $element . data ( 'type' ) === 'dir' ) {
this . _fillFilePicker ( this . $filePicker . data ( 'path' ) + '/' + $element . data ( 'entryname' ) , type )
this . _changeButtonsText ( type , $element . data ( 'entryname' ) )
if ( this . $filePicker . data ( 'mimetype' ) . indexOf ( 'httpd/unix-directory' ) !== - 1 || this . $filePicker . data ( 'allowDirectoryChooser' ) ) {
buttonEnableDisable . prop ( 'disabled' , false )
} else {
buttonEnableDisable . prop ( 'disabled' , true )
}
}
} ,
/ * *
* Handle
* @ param type of action
* @ param dir on which to change buttons text
* @ private
* /
_changeButtonsText : function ( type , dir ) {
var copyText = dir === '' ? t ( 'core' , 'Copy' ) : t ( 'core' , 'Copy to {folder}' , { folder : dir } )
var moveText = dir === '' ? t ( 'core' , 'Move' ) : t ( 'core' , 'Move to {folder}' , { folder : dir } )
var buttons = $ ( '.oc-dialog-buttonrow button' )
switch ( type ) {
case this . FILEPICKER _TYPE _CHOOSE :
break
case this . FILEPICKER _TYPE _CUSTOM :
break
case this . FILEPICKER _TYPE _COPY :
buttons . text ( copyText )
break
case this . FILEPICKER _TYPE _MOVE :
buttons . text ( moveText )
break
case this . FILEPICKER _TYPE _COPY _MOVE :
buttons . eq ( 0 ) . text ( copyText )
buttons . eq ( 1 ) . text ( moveText )
break
}
}
}
export default Dialogs