You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Favorites.ts 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /**
  2. * @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
  3. *
  4. * @author John Molakvoæ <skjnldsv@protonmail.com>
  5. *
  6. * @license AGPL-3.0-or-later
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Affero General Public License as
  10. * published by the Free Software Foundation, either version 3 of the
  11. * License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Affero General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. import { File, Folder, davParsePermissions } from '@nextcloud/files'
  23. import { generateRemoteUrl } from '@nextcloud/router'
  24. import { getClient, rootPath } from './WebdavClient'
  25. import { getCurrentUser } from '@nextcloud/auth'
  26. import { getDavNameSpaces, getDavProperties, getDefaultPropfind } from './DavProperties'
  27. import type { ContentsWithRoot } from './Navigation'
  28. import type { FileStat, ResponseDataDetailed, DAVResultResponseProps } from 'webdav'
  29. const client = getClient()
  30. const reportPayload = `<?xml version="1.0"?>
  31. <oc:filter-files ${getDavNameSpaces()}>
  32. <d:prop>
  33. ${getDavProperties()}
  34. </d:prop>
  35. <oc:filter-rules>
  36. <oc:favorite>1</oc:favorite>
  37. </oc:filter-rules>
  38. </oc:filter-files>`
  39. interface ResponseProps extends DAVResultResponseProps {
  40. permissions: string,
  41. fileid: number,
  42. size: number,
  43. }
  44. const resultToNode = function(node: FileStat): File | Folder {
  45. const props = node.props as ResponseProps
  46. const permissions = davParsePermissions(props?.permissions)
  47. const owner = getCurrentUser()?.uid as string
  48. const nodeData = {
  49. id: props?.fileid as number || 0,
  50. source: generateRemoteUrl('dav' + rootPath + node.filename),
  51. mtime: new Date(node.lastmod),
  52. mime: node.mime as string,
  53. size: props?.size as number || 0,
  54. permissions,
  55. owner,
  56. root: rootPath,
  57. attributes: {
  58. ...node,
  59. ...props,
  60. hasPreview: props?.['has-preview'],
  61. },
  62. }
  63. delete nodeData.attributes.props
  64. return node.type === 'file'
  65. ? new File(nodeData)
  66. : new Folder(nodeData)
  67. }
  68. export const getContents = async (path = '/'): Promise<ContentsWithRoot> => {
  69. const propfindPayload = getDefaultPropfind()
  70. // Get root folder
  71. let rootResponse
  72. if (path === '/') {
  73. rootResponse = await client.stat(path, {
  74. details: true,
  75. data: getDefaultPropfind(),
  76. }) as ResponseDataDetailed<FileStat>
  77. }
  78. const contentsResponse = await client.getDirectoryContents(path, {
  79. details: true,
  80. // Only filter favorites if we're at the root
  81. data: path === '/' ? reportPayload : propfindPayload,
  82. headers: {
  83. // Patched in WebdavClient.ts
  84. method: path === '/' ? 'REPORT' : 'PROPFIND',
  85. },
  86. includeSelf: true,
  87. }) as ResponseDataDetailed<FileStat[]>
  88. const root = rootResponse?.data || contentsResponse.data[0]
  89. const contents = contentsResponse.data.filter(node => node.filename !== path)
  90. return {
  91. folder: resultToNode(root) as Folder,
  92. contents: contents.map(resultToNode),
  93. }
  94. }