1 |
- {"version":3,"mappings":"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","names":["canUnshareOnly","nodes","node","canDisconnectOnly","isMixedUnshareAndDelete","hasSharedItems","hasDeleteItems","isAllFiles","FileType","isAllFolders","displayName","view","t","queue","PQueue","action","FileAction","CloseSvg","NetworkOffSvg","TrashCanSvg","permission","Permission","dir","axios","emit","error","logger","resolve","decision","showInfo","promises","result","triggerDownload","url","hiddenElement","downloadNodes","secret","generateUrl","isDownloadable","_a","_b","shareAttributes","downloadAttribute","attribute","ArrowDownSvg","openLocalClient","path","link","generateOcsUrl","uid","getCurrentUser","encodePath","showError","LaptopSvg","shouldFavorite","favoriteNode","willFavorite","Vue","StarOutlineSvg","StarSvg","files","FolderSvg","DefaultType","PencilSvg","FolderMoveSvg","_sfc_main","defineComponent","NcButton","NcDialog","NcTextField","name","getUniqueName","state","newNodeName","defaultName","folderContent","labels","contentNames","spawnDialog","NewNodeDialog","folderName","createNewFolder","root","source","encodedSource","response","entry","context","FolderPlusSvg","content","_c","_d","_e","fileid","folder","Folder","showSuccess","basename","templatesPath","loadState","initTemplatesFolder","directory","templatePath","join","data","PlusSvg","removeNewFileMenuEntry","TemplatePickerVue","defineAsyncComponent","__vitePreload","TemplatePicker","getTemplatePicker","mountingPoint","h","args","registerTemplateEntries","provider","index","addNewFileMenuEntry","templatePicker","getContents","filesContents","CancelablePromise","reject","cancel","promise","getFavoriteNodes","client","contents","davRemoteURL","davRootPath","generateFavoriteFolderView","View","generateIdFromPath","registerFavoritesView","favoriteFolders","favoriteFoldersViews","Navigation","getNavigation","subscribe","addToFavorites","removePathFromFavorites","updateAndSortViews","a","b","getLanguage","newFavoriteFolder","id","lastTwoWeeksTimestamp","store","useUserConfigStore","pinia","filterHidden","controller","handler","davGetRecentSearch","resultToNode","registerRecentView","HistorySvg","currentUserId","isPersonalFile","sharedMountTypes","mountType","getFiles","registerPersonalFilesView","AccountIcon","registerFilesView","registerPreviewServiceWorker","registration","registerFileAction","deleteAction","downloadAction","editLocallyAction","favoriteAction","moveOrCopyAction","openFolderAction","openInFilesAction","renameAction","sidebarAction","viewInFolderAction","newFolderEntry","newTemplatesFolder","registerDavProperty","initLivePhotos"],"ignoreList":[],"sources":["../apps/files/src/actions/deleteAction.ts","../apps/files/src/actions/downloadAction.ts","../apps/files/src/actions/editLocallyAction.ts","../apps/files/src/actions/favoriteAction.ts","../apps/files/src/actions/openFolderAction.ts","../apps/files/src/actions/openInFilesAction.ts","../apps/files/src/actions/renameAction.ts","../apps/files/src/actions/viewInFolderAction.ts","../apps/files/src/components/NewNodeDialog.vue","../apps/files/src/utils/newNodeDialog.ts","../apps/files/src/newMenu/newFolder.ts","../apps/files/src/newMenu/newTemplatesFolder.ts","../apps/files/src/newMenu/newFromTemplate.ts","../apps/files/src/services/Favorites.ts","../apps/files/src/views/favorites.ts","../apps/files/src/services/Recent.ts","../apps/files/src/views/recent.ts","../apps/files/src/services/PersonalFiles.ts","../apps/files/src/views/personal-files.ts","../apps/files/src/views/files.ts","../apps/files/src/services/ServiceWorker.js","../apps/files/src/init.ts"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { emit } from '@nextcloud/event-bus'\nimport { Permission, Node, View, FileAction, FileType } from '@nextcloud/files'\nimport { showInfo } from '@nextcloud/dialogs'\nimport { translate as t } from '@nextcloud/l10n'\nimport axios from '@nextcloud/axios'\n\nimport CloseSvg from '@mdi/svg/svg/close.svg?raw'\nimport NetworkOffSvg from '@mdi/svg/svg/network-off.svg?raw'\nimport TrashCanSvg from '@mdi/svg/svg/trash-can.svg?raw'\n\nimport logger from '../logger.js'\nimport PQueue from 'p-queue'\n\nconst canUnshareOnly = (nodes: Node[]) => {\n\treturn nodes.every(node => node.attributes['is-mount-root'] === true\n\t\t&& node.attributes['mount-type'] === 'shared')\n}\n\nconst canDisconnectOnly = (nodes: Node[]) => {\n\treturn nodes.every(node => node.attributes['is-mount-root'] === true\n\t\t&& node.attributes['mount-type'] === 'external')\n}\n\nconst isMixedUnshareAndDelete = (nodes: Node[]) => {\n\tif (nodes.length === 1) {\n\t\treturn false\n\t}\n\n\tconst hasSharedItems = nodes.some(node => canUnshareOnly([node]))\n\tconst hasDeleteItems = nodes.some(node => !canUnshareOnly([node]))\n\treturn hasSharedItems && hasDeleteItems\n}\n\nconst isAllFiles = (nodes: Node[]) => {\n\treturn !nodes.some(node => node.type !== FileType.File)\n}\n\nconst isAllFolders = (nodes: Node[]) => {\n\treturn !nodes.some(node => node.type !== FileType.Folder)\n}\n\nconst displayName = (nodes: Node[], view: View) => {\n\t/**\n\t * If we're in the trashbin, we can only delete permanently\n\t */\n\tif (view.id === 'trashbin') {\n\t\treturn t('files', 'Delete permanently')\n\t}\n\n\t/**\n\t * If we're in the sharing view, we can only unshare\n\t */\n\tif (isMixedUnshareAndDelete(nodes)) {\n\t\treturn t('files', 'Delete and unshare')\n\t}\n\n\t/**\n\t * If those nodes are all the root node of a\n\t * share, we can only unshare them.\n\t */\n\tif (canUnshareOnly(nodes)) {\n\t\tif (nodes.length === 1) {\n\t\t\treturn t('files', 'Leave this share')\n\t\t}\n\t\treturn t('files', 'Leave these shares')\n\t}\n\n\t/**\n\t * If those nodes are all the root node of an\n\t * external storage, we can only disconnect it.\n\t */\n\tif (canDisconnectOnly(nodes)) {\n\t\tif (nodes.length === 1) {\n\t\t\treturn t('files', 'Disconnect storage')\n\t\t}\n\t\treturn t('files', 'Disconnect storages')\n\t}\n\n\t/**\n\t * If we're only selecting files, use proper wording\n\t */\n\tif (isAllFiles(nodes)) {\n\t\tif (nodes.length === 1) {\n\t\t\treturn t('files', 'Delete file')\n\t\t}\n\t\treturn t('files', 'Delete files')\n\t}\n\n\t/**\n\t * If we're only selecting folders, use proper wording\n\t */\n\tif (isAllFolders(nodes)) {\n\t\tif (nodes.length === 1) {\n\t\t\treturn t('files', 'Delete folder')\n\t\t}\n\t\treturn t('files', 'Delete folders')\n\t}\n\n\treturn t('files', 'Delete')\n}\n\nconst queue = new PQueue({ concurrency: 5 })\n\nexport const action = new FileAction({\n\tid: 'delete',\n\tdisplayName,\n\ticonSvgInline: (nodes: Node[]) => {\n\t\tif (canUnshareOnly(nodes)) {\n\t\t\treturn CloseSvg\n\t\t}\n\n\t\tif (canDisconnectOnly(nodes)) {\n\t\t\treturn NetworkOffSvg\n\t\t}\n\n\t\treturn TrashCanSvg\n\t},\n\n\tenabled(nodes: Node[]) {\n\t\treturn nodes.length > 0 && nodes\n\t\t\t.map(node => node.permissions)\n\t\t\t.every(permission => (permission & Permission.DELETE) !== 0)\n\t},\n\n\tasync exec(node: Node, view: View, dir: string) {\n\t\ttry {\n\t\t\tawait axios.delete(node.encodedSource)\n\n\t\t\t// Let's delete even if it's moved to the trashbin\n\t\t\t// since it has been removed from the current view\n\t\t\t// and changing the view will trigger a reload anyway.\n\t\t\temit('files:node:deleted', node)\n\n\t\t\treturn true\n\t\t} catch (error) {\n\t\t\tlogger.error('Error while deleting a file', { error, source: node.source, node })\n\t\t\treturn false\n\t\t}\n\t},\n\n\tasync execBatch(nodes: Node[], view: View, dir: string): Promise<(boolean | null)[]> {\n\t\tconst confirm = await new Promise<boolean>(resolve => {\n\t\t\tif (nodes.length >= 5 && !canUnshareOnly(nodes) && !canDisconnectOnly(nodes)) {\n\t\t\t\t// TODO use a proper dialog from @nextcloud/dialogs when available\n\t\t\t\twindow.OC.dialogs.confirmDestructive(\n\t\t\t\t\tt('files', 'You are about to delete {count} items.', { count: nodes.length }),\n\t\t\t\t\tt('files', 'Confirm deletion'),\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: window.OC.dialogs.YES_NO_BUTTONS,\n\t\t\t\t\t\tconfirm: displayName(nodes, view),\n\t\t\t\t\t\tconfirmClasses: 'error',\n\t\t\t\t\t\tcancel: t('files', 'Cancel'),\n\t\t\t\t\t},\n\t\t\t\t\t(decision: boolean) => {\n\t\t\t\t\t\tresolve(decision)\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tresolve(true)\n\t\t})\n\n\t\t// If the user cancels the deletion, we don't want to do anything\n\t\tif (confirm === false) {\n\t\t\tshowInfo(t('files', 'Deletion cancelled'))\n\t\t\treturn Promise.all(nodes.map(() => false))\n\t\t}\n\n\t\t// Map each node to a promise that resolves with the result of exec(node)\n\t\tconst promises = nodes.map(node => {\n\t\t // Create a promise that resolves with the result of exec(node)\n\t\t const promise = new Promise<boolean>(resolve => {\n\t\t\t\tqueue.add(async () => {\n\t\t\t\t\tconst result = await this.exec(node, view, dir)\n\t\t\t\t\tresolve(result !== null ? result : false)\n\t\t\t\t})\n\t\t\t})\n\t\t\treturn promise\n\t\t})\n\n\t\treturn Promise.all(promises)\n\t},\n\n\torder: 100,\n})\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { generateUrl } from '@nextcloud/router'\nimport { FileAction, Permission, Node, FileType, View } from '@nextcloud/files'\nimport { translate as t } from '@nextcloud/l10n'\nimport ArrowDownSvg from '@mdi/svg/svg/arrow-down.svg?raw'\n\nconst triggerDownload = function(url: string) {\n\tconst hiddenElement = document.createElement('a')\n\thiddenElement.download = ''\n\thiddenElement.href = url\n\thiddenElement.click()\n}\n\nconst downloadNodes = function(dir: string, nodes: Node[]) {\n\tconst secret = Math.random().toString(36).substring(2)\n\tconst url = generateUrl('/apps/files/ajax/download.php?dir={dir}&files={files}&downloadStartSecret={secret}', {\n\t\tdir,\n\t\tsecret,\n\t\tfiles: JSON.stringify(nodes.map(node => node.basename)),\n\t})\n\ttriggerDownload(url)\n}\n\nconst isDownloadable = function(node: Node) {\n\tif ((node.permissions & Permission.READ) === 0) {\n\t\treturn false\n\t}\n\n\t// If the mount type is a share, ensure it got download permissions.\n\tif (node.attributes['mount-type'] === 'shared') {\n\t\tconst shareAttributes = JSON.parse(node.attributes['share-attributes'] ?? 'null')\n\t\tconst downloadAttribute = shareAttributes?.find?.((attribute: { scope: string; key: string }) => attribute.scope === 'permissions' && attribute.key === 'download')\n\t\tif (downloadAttribute !== undefined && downloadAttribute.enabled === false) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nexport const action = new FileAction({\n\tid: 'download',\n\tdisplayName: () => t('files', 'Download'),\n\ticonSvgInline: () => ArrowDownSvg,\n\n\tenabled(nodes: Node[]) {\n\t\tif (nodes.length === 0) {\n\t\t\treturn false\n\t\t}\n\n\t\t// We can download direct dav files. But if we have\n\t\t// some folders, we need to use the /apps/files/ajax/download.php\n\t\t// endpoint, which only supports user root folder.\n\t\tif (nodes.some(node => node.type === FileType.Folder)\n\t\t\t&& nodes.some(node => !node.root?.startsWith('/files'))) {\n\t\t\treturn false\n\t\t}\n\n\t\treturn nodes.every(isDownloadable)\n\t},\n\n\tasync exec(node: Node, view: View, dir: string) {\n\t\tif (node.type === FileType.Folder) {\n\t\t\tdownloadNodes(dir, [node])\n\t\t\treturn null\n\t\t}\n\n\t\ttriggerDownload(node.encodedSource)\n\t\treturn null\n\t},\n\n\tasync execBatch(nodes: Node[], view: View, dir: string) {\n\t\tif (nodes.length === 1) {\n\t\t\tthis.exec(nodes[0], view, dir)\n\t\t\treturn [null]\n\t\t}\n\n\t\tdownloadNodes(dir, nodes)\n\t\treturn new Array(nodes.length).fill(null)\n\t},\n\n\torder: 30,\n})\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { encodePath } from '@nextcloud/paths'\nimport { generateOcsUrl } from '@nextcloud/router'\nimport { getCurrentUser } from '@nextcloud/auth'\nimport { FileAction, Permission, type Node } from '@nextcloud/files'\nimport { showError } from '@nextcloud/dialogs'\nimport { translate as t } from '@nextcloud/l10n'\nimport axios from '@nextcloud/axios'\n\nimport LaptopSvg from '@mdi/svg/svg/laptop.svg?raw'\n\nconst openLocalClient = async function(path: string) {\n\tconst link = generateOcsUrl('apps/files/api/v1') + '/openlocaleditor?format=json'\n\n\ttry {\n\t\tconst result = await axios.post(link, { path })\n\t\tconst uid = getCurrentUser()?.uid\n\t\tlet url = `nc://open/${uid}@` + window.location.host + encodePath(path)\n\t\turl += '?token=' + result.data.ocs.data.token\n\n\t\twindow.location.href = url\n\t} catch (error) {\n\t\tshowError(t('files', 'Failed to redirect to client'))\n\t}\n}\n\nexport const action = new FileAction({\n\tid: 'edit-locally',\n\tdisplayName: () => t('files', 'Edit locally'),\n\ticonSvgInline: () => LaptopSvg,\n\n\t// Only works on single files\n\tenabled(nodes: Node[]) {\n\t\t// Only works on single node\n\t\tif (nodes.length !== 1) {\n\t\t\treturn false\n\t\t}\n\n\t\treturn (nodes[0].permissions & Permission.UPDATE) !== 0\n\t},\n\n\tasync exec(node: Node) {\n\t\topenLocalClient(node.path)\n\t\treturn null\n\t},\n\n\torder: 25,\n})\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { emit } from '@nextcloud/event-bus'\nimport { generateUrl } from '@nextcloud/router'\nimport { Permission, type Node, View, FileAction } from '@nextcloud/files'\nimport { translate as t } from '@nextcloud/l10n'\nimport axios from '@nextcloud/axios'\nimport Vue from 'vue'\n\nimport StarOutlineSvg from '@mdi/svg/svg/star-outline.svg?raw'\nimport StarSvg from '@mdi/svg/svg/star.svg?raw'\n\nimport logger from '../logger.js'\nimport { encodePath } from '@nextcloud/paths'\n\n// If any of the nodes is not favorited, we display the favorite action.\nconst shouldFavorite = (nodes: Node[]): boolean => {\n\treturn nodes.some(node => node.attributes.favorite !== 1)\n}\n\nexport const favoriteNode = async (node: Node, view: View, willFavorite: boolean): Promise<boolean> => {\n\ttry {\n\t\t// TODO: migrate to webdav tags plugin\n\t\tconst url = generateUrl('/apps/files/api/v1/files') + encodePath(node.path)\n\t\tawait axios.post(url, {\n\t\t\ttags: willFavorite\n\t\t\t\t? [window.OC.TAG_FAVORITE]\n\t\t\t\t: [],\n\t\t})\n\n\t\t// Let's delete if we are in the favourites view\n\t\t// AND if it is removed from the user favorites\n\t\t// AND it's in the root of the favorites view\n\t\tif (view.id === 'favorites' && !willFavorite && node.dirname === '/') {\n\t\t\temit('files:node:deleted', node)\n\t\t}\n\n\t\t// Update the node webdav attribute\n\t\tVue.set(node.attributes, 'favorite', willFavorite ? 1 : 0)\n\n\t\t// Dispatch event to whoever is interested\n\t\tif (willFavorite) {\n\t\t\temit('files:favorites:added', node)\n\t\t} else {\n\t\t\temit('files:favorites:removed', node)\n\t\t}\n\n\t\treturn true\n\t} catch (error) {\n\t\tconst action = willFavorite ? 'adding a file to favourites' : 'removing a file from favourites'\n\t\tlogger.error('Error while ' + action, { error, source: node.source, node })\n\t\treturn false\n\t}\n}\n\nexport const action = new FileAction({\n\tid: 'favorite',\n\tdisplayName(nodes: Node[]) {\n\t\treturn shouldFavorite(nodes)\n\t\t\t? t('files', 'Add to favorites')\n\t\t\t: t('files', 'Remove from favorites')\n\t},\n\ticonSvgInline: (nodes: Node[]) => {\n\t\treturn shouldFavorite(nodes)\n\t\t\t? StarOutlineSvg\n\t\t\t: StarSvg\n\t},\n\n\tenabled(nodes: Node[]) {\n\t\t// We can only favorite nodes within files and with permissions\n\t\treturn !nodes.some(node => !node.root?.startsWith?.('/files'))\n\t\t\t&& nodes.every(node => node.permissions !== Permission.NONE)\n\t},\n\n\tasync exec(node: Node, view: View) {\n\t\tconst willFavorite = shouldFavorite([node])\n\t\treturn await favoriteNode(node, view, willFavorite)\n\t},\n\tasync execBatch(nodes: Node[], view: View) {\n\t\tconst willFavorite = shouldFavorite(nodes)\n\t\treturn Promise.all(nodes.map(async node => await favoriteNode(node, view, willFavorite)))\n\t},\n\n\torder: -50,\n})\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { Permission, Node, FileType, View, FileAction, DefaultType } from '@nextcloud/files'\nimport { translate as t } from '@nextcloud/l10n'\nimport FolderSvg from '@mdi/svg/svg/folder.svg?raw'\n\nexport const action = new FileAction({\n\tid: 'open-folder',\n\tdisplayName(files: Node[]) {\n\t\t// Only works on single node\n\t\tconst displayName = files[0].attributes.displayName || files[0].basename\n\t\treturn t('files', 'Open folder {displayName}', { displayName })\n\t},\n\ticonSvgInline: () => FolderSvg,\n\n\tenabled(nodes: Node[]) {\n\t\t// Only works on single node\n\t\tif (nodes.length !== 1) {\n\t\t\treturn false\n\t\t}\n\n\t\tconst node = nodes[0]\n\n\t\tif (!node.isDavRessource) {\n\t\t\treturn false\n\t\t}\n\n\t\treturn node.type === FileType.Folder\n\t\t\t&& (node.permissions & Permission.READ) !== 0\n\t},\n\n\tasync exec(node: Node, view: View) {\n\t\tif (!node || node.type !== FileType.Folder) {\n\t\t\treturn false\n\t\t}\n\n\t\twindow.OCP.Files.Router.goToRoute(\n\t\t\tnull,\n\t\t\t{ view: view.id, fileid: node.fileid },\n\t\t\t{ dir: node.path },\n\t\t)\n\t\treturn null\n\t},\n\n\t// Main action if enabled, meaning folders only\n\tdefault: DefaultType.HIDDEN,\n\torder: -100,\n})\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { translate as t } from '@nextcloud/l10n'\nimport { type Node, FileType, FileAction, DefaultType } from '@nextcloud/files'\n\n/**\n * TODO: Move away from a redirect and handle\n * navigation straight out of the recent view\n */\nexport const action = new FileAction({\n\tid: 'open-in-files-recent',\n\tdisplayName: () => t('files', 'Open in Files'),\n\ticonSvgInline: () => '',\n\n\tenabled: (nodes, view) => view.id === 'recent',\n\n\tasync exec(node: Node) {\n\t\tlet dir = node.dirname\n\t\tif (node.type === FileType.Folder) {\n\t\t\tdir = dir + '/' + node.basename\n\t\t}\n\n\t\twindow.OCP.Files.Router.goToRoute(\n\t\t\tnull, // use default route\n\t\t\t{ view: 'files', fileid: node.fileid },\n\t\t\t{ dir, openfile: 'true' },\n\t\t)\n\t\treturn null\n\t},\n\n\t// Before openFolderAction\n\torder: -1000,\n\tdefault: DefaultType.HIDDEN,\n})\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { emit } from '@nextcloud/event-bus'\nimport { Permission, type Node, FileAction } from '@nextcloud/files'\nimport { translate as t } from '@nextcloud/l10n'\nimport PencilSvg from '@mdi/svg/svg/pencil.svg?raw'\n\nexport const ACTION_DETAILS = 'details'\n\nexport const action = new FileAction({\n\tid: 'rename',\n\tdisplayName: () => t('files', 'Rename'),\n\ticonSvgInline: () => PencilSvg,\n\n\tenabled: (nodes: Node[]) => {\n\t\treturn nodes.length > 0 && nodes\n\t\t\t.map(node => node.permissions)\n\t\t\t.every(permission => (permission & Permission.UPDATE) !== 0)\n\t},\n\n\tasync exec(node: Node) {\n\t\t// Renaming is a built-in feature of the files app\n\t\temit('files:node:rename', node)\n\t\treturn null\n\t},\n\n\torder: 10,\n})\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { Node, FileType, Permission, View, FileAction } from '@nextcloud/files'\nimport { translate as t } from '@nextcloud/l10n'\nimport FolderMoveSvg from '@mdi/svg/svg/folder-move.svg?raw'\n\nexport const action = new FileAction({\n\tid: 'view-in-folder',\n\tdisplayName() {\n\t\treturn t('files', 'View in folder')\n\t},\n\ticonSvgInline: () => FolderMoveSvg,\n\n\tenabled(nodes: Node[], view: View) {\n\t\t// Only works outside of the main files view\n\t\tif (view.id === 'files') {\n\t\t\treturn false\n\t\t}\n\n\t\t// Only works on single node\n\t\tif (nodes.length !== 1) {\n\t\t\treturn false\n\t\t}\n\n\t\tconst node = nodes[0]\n\n\t\tif (!node.isDavRessource) {\n\t\t\treturn false\n\t\t}\n\n\t\tif (node.permissions === Permission.NONE) {\n\t\t\treturn false\n\t\t}\n\n\t\treturn node.type === FileType.File\n\t},\n\n\tasync exec(node: Node) {\n\t\tif (!node || node.type !== FileType.File) {\n\t\t\treturn false\n\t\t}\n\n\t\twindow.OCP.Files.Router.goToRoute(\n\t\t\tnull,\n\t\t\t{ view: 'files', fileid: node.fileid },\n\t\t\t{ dir: node.dirname },\n\t\t)\n\t\treturn null\n\t},\n\n\torder: 80,\n})\n","<!--\n - SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n-->\n<template>\n\t<NcDialog :name=\"name\"\n\t\t:open=\"open\"\n\t\tclose-on-click-outside\n\t\tout-transition\n\t\t@update:open=\"onClose\">\n\t\t<template #actions>\n\t\t\t<NcButton type=\"primary\"\n\t\t\t\t:disabled=\"!isUniqueName\"\n\t\t\t\t@click=\"onCreate\">\n\t\t\t\t{{ t('files', 'Create') }}\n\t\t\t</NcButton>\n\t\t</template>\n\t\t<form @submit.prevent=\"onCreate\">\n\t\t\t<NcTextField ref=\"input\"\n\t\t\t\t:error=\"!isUniqueName\"\n\t\t\t\t:helper-text=\"errorMessage\"\n\t\t\t\t:label=\"label\"\n\t\t\t\t:value.sync=\"localDefaultName\" />\n\t\t</form>\n\t</NcDialog>\n</template>\n\n<script lang=\"ts\">\nimport type { PropType } from 'vue'\n\nimport { defineComponent } from 'vue'\nimport { translate as t } from '@nextcloud/l10n'\nimport { getUniqueName } from '../utils/fileUtils'\n\nimport NcButton from '@nextcloud/vue/dist/Components/NcButton.js'\nimport NcDialog from '@nextcloud/vue/dist/Components/NcDialog.js'\nimport NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'\n\ninterface ICanFocus {\n\tfocus: () => void\n}\n\nexport default defineComponent({\n\tname: 'NewNodeDialog',\n\tcomponents: {\n\t\tNcButton,\n\t\tNcDialog,\n\t\tNcTextField,\n\t},\n\tprops: {\n\t\t/**\n\t\t * The name to be used by default\n\t\t */\n\t\tdefaultName: {\n\t\t\ttype: String,\n\t\t\tdefault: t('files', 'New folder'),\n\t\t},\n\t\t/**\n\t\t * Other files that are in the current directory\n\t\t */\n\t\totherNames: {\n\t\t\ttype: Array as PropType<string[]>,\n\t\t\tdefault: () => [],\n\t\t},\n\t\t/**\n\t\t * Open state of the dialog\n\t\t */\n\t\topen: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\t\t/**\n\t\t * Dialog name\n\t\t */\n\t\tname: {\n\t\t\ttype: String,\n\t\t\tdefault: t('files', 'Create new folder'),\n\t\t},\n\t\t/**\n\t\t * Input label\n\t\t */\n\t\tlabel: {\n\t\t\ttype: String,\n\t\t\tdefault: t('files', 'Folder name'),\n\t\t},\n\t},\n\temits: {\n\t\tclose: (name: string|null) => name === null || name,\n\t},\n\tdata() {\n\t\treturn {\n\t\t\tlocalDefaultName: this.defaultName || t('files', 'New folder'),\n\t\t}\n\t},\n\tcomputed: {\n\t\terrorMessage() {\n\t\t\tif (this.isUniqueName) {\n\t\t\t\treturn ''\n\t\t\t} else {\n\t\t\t\treturn t('files', 'A file or folder with that name already exists.')\n\t\t\t}\n\t\t},\n\t\tuniqueName() {\n\t\t\treturn getUniqueName(this.localDefaultName, this.otherNames)\n\t\t},\n\t\tisUniqueName() {\n\t\t\treturn this.localDefaultName === this.uniqueName\n\t\t},\n\t},\n\twatch: {\n\t\tdefaultName() {\n\t\t\tthis.localDefaultName = this.defaultName || t('files', 'New folder')\n\t\t},\n\n\t\t/**\n\t\t * Ensure the input is focussed even if the dialog is already mounted but not open\n\t\t */\n\t\topen() {\n\t\t\tthis.$nextTick(() => this.focusInput())\n\t\t},\n\t},\n\tmounted() {\n\t\t// on mounted lets use the unique name\n\t\tthis.localDefaultName = this.uniqueName\n\t\tthis.$nextTick(() => this.focusInput())\n\t},\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * Focus the filename input field\n\t\t */\n\t\tfocusInput() {\n\t\t\tif (this.open) {\n\t\t\t\tthis.$nextTick(() => (this.$refs.input as unknown as ICanFocus)?.focus?.())\n\t\t\t}\n\t\t},\n\n\t\tonCreate() {\n\t\t\tthis.$emit('close', this.localDefaultName)\n\t\t},\n\t\tonClose(state: boolean) {\n\t\t\tif (!state) {\n\t\t\t\tthis.$emit('close', null)\n\t\t\t}\n\t\t},\n\t},\n})\n</script>\n","/**\n * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport type { Node } from '@nextcloud/files'\nimport { spawnDialog } from '@nextcloud/dialogs'\nimport NewNodeDialog from '../components/NewNodeDialog.vue'\n\ninterface ILabels {\n\t/**\n\t * Dialog heading, defaults to \"New folder name\"\n\t */\n\tname?: string\n\t/**\n\t * Label for input box, defaults to \"New folder\"\n\t */\n\tlabel?: string\n}\n\n/**\n * Ask user for file or folder name\n * @param defaultName Default name to use\n * @param folderContent Nodes with in the current folder to check for unique name\n * @param labels Labels to set on the dialog\n * @return string if successfull otherwise null if aborted\n */\nexport function newNodeName(defaultName: string, folderContent: Node[], labels: ILabels = {}) {\n\tconst contentNames = folderContent.map((node: Node) => node.basename)\n\n\treturn new Promise<string|null>((resolve) => {\n\t\tspawnDialog(NewNodeDialog, {\n\t\t\t...labels,\n\t\t\tdefaultName,\n\t\t\totherNames: contentNames,\n\t\t}, (folderName) => {\n\t\t\tresolve(folderName as string|null)\n\t\t})\n\t})\n}\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport type { Entry, Node } from '@nextcloud/files'\n\nimport { basename } from 'path'\nimport { emit } from '@nextcloud/event-bus'\nimport { getCurrentUser } from '@nextcloud/auth'\nimport { Permission, Folder } from '@nextcloud/files'\nimport { showSuccess } from '@nextcloud/dialogs'\nimport { translate as t } from '@nextcloud/l10n'\nimport axios from '@nextcloud/axios'\n\nimport FolderPlusSvg from '@mdi/svg/svg/folder-plus.svg?raw'\n\nimport { newNodeName } from '../utils/newNodeDialog'\nimport logger from '../logger'\n\ntype createFolderResponse = {\n\tfileid: number\n\tsource: string\n}\n\nconst createNewFolder = async (root: Folder, name: string): Promise<createFolderResponse> => {\n\tconst source = root.source + '/' + name\n\tconst encodedSource = root.encodedSource + '/' + encodeURIComponent(name)\n\n\tconst response = await axios({\n\t\tmethod: 'MKCOL',\n\t\turl: encodedSource,\n\t\theaders: {\n\t\t\tOverwrite: 'F',\n\t\t},\n\t})\n\treturn {\n\t\tfileid: parseInt(response.headers['oc-fileid']),\n\t\tsource,\n\t}\n}\n\nexport const entry = {\n\tid: 'newFolder',\n\tdisplayName: t('files', 'New folder'),\n\tenabled: (context: Folder) => (context.permissions & Permission.CREATE) !== 0,\n\ticonSvgInline: FolderPlusSvg,\n\torder: 0,\n\tasync handler(context: Folder, content: Node[]) {\n\t\tconst name = await newNodeName(t('files', 'New folder'), content)\n\t\tif (name !== null) {\n\t\t\tconst { fileid, source } = await createNewFolder(context, name)\n\t\t\t// Create the folder in the store\n\t\t\tconst folder = new Folder({\n\t\t\t\tsource,\n\t\t\t\tid: fileid,\n\t\t\t\tmtime: new Date(),\n\t\t\t\towner: getCurrentUser()?.uid || null,\n\t\t\t\tpermissions: Permission.ALL,\n\t\t\t\troot: context?.root || '/files/' + getCurrentUser()?.uid,\n\t\t\t\t// Include mount-type from parent folder as this is inherited\n\t\t\t\tattributes: {\n\t\t\t\t\t'mount-type': context.attributes?.['mount-type'],\n\t\t\t\t\t'owner-id': context.attributes?.['owner-id'],\n\t\t\t\t\t'owner-display-name': context.attributes?.['owner-display-name'],\n\t\t\t\t},\n\t\t\t})\n\n\t\t\tshowSuccess(t('files', 'Created new folder \"{name}\"', { name: basename(source) }))\n\t\t\tlogger.debug('Created new folder', { folder, source })\n\t\t\temit('files:node:created', folder)\n\t\t\twindow.OCP.Files.Router.goToRoute(\n\t\t\t\tnull, // use default route\n\t\t\t\t{ view: 'files', fileid: folder.fileid },\n\t\t\t\t{ dir: context.path },\n\t\t\t)\n\t\t}\n\t},\n} as Entry\n","/**\n * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport type { Entry, Folder, Node } from '@nextcloud/files'\n\nimport { getCurrentUser } from '@nextcloud/auth'\nimport { showError } from '@nextcloud/dialogs'\nimport { Permission, removeNewFileMenuEntry } from '@nextcloud/files'\nimport { loadState } from '@nextcloud/initial-state'\nimport { translate as t } from '@nextcloud/l10n'\nimport { generateOcsUrl } from '@nextcloud/router'\nimport { join } from 'path'\nimport { newNodeName } from '../utils/newNodeDialog'\n\nimport PlusSvg from '@mdi/svg/svg/plus.svg?raw'\nimport axios from '@nextcloud/axios'\nimport logger from '../logger.js'\n\nlet templatesPath = loadState<string|false>('files', 'templates_path', false)\nlogger.debug('Initial templates folder', { templatesPath })\n\n/**\n * Init template folder\n * @param directory Folder where to create the templates folder\n * @param name Name to use or the templates folder\n */\nconst initTemplatesFolder = async function(directory: Folder, name: string) {\n\tconst templatePath = join(directory.path, name)\n\ttry {\n\t\tlogger.debug('Initializing the templates directory', { templatePath })\n\t\tconst { data } = await axios.post(generateOcsUrl('apps/files/api/v1/templates/path'), {\n\t\t\ttemplatePath,\n\t\t\tcopySystemTemplates: true,\n\t\t})\n\n\t\t// Go to template directory\n\t\twindow.OCP.Files.Router.goToRoute(\n\t\t\tnull, // use default route\n\t\t\t{ view: 'files', fileid: undefined },\n\t\t\t{ dir: templatePath },\n\t\t)\n\n\t\tlogger.info('Created new templates folder', {\n\t\t\t...data.ocs.data,\n\t\t})\n\t\ttemplatesPath = data.ocs.data.templates_path as string\n\t} catch (error) {\n\t\tlogger.error('Unable to initialize the templates directory')\n\t\tshowError(t('files', 'Unable to initialize the templates directory'))\n\t}\n}\n\nexport const entry = {\n\tid: 'template-picker',\n\tdisplayName: t('files', 'Create new templates folder'),\n\ticonSvgInline: PlusSvg,\n\torder: 10,\n\tenabled(context: Folder): boolean {\n\t\t// Templates folder already initialized\n\t\tif (templatesPath) {\n\t\t\treturn false\n\t\t}\n\t\t// Allow creation on your own folders only\n\t\tif (context.owner !== getCurrentUser()?.uid) {\n\t\t\treturn false\n\t\t}\n\t\treturn (context.permissions & Permission.CREATE) !== 0\n\t},\n\tasync handler(context: Folder, content: Node[]) {\n\t\tconst name = await newNodeName(t('files', 'Templates'), content, { name: t('files', 'New template folder') })\n\n\t\tif (name !== null) {\n\t\t\t// Create the template folder\n\t\t\tinitTemplatesFolder(context, name)\n\n\t\t\t// Remove the menu entry\n\t\t\tremoveNewFileMenuEntry('template-picker')\n\t\t}\n\t},\n} as Entry\n","/**\n * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport type { Entry } from '@nextcloud/files'\nimport type { ComponentInstance } from 'vue'\nimport type { TemplateFile } from '../types.ts'\n\nimport { Folder, Node, Permission, addNewFileMenuEntry } from '@nextcloud/files'\nimport { loadState } from '@nextcloud/initial-state'\nimport { newNodeName } from '../utils/newNodeDialog'\nimport { translate as t } from '@nextcloud/l10n'\nimport Vue, { defineAsyncComponent } from 'vue'\n\n// async to reduce bundle size\nconst TemplatePickerVue = defineAsyncComponent(() => import('../views/TemplatePicker.vue'))\nlet TemplatePicker: ComponentInstance & { open: (n: string, t: TemplateFile) => void } | null = null\n\nconst getTemplatePicker = async (context: Folder) => {\n\tif (TemplatePicker === null) {\n\t\t// Create document root\n\t\tconst mountingPoint = document.createElement('div')\n\t\tmountingPoint.id = 'template-picker'\n\t\tdocument.body.appendChild(mountingPoint)\n\n\t\t// Init vue app\n\t\tTemplatePicker = new Vue({\n\t\t\trender: (h) => h(\n\t\t\t\tTemplatePickerVue,\n\t\t\t\t{\n\t\t\t\t\tref: 'picker',\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tparent: context,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t),\n\t\t\tmethods: { open(...args) { this.$refs.picker.open(...args) } },\n\t\t\tel: mountingPoint,\n\t\t})\n\t}\n\treturn TemplatePicker\n}\n\n/**\n * Register all new-file-menu entries for all template providers\n */\nexport function registerTemplateEntries() {\n\tconst templates = loadState<TemplateFile[]>('files', 'templates', [])\n\n\t// Init template files menu\n\ttemplates.forEach((provider, index) => {\n\t\taddNewFileMenuEntry({\n\t\t\tid: `template-new-${provider.app}-${index}`,\n\t\t\tdisplayName: provider.label,\n\t\t\ticonClass: provider.iconClass || 'icon-file',\n\t\t\ticonSvgInline: provider.iconSvgInline,\n\t\t\tenabled(context: Folder): boolean {\n\t\t\t\treturn (context.permissions & Permission.CREATE) !== 0\n\t\t\t},\n\t\t\torder: 11,\n\t\t\tasync handler(context: Folder, content: Node[]) {\n\t\t\t\tconst templatePicker = getTemplatePicker(context)\n\t\t\t\tconst name = await newNodeName(`${provider.label}${provider.extension}`, content, {\n\t\t\t\t\tlabel: t('files', 'Filename'),\n\t\t\t\t\tname: provider.label,\n\t\t\t\t})\n\n\t\t\t\tif (name !== null) {\n\t\t\t\t\t// Create the file\n\t\t\t\t\tconst picker = await templatePicker\n\t\t\t\t\tpicker.open(name, provider)\n\t\t\t\t}\n\t\t\t},\n\t\t} as Entry)\n\t})\n}\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport type { ContentsWithRoot } from '@nextcloud/files'\n\nimport { getCurrentUser } from '@nextcloud/auth'\nimport { Folder, Permission, davRemoteURL, davRootPath, getFavoriteNodes } from '@nextcloud/files'\nimport { CancelablePromise } from 'cancelable-promise'\nimport { getContents as filesContents } from './Files.ts'\nimport { client } from './WebdavClient.ts'\n\nexport const getContents = (path = '/'): CancelablePromise<ContentsWithRoot> => {\n\t// We only filter root files for favorites, for subfolders we can simply reuse the files contents\n\tif (path !== '/') {\n\t\treturn filesContents(path)\n\t}\n\n\treturn new CancelablePromise((resolve, reject, cancel) => {\n\t\tconst promise = getFavoriteNodes(client)\n\t\t\t.catch(reject)\n\t\t\t.then((contents) => {\n\t\t\t\tif (!contents) {\n\t\t\t\t\treject()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tresolve({\n\t\t\t\t\tcontents,\n\t\t\t\t\tfolder: new Folder({\n\t\t\t\t\t\tid: 0,\n\t\t\t\t\t\tsource: `${davRemoteURL}${davRootPath}`,\n\t\t\t\t\t\troot: davRootPath,\n\t\t\t\t\t\towner: getCurrentUser()?.uid || null,\n\t\t\t\t\t\tpermissions: Permission.READ,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t})\n\t\tcancel(() => promise.cancel())\n\t})\n}\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport type { Folder, Node } from '@nextcloud/files'\n\nimport { subscribe } from '@nextcloud/event-bus'\nimport { FileType, View, getNavigation } from '@nextcloud/files'\nimport { loadState } from '@nextcloud/initial-state'\nimport { getLanguage, translate as t } from '@nextcloud/l10n'\nimport { basename } from 'path'\nimport FolderSvg from '@mdi/svg/svg/folder.svg?raw'\nimport StarSvg from '@mdi/svg/svg/star.svg?raw'\n\nimport { getContents } from '../services/Favorites'\nimport { hashCode } from '../utils/hashUtils'\nimport logger from '../logger'\n\n// The return type of the initial state\ninterface IFavoriteFolder {\n\tfileid: number\n\tpath: string\n}\n\nexport const generateFavoriteFolderView = function(folder: IFavoriteFolder, index = 0): View {\n\treturn new View({\n\t\tid: generateIdFromPath(folder.path),\n\t\tname: basename(folder.path),\n\n\t\ticon: FolderSvg,\n\t\torder: index,\n\t\tparams: {\n\t\t\tdir: folder.path,\n\t\t\tfileid: folder.fileid.toString(),\n\t\t\tview: 'favorites',\n\t\t},\n\n\t\tparent: 'favorites',\n\n\t\tcolumns: [],\n\n\t\tgetContents,\n\t})\n}\n\nexport const generateIdFromPath = function(path: string): string {\n\treturn `favorite-${hashCode(path)}`\n}\n\nexport default () => {\n\t// Load state in function for mock testing purposes\n\tconst favoriteFolders = loadState<IFavoriteFolder[]>('files', 'favoriteFolders', [])\n\tconst favoriteFoldersViews = favoriteFolders.map((folder, index) => generateFavoriteFolderView(folder, index)) as View[]\n\tlogger.debug('Generating favorites view', { favoriteFolders })\n\n\tconst Navigation = getNavigation()\n\tNavigation.register(new View({\n\t\tid: 'favorites',\n\t\tname: t('files', 'Favorites'),\n\t\tcaption: t('files', 'List of favorites files and folders.'),\n\n\t\temptyTitle: t('files', 'No favorites yet'),\n\t\temptyCaption: t('files', 'Files and folders you mark as favorite will show up here'),\n\n\t\ticon: StarSvg,\n\t\torder: 15,\n\n\t\tcolumns: [],\n\n\t\tgetContents,\n\t}))\n\n\tfavoriteFoldersViews.forEach(view => Navigation.register(view))\n\n\t/**\n\t * Update favourites navigation when a new folder is added\n\t */\n\tsubscribe('files:favorites:added', (node: Node) => {\n\t\tif (node.type !== FileType.Folder) {\n\t\t\treturn\n\t\t}\n\n\t\t// Sanity check\n\t\tif (node.path === null || !node.root?.startsWith('/files')) {\n\t\t\tlogger.error('Favorite folder is not within user files root', { node })\n\t\t\treturn\n\t\t}\n\n\t\taddToFavorites(node as Folder)\n\t})\n\n\t/**\n\t * Remove favourites navigation when a folder is removed\n\t */\n\tsubscribe('files:favorites:removed', (node: Node) => {\n\t\tif (node.type !== FileType.Folder) {\n\t\t\treturn\n\t\t}\n\n\t\t// Sanity check\n\t\tif (node.path === null || !node.root?.startsWith('/files')) {\n\t\t\tlogger.error('Favorite folder is not within user files root', { node })\n\t\t\treturn\n\t\t}\n\n\t\tremovePathFromFavorites(node.path)\n\t})\n\n\t/**\n\t * Sort the favorites paths array and\n\t * update the order property of the existing views\n\t */\n\tconst updateAndSortViews = function() {\n\t\tfavoriteFolders.sort((a, b) => a.path.localeCompare(b.path, getLanguage(), { ignorePunctuation: true }))\n\t\tfavoriteFolders.forEach((folder, index) => {\n\t\t\tconst view = favoriteFoldersViews.find((view) => view.id === generateIdFromPath(folder.path))\n\t\t\tif (view) {\n\t\t\t\tview.order = index\n\t\t\t}\n\t\t})\n\t}\n\n\t// Add a folder to the favorites paths array and update the views\n\tconst addToFavorites = function(node: Folder) {\n\t\tconst newFavoriteFolder: IFavoriteFolder = { path: node.path, fileid: node.fileid! }\n\t\tconst view = generateFavoriteFolderView(newFavoriteFolder)\n\n\t\t// Skip if already exists\n\t\tif (favoriteFolders.find((folder) => folder.path === node.path)) {\n\t\t\treturn\n\t\t}\n\n\t\t// Update arrays\n\t\tfavoriteFolders.push(newFavoriteFolder)\n\t\tfavoriteFoldersViews.push(view)\n\n\t\t// Update and sort views\n\t\tupdateAndSortViews()\n\t\tNavigation.register(view)\n\t}\n\n\t// Remove a folder from the favorites paths array and update the views\n\tconst removePathFromFavorites = function(path: string) {\n\t\tconst id = generateIdFromPath(path)\n\t\tconst index = favoriteFolders.findIndex((folder) => folder.path === path)\n\n\t\t// Skip if not exists\n\t\tif (index === -1) {\n\t\t\treturn\n\t\t}\n\n\t\t// Update arrays\n\t\tfavoriteFolders.splice(index, 1)\n\t\tfavoriteFoldersViews.splice(index, 1)\n\n\t\t// Update and sort views\n\t\tNavigation.remove(id)\n\t\tupdateAndSortViews()\n\t}\n}\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport type { ContentsWithRoot, Node } from '@nextcloud/files'\nimport type { ResponseDataDetailed, SearchResult } from 'webdav'\n\nimport { getCurrentUser } from '@nextcloud/auth'\nimport { Folder, Permission, davGetRecentSearch, davRootPath, davRemoteURL } from '@nextcloud/files'\nimport { CancelablePromise } from 'cancelable-promise'\nimport { useUserConfigStore } from '../store/userconfig.ts'\nimport { pinia } from '../store/index.ts'\nimport { client } from './WebdavClient.ts'\nimport { resultToNode } from './Files.ts'\n\nconst lastTwoWeeksTimestamp = Math.round((Date.now() / 1000) - (60 * 60 * 24 * 14))\n\n/**\n * Get recently changed nodes\n *\n * This takes the users preference about hidden files into account.\n * If hidden files are not shown, then also recently changed files *in* hidden directories are filtered.\n *\n * @param path Path to search for recent changes\n */\nexport const getContents = (path = '/'): CancelablePromise<ContentsWithRoot> => {\n\tconst store = useUserConfigStore(pinia)\n\n\t/**\n\t * Filter function that returns only the visible nodes - or hidden if explicitly configured\n\t * @param node The node to check\n\t */\n\tconst filterHidden = (node: Node) =>\n\t\tpath !== '/' // We need to hide files from hidden directories in the root if not configured to show\n\t\t|| store.userConfig.show_hidden // If configured to show hidden files we can early return\n\t\t|| !node.dirname.split('/').some((dir) => dir.startsWith('.')) // otherwise only include the file if non of the parent directories is hidden\n\n\tconst controller = new AbortController()\n\tconst handler = async () => {\n\t\tconst contentsResponse = await client.search('/', {\n\t\t\tsignal: controller.signal,\n\t\t\tdetails: true,\n\t\t\tdata: davGetRecentSearch(lastTwoWeeksTimestamp),\n\t\t}) as ResponseDataDetailed<SearchResult>\n\n\t\tconst contents = contentsResponse.data.results\n\t\t\t.map(resultToNode)\n\t\t\t.filter(filterHidden)\n\n\t\treturn {\n\t\t\tfolder: new Folder({\n\t\t\t\tid: 0,\n\t\t\t\tsource: `${davRemoteURL}${davRootPath}`,\n\t\t\t\troot: davRootPath,\n\t\t\t\towner: getCurrentUser()?.uid || null,\n\t\t\t\tpermissions: Permission.READ,\n\t\t\t}),\n\t\t\tcontents,\n\t\t}\n\t}\n\n\treturn new CancelablePromise(async (resolve, reject, cancel) => {\n\t\tcancel(() => controller.abort())\n\t\tresolve(handler())\n\t})\n}\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { View, getNavigation } from '@nextcloud/files'\nimport { translate as t } from '@nextcloud/l10n'\nimport HistorySvg from '@mdi/svg/svg/history.svg?raw'\n\nimport { getContents } from '../services/Recent'\n\nexport default () => {\n\tconst Navigation = getNavigation()\n\tNavigation.register(new View({\n\t\tid: 'recent',\n\t\tname: t('files', 'Recent'),\n\t\tcaption: t('files', 'List of recently modified files and folders.'),\n\n\t\temptyTitle: t('files', 'No recently modified files'),\n\t\temptyCaption: t('files', 'Files and folders you recently modified will show up here.'),\n\n\t\ticon: HistorySvg,\n\t\torder: 10,\n\n\t\tdefaultSortKey: 'mtime',\n\n\t\tgetContents,\n\t}))\n}\n","/**\n * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport type { Node, ContentsWithRoot } from '@nextcloud/files'\nimport type { CancelablePromise } from 'cancelable-promise'\nimport { getCurrentUser } from '@nextcloud/auth'\n\nimport { getContents as getFiles } from './Files'\n\nconst currentUserId = getCurrentUser()?.uid\n\n/**\n * Filters each file/folder on its shared status\n *\n * A personal file is considered a file that has all of the following properties:\n * 1. the current user owns\n * 2. the file is not shared with anyone\n * 3. the file is not a group folder\n * @todo Move to `@nextcloud/files`\n * @param node The node to check\n */\nexport const isPersonalFile = function(node: Node): boolean {\n\t// the type of mounts that determine whether the file is shared\n\tconst sharedMountTypes = ['group', 'shared']\n\tconst mountType = node.attributes['mount-type']\n\n\treturn currentUserId === node.owner && !sharedMountTypes.includes(mountType)\n}\n\nexport const getContents = (path: string = '/'): CancelablePromise<ContentsWithRoot> => {\n\t// get all the files from the current path as a cancellable promise\n\t// then filter the files that the user does not own, or has shared / is a group folder\n\treturn getFiles(path)\n\t\t.then((content) => {\n\t\t\tcontent.contents = content.contents.filter(isPersonalFile)\n\t\t\treturn content\n\t\t})\n}\n","/**\n * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { translate as t } from '@nextcloud/l10n'\nimport { View, getNavigation } from '@nextcloud/files'\n\nimport { getContents } from '../services/PersonalFiles'\nimport AccountIcon from '@mdi/svg/svg/account.svg?raw'\n\nexport default () => {\n\tconst Navigation = getNavigation()\n\tNavigation.register(new View({\n\t\tid: 'personal',\n\t\tname: t('files', 'Personal Files'),\n\t\tcaption: t('files', 'List of your files and folders that are not shared.'),\n\n\t\temptyTitle: t('files', 'No personal files found'),\n\t\temptyCaption: t('files', 'Files that are not shared will show up here.'),\n\n\t\ticon: AccountIcon,\n\t\torder: 5,\n\n\t\tgetContents,\n\t}))\n}\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { translate as t } from '@nextcloud/l10n'\nimport FolderSvg from '@mdi/svg/svg/folder.svg?raw'\n\nimport { getContents } from '../services/Files'\nimport { View, getNavigation } from '@nextcloud/files'\n\nexport default () => {\n\tconst Navigation = getNavigation()\n\tNavigation.register(new View({\n\t\tid: 'files',\n\t\tname: t('files', 'All files'),\n\t\tcaption: t('files', 'List of your files and folders.'),\n\n\t\ticon: FolderSvg,\n\t\torder: 0,\n\n\t\tgetContents,\n\t}))\n}\n","/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { generateUrl } from '@nextcloud/router'\nimport logger from '../logger.js'\n\nexport default () => {\n\tif ('serviceWorker' in navigator) {\n\t\t// Use the window load event to keep the page load performant\n\t\twindow.addEventListener('load', async () => {\n\t\t\ttry {\n\t\t\t\tconst url = generateUrl('/apps/files/preview-service-worker.js', {}, { noRewrite: true })\n\t\t\t\tconst registration = await navigator.serviceWorker.register(url, { scope: '/' })\n\t\t\t\tlogger.debug('SW registered: ', { registration })\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error('SW registration failed: ', { error })\n\t\t\t}\n\t\t})\n\t} else {\n\t\tlogger.debug('Service Worker is not enabled on this browser.')\n\t}\n}\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { addNewFileMenuEntry, registerDavProperty, registerFileAction } from '@nextcloud/files'\n\nimport { action as deleteAction } from './actions/deleteAction'\nimport { action as downloadAction } from './actions/downloadAction'\nimport { action as editLocallyAction } from './actions/editLocallyAction'\nimport { action as favoriteAction } from './actions/favoriteAction'\nimport { action as moveOrCopyAction } from './actions/moveOrCopyAction'\nimport { action as openFolderAction } from './actions/openFolderAction'\nimport { action as openInFilesAction } from './actions/openInFilesAction'\nimport { action as renameAction } from './actions/renameAction'\nimport { action as sidebarAction } from './actions/sidebarAction'\nimport { action as viewInFolderAction } from './actions/viewInFolderAction'\nimport { entry as newFolderEntry } from './newMenu/newFolder.ts'\nimport { entry as newTemplatesFolder } from './newMenu/newTemplatesFolder.ts'\nimport { registerTemplateEntries } from './newMenu/newFromTemplate.ts'\n\nimport registerFavoritesView from './views/favorites'\nimport registerRecentView from './views/recent'\nimport registerPersonalFilesView from './views/personal-files'\nimport registerFilesView from './views/files'\nimport registerPreviewServiceWorker from './services/ServiceWorker.js'\n\n\nimport { initLivePhotos } from './services/LivePhotos'\n\n// Register file actions\nregisterFileAction(deleteAction)\nregisterFileAction(downloadAction)\nregisterFileAction(editLocallyAction)\nregisterFileAction(favoriteAction)\nregisterFileAction(moveOrCopyAction)\nregisterFileAction(openFolderAction)\nregisterFileAction(openInFilesAction)\nregisterFileAction(renameAction)\nregisterFileAction(sidebarAction)\nregisterFileAction(viewInFolderAction)\n\n// Register new menu entry\naddNewFileMenuEntry(newFolderEntry)\naddNewFileMenuEntry(newTemplatesFolder)\nregisterTemplateEntries()\n\n// Register files views\nregisterFavoritesView()\nregisterFilesView()\nregisterRecentView()\nregisterPersonalFilesView()\n\n// Register preview service worker\nregisterPreviewServiceWorker()\n\nregisterDavProperty('nc:hidden', { nc: 'http://nextcloud.org/ns' })\nregisterDavProperty('nc:is-mount-root', { nc: 'http://nextcloud.org/ns' })\n\ninitLivePhotos()\n"],"file":"files-init.mjs"}
|