\n\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t{{ t('photos', 'Create new album') }}\n\t\t\n\t
\n\n\t\n\n\n\n\n\n","/**\n * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport axios from '@nextcloud/axios'\nimport {\n\ttype Node,\n\n\tFileType,\n} from '@nextcloud/files'\n\n/**\n * Trigger downloading a file.\n *\n * @param url The url of the asset to download\n * @param name Optionally the recommended name of the download (browsers might ignore it)\n */\nasync function triggerDownload(url: string, name?: string) {\n\t// try to see if the resource is still available\n\tawait axios.head(url)\n\n\tconst hiddenElement = document.createElement('a')\n\thiddenElement.download = name ?? ''\n\thiddenElement.href = url\n\thiddenElement.click()\n}\n\n/**\n * Find the longest common path prefix of both input paths\n *\n * @param first The first path\n * @param second The second path\n */\nfunction longestCommonPath(first: string, second: string): string {\n\tconst firstSegments = first.split('/').filter(Boolean)\n\tconst secondSegments = second.split('/').filter(Boolean)\n\tlet base = ''\n\tfor (const [index, segment] of firstSegments.entries()) {\n\t\tif (index >= second.length) {\n\t\t\tbreak\n\t\t}\n\t\tif (segment !== secondSegments[index]) {\n\t\t\tbreak\n\t\t}\n\t\tconst sep = base === '' ? '' : '/'\n\t\tbase = `${base}${sep}${segment}`\n\t}\n\treturn base\n}\n\n/**\n * Download the given nodes.\n *\n * If only one node is given, it will be downloaded directly.\n * If multiple nodes are given, they will be zipped and downloaded.\n *\n * @param nodes The node(s) to download\n */\nexport async function downloadFiles(nodes: Node[]) {\n\tlet url: URL\n\n\tif (nodes.length === 1) {\n\t\tif (nodes[0]!.type === FileType.File) {\n\t\t\tawait triggerDownload(nodes[0]!.encodedSource, nodes[0]!.displayname)\n\t\t\treturn\n\t\t} else {\n\t\t\turl = new URL(nodes[0]!.encodedSource)\n\t\t\turl.searchParams.append('accept', 'zip')\n\t\t}\n\t} else {\n\t\turl = new URL(nodes[0]!.encodedSource)\n\t\tlet base = url.pathname\n\t\tfor (const node of nodes.slice(1)) {\n\t\t\tbase = longestCommonPath(base, (new URL(node.encodedSource).pathname))\n\t\t}\n\t\turl.pathname = base\n\n\t\t// The URL contains the path encoded so we need to decode as the query.append will re-encode it\n\t\tconst filenames = nodes.map((node) => decodeURIComponent(node.encodedSource.slice(url.href.length + 1)))\n\t\turl.searchParams.append('accept', 'zip')\n\t\turl.searchParams.append('files', JSON.stringify(filenames))\n\t}\n\n\tif (url.pathname.at(-1) !== '/') {\n\t\turl.pathname = `${url.pathname}/`\n\t}\n\n\tawait triggerDownload(url.href)\n}\n","\n\n\n\t\n\t