|
44 | 44 | <td class="files-list__row-name" data-cy-files-list-row-name> |
45 | 45 | <!-- Icon or preview --> |
46 | 46 | <span class="files-list__row-icon" @click="execDefaultAction"> |
47 | | - <FolderIcon v-if="source.type === 'folder'" /> |
| 47 | + <template v-if="source.type === 'folder'"> |
| 48 | + <FolderIcon /> |
| 49 | + <OverlayIcon :is="folderOverlay" |
| 50 | + v-if="folderOverlay" |
| 51 | + class="files-list__row-icon-overlay" /> |
| 52 | + </template> |
48 | 53 |
|
49 | 54 | <!-- Decorative image, should not be aria documented --> |
50 | 55 | <span v-else-if="previewUrl && !backgroundFailed" |
@@ -171,20 +176,27 @@ import { debounce } from 'debounce' |
171 | 176 | import { emit } from '@nextcloud/event-bus' |
172 | 177 | import { extname } from 'path' |
173 | 178 | import { generateUrl } from '@nextcloud/router' |
174 | | -import { getFileActions, DefaultType, FileType, formatFileSize, Permission, NodeStatus } from '@nextcloud/files' |
| 179 | +import { getFileActions, DefaultType, FileType, formatFileSize, Permission } from '@nextcloud/files' |
175 | 180 | import { showError, showSuccess } from '@nextcloud/dialogs' |
176 | 181 | import { translate } from '@nextcloud/l10n' |
| 182 | +import { Type as ShareType } from '@nextcloud/sharing' |
177 | 183 | import { vOnClickOutside } from '@vueuse/components' |
178 | 184 | import axios from '@nextcloud/axios' |
| 185 | +import moment from '@nextcloud/moment' |
| 186 | +import Vue from 'vue' |
| 187 | +
|
| 188 | +import AccountGroupIcon from 'vue-material-design-icons/AccountGroup.vue' |
179 | 189 | import FileIcon from 'vue-material-design-icons/File.vue' |
180 | 190 | import FolderIcon from 'vue-material-design-icons/Folder.vue' |
181 | | -import moment from '@nextcloud/moment' |
| 191 | +import KeyIcon from 'vue-material-design-icons/Key.vue' |
| 192 | +import LinkIcon from 'vue-material-design-icons/Link.vue' |
| 193 | +import NetworkIcon from 'vue-material-design-icons/Network.vue' |
| 194 | +import ShareVariantIcon from 'vue-material-design-icons/ShareVariant.vue' |
182 | 195 | import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js' |
183 | 196 | import NcActions from '@nextcloud/vue/dist/Components/NcActions.js' |
184 | 197 | import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js' |
185 | 198 | import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js' |
186 | 199 | import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js' |
187 | | -import Vue from 'vue' |
188 | 200 |
|
189 | 201 | import { ACTION_DETAILS } from '../actions/sidebarAction.ts' |
190 | 202 | import { hashCode } from '../utils/hashUtils.ts' |
@@ -219,6 +231,7 @@ export default Vue.extend({ |
219 | 231 | NcCheckboxRadioSwitch, |
220 | 232 | NcLoadingIcon, |
221 | 233 | NcTextField, |
| 234 | + Lock, |
222 | 235 | }, |
223 | 236 |
|
224 | 237 | props: { |
@@ -353,6 +366,38 @@ export default Vue.extend({ |
353 | 366 | return '' |
354 | 367 | }, |
355 | 368 |
|
| 369 | + folderOverlay() { |
| 370 | + if (this.source.type !== FileType.Folder) { |
| 371 | + return null |
| 372 | + } |
| 373 | +
|
| 374 | + // Link and mail shared folders |
| 375 | + const shareTypes = Object.values(this.source?.attributes?.['share-types'] || {}).flat() as number[] |
| 376 | + if (shareTypes.some(type => type === ShareType.SHARE_TYPE_LINK || type === ShareType.SHARE_TYPE_EMAIL)) { |
| 377 | + return LinkIcon |
| 378 | + } |
| 379 | +
|
| 380 | + // Shared folders |
| 381 | + if (shareTypes.length > 0) { |
| 382 | + return ShareVariantIcon |
| 383 | + } |
| 384 | +
|
| 385 | + // Encrypted folders |
| 386 | + if (this.source?.attributes?.['is-encrypted'] === 1) { |
| 387 | + return KeyIcon |
| 388 | + } |
| 389 | +
|
| 390 | + switch (this.source?.attributes?.['mount-type']) { |
| 391 | + case 'external': |
| 392 | + case 'external-session': |
| 393 | + return NetworkIcon |
| 394 | + case 'group': |
| 395 | + return AccountGroupIcon |
| 396 | + } |
| 397 | +
|
| 398 | + return null |
| 399 | + }, |
| 400 | +
|
356 | 401 | linkTo() { |
357 | 402 | if (this.source.attributes.failed) { |
358 | 403 | return { |
@@ -869,12 +914,21 @@ export default Vue.extend({ |
869 | 914 | /* Hover effect on tbody lines only */ |
870 | 915 | tr { |
871 | 916 | &:hover, |
872 | | - &:focus, |
873 | | - &:visible { |
| 917 | + &:focus { |
874 | 918 | background-color: var(--color-background-dark); |
875 | 919 | } |
876 | 920 | } |
877 | 921 |
|
| 922 | +// Folder overlay |
| 923 | +.files-list__row-icon-overlay { |
| 924 | + position: absolute; |
| 925 | + max-height: 18px; |
| 926 | + max-width: 18px; |
| 927 | + color: var(--color-main-background); |
| 928 | + // better alignment with the folder icon |
| 929 | + margin-top: 2px; |
| 930 | +} |
| 931 | +
|
878 | 932 | /* Preview not loaded animation effect */ |
879 | 933 | .files-list__row-icon-preview:not([style*='background']) { |
880 | 934 | background: var(--color-loading-dark); |
|
0 commit comments