mirror of
https://github.com/nextcloud/server.git
synced 2026-06-06 23:34:22 -04:00
Merge pull request #46422 from nextcloud/backport/46374/stable28
[stable28] fix: Update Nextcloud libraries
This commit is contained in:
commit
52718fe2f5
169 changed files with 866 additions and 946 deletions
|
|
@ -27,3 +27,6 @@ import 'jest-location-mock'
|
|||
|
||||
// Mock `window.fetch` with Jest
|
||||
import 'jest-fetch-mock'
|
||||
|
||||
// Mock webroot to be empty
|
||||
(window as unknown as Record<string, unknown>)._oc_webroot = ''
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import { AxiosError } from 'axios'
|
|||
import { basename, join } from 'path'
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import { FilePickerClosed, getFilePickerBuilder, showError } from '@nextcloud/dialogs'
|
||||
import { Permission, FileAction, FileType, NodeStatus, davGetClient, davRootPath, davResultToNode, davGetDefaultPropfind } from '@nextcloud/files'
|
||||
import { FileAction, FileType, NodeStatus, davGetClient, davRootPath, davResultToNode, davGetDefaultPropfind, getUniqueName } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import { openConflictPicker, hasConflict } from '@nextcloud/upload'
|
||||
import Vue from 'vue'
|
||||
|
|
@ -41,7 +41,6 @@ import FolderMoveSvg from '@mdi/svg/svg/folder-move.svg?raw'
|
|||
import { MoveCopyAction, canCopy, canMove, getQueue } from './moveOrCopyActionUtils'
|
||||
import { getContents } from '../services/Files'
|
||||
import logger from '../logger'
|
||||
import { getUniqueName } from '../utils/fileUtils'
|
||||
|
||||
/**
|
||||
* Return the action that is possible for the given nodes
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export const action = new FileAction({
|
|||
id: 'open-folder',
|
||||
displayName(files: Node[]) {
|
||||
// Only works on single node
|
||||
const displayName = files[0].attributes.displayName || files[0].basename
|
||||
const displayName = files[0].attributes.displayname || files[0].basename
|
||||
return t('files', 'Open folder {displayName}', { displayName })
|
||||
},
|
||||
iconSvgInline: () => FolderSvg,
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
|
||||
<script lang="ts">
|
||||
import type { Node } from '@nextcloud/files'
|
||||
import type { FileSource } from '../types.ts'
|
||||
|
||||
import { basename } from 'path'
|
||||
import { defineComponent } from 'vue'
|
||||
|
|
@ -62,6 +63,7 @@ import NcBreadcrumb from '@nextcloud/vue/dist/Components/NcBreadcrumb.js'
|
|||
import NcBreadcrumbs from '@nextcloud/vue/dist/Components/NcBreadcrumbs.js'
|
||||
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
|
||||
|
||||
import { useNavigation } from '../composables/useNavigation'
|
||||
import { onDropInternalFiles, dataTransferToFileTree, onDropExternalFiles } from '../services/DropService'
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import { useDragAndDropStore } from '../store/dragging.ts'
|
||||
|
|
@ -71,7 +73,6 @@ import { useSelectionStore } from '../store/selection.ts'
|
|||
import { useUploaderStore } from '../store/uploader.ts'
|
||||
import filesListWidthMixin from '../mixins/filesListWidth.ts'
|
||||
import logger from '../logger'
|
||||
import type { FileSource } from '../types.ts'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'BreadCrumbs',
|
||||
|
|
@ -99,6 +100,7 @@ export default defineComponent({
|
|||
const pathsStore = usePathsStore()
|
||||
const selectionStore = useSelectionStore()
|
||||
const uploaderStore = useUploaderStore()
|
||||
const { currentView } = useNavigation()
|
||||
|
||||
return {
|
||||
draggingStore,
|
||||
|
|
@ -106,14 +108,12 @@ export default defineComponent({
|
|||
pathsStore,
|
||||
selectionStore,
|
||||
uploaderStore,
|
||||
|
||||
currentView,
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
currentView() {
|
||||
return this.$navigation.active
|
||||
},
|
||||
|
||||
dirs(): string[] {
|
||||
const cumulativePath = (acc: string) => (value: string) => (acc += `${value}/`)
|
||||
// Generate a cumulative path for each path segment: ['/', '/foo', '/foo/bar', ...] etc
|
||||
|
|
@ -167,17 +167,17 @@ export default defineComponent({
|
|||
getNodeFromSource(source: FileSource): Node | undefined {
|
||||
return this.filesStore.getNode(source)
|
||||
},
|
||||
getFileSourceFromPath(path: string): FileSource | undefined {
|
||||
return this.pathsStore.getPath(this.currentView!.id, path)
|
||||
getFileSourceFromPath(path: string): FileSource | null {
|
||||
return (this.currentView && this.pathsStore.getPath(this.currentView.id, path)) ?? null
|
||||
},
|
||||
getDirDisplayName(path: string): string {
|
||||
if (path === '/') {
|
||||
return this.$navigation?.active?.name || t('files', 'Home')
|
||||
}
|
||||
|
||||
const source: FileSource | undefined = this.getFileSourceFromPath(path)
|
||||
const source: FileSource | null = this.getFileSourceFromPath(path)
|
||||
const node: Node | undefined = source ? this.getNodeFromSource(source) : undefined
|
||||
return node?.attributes?.displayName || basename(path)
|
||||
return node?.attributes?.displayname || basename(path)
|
||||
},
|
||||
|
||||
onClick(to) {
|
||||
|
|
@ -187,6 +187,10 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
onDragOver(event: DragEvent, path: string) {
|
||||
if (!event.dataTransfer) {
|
||||
return
|
||||
}
|
||||
|
||||
// Cannot drop on the current directory
|
||||
if (path === this.dirs[this.dirs.length - 1]) {
|
||||
event.dataTransfer.dropEffect = 'none'
|
||||
|
|
|
|||
|
|
@ -44,16 +44,18 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { Folder, Permission } from '@nextcloud/files'
|
||||
import type { Folder } from '@nextcloud/files'
|
||||
import { Permission } from '@nextcloud/files'
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import { UploadStatus } from '@nextcloud/upload'
|
||||
import { defineComponent, type PropType } from 'vue'
|
||||
|
||||
import TrayArrowDownIcon from 'vue-material-design-icons/TrayArrowDown.vue'
|
||||
|
||||
import logger from '../logger.js'
|
||||
import { useNavigation } from '../composables/useNavigation'
|
||||
import { dataTransferToFileTree, onDropExternalFiles } from '../services/DropService'
|
||||
import logger from '../logger.js'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'DragAndDropNotice',
|
||||
|
|
@ -64,11 +66,19 @@ export default defineComponent({
|
|||
|
||||
props: {
|
||||
currentFolder: {
|
||||
type: Folder,
|
||||
type: Object as PropType<Folder>,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
setup() {
|
||||
const { currentView } = useNavigation()
|
||||
|
||||
return {
|
||||
currentView,
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
dragover: false,
|
||||
|
|
@ -76,10 +86,6 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
computed: {
|
||||
currentView() {
|
||||
return this.$navigation.active
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the current folder has create permissions
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ export default Vue.extend({
|
|||
summary(): string {
|
||||
if (this.isSingleNode) {
|
||||
const node = this.nodes[0]
|
||||
return node.attributes?.displayName || node.basename
|
||||
return node.attributes?.displayname || node.basename
|
||||
}
|
||||
|
||||
return getSummaryFor(this.nodes)
|
||||
|
|
|
|||
|
|
@ -103,9 +103,10 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { Permission, formatFileSize } from '@nextcloud/files'
|
||||
import { formatFileSize } from '@nextcloud/files'
|
||||
import moment from '@nextcloud/moment'
|
||||
|
||||
import { useNavigation } from '../composables/useNavigation'
|
||||
import { useActionsMenuStore } from '../store/actionsmenu.ts'
|
||||
import { useDragAndDropStore } from '../store/dragging.ts'
|
||||
import { useFilesStore } from '../store/files.ts'
|
||||
|
|
@ -157,12 +158,16 @@ export default defineComponent({
|
|||
const filesStore = useFilesStore()
|
||||
const renamingStore = useRenamingStore()
|
||||
const selectionStore = useSelectionStore()
|
||||
const { currentView } = useNavigation()
|
||||
|
||||
return {
|
||||
actionsMenuStore,
|
||||
draggingStore,
|
||||
filesStore,
|
||||
renamingStore,
|
||||
selectionStore,
|
||||
|
||||
currentView,
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -196,21 +201,22 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
size() {
|
||||
const size = parseInt(this.source.size, 10)
|
||||
if (typeof size !== 'number' || isNaN(size) || size < 0) {
|
||||
const size = this.source.size
|
||||
if (!size || size < 0) {
|
||||
return this.t('files', 'Pending')
|
||||
}
|
||||
return formatFileSize(size, true)
|
||||
},
|
||||
|
||||
sizeOpacity() {
|
||||
const maxOpacitySize = 10 * 1024 * 1024
|
||||
|
||||
const size = parseInt(this.source.size, 10)
|
||||
const size = this.source.size
|
||||
if (!size || isNaN(size) || size < 0) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const ratio = Math.round(Math.min(100, 100 * Math.pow((this.source.size / maxOpacitySize), 2)))
|
||||
const ratio = Math.round(Math.min(100, 100 * Math.pow((size / maxOpacitySize), 2)))
|
||||
return {
|
||||
color: `color-mix(in srgb, var(--color-main-text) ${ratio}%, var(--color-text-maxcontrast))`,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,13 +93,13 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { PropType, ShallowRef } from 'vue'
|
||||
import type { FileAction, Node, View } from '@nextcloud/files'
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
import { showError, showSuccess } from '@nextcloud/dialogs'
|
||||
import { DefaultType, NodeStatus, getFileActions } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import Vue, { defineComponent } from 'vue'
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
import ArrowLeftIcon from 'vue-material-design-icons/ArrowLeft.vue'
|
||||
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
|
||||
|
|
@ -108,6 +108,7 @@ import NcActionSeparator from '@nextcloud/vue/dist/Components/NcActionSeparator.
|
|||
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
|
||||
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
|
||||
|
||||
import { useNavigation } from '../../composables/useNavigation'
|
||||
import CustomElementRender from '../CustomElementRender.vue'
|
||||
import logger from '../../logger.js'
|
||||
|
||||
|
|
@ -150,6 +151,15 @@ export default defineComponent({
|
|||
},
|
||||
},
|
||||
|
||||
setup() {
|
||||
const { currentView } = useNavigation()
|
||||
|
||||
return {
|
||||
// The file list is guaranteed to be only shown with active view
|
||||
currentView: currentView as ShallowRef<View>,
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
openedSubmenu: null as FileAction | null,
|
||||
|
|
@ -161,9 +171,6 @@ export default defineComponent({
|
|||
// Remove any trailing slash but leave root slash
|
||||
return (this.$route?.query?.dir?.toString() || '/').replace(/^(.+)\/$/, '$1')
|
||||
},
|
||||
currentView(): View {
|
||||
return this.$navigation.active as View
|
||||
},
|
||||
isLoading() {
|
||||
return this.source.status === NodeStatus.LOADING
|
||||
},
|
||||
|
|
@ -287,7 +294,7 @@ export default defineComponent({
|
|||
try {
|
||||
// Set the loading marker
|
||||
this.$emit('update:loading', action.id)
|
||||
Vue.set(this.source, 'status', NodeStatus.LOADING)
|
||||
this.$set(this.source, 'status', NodeStatus.LOADING)
|
||||
|
||||
const success = await action.exec(this.source, this.currentView, this.currentDir)
|
||||
|
||||
|
|
@ -307,7 +314,7 @@ export default defineComponent({
|
|||
} finally {
|
||||
// Reset the loading marker
|
||||
this.$emit('update:loading', '')
|
||||
Vue.set(this.source, 'status', undefined)
|
||||
this.$set(this.source, 'status', undefined)
|
||||
|
||||
// If that was a submenu, we just go back after the action
|
||||
if (isSubmenu) {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { Node } from '@nextcloud/files'
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
|
|
@ -66,6 +67,7 @@ import Vue from 'vue'
|
|||
|
||||
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
|
||||
|
||||
import { useNavigation } from '../../composables/useNavigation'
|
||||
import { useRenamingStore } from '../../store/renaming.ts'
|
||||
import logger from '../../logger.js'
|
||||
|
||||
|
|
@ -106,8 +108,12 @@ export default Vue.extend({
|
|||
},
|
||||
|
||||
setup() {
|
||||
const { currentView } = useNavigation()
|
||||
const renamingStore = useRenamingStore()
|
||||
|
||||
return {
|
||||
currentView,
|
||||
|
||||
renamingStore,
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@
|
|||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
import { useNavigation } from '../composables/useNavigation'
|
||||
import { useActionsMenuStore } from '../store/actionsmenu.ts'
|
||||
import { useDragAndDropStore } from '../store/dragging.ts'
|
||||
import { useFilesStore } from '../store/files.ts'
|
||||
|
|
@ -110,12 +111,16 @@ export default defineComponent({
|
|||
const filesStore = useFilesStore()
|
||||
const renamingStore = useRenamingStore()
|
||||
const selectionStore = useSelectionStore()
|
||||
const { currentView } = useNavigation()
|
||||
|
||||
return {
|
||||
actionsMenuStore,
|
||||
draggingStore,
|
||||
filesStore,
|
||||
renamingStore,
|
||||
selectionStore,
|
||||
|
||||
currentView,
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -65,10 +65,6 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
computed: {
|
||||
currentView(): View {
|
||||
return this.$navigation.active as View
|
||||
},
|
||||
|
||||
currentDir() {
|
||||
// Remove any trailing slash but leave root slash
|
||||
return (this.$route?.query?.dir?.toString() || '/').replace(/^(.+)\/$/, '$1')
|
||||
|
|
@ -88,15 +84,14 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
extension() {
|
||||
if (this.source.attributes?.displayName) {
|
||||
return extname(this.source.attributes.displayName)
|
||||
if (this.source.attributes?.displayname) {
|
||||
return extname(this.source.attributes.displayname)
|
||||
}
|
||||
return this.source.extension || ''
|
||||
},
|
||||
displayName() {
|
||||
const ext = this.extension
|
||||
const name = (this.source.attributes.displayName
|
||||
|| this.source.basename)
|
||||
const name = String(this.source.attributes.displayname || this.source.basename)
|
||||
|
||||
// Strip extension from name if defined
|
||||
return !ext ? name : name.slice(0, 0 - ext.length)
|
||||
|
|
|
|||
|
|
@ -71,17 +71,21 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
|
||||
import { defineComponent, type PropType } from 'vue'
|
||||
import type { Node } from '@nextcloud/files'
|
||||
import type { PropType } from 'vue'
|
||||
import type { FileSource } from '../types.ts'
|
||||
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
|
||||
import FilesListTableHeaderButton from './FilesListTableHeaderButton.vue'
|
||||
|
||||
import { useNavigation } from '../composables/useNavigation'
|
||||
import { useFilesStore } from '../store/files.ts'
|
||||
import { useSelectionStore } from '../store/selection.ts'
|
||||
import FilesListTableHeaderButton from './FilesListTableHeaderButton.vue'
|
||||
import filesSortingMixin from '../mixins/filesSorting.ts'
|
||||
import logger from '../logger.js'
|
||||
import type { Node } from '@nextcloud/files'
|
||||
import type { FileSource } from '../types.ts'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FilesListTableHeader',
|
||||
|
|
@ -117,17 +121,17 @@ export default defineComponent({
|
|||
setup() {
|
||||
const filesStore = useFilesStore()
|
||||
const selectionStore = useSelectionStore()
|
||||
const { currentView } = useNavigation()
|
||||
|
||||
return {
|
||||
filesStore,
|
||||
selectionStore,
|
||||
|
||||
currentView,
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
currentView() {
|
||||
return this.$navigation.active
|
||||
},
|
||||
|
||||
columns() {
|
||||
// Hide columns if the list is too small
|
||||
if (this.filesListWidth < 512) {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ import type { PropType } from 'vue'
|
|||
|
||||
import { defineComponent } from 'vue'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import { getUniqueName } from '../utils/fileUtils'
|
||||
import { getUniqueName } from '@nextcloud/files'
|
||||
|
||||
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
|
||||
import NcDialog from '@nextcloud/vue/dist/Components/NcDialog.js'
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
import type { File, Folder, Node } from '@nextcloud/files'
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
import { debounce } from 'debounce'
|
||||
import debounce from 'debounce'
|
||||
import Vue from 'vue'
|
||||
|
||||
import filesListWidthMixin from '../mixins/filesListWidth.ts'
|
||||
|
|
|
|||
98
apps/files/src/composables/useNavigation.spec.ts
Normal file
98
apps/files/src/composables/useNavigation.spec.ts
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
import { beforeEach, describe, expect, it, jest } from '@jest/globals'
|
||||
import { Navigation, View } from '@nextcloud/files'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { defineComponent, nextTick } from 'vue'
|
||||
import { useNavigation } from './useNavigation'
|
||||
|
||||
import nextcloudFiles from '@nextcloud/files'
|
||||
|
||||
// Just a wrapper so we can test the composable
|
||||
const TestComponent = defineComponent({
|
||||
template: '<div></div>',
|
||||
setup() {
|
||||
const { currentView, views } = useNavigation()
|
||||
return {
|
||||
currentView,
|
||||
views,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
describe('Composables: useNavigation', () => {
|
||||
const spy = jest.spyOn(nextcloudFiles, 'getNavigation')
|
||||
let navigation: Navigation
|
||||
|
||||
describe('currentView', () => {
|
||||
beforeEach(() => {
|
||||
navigation = new Navigation()
|
||||
spy.mockImplementation(() => navigation)
|
||||
})
|
||||
|
||||
it('should return null without active navigation', () => {
|
||||
const wrapper = mount(TestComponent)
|
||||
expect((wrapper.vm as unknown as { currentView: View | null}).currentView).toBe(null)
|
||||
})
|
||||
|
||||
it('should return already active navigation', async () => {
|
||||
const view = new View({ getContents: () => Promise.reject(), icon: '<svg></svg>', id: 'view-1', name: 'My View 1', order: 0 })
|
||||
navigation.register(view)
|
||||
navigation.setActive(view)
|
||||
// Now the navigation is already set it should take the active navigation
|
||||
const wrapper = mount(TestComponent)
|
||||
expect((wrapper.vm as unknown as { currentView: View | null}).currentView).toBe(view)
|
||||
})
|
||||
|
||||
it('should be reactive on updating active navigation', async () => {
|
||||
const view = new View({ getContents: () => Promise.reject(), icon: '<svg></svg>', id: 'view-1', name: 'My View 1', order: 0 })
|
||||
navigation.register(view)
|
||||
const wrapper = mount(TestComponent)
|
||||
|
||||
// no active navigation
|
||||
expect((wrapper.vm as unknown as { currentView: View | null}).currentView).toBe(null)
|
||||
|
||||
navigation.setActive(view)
|
||||
// Now the navigation is set it should take the active navigation
|
||||
expect((wrapper.vm as unknown as { currentView: View | null}).currentView).toBe(view)
|
||||
})
|
||||
})
|
||||
|
||||
describe('views', () => {
|
||||
beforeEach(() => {
|
||||
navigation = new Navigation()
|
||||
spy.mockImplementation(() => navigation)
|
||||
})
|
||||
|
||||
it('should return empty array without registered views', () => {
|
||||
const wrapper = mount(TestComponent)
|
||||
expect((wrapper.vm as unknown as { views: View[]}).views).toStrictEqual([])
|
||||
})
|
||||
|
||||
it('should return already registered views', () => {
|
||||
const view = new View({ getContents: () => Promise.reject(), icon: '<svg></svg>', id: 'view-1', name: 'My View 1', order: 0 })
|
||||
// register before mount
|
||||
navigation.register(view)
|
||||
// now mount and check that the view is listed
|
||||
const wrapper = mount(TestComponent)
|
||||
expect((wrapper.vm as unknown as { views: View[]}).views).toStrictEqual([view])
|
||||
})
|
||||
|
||||
it('should be reactive on registering new views', () => {
|
||||
const view = new View({ getContents: () => Promise.reject(), icon: '<svg></svg>', id: 'view-1', name: 'My View 1', order: 0 })
|
||||
const view2 = new View({ getContents: () => Promise.reject(), icon: '<svg></svg>', id: 'view-2', name: 'My View 2', order: 1 })
|
||||
|
||||
// register before mount
|
||||
navigation.register(view)
|
||||
// now mount and check that the view is listed
|
||||
const wrapper = mount(TestComponent)
|
||||
expect((wrapper.vm as unknown as { views: View[]}).views).toStrictEqual([view])
|
||||
|
||||
// now register view 2 and check it is reactivly added
|
||||
navigation.register(view2)
|
||||
expect((wrapper.vm as unknown as { views: View[]}).views).toStrictEqual([view, view2])
|
||||
})
|
||||
})
|
||||
})
|
||||
46
apps/files/src/composables/useNavigation.ts
Normal file
46
apps/files/src/composables/useNavigation.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
import type { View } from '@nextcloud/files'
|
||||
|
||||
import { getNavigation } from '@nextcloud/files'
|
||||
import { onMounted, onUnmounted, shallowRef, type ShallowRef } from 'vue'
|
||||
|
||||
/**
|
||||
* Composable to get the currently active files view from the files navigation
|
||||
*/
|
||||
export function useNavigation() {
|
||||
const navigation = getNavigation()
|
||||
const views: ShallowRef<View[]> = shallowRef(navigation.views)
|
||||
const currentView: ShallowRef<View | null> = shallowRef(navigation.active)
|
||||
|
||||
/**
|
||||
* Event listener to update the `currentView`
|
||||
* @param event The update event
|
||||
*/
|
||||
function onUpdateActive(event: CustomEvent<View|null>) {
|
||||
currentView.value = event.detail
|
||||
}
|
||||
|
||||
/**
|
||||
* Event listener to update all registered views
|
||||
*/
|
||||
function onUpdateViews() {
|
||||
views.value = navigation.views
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
navigation.addEventListener('update', onUpdateViews)
|
||||
navigation.addEventListener('updateActive', onUpdateActive)
|
||||
})
|
||||
onUnmounted(() => {
|
||||
navigation.removeEventListener('update', onUpdateViews)
|
||||
navigation.removeEventListener('updateActive', onUpdateActive)
|
||||
})
|
||||
|
||||
return {
|
||||
currentView,
|
||||
views,
|
||||
}
|
||||
}
|
||||
1
apps/files/src/eventbus.d.ts
vendored
1
apps/files/src/eventbus.d.ts
vendored
|
|
@ -6,6 +6,7 @@ declare module '@nextcloud/event-bus' {
|
|||
'files:favorites:removed': Node
|
||||
'files:favorites:added': Node
|
||||
'files:node:renamed': Node
|
||||
'nextcloud:unified-search.search': { query: string }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,17 +20,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import { generateRemoteUrl } from '@nextcloud/router'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
|
||||
export const getRootPath = function() {
|
||||
if (getCurrentUser()) {
|
||||
return generateRemoteUrl(`dav/files/${getCurrentUser().uid}`)
|
||||
} else {
|
||||
return generateRemoteUrl('webdav').replace('/remote.php', '/public.php')
|
||||
}
|
||||
}
|
||||
|
||||
export const isPublic = function() {
|
||||
return !getCurrentUser()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,41 +21,6 @@
|
|||
*/
|
||||
import { FileType, type Node } from '@nextcloud/files'
|
||||
import { translate as t, translatePlural as n } from '@nextcloud/l10n'
|
||||
import { basename, extname } from 'path'
|
||||
|
||||
// TODO: move to @nextcloud/files
|
||||
/**
|
||||
* Create an unique file name
|
||||
* @param name The initial name to use
|
||||
* @param otherNames Other names that are already used
|
||||
* @param options Optional parameters for tuning the behavior
|
||||
* @param options.suffix A function that takes an index and returns a suffix to add to the file name, defaults to '(index)'
|
||||
* @param options.ignoreFileExtension Set to true to ignore the file extension when adding the suffix (when getting a unique directory name)
|
||||
* @return Either the initial name, if unique, or the name with the suffix so that the name is unique
|
||||
*/
|
||||
export const getUniqueName = (
|
||||
name: string,
|
||||
otherNames: string[],
|
||||
options: {
|
||||
suffix?: (i: number) => string,
|
||||
ignoreFileExtension?: boolean,
|
||||
} = {},
|
||||
): string => {
|
||||
const opts = {
|
||||
suffix: (n: number) => `(${n})`,
|
||||
ignoreFileExtension: false,
|
||||
...options,
|
||||
}
|
||||
|
||||
let newName = name
|
||||
let i = 1
|
||||
while (otherNames.includes(newName)) {
|
||||
const ext = opts.ignoreFileExtension ? '' : extname(name)
|
||||
const base = basename(name, ext)
|
||||
newName = `${base} ${opts.suffix(i++)}${ext}`
|
||||
}
|
||||
return newName
|
||||
}
|
||||
|
||||
export const encodeFilePath = function(path) {
|
||||
const pathSections = (path.startsWith('/') ? path : `/${path}`).split('/')
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
type="tertiary"
|
||||
@click="openSharingSidebar">
|
||||
<template #icon>
|
||||
<LinkIcon v-if="shareButtonType === Type.SHARE_TYPE_LINK" />
|
||||
<LinkIcon v-if="shareButtonType === ShareType.Link" />
|
||||
<AccountPlusIcon v-else :size="20" />
|
||||
</template>
|
||||
</NcButton>
|
||||
|
|
@ -116,21 +116,23 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { Route } from 'vue-router'
|
||||
import type { ContentsWithRoot } from '@nextcloud/files'
|
||||
import type { Upload } from '@nextcloud/upload'
|
||||
import type { CancelablePromise } from 'cancelable-promise'
|
||||
import type { ComponentInstance } from 'vue'
|
||||
import type { Route } from 'vue-router'
|
||||
import type { UserConfig } from '../types.ts'
|
||||
import type { View, ContentsWithRoot } from '@nextcloud/files'
|
||||
|
||||
import { getCapabilities } from '@nextcloud/capabilities'
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus'
|
||||
import { Folder, Node, Permission } from '@nextcloud/files'
|
||||
import { getCapabilities } from '@nextcloud/capabilities'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { translate as t, translatePlural as n } from '@nextcloud/l10n'
|
||||
import { ShareType } from '@nextcloud/sharing'
|
||||
import { UploadPicker } from '@nextcloud/upload'
|
||||
import { join, dirname } from 'path'
|
||||
import { Parser } from 'xml2js'
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import { translate, translatePlural } from '@nextcloud/l10n'
|
||||
import { Type } from '@nextcloud/sharing'
|
||||
import { UploadPicker } from '@nextcloud/upload'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
import LinkIcon from 'vue-material-design-icons/Link.vue'
|
||||
|
|
@ -145,6 +147,7 @@ import AccountPlusIcon from 'vue-material-design-icons/AccountPlus.vue'
|
|||
import ViewGridIcon from 'vue-material-design-icons/ViewGrid.vue'
|
||||
|
||||
import { action as sidebarAction } from '../actions/sidebarAction.ts'
|
||||
import { useNavigation } from '../composables/useNavigation.ts'
|
||||
import { useFilesStore } from '../store/files.ts'
|
||||
import { usePathsStore } from '../store/paths.ts'
|
||||
import { useSelectionStore } from '../store/selection.ts'
|
||||
|
|
@ -194,10 +197,15 @@ export default defineComponent({
|
|||
const uploaderStore = useUploaderStore()
|
||||
const userConfigStore = useUserConfigStore()
|
||||
const viewConfigStore = useViewConfigStore()
|
||||
const { currentView } = useNavigation()
|
||||
|
||||
const enableGridView = (loadState('core', 'config', [])['enable_non-accessible_features'] ?? true)
|
||||
|
||||
return {
|
||||
currentView,
|
||||
n,
|
||||
t,
|
||||
|
||||
filesStore,
|
||||
pathsStore,
|
||||
selectionStore,
|
||||
|
|
@ -205,6 +213,8 @@ export default defineComponent({
|
|||
userConfigStore,
|
||||
viewConfigStore,
|
||||
enableGridView,
|
||||
|
||||
ShareType,
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -212,10 +222,9 @@ export default defineComponent({
|
|||
return {
|
||||
filterText: '',
|
||||
loading: true,
|
||||
promise: null,
|
||||
Type,
|
||||
promise: null as Promise<ContentsWithRoot> | CancelablePromise<ContentsWithRoot> | null,
|
||||
|
||||
_unsubscribeStore: () => {},
|
||||
unsubscribeStoreCallback: () => {},
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -224,10 +233,6 @@ export default defineComponent({
|
|||
return this.userConfigStore.userConfig
|
||||
},
|
||||
|
||||
currentView(): View {
|
||||
return this.$navigation.active || this.$navigation.views.find((view) => view.id === (this.$route.params?.view ?? 'files'))
|
||||
},
|
||||
|
||||
pageHeading(): string {
|
||||
return this.currentView?.name ?? this.t('files', 'Files')
|
||||
},
|
||||
|
|
@ -280,8 +285,8 @@ export default defineComponent({
|
|||
...(this.userConfig.sort_folders_first ? [v => v.type !== 'folder'] : []),
|
||||
// 3: Use sorting mode if NOT basename (to be able to use displayName too)
|
||||
...(this.sortingMode !== 'basename' ? [v => v[this.sortingMode]] : []),
|
||||
// 4: Use displayName if available, fallback to name
|
||||
v => v.attributes?.displayName || v.basename,
|
||||
// 4: Use displayname if available, fallback to name
|
||||
v => v.attributes?.displayname || v.basename,
|
||||
// 5: Finally, use basename if all previous sorting methods failed
|
||||
v => v.basename,
|
||||
]
|
||||
|
|
@ -384,22 +389,22 @@ export default defineComponent({
|
|||
return this.t('files', 'Share')
|
||||
}
|
||||
|
||||
if (this.shareButtonType === Type.SHARE_TYPE_LINK) {
|
||||
if (this.shareButtonType === ShareType.Link) {
|
||||
return this.t('files', 'Shared by link')
|
||||
}
|
||||
return this.t('files', 'Shared')
|
||||
},
|
||||
shareButtonType(): Type | null {
|
||||
shareButtonType(): ShareType | null {
|
||||
if (!this.shareAttributes) {
|
||||
return null
|
||||
}
|
||||
|
||||
// If all types are links, show the link icon
|
||||
if (this.shareAttributes.some(type => type === Type.SHARE_TYPE_LINK)) {
|
||||
return Type.SHARE_TYPE_LINK
|
||||
if (this.shareAttributes.some(type => type === ShareType.Link)) {
|
||||
return ShareType.Link
|
||||
}
|
||||
|
||||
return Type.SHARE_TYPE_USER
|
||||
return ShareType.User
|
||||
},
|
||||
|
||||
gridViewButtonLabel() {
|
||||
|
|
@ -431,6 +436,18 @@ export default defineComponent({
|
|||
return isSharingEnabled
|
||||
&& this.currentFolder && (this.currentFolder.permissions & Permission.SHARE) !== 0
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle search event from unified search.
|
||||
*
|
||||
* @return {(searchEvent: {query: string}) => void}
|
||||
*/
|
||||
onSearch() {
|
||||
return debounce((searchEvent: { query: string }) => {
|
||||
console.debug('Files app handling search event from unified search...', searchEvent)
|
||||
this.filterText = searchEvent.query
|
||||
}, 500)
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
|
|
@ -453,8 +470,9 @@ export default defineComponent({
|
|||
this.fetchContent()
|
||||
|
||||
// Scroll to top, force virtual scroller to re-render
|
||||
if (this.$refs?.filesListVirtual?.$el) {
|
||||
this.$refs.filesListVirtual.$el.scrollTop = 0
|
||||
const filesListVirtual = this.$refs?.filesListVirtual as ComponentInstance | undefined
|
||||
if (filesListVirtual?.$el) {
|
||||
filesListVirtual.$el.scrollTop = 0
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -470,18 +488,18 @@ export default defineComponent({
|
|||
subscribe('files:node:deleted', this.onNodeDeleted)
|
||||
subscribe('files:node:updated', this.onUpdatedNode)
|
||||
subscribe('nextcloud:unified-search.search', this.onSearch)
|
||||
subscribe('nextcloud:unified-search.reset', this.onSearch)
|
||||
subscribe('nextcloud:unified-search.reset', this.resetSearch)
|
||||
|
||||
// reload on settings change
|
||||
this._unsubscribeStore = this.userConfigStore.$subscribe(() => this.fetchContent(), { deep: true })
|
||||
this.unsubscribeStoreCallback = this.userConfigStore.$subscribe(() => this.fetchContent(), { deep: true })
|
||||
},
|
||||
|
||||
unmounted() {
|
||||
unsubscribe('files:node:deleted', this.onNodeDeleted)
|
||||
unsubscribe('files:node:updated', this.onUpdatedNode)
|
||||
unsubscribe('nextcloud:unified-search.search', this.onSearch)
|
||||
unsubscribe('nextcloud:unified-search.reset', this.onSearch)
|
||||
this._unsubscribeStore()
|
||||
unsubscribe('nextcloud:unified-search.reset', this.resetSearch)
|
||||
this.unsubscribeStoreCallback()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
@ -496,7 +514,7 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
// If we have a cancellable promise ongoing, cancel it
|
||||
if (typeof this.promise?.cancel === 'function') {
|
||||
if (this.promise && 'cancel' in this.promise) {
|
||||
this.promise.cancel()
|
||||
logger.debug('Cancelled previous ongoing fetch')
|
||||
}
|
||||
|
|
@ -531,7 +549,7 @@ export default defineComponent({
|
|||
// Update paths store
|
||||
const folders = contents.filter(node => node.type === 'folder')
|
||||
folders.forEach(node => {
|
||||
this.pathsStore.addPath({ service: currentView.id, fileid: node.fileid, path: join(dir, node.basename) })
|
||||
this.pathsStore.addPath({ service: currentView.id, source: node.source, path: join(dir, node.basename) })
|
||||
})
|
||||
} catch (error) {
|
||||
logger.error('Error while fetching content', { error })
|
||||
|
|
@ -642,20 +660,14 @@ export default defineComponent({
|
|||
this.fetchContent()
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Handle search event from unified search.
|
||||
*
|
||||
* @param searchEvent is event object.
|
||||
*/
|
||||
onSearch: debounce(function(searchEvent) {
|
||||
console.debug('Files app handling search event from unified search...', searchEvent)
|
||||
this.filterText = searchEvent.query
|
||||
}, 500),
|
||||
|
||||
/**
|
||||
* Reset the search query
|
||||
*/
|
||||
resetSearch() {
|
||||
// Reset debounced calls to not set the query again
|
||||
this.onSearch.clear()
|
||||
// Reset filter query
|
||||
this.filterText = ''
|
||||
},
|
||||
|
||||
|
|
@ -668,14 +680,11 @@ export default defineComponent({
|
|||
if (window?.OCA?.Files?.Sidebar?.setActiveTab) {
|
||||
window.OCA.Files.Sidebar.setActiveTab('sharing')
|
||||
}
|
||||
sidebarAction.exec(this.currentFolder, this.currentView, this.currentFolder.path)
|
||||
sidebarAction.exec(this.currentFolder, this.currentView!, this.currentFolder.path)
|
||||
},
|
||||
toggleGridView() {
|
||||
this.userConfigStore.update('grid_view', !this.userConfig.grid_view)
|
||||
},
|
||||
|
||||
t: translate,
|
||||
n: translatePlural,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,19 +1,40 @@
|
|||
import FolderSvg from '@mdi/svg/svg/folder.svg'
|
||||
import ShareSvg from '@mdi/svg/svg/share-variant.svg'
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
import type { Navigation } from '@nextcloud/files'
|
||||
|
||||
import { createTestingPinia } from '@pinia/testing'
|
||||
import FolderSvg from '@mdi/svg/svg/folder.svg?raw'
|
||||
|
||||
import NavigationView from './Navigation.vue'
|
||||
import router from '../router/router'
|
||||
import { useViewConfigStore } from '../store/viewConfig'
|
||||
import { Folder, View, getNavigation } from '@nextcloud/files'
|
||||
|
||||
import Vue from 'vue'
|
||||
import router from '../router/router'
|
||||
|
||||
const resetNavigation = () => {
|
||||
const nav = getNavigation()
|
||||
;[...nav.views].forEach(({ id }) => nav.remove(id))
|
||||
nav.setActive(null)
|
||||
}
|
||||
|
||||
const createView = (id: string, name: string, parent?: string) => new View({
|
||||
id,
|
||||
name,
|
||||
getContents: async () => ({ folder: {} as Folder, contents: [] }),
|
||||
icon: FolderSvg,
|
||||
order: 1,
|
||||
parent,
|
||||
})
|
||||
|
||||
describe('Navigation renders', () => {
|
||||
delete window._nc_navigation
|
||||
const Navigation = getNavigation()
|
||||
let Navigation: Navigation
|
||||
|
||||
before(() => {
|
||||
delete window._nc_navigation
|
||||
Navigation = getNavigation()
|
||||
Vue.prototype.$navigation = Navigation
|
||||
|
||||
cy.mockInitialState('files', 'storageStats', {
|
||||
|
|
@ -40,29 +61,31 @@ describe('Navigation renders', () => {
|
|||
})
|
||||
|
||||
describe('Navigation API', () => {
|
||||
delete window._nc_navigation
|
||||
const Navigation = getNavigation()
|
||||
let Navigation: Navigation
|
||||
|
||||
before(async () => {
|
||||
delete window._nc_navigation
|
||||
Navigation = getNavigation()
|
||||
|
||||
before(() => {
|
||||
Vue.prototype.$navigation = Navigation
|
||||
await router.replace({ name: 'filelist', params: { view: 'files' } })
|
||||
})
|
||||
|
||||
beforeEach(() => resetNavigation())
|
||||
|
||||
it('Check API entries rendering', () => {
|
||||
Navigation.register(new View({
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
getContents: async () => ({ folder: {} as Folder, contents: [] }),
|
||||
icon: FolderSvg,
|
||||
order: 1,
|
||||
}))
|
||||
Navigation.register(createView('files', 'Files'))
|
||||
console.warn(Navigation.views)
|
||||
|
||||
cy.mount(NavigationView, {
|
||||
global: {
|
||||
plugins: [createTestingPinia({
|
||||
createSpy: cy.spy,
|
||||
})],
|
||||
},
|
||||
router,
|
||||
global: {
|
||||
plugins: [
|
||||
createTestingPinia({
|
||||
createSpy: cy.spy,
|
||||
}),
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
cy.get('[data-cy-files-navigation]').should('be.visible')
|
||||
|
|
@ -72,21 +95,16 @@ describe('Navigation API', () => {
|
|||
})
|
||||
|
||||
it('Adds a new entry and render', () => {
|
||||
Navigation.register(new View({
|
||||
id: 'sharing',
|
||||
name: 'Sharing',
|
||||
getContents: async () => ({ folder: {} as Folder, contents: [] }),
|
||||
icon: ShareSvg,
|
||||
order: 2,
|
||||
}))
|
||||
Navigation.register(createView('files', 'Files'))
|
||||
Navigation.register(createView('sharing', 'Sharing'))
|
||||
|
||||
cy.mount(NavigationView, {
|
||||
router,
|
||||
global: {
|
||||
plugins: [createTestingPinia({
|
||||
createSpy: cy.spy,
|
||||
})],
|
||||
},
|
||||
router,
|
||||
})
|
||||
|
||||
cy.get('[data-cy-files-navigation]').should('be.visible')
|
||||
|
|
@ -96,22 +114,17 @@ describe('Navigation API', () => {
|
|||
})
|
||||
|
||||
it('Adds a new children, render and open menu', () => {
|
||||
Navigation.register(new View({
|
||||
id: 'sharingin',
|
||||
name: 'Shared with me',
|
||||
getContents: async () => ({ folder: {} as Folder, contents: [] }),
|
||||
parent: 'sharing',
|
||||
icon: ShareSvg,
|
||||
order: 1,
|
||||
}))
|
||||
Navigation.register(createView('files', 'Files'))
|
||||
Navigation.register(createView('sharing', 'Sharing'))
|
||||
Navigation.register(createView('sharingin', 'Shared with me', 'sharing'))
|
||||
|
||||
cy.mount(NavigationView, {
|
||||
router,
|
||||
global: {
|
||||
plugins: [createTestingPinia({
|
||||
createSpy: cy.spy,
|
||||
})],
|
||||
},
|
||||
router,
|
||||
})
|
||||
|
||||
cy.wrap(useViewConfigStore()).as('viewConfigStore')
|
||||
|
|
@ -139,23 +152,18 @@ describe('Navigation API', () => {
|
|||
})
|
||||
|
||||
it('Throws when adding a duplicate entry', () => {
|
||||
expect(() => {
|
||||
Navigation.register(new View({
|
||||
id: 'files',
|
||||
name: 'Files',
|
||||
getContents: async () => ({ folder: {} as Folder, contents: [] }),
|
||||
icon: FolderSvg,
|
||||
order: 1,
|
||||
}))
|
||||
}).to.throw('View id files is already registered')
|
||||
Navigation.register(createView('files', 'Files'))
|
||||
expect(() => Navigation.register(createView('files', 'Files')))
|
||||
.to.throw('View id files is already registered')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Quota rendering', () => {
|
||||
delete window._nc_navigation
|
||||
const Navigation = getNavigation()
|
||||
let Navigation: Navigation
|
||||
|
||||
before(() => {
|
||||
delete window._nc_navigation
|
||||
Navigation = getNavigation()
|
||||
Vue.prototype.$navigation = Navigation
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
:name="t('files', 'Files settings')"
|
||||
data-cy-files-navigation-settings-button
|
||||
@click.prevent.stop="openSettings">
|
||||
<Cog slot="icon" :size="20" />
|
||||
<IconCog slot="icon" :size="20" />
|
||||
</NcAppNavigationItem>
|
||||
</ul>
|
||||
</template>
|
||||
|
|
@ -75,24 +75,29 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { View } from '@nextcloud/files'
|
||||
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import { translate } from '@nextcloud/l10n'
|
||||
import Cog from 'vue-material-design-icons/Cog.vue'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
import IconCog from 'vue-material-design-icons/Cog.vue'
|
||||
import NcAppNavigation from '@nextcloud/vue/dist/Components/NcAppNavigation.js'
|
||||
import NcAppNavigationItem from '@nextcloud/vue/dist/Components/NcAppNavigationItem.js'
|
||||
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
|
||||
|
||||
import { useViewConfigStore } from '../store/viewConfig.ts'
|
||||
import logger from '../logger.js'
|
||||
import type { View } from '@nextcloud/files'
|
||||
import NavigationQuota from '../components/NavigationQuota.vue'
|
||||
import SettingsModal from './Settings.vue'
|
||||
|
||||
export default {
|
||||
import { useNavigation } from '../composables/useNavigation'
|
||||
import { useViewConfigStore } from '../store/viewConfig.ts'
|
||||
import logger from '../logger.js'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Navigation',
|
||||
|
||||
components: {
|
||||
Cog,
|
||||
IconCog,
|
||||
|
||||
NavigationQuota,
|
||||
NcAppNavigation,
|
||||
NcAppNavigationItem,
|
||||
|
|
@ -102,7 +107,12 @@ export default {
|
|||
|
||||
setup() {
|
||||
const viewConfigStore = useViewConfigStore()
|
||||
const { currentView, views } = useNavigation()
|
||||
|
||||
return {
|
||||
currentView,
|
||||
views,
|
||||
|
||||
viewConfigStore,
|
||||
}
|
||||
},
|
||||
|
|
@ -114,18 +124,13 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
/**
|
||||
* The current view ID from the route params
|
||||
*/
|
||||
currentViewId() {
|
||||
return this.$route?.params?.view || 'files'
|
||||
},
|
||||
|
||||
currentView(): View {
|
||||
return this.views.find(view => view.id === this.currentViewId)!
|
||||
},
|
||||
|
||||
views(): View[] {
|
||||
return this.$navigation.views
|
||||
},
|
||||
|
||||
parentViews(): View[] {
|
||||
return this.views
|
||||
// filter child views
|
||||
|
|
@ -153,24 +158,27 @@ export default {
|
|||
},
|
||||
|
||||
watch: {
|
||||
currentView(view, oldView) {
|
||||
if (view.id !== oldView?.id) {
|
||||
this.$navigation.setActive(view)
|
||||
logger.debug('Navigation changed', { id: view.id, view })
|
||||
|
||||
currentViewId(newView, oldView) {
|
||||
if (this.currentViewId !== this.currentView?.id) {
|
||||
// This is guaranteed to be a view because `currentViewId` falls back to the default 'files' view
|
||||
const view = this.views.find(({ id }) => id === this.currentViewId)!
|
||||
// The the new view as active
|
||||
this.showView(view)
|
||||
logger.debug(`Navigation changed from ${oldView} to ${newView}`, { to: view })
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
beforeMount() {
|
||||
if (this.currentView) {
|
||||
logger.debug('Navigation mounted. Showing requested view', { view: this.currentView })
|
||||
this.showView(this.currentView)
|
||||
}
|
||||
// This is guaranteed to be a view because `currentViewId` falls back to the default 'files' view
|
||||
const view = this.views.find(({ id }) => id === this.currentViewId)!
|
||||
this.showView(view)
|
||||
logger.debug('Navigation mounted. Showing requested view', { view })
|
||||
},
|
||||
|
||||
methods: {
|
||||
t,
|
||||
|
||||
/**
|
||||
* Only use exact route matching on routes with child views
|
||||
* Because if a view does not have children (like the files view) then multiple routes might be matched for it
|
||||
|
|
@ -181,9 +189,13 @@ export default {
|
|||
return this.childViews[view.id]?.length > 0
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the view as active on the navigation and handle internal state
|
||||
* @param view View to set active
|
||||
*/
|
||||
showView(view: View) {
|
||||
// Closing any opened sidebar
|
||||
window?.OCA?.Files?.Sidebar?.close?.()
|
||||
window.OCA?.Files?.Sidebar?.close?.()
|
||||
this.$navigation.setActive(view)
|
||||
emit('files:navigation:changed', view)
|
||||
},
|
||||
|
|
@ -237,10 +249,8 @@ export default {
|
|||
onSettingsClose() {
|
||||
this.settingsOpened = false
|
||||
},
|
||||
|
||||
t: translate,
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
|||
|
|
@ -193,10 +193,11 @@ import {
|
|||
import { showError, showSuccess } from '@nextcloud/dialogs'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { snakeCase } from 'lodash'
|
||||
import { defineComponent } from 'vue'
|
||||
import debounce from 'debounce'
|
||||
|
||||
import SelectSharingPermissions from './SelectSharingPermissions.vue'
|
||||
import { snakeCase, debounce } from 'lodash'
|
||||
|
||||
interface IShareSettings {
|
||||
enabled: boolean
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
import { vElementVisibility } from '@vueuse/components'
|
||||
import { debounce } from 'debounce'
|
||||
import debounce from 'debounce'
|
||||
|
||||
import logger from '../../logger.js'
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,8 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { debounce } from 'debounce'
|
||||
import debounce from 'debounce'
|
||||
|
||||
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
|
||||
import NcColorPicker from '@nextcloud/vue/dist/Components/NcColorPicker.js'
|
||||
import NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
dist/1110-1110.js
vendored
3
dist/1110-1110.js
vendored
|
|
@ -1,3 +0,0 @@
|
|||
/*! For license information please see 1110-1110.js.LICENSE.txt */
|
||||
"use strict";(self.webpackChunknextcloud=self.webpackChunknextcloud||[]).push([[1110],{91110:(e,c,l)=>{l.d(c,{FilePickerVue:()=>n});const n=(0,l(85471).$V)((()=>Promise.all([l.e(4208),l.e(7422)]).then(l.bind(l,87368))))}}]);
|
||||
//# sourceMappingURL=1110-1110.js.map?v=ee198291c8b389847012
|
||||
21
dist/1110-1110.js.LICENSE.txt
vendored
21
dist/1110-1110.js.LICENSE.txt
vendored
|
|
@ -1,21 +0,0 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @author Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
1
dist/1110-1110.js.map
vendored
1
dist/1110-1110.js.map
vendored
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"1110-1110.js?v=ee198291c8b389847012","mappings":";oIAsBA,MAAMA,GAAI,gBAAE,IAAM","sources":["webpack:///nextcloud/node_modules/@nextcloud/dialogs/dist/chunks/index-CqRCpcyw.mjs"],"sourcesContent":["import { defineAsyncComponent as e } from \"vue\";\n/**\n * @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>\n *\n * @author Ferdinand Thiessen <opensource@fthiessen.de>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\nconst i = e(() => import(\"./FilePicker-pvhGKHps.mjs\"));\nexport {\n i as FilePickerVue\n};\n"],"names":["i"],"sourceRoot":""}
|
||||
2
dist/4065-4065.js
vendored
Normal file
2
dist/4065-4065.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/4065-4065.js.map
vendored
Normal file
1
dist/4065-4065.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
dist/4254-4254.js
vendored
Normal file
2
dist/4254-4254.js
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
"use strict";(self.webpackChunknextcloud=self.webpackChunknextcloud||[]).push([[4254],{11873:(e,c,l)=>{l.d(c,{FilePickerVue:()=>n});const n=(0,l(85471).$V)((()=>Promise.all([l.e(4208),l.e(4065)]).then(l.bind(l,17207))))}}]);
|
||||
//# sourceMappingURL=4254-4254.js.map?v=96661b9f421b07ce7189
|
||||
1
dist/4254-4254.js.map
vendored
Normal file
1
dist/4254-4254.js.map
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"4254-4254.js?v=96661b9f421b07ce7189","mappings":"oIACA,MAAMA,GAAgB,E,SAAA,KAAqB,IAAM,0D","sources":["webpack:///nextcloud/node_modules/@nextcloud/dialogs/dist/chunks/index-CYiQsZoY.mjs"],"sourcesContent":["import { defineAsyncComponent } from \"vue\";\nconst FilePickerVue = defineAsyncComponent(() => import(\"./FilePicker-DUbP4INd.mjs\"));\nexport {\n FilePickerVue\n};\n"],"names":["FilePickerVue"],"sourceRoot":""}
|
||||
1
dist/5929-5929.js.map
vendored
1
dist/5929-5929.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/6075-6075.js
vendored
4
dist/6075-6075.js
vendored
File diff suppressed because one or more lines are too long
2
dist/6075-6075.js.map
vendored
2
dist/6075-6075.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/7144-7144.js
vendored
4
dist/7144-7144.js
vendored
File diff suppressed because one or more lines are too long
2
dist/7144-7144.js.map
vendored
2
dist/7144-7144.js.map
vendored
File diff suppressed because one or more lines are too long
3
dist/7422-7422.js
vendored
3
dist/7422-7422.js
vendored
File diff suppressed because one or more lines are too long
63
dist/7422-7422.js.LICENSE.txt
vendored
63
dist/7422-7422.js.LICENSE.txt
vendored
|
|
@ -1,63 +0,0 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @author Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @author Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2024 Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @author Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
1
dist/7422-7422.js.map
vendored
1
dist/7422-7422.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/7462-7462.js
vendored
4
dist/7462-7462.js
vendored
File diff suppressed because one or more lines are too long
2
dist/7462-7462.js.map
vendored
2
dist/7462-7462.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/7883-7883.js
vendored
4
dist/7883-7883.js
vendored
File diff suppressed because one or more lines are too long
2
dist/7883-7883.js.map
vendored
2
dist/7883-7883.js.map
vendored
File diff suppressed because one or more lines are too long
6
dist/5929-5929.js → dist/9647-9647.js
vendored
6
dist/5929-5929.js → dist/9647-9647.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
* @copyright Copyright (c) 2021 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
1
dist/9647-9647.js.map
vendored
Normal file
1
dist/9647-9647.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
4
dist/comments-comments-app.js
vendored
4
dist/comments-comments-app.js
vendored
File diff suppressed because one or more lines are too long
2
dist/comments-comments-app.js.map
vendored
2
dist/comments-comments-app.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/comments-comments-tab.js
vendored
4
dist/comments-comments-tab.js
vendored
File diff suppressed because one or more lines are too long
2
dist/comments-comments-tab.js.map
vendored
2
dist/comments-comments-tab.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/comments-init.js
vendored
4
dist/comments-init.js
vendored
|
|
@ -1,3 +1,3 @@
|
|||
/*! For license information please see comments-init.js.LICENSE.txt */
|
||||
(()=>{"use strict";var e,r={84350:(e,r,t)=>{var n=t(6388),o=t(53334);const i=(0,t(53529).YK)().setApp("comments").detectUser().build(),a=new n.hY({id:"comments-unread",title(e){const r=e[0].attributes["comments-unread"];return r>=0?(0,o.zw)("comments","1 new comment","{unread} new comments",r,{unread:r}):(0,o.Tl)("comments","Comment")},displayName:()=>"",iconSvgInline:()=>'<svg xmlns="http://www.w3.org/2000/svg" id="mdi-comment-processing" viewBox="0 0 24 24"><path d="M9,22A1,1 0 0,1 8,21V18H4A2,2 0 0,1 2,16V4C2,2.89 2.9,2 4,2H20A2,2 0 0,1 22,4V16A2,2 0 0,1 20,18H13.9L10.2,21.71C10,21.9 9.75,22 9.5,22V22H9M17,11V9H15V11H17M13,11V9H11V11H13M9,11V9H7V11H9Z" /></svg>',enabled(e){const r=e[0].attributes["comments-unread"];return"number"==typeof r&&r>0},async exec(e){try{return window.OCA.Files.Sidebar.setActiveTab("comments"),await window.OCA.Files.Sidebar.open(e.path),null}catch(e){return i.error("Error while opening sidebar",{error:e}),!1}},inline:()=>!0,order:-140});(0,n.Gg)(a)}},t={};function n(e){var o=t[e];if(void 0!==o)return o.exports;var i=t[e]={id:e,loaded:!1,exports:{}};return r[e].call(i.exports,i,i.exports,n),i.loaded=!0,i.exports}n.m=r,e=[],n.O=(r,t,o,i)=>{if(!t){var a=1/0;for(c=0;c<e.length;c++){t=e[c][0],o=e[c][1],i=e[c][2];for(var s=!0,l=0;l<t.length;l++)(!1&i||a>=i)&&Object.keys(n.O).every((e=>n.O[e](t[l])))?t.splice(l--,1):(s=!1,i<a&&(a=i));if(s){e.splice(c--,1);var d=o();void 0!==d&&(r=d)}}return r}i=i||0;for(var c=e.length;c>0&&e[c-1][2]>i;c--)e[c]=e[c-1];e[c]=[t,o,i]},n.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return n.d(r,{a:r}),r},n.d=(e,r)=>{for(var t in r)n.o(r,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},n.e=()=>Promise.resolve(),n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),n.j=3260,(()=>{n.b=document.baseURI||self.location.href;var e={3260:0};n.O.j=r=>0===e[r];var r=(r,t)=>{var o,i,a=t[0],s=t[1],l=t[2],d=0;if(a.some((r=>0!==e[r]))){for(o in s)n.o(s,o)&&(n.m[o]=s[o]);if(l)var c=l(n)}for(r&&r(t);d<a.length;d++)i=a[d],n.o(e,i)&&e[i]&&e[i][0](),e[i]=0;return n.O(c)},t=self.webpackChunknextcloud=self.webpackChunknextcloud||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),n.nc=void 0;var o=n.O(void 0,[4208],(()=>n(84350)));o=n.O(o)})();
|
||||
//# sourceMappingURL=comments-init.js.map?v=0919736da5d13fc31be8
|
||||
(()=>{"use strict";var e,r={84350:(e,r,t)=>{var n=t(92320),o=t(53334);const i=(0,t(53529).YK)().setApp("comments").detectUser().build(),a=new n.hY({id:"comments-unread",title(e){const r=e[0].attributes["comments-unread"];return r>=0?(0,o.zw)("comments","1 new comment","{unread} new comments",r,{unread:r}):(0,o.Tl)("comments","Comment")},displayName:()=>"",iconSvgInline:()=>'<svg xmlns="http://www.w3.org/2000/svg" id="mdi-comment-processing" viewBox="0 0 24 24"><path d="M9,22A1,1 0 0,1 8,21V18H4A2,2 0 0,1 2,16V4C2,2.89 2.9,2 4,2H20A2,2 0 0,1 22,4V16A2,2 0 0,1 20,18H13.9L10.2,21.71C10,21.9 9.75,22 9.5,22V22H9M17,11V9H15V11H17M13,11V9H11V11H13M9,11V9H7V11H9Z" /></svg>',enabled(e){const r=e[0].attributes["comments-unread"];return"number"==typeof r&&r>0},async exec(e){try{return window.OCA.Files.Sidebar.setActiveTab("comments"),await window.OCA.Files.Sidebar.open(e.path),null}catch(e){return i.error("Error while opening sidebar",{error:e}),!1}},inline:()=>!0,order:-140});(0,n.Gg)(a)}},t={};function n(e){var o=t[e];if(void 0!==o)return o.exports;var i=t[e]={id:e,loaded:!1,exports:{}};return r[e].call(i.exports,i,i.exports,n),i.loaded=!0,i.exports}n.m=r,e=[],n.O=(r,t,o,i)=>{if(!t){var a=1/0;for(c=0;c<e.length;c++){t=e[c][0],o=e[c][1],i=e[c][2];for(var s=!0,l=0;l<t.length;l++)(!1&i||a>=i)&&Object.keys(n.O).every((e=>n.O[e](t[l])))?t.splice(l--,1):(s=!1,i<a&&(a=i));if(s){e.splice(c--,1);var d=o();void 0!==d&&(r=d)}}return r}i=i||0;for(var c=e.length;c>0&&e[c-1][2]>i;c--)e[c]=e[c-1];e[c]=[t,o,i]},n.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return n.d(r,{a:r}),r},n.d=(e,r)=>{for(var t in r)n.o(r,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},n.e=()=>Promise.resolve(),n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),n.j=3260,(()=>{n.b=document.baseURI||self.location.href;var e={3260:0};n.O.j=r=>0===e[r];var r=(r,t)=>{var o,i,a=t[0],s=t[1],l=t[2],d=0;if(a.some((r=>0!==e[r]))){for(o in s)n.o(s,o)&&(n.m[o]=s[o]);if(l)var c=l(n)}for(r&&r(t);d<a.length;d++)i=a[d],n.o(e,i)&&e[i]&&e[i][0](),e[i]=0;return n.O(c)},t=self.webpackChunknextcloud=self.webpackChunknextcloud||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),n.nc=void 0;var o=n.O(void 0,[4208],(()=>n(84350)));o=n.O(o)})();
|
||||
//# sourceMappingURL=comments-init.js.map?v=34aa19676660a084c8ec
|
||||
2
dist/comments-init.js.map
vendored
2
dist/comments-init.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/core-common.js
vendored
4
dist/core-common.js
vendored
File diff suppressed because one or more lines are too long
179
dist/core-common.js.LICENSE.txt
vendored
179
dist/core-common.js.LICENSE.txt
vendored
|
|
@ -78,185 +78,6 @@
|
|||
|
||||
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||
|
||||
/**
|
||||
* @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
*
|
||||
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
*
|
||||
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2022 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @author Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @author Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
* @author Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**!
|
||||
* @fileOverview Kickass library to create and place poppers near their reference elements.
|
||||
* @version 1.16.1
|
||||
|
|
|
|||
2
dist/core-common.js.map
vendored
2
dist/core-common.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/core-legacy-unified-search.js
vendored
4
dist/core-legacy-unified-search.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-legacy-unified-search.js.map
vendored
2
dist/core-legacy-unified-search.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/core-login.js
vendored
4
dist/core-login.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-login.js.map
vendored
2
dist/core-login.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/core-main.js
vendored
4
dist/core-main.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-main.js.map
vendored
2
dist/core-main.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/core-maintenance.js
vendored
4
dist/core-maintenance.js
vendored
|
|
@ -1,3 +1,3 @@
|
|||
/*! For license information please see core-maintenance.js.LICENSE.txt */
|
||||
(()=>{"use strict";var e,t={77748:(e,t,n)=>{var o=n(26287),r=n(99498),i=n(96763);const a=(0,r.aU)()+"/status.php",l=()=>{i.info("checking the Nextcloud maintenance status"),o.A.get(a).then((e=>e.data)).then((e=>{if(!1===e.maintenance)return i.info("Nextcloud is not in maintenance mode anymore -> reloading"),void window.location.reload();i.info("Nextcloud is still in maintenance mode"),setTimeout(l,2e4)})).catch(i.error.bind(void 0))};l()}},n={};function o(e){var r=n[e];if(void 0!==r)return r.exports;var i=n[e]={id:e,loaded:!1,exports:{}};return t[e].call(i.exports,i,i.exports,o),i.loaded=!0,i.exports}o.m=t,e=[],o.O=(t,n,r,i)=>{if(!n){var a=1/0;for(u=0;u<e.length;u++){n=e[u][0],r=e[u][1],i=e[u][2];for(var l=!0,d=0;d<n.length;d++)(!1&i||a>=i)&&Object.keys(o.O).every((e=>o.O[e](n[d])))?n.splice(d--,1):(l=!1,i<a&&(a=i));if(l){e.splice(u--,1);var c=r();void 0!==c&&(t=c)}}return t}i=i||0;for(var u=e.length;u>0&&e[u-1][2]>i;u--)e[u]=e[u-1];e[u]=[n,r,i]},o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var n in t)o.o(t,n)&&!o.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o.e=()=>Promise.resolve(),o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),o.j=2076,(()=>{o.b=document.baseURI||self.location.href;var e={2076:0};o.O.j=t=>0===e[t];var t=(t,n)=>{var r,i,a=n[0],l=n[1],d=n[2],c=0;if(a.some((t=>0!==e[t]))){for(r in l)o.o(l,r)&&(o.m[r]=l[r]);if(d)var u=d(o)}for(t&&t(n);c<a.length;c++)i=a[c],o.o(e,i)&&e[i]&&e[i][0](),e[i]=0;return o.O(u)},n=self.webpackChunknextcloud=self.webpackChunknextcloud||[];n.forEach(t.bind(null,0)),n.push=t.bind(null,n.push.bind(n))})(),o.nc=void 0;var r=o.O(void 0,[4208],(()=>o(77748)));r=o.O(r)})();
|
||||
//# sourceMappingURL=core-maintenance.js.map?v=19735ee2a2994fc2343a
|
||||
(()=>{"use strict";var e,t={77748:(e,t,n)=>{var o=n(26287),r=n(63814),i=n(96763);const a=(0,r.aU)()+"/status.php",l=()=>{i.info("checking the Nextcloud maintenance status"),o.A.get(a).then((e=>e.data)).then((e=>{if(!1===e.maintenance)return i.info("Nextcloud is not in maintenance mode anymore -> reloading"),void window.location.reload();i.info("Nextcloud is still in maintenance mode"),setTimeout(l,2e4)})).catch(i.error.bind(void 0))};l()}},n={};function o(e){var r=n[e];if(void 0!==r)return r.exports;var i=n[e]={id:e,loaded:!1,exports:{}};return t[e].call(i.exports,i,i.exports,o),i.loaded=!0,i.exports}o.m=t,e=[],o.O=(t,n,r,i)=>{if(!n){var a=1/0;for(u=0;u<e.length;u++){n=e[u][0],r=e[u][1],i=e[u][2];for(var l=!0,d=0;d<n.length;d++)(!1&i||a>=i)&&Object.keys(o.O).every((e=>o.O[e](n[d])))?n.splice(d--,1):(l=!1,i<a&&(a=i));if(l){e.splice(u--,1);var c=r();void 0!==c&&(t=c)}}return t}i=i||0;for(var u=e.length;u>0&&e[u-1][2]>i;u--)e[u]=e[u-1];e[u]=[n,r,i]},o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var n in t)o.o(t,n)&&!o.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o.e=()=>Promise.resolve(),o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),o.j=2076,(()=>{o.b=document.baseURI||self.location.href;var e={2076:0};o.O.j=t=>0===e[t];var t=(t,n)=>{var r,i,a=n[0],l=n[1],d=n[2],c=0;if(a.some((t=>0!==e[t]))){for(r in l)o.o(l,r)&&(o.m[r]=l[r]);if(d)var u=d(o)}for(t&&t(n);c<a.length;c++)i=a[c],o.o(e,i)&&e[i]&&e[i][0](),e[i]=0;return o.O(u)},n=self.webpackChunknextcloud=self.webpackChunknextcloud||[];n.forEach(t.bind(null,0)),n.push=t.bind(null,n.push.bind(n))})(),o.nc=void 0;var r=o.O(void 0,[4208],(()=>o(77748)));r=o.O(r)})();
|
||||
//# sourceMappingURL=core-maintenance.js.map?v=894222d2ba7f2c142a30
|
||||
2
dist/core-maintenance.js.map
vendored
2
dist/core-maintenance.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/core-profile.js
vendored
4
dist/core-profile.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-profile.js.map
vendored
2
dist/core-profile.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/core-recommendedapps.js
vendored
4
dist/core-recommendedapps.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-recommendedapps.js.map
vendored
2
dist/core-recommendedapps.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/core-systemtags.js
vendored
4
dist/core-systemtags.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-systemtags.js.map
vendored
2
dist/core-systemtags.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/core-unified-search.js
vendored
4
dist/core-unified-search.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-unified-search.js.map
vendored
2
dist/core-unified-search.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/core-unsupported-browser-redirect.js
vendored
4
dist/core-unsupported-browser-redirect.js
vendored
|
|
@ -1,3 +1,3 @@
|
|||
/*! For license information please see core-unsupported-browser-redirect.js.LICENSE.txt */
|
||||
(()=>{"use strict";var e,r,t,o={47210:(e,r,t)=>{var o,n=t(21777);t.nc=btoa((0,n.do)()),window.TESTING||null!==(o=OC)&&void 0!==o&&null!==(o=o.config)&&void 0!==o&&o.no_unsupported_browser_warning||window.addEventListener("DOMContentLoaded",(async function(){const{testSupportedBrowser:e}=await Promise.all([t.e(4208),t.e(7883)]).then(t.bind(t,77883));e()}))}},n={};function a(e){var r=n[e];if(void 0!==r)return r.exports;var t=n[e]={id:e,loaded:!1,exports:{}};return o[e].call(t.exports,t,t.exports,a),t.loaded=!0,t.exports}a.m=o,e=[],a.O=(r,t,o,n)=>{if(!t){var i=1/0;for(u=0;u<e.length;u++){t=e[u][0],o=e[u][1],n=e[u][2];for(var l=!0,d=0;d<t.length;d++)(!1&n||i>=n)&&Object.keys(a.O).every((e=>a.O[e](t[d])))?t.splice(d--,1):(l=!1,n<i&&(i=n));if(l){e.splice(u--,1);var c=o();void 0!==c&&(r=c)}}return r}n=n||0;for(var u=e.length;u>0&&e[u-1][2]>n;u--)e[u]=e[u-1];e[u]=[t,o,n]},a.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return a.d(r,{a:r}),r},a.d=(e,r)=>{for(var t in r)a.o(r,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},a.f={},a.e=e=>Promise.all(Object.keys(a.f).reduce(((r,t)=>(a.f[t](e,r),r)),[])),a.u=e=>e+"-"+e+".js?v=3b65531cae454a74494b",a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),r={},t="nextcloud:",a.l=(e,o,n,i)=>{if(r[e])r[e].push(o);else{var l,d;if(void 0!==n)for(var c=document.getElementsByTagName("script"),u=0;u<c.length;u++){var s=c[u];if(s.getAttribute("src")==e||s.getAttribute("data-webpack")==t+n){l=s;break}}l||(d=!0,(l=document.createElement("script")).charset="utf-8",l.timeout=120,a.nc&&l.setAttribute("nonce",a.nc),l.setAttribute("data-webpack",t+n),l.src=e),r[e]=[o];var p=(t,o)=>{l.onerror=l.onload=null,clearTimeout(f);var n=r[e];if(delete r[e],l.parentNode&&l.parentNode.removeChild(l),n&&n.forEach((e=>e(o))),t)return t(o)},f=setTimeout(p.bind(null,void 0,{type:"timeout",target:l}),12e4);l.onerror=p.bind(null,l.onerror),l.onload=p.bind(null,l.onload),d&&document.head.appendChild(l)}},a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),a.j=3604,(()=>{var e;a.g.importScripts&&(e=a.g.location+"");var r=a.g.document;if(!e&&r&&(r.currentScript&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var o=t.length-1;o>-1&&(!e||!/^http(s?):/.test(e));)e=t[o--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),a.p=e})(),(()=>{a.b=document.baseURI||self.location.href;var e={3604:0};a.f.j=(r,t)=>{var o=a.o(e,r)?e[r]:void 0;if(0!==o)if(o)t.push(o[2]);else{var n=new Promise(((t,n)=>o=e[r]=[t,n]));t.push(o[2]=n);var i=a.p+a.u(r),l=new Error;a.l(i,(t=>{if(a.o(e,r)&&(0!==(o=e[r])&&(e[r]=void 0),o)){var n=t&&("load"===t.type?"missing":t.type),i=t&&t.target&&t.target.src;l.message="Loading chunk "+r+" failed.\n("+n+": "+i+")",l.name="ChunkLoadError",l.type=n,l.request=i,o[1](l)}}),"chunk-"+r,r)}},a.O.j=r=>0===e[r];var r=(r,t)=>{var o,n,i=t[0],l=t[1],d=t[2],c=0;if(i.some((r=>0!==e[r]))){for(o in l)a.o(l,o)&&(a.m[o]=l[o]);if(d)var u=d(a)}for(r&&r(t);c<i.length;c++)n=i[c],a.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return a.O(u)},t=self.webpackChunknextcloud=self.webpackChunknextcloud||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),a.nc=void 0;var i=a.O(void 0,[4208],(()=>a(47210)));i=a.O(i)})();
|
||||
//# sourceMappingURL=core-unsupported-browser-redirect.js.map?v=7d93fa13fa2e955e5019
|
||||
(()=>{"use strict";var e,r,t,o={47210:(e,r,t)=>{var o,n=t(21777);t.nc=btoa((0,n.do)()),window.TESTING||null!==(o=OC)&&void 0!==o&&null!==(o=o.config)&&void 0!==o&&o.no_unsupported_browser_warning||window.addEventListener("DOMContentLoaded",(async function(){const{testSupportedBrowser:e}=await Promise.all([t.e(4208),t.e(7883)]).then(t.bind(t,77883));e()}))}},n={};function a(e){var r=n[e];if(void 0!==r)return r.exports;var t=n[e]={id:e,loaded:!1,exports:{}};return o[e].call(t.exports,t,t.exports,a),t.loaded=!0,t.exports}a.m=o,e=[],a.O=(r,t,o,n)=>{if(!t){var i=1/0;for(u=0;u<e.length;u++){t=e[u][0],o=e[u][1],n=e[u][2];for(var l=!0,d=0;d<t.length;d++)(!1&n||i>=n)&&Object.keys(a.O).every((e=>a.O[e](t[d])))?t.splice(d--,1):(l=!1,n<i&&(i=n));if(l){e.splice(u--,1);var c=o();void 0!==c&&(r=c)}}return r}n=n||0;for(var u=e.length;u>0&&e[u-1][2]>n;u--)e[u]=e[u-1];e[u]=[t,o,n]},a.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return a.d(r,{a:r}),r},a.d=(e,r)=>{for(var t in r)a.o(r,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},a.f={},a.e=e=>Promise.all(Object.keys(a.f).reduce(((r,t)=>(a.f[t](e,r),r)),[])),a.u=e=>e+"-"+e+".js?v=c1221c9531a3138e051a",a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),r={},t="nextcloud:",a.l=(e,o,n,i)=>{if(r[e])r[e].push(o);else{var l,d;if(void 0!==n)for(var c=document.getElementsByTagName("script"),u=0;u<c.length;u++){var s=c[u];if(s.getAttribute("src")==e||s.getAttribute("data-webpack")==t+n){l=s;break}}l||(d=!0,(l=document.createElement("script")).charset="utf-8",l.timeout=120,a.nc&&l.setAttribute("nonce",a.nc),l.setAttribute("data-webpack",t+n),l.src=e),r[e]=[o];var p=(t,o)=>{l.onerror=l.onload=null,clearTimeout(f);var n=r[e];if(delete r[e],l.parentNode&&l.parentNode.removeChild(l),n&&n.forEach((e=>e(o))),t)return t(o)},f=setTimeout(p.bind(null,void 0,{type:"timeout",target:l}),12e4);l.onerror=p.bind(null,l.onerror),l.onload=p.bind(null,l.onload),d&&document.head.appendChild(l)}},a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),a.j=3604,(()=>{var e;a.g.importScripts&&(e=a.g.location+"");var r=a.g.document;if(!e&&r&&(r.currentScript&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var o=t.length-1;o>-1&&(!e||!/^http(s?):/.test(e));)e=t[o--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),a.p=e})(),(()=>{a.b=document.baseURI||self.location.href;var e={3604:0};a.f.j=(r,t)=>{var o=a.o(e,r)?e[r]:void 0;if(0!==o)if(o)t.push(o[2]);else{var n=new Promise(((t,n)=>o=e[r]=[t,n]));t.push(o[2]=n);var i=a.p+a.u(r),l=new Error;a.l(i,(t=>{if(a.o(e,r)&&(0!==(o=e[r])&&(e[r]=void 0),o)){var n=t&&("load"===t.type?"missing":t.type),i=t&&t.target&&t.target.src;l.message="Loading chunk "+r+" failed.\n("+n+": "+i+")",l.name="ChunkLoadError",l.type=n,l.request=i,o[1](l)}}),"chunk-"+r,r)}},a.O.j=r=>0===e[r];var r=(r,t)=>{var o,n,i=t[0],l=t[1],d=t[2],c=0;if(i.some((r=>0!==e[r]))){for(o in l)a.o(l,o)&&(a.m[o]=l[o]);if(d)var u=d(a)}for(r&&r(t);c<i.length;c++)n=i[c],a.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return a.O(u)},t=self.webpackChunknextcloud=self.webpackChunknextcloud||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),a.nc=void 0;var i=a.O(void 0,[4208],(()=>a(47210)));i=a.O(i)})();
|
||||
//# sourceMappingURL=core-unsupported-browser-redirect.js.map?v=e242c378a151a301818e
|
||||
File diff suppressed because one or more lines are too long
4
dist/core-unsupported-browser.js
vendored
4
dist/core-unsupported-browser.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-unsupported-browser.js.map
vendored
2
dist/core-unsupported-browser.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/dashboard-main.js
vendored
4
dist/dashboard-main.js
vendored
File diff suppressed because one or more lines are too long
2
dist/dashboard-main.js.map
vendored
2
dist/dashboard-main.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/dav-settings-admin-caldav.js
vendored
4
dist/dav-settings-admin-caldav.js
vendored
File diff suppressed because one or more lines are too long
2
dist/dav-settings-admin-caldav.js.map
vendored
2
dist/dav-settings-admin-caldav.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/dav-settings-personal-availability.js
vendored
4
dist/dav-settings-personal-availability.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
dist/federatedfilesharing-external.js
vendored
4
dist/federatedfilesharing-external.js
vendored
|
|
@ -1,2 +1,2 @@
|
|||
(()=>{"use strict";var e,o={54878:(e,o,n)=>{var r=n(32981),i=n(99498);window.OCA.Sharing=window.OCA.Sharing||{},window.OCA.Sharing.showAddExternalDialog=function(e,o,n){const r=e.remote,i=e.ownerDisplayName||e.owner,a=e.name,s=r.replace(/^https?:\/\//,"").replace(/\/$/,"");o?window.OC.dialogs.prompt(t("files_sharing","Do you want to add the remote share {name} from {owner}@{remote}?",{name:a,owner:i,remote:s}),t("files_sharing","Remote share"),(function(o,t){e.password=t,n(o,e)}),!0,t("files_sharing","Remote share password"),!0).then(this._adjustDialog):window.OC.dialogs.confirm(t("files_sharing","Do you want to add the remote share {name} from {owner}@{remote}?",{name:a,owner:i,remote:s}),t("files_sharing","Remote share"),(function(o){n(o,e)}),!0).then(this._adjustDialog)},window.OCA.Sharing._adjustDialog=function(){const e=$(".oc-dialog:visible"),o=e.find("button");e.find(".ui-icon").remove(),o.eq(1).text(t("core","Cancel")),o.eq(2).text(t("files_sharing","Add remote share"))};const a=function(){var e;null!==(e=window)&&void 0!==e&&null!==(e=e.OCP)&&void 0!==e&&null!==(e=e.Files)&&void 0!==e&&null!==(e=e.Router)&&void 0!==e&&e.goToRoute?window.OCP.Files.Router.goToRoute(null,{...window.OCP.Files.Router.params,fileid:void 0},{...window.OCP.Files.Router.query,dir:"/",openfile:void 0}):window.location.reload()};!function(){const e=window.OC.Util.History.parseUrlQuery();if(e.remote&&e.token&&e.name){const o=function(e,o){const n=o.password||"";e&&$.post((0,i.Jv)("apps/federatedfilesharing/askForFederatedShare"),{remote:o.remote,token:o.token,owner:o.owner,ownerDisplayName:o.ownerDisplayName||o.owner,name:o.name,password:n}).done((function(e){e.hasOwnProperty("legacyMount")?a():window.OC.Notification.showTemporary(e.message)})).fail((function(e){window.OC.Notification.showTemporary(JSON.parse(e.responseText).message)}))};location.hash="",e.passwordProtected=1===parseInt(e.protected,10),window.OCA.Sharing.showAddExternalDialog(e,e.passwordProtected,o)}}(),!0!==(0,r.C)("federatedfilesharing","notificationsEnabled",!0)&&$.get((0,i.Jv)("/apps/files_sharing/api/externalShares"),{},(function(e){let o;for(o=0;o<e.length;++o)window.OCA.Sharing.showAddExternalDialog(e[o],!1,(function(e,o){e?$.post((0,i.Jv)("/apps/files_sharing/api/externalShares"),{id:o.id}).then((function(){a()})):$.ajax({url:(0,i.Jv)("/apps/files_sharing/api/externalShares/"+o.id),type:"DELETE"})}))})),$("body").on("window.OCA.Notification.Action",(function(e){"files_sharing"===e.notification.app&&"remote_share"===e.notification.object_type&&"POST"===e.action.type&&a()}))}},n={};function r(e){var t=n[e];if(void 0!==t)return t.exports;var i=n[e]={id:e,loaded:!1,exports:{}};return o[e].call(i.exports,i,i.exports,r),i.loaded=!0,i.exports}r.m=o,e=[],r.O=(o,n,t,i)=>{if(!n){var a=1/0;for(f=0;f<e.length;f++){n=e[f][0],t=e[f][1],i=e[f][2];for(var s=!0,l=0;l<n.length;l++)(!1&i||a>=i)&&Object.keys(r.O).every((e=>r.O[e](n[l])))?n.splice(l--,1):(s=!1,i<a&&(a=i));if(s){e.splice(f--,1);var d=t();void 0!==d&&(o=d)}}return o}i=i||0;for(var f=e.length;f>0&&e[f-1][2]>i;f--)e[f]=e[f-1];e[f]=[n,t,i]},r.n=e=>{var o=e&&e.__esModule?()=>e.default:()=>e;return r.d(o,{a:o}),o},r.d=(e,o)=>{for(var n in o)r.o(o,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:o[n]})},r.e=()=>Promise.resolve(),r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),r.j=2299,(()=>{r.b=document.baseURI||self.location.href;var e={2299:0};r.O.j=o=>0===e[o];var o=(o,n)=>{var t,i,a=n[0],s=n[1],l=n[2],d=0;if(a.some((o=>0!==e[o]))){for(t in s)r.o(s,t)&&(r.m[t]=s[t]);if(l)var f=l(r)}for(o&&o(n);d<a.length;d++)i=a[d],r.o(e,i)&&e[i]&&e[i][0](),e[i]=0;return r.O(f)},n=self.webpackChunknextcloud=self.webpackChunknextcloud||[];n.forEach(o.bind(null,0)),n.push=o.bind(null,n.push.bind(n))})(),r.nc=void 0;var i=r.O(void 0,[4208],(()=>r(54878)));i=r.O(i)})();
|
||||
//# sourceMappingURL=federatedfilesharing-external.js.map?v=29ee99678d009e83e464
|
||||
(()=>{"use strict";var e,o={54878:(e,o,n)=>{var r=n(32981),i=n(63814);window.OCA.Sharing=window.OCA.Sharing||{},window.OCA.Sharing.showAddExternalDialog=function(e,o,n){const r=e.remote,i=e.ownerDisplayName||e.owner,a=e.name,s=r.replace(/^https?:\/\//,"").replace(/\/$/,"");o?window.OC.dialogs.prompt(t("files_sharing","Do you want to add the remote share {name} from {owner}@{remote}?",{name:a,owner:i,remote:s}),t("files_sharing","Remote share"),(function(o,t){e.password=t,n(o,e)}),!0,t("files_sharing","Remote share password"),!0).then(this._adjustDialog):window.OC.dialogs.confirm(t("files_sharing","Do you want to add the remote share {name} from {owner}@{remote}?",{name:a,owner:i,remote:s}),t("files_sharing","Remote share"),(function(o){n(o,e)}),!0).then(this._adjustDialog)},window.OCA.Sharing._adjustDialog=function(){const e=$(".oc-dialog:visible"),o=e.find("button");e.find(".ui-icon").remove(),o.eq(1).text(t("core","Cancel")),o.eq(2).text(t("files_sharing","Add remote share"))};const a=function(){var e;null!==(e=window)&&void 0!==e&&null!==(e=e.OCP)&&void 0!==e&&null!==(e=e.Files)&&void 0!==e&&null!==(e=e.Router)&&void 0!==e&&e.goToRoute?window.OCP.Files.Router.goToRoute(null,{...window.OCP.Files.Router.params,fileid:void 0},{...window.OCP.Files.Router.query,dir:"/",openfile:void 0}):window.location.reload()};!function(){const e=window.OC.Util.History.parseUrlQuery();if(e.remote&&e.token&&e.name){const o=function(e,o){const n=o.password||"";e&&$.post((0,i.Jv)("apps/federatedfilesharing/askForFederatedShare"),{remote:o.remote,token:o.token,owner:o.owner,ownerDisplayName:o.ownerDisplayName||o.owner,name:o.name,password:n}).done((function(e){e.hasOwnProperty("legacyMount")?a():window.OC.Notification.showTemporary(e.message)})).fail((function(e){window.OC.Notification.showTemporary(JSON.parse(e.responseText).message)}))};location.hash="",e.passwordProtected=1===parseInt(e.protected,10),window.OCA.Sharing.showAddExternalDialog(e,e.passwordProtected,o)}}(),!0!==(0,r.C)("federatedfilesharing","notificationsEnabled",!0)&&$.get((0,i.Jv)("/apps/files_sharing/api/externalShares"),{},(function(e){let o;for(o=0;o<e.length;++o)window.OCA.Sharing.showAddExternalDialog(e[o],!1,(function(e,o){e?$.post((0,i.Jv)("/apps/files_sharing/api/externalShares"),{id:o.id}).then((function(){a()})):$.ajax({url:(0,i.Jv)("/apps/files_sharing/api/externalShares/"+o.id),type:"DELETE"})}))})),$("body").on("window.OCA.Notification.Action",(function(e){"files_sharing"===e.notification.app&&"remote_share"===e.notification.object_type&&"POST"===e.action.type&&a()}))}},n={};function r(e){var t=n[e];if(void 0!==t)return t.exports;var i=n[e]={id:e,loaded:!1,exports:{}};return o[e].call(i.exports,i,i.exports,r),i.loaded=!0,i.exports}r.m=o,e=[],r.O=(o,n,t,i)=>{if(!n){var a=1/0;for(f=0;f<e.length;f++){n=e[f][0],t=e[f][1],i=e[f][2];for(var s=!0,l=0;l<n.length;l++)(!1&i||a>=i)&&Object.keys(r.O).every((e=>r.O[e](n[l])))?n.splice(l--,1):(s=!1,i<a&&(a=i));if(s){e.splice(f--,1);var d=t();void 0!==d&&(o=d)}}return o}i=i||0;for(var f=e.length;f>0&&e[f-1][2]>i;f--)e[f]=e[f-1];e[f]=[n,t,i]},r.n=e=>{var o=e&&e.__esModule?()=>e.default:()=>e;return r.d(o,{a:o}),o},r.d=(e,o)=>{for(var n in o)r.o(o,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:o[n]})},r.e=()=>Promise.resolve(),r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),r.j=2299,(()=>{r.b=document.baseURI||self.location.href;var e={2299:0};r.O.j=o=>0===e[o];var o=(o,n)=>{var t,i,a=n[0],s=n[1],l=n[2],d=0;if(a.some((o=>0!==e[o]))){for(t in s)r.o(s,t)&&(r.m[t]=s[t]);if(l)var f=l(r)}for(o&&o(n);d<a.length;d++)i=a[d],r.o(e,i)&&e[i]&&e[i][0](),e[i]=0;return r.O(f)},n=self.webpackChunknextcloud=self.webpackChunknextcloud||[];n.forEach(o.bind(null,0)),n.push=o.bind(null,n.push.bind(n))})(),r.nc=void 0;var i=r.O(void 0,[4208],(()=>r(54878)));i=r.O(i)})();
|
||||
//# sourceMappingURL=federatedfilesharing-external.js.map?v=c189f97cbeb77a056e14
|
||||
2
dist/federatedfilesharing-external.js.map
vendored
2
dist/federatedfilesharing-external.js.map
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
dist/files-init.js
vendored
4
dist/files-init.js
vendored
File diff suppressed because one or more lines are too long
22
dist/files-init.js.LICENSE.txt
vendored
22
dist/files-init.js.LICENSE.txt
vendored
|
|
@ -26,28 +26,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2022 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
|
|
|
|||
2
dist/files-init.js.map
vendored
2
dist/files-init.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/files-main.js
vendored
4
dist/files-main.js
vendored
File diff suppressed because one or more lines are too long
22
dist/files-main.js.LICENSE.txt
vendored
22
dist/files-main.js.LICENSE.txt
vendored
|
|
@ -75,6 +75,28 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2022 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
|
|
|
|||
2
dist/files-main.js.map
vendored
2
dist/files-main.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/files-personal-settings.js
vendored
4
dist/files-personal-settings.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files-personal-settings.js.map
vendored
2
dist/files-personal-settings.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/files-reference-files.js
vendored
4
dist/files-reference-files.js
vendored
File diff suppressed because one or more lines are too long
22
dist/files-reference-files.js.LICENSE.txt
vendored
22
dist/files-reference-files.js.LICENSE.txt
vendored
|
|
@ -18,25 +18,3 @@
|
|||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @author Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue