main.ts 3.3 KB

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 './trashbin.scss'
  23. import { translate as t } from '@nextcloud/l10n'
  24. import DeleteSvg from '@mdi/svg/svg/delete.svg?raw'
  25. import moment from '@nextcloud/moment'
  26. import { getContents } from './services/trashbin'
  27. // Register restore action
  28. import './actions/restoreAction'
  29. import { Column, Node, View, getNavigation } from '@nextcloud/files'
  30. import { dirname, joinPaths } from '@nextcloud/paths'
  31. const parseOriginalLocation = (node: Node): string => {
  32. const path = node.attributes?.['trashbin-original-location'] !== undefined ? String(node.attributes?.['trashbin-original-location']) : null
  33. if (!path) {
  34. return t('files_trashbin', 'Unknown')
  35. }
  36. const dir = dirname(path)
  37. if (dir === path) { // Node is in root folder
  38. return t('files_trashbin', 'All files')
  39. }
  40. return joinPaths(t('files_trashbin', 'All files'), dir)
  41. }
  42. const Navigation = getNavigation()
  43. Navigation.register(new View({
  44. id: 'trashbin',
  45. name: t('files_trashbin', 'Deleted files'),
  46. caption: t('files_trashbin', 'List of files that have been deleted.'),
  47. emptyTitle: t('files_trashbin', 'No deleted files'),
  48. emptyCaption: t('files_trashbin', 'Files and folders you have deleted will show up here'),
  49. icon: DeleteSvg,
  50. order: 50,
  51. sticky: true,
  52. defaultSortKey: 'deleted',
  53. columns: [
  54. new Column({
  55. id: 'original-location',
  56. title: t('files_trashbin', 'Original location'),
  57. render(node) {
  58. const originalLocation = parseOriginalLocation(node)
  59. const span = document.createElement('span')
  60. span.title = originalLocation
  61. span.textContent = originalLocation
  62. return span
  63. },
  64. sort(nodeA, nodeB) {
  65. const locationA = parseOriginalLocation(nodeA)
  66. const locationB = parseOriginalLocation(nodeB)
  67. return locationA.localeCompare(locationB)
  68. },
  69. }),
  70. new Column({
  71. id: 'deleted',
  72. title: t('files_trashbin', 'Deleted'),
  73. render(node) {
  74. const deletionTime = node.attributes?.['trashbin-deletion-time']
  75. const span = document.createElement('span')
  76. if (deletionTime) {
  77. span.title = moment.unix(deletionTime).format('LLL')
  78. span.textContent = moment.unix(deletionTime).fromNow()
  79. return span
  80. }
  81. // Unknown deletion time
  82. span.textContent = t('files_trashbin', 'A long time ago')
  83. return span
  84. },
  85. sort(nodeA, nodeB) {
  86. const deletionTimeA = nodeA.attributes?.['trashbin-deletion-time'] || nodeA?.mtime || 0
  87. const deletionTimeB = nodeB.attributes?.['trashbin-deletion-time'] || nodeB?.mtime || 0
  88. return deletionTimeB - deletionTimeA
  89. },
  90. }),
  91. ],
  92. getContents,
  93. }))