diff --git a/changelog/unreleased/enhancement-file-size-warning-in-editors b/changelog/unreleased/enhancement-file-size-warning-in-editors new file mode 100644 index 00000000000..c8eb3e7d130 --- /dev/null +++ b/changelog/unreleased/enhancement-file-size-warning-in-editors @@ -0,0 +1,7 @@ +Enhancement: File size warning in editors + +We've added a warning to the editors, when the respective file size exceeds 2MB. +This will help the user to avoid performance issues when working with large files. + +https://github.com/owncloud/web/pull/11731 +https://github.com/owncloud/web/issues/8038 diff --git a/packages/web-app-text-editor/src/index.ts b/packages/web-app-text-editor/src/index.ts index 8a88ed81095..a83b66c1971 100644 --- a/packages/web-app-text-editor/src/index.ts +++ b/packages/web-app-text-editor/src/index.ts @@ -105,6 +105,9 @@ export default defineWebApplication({ icon: 'file-text', color: '#0D856F', defaultExtension: 'txt', + meta: { + fileSizeLimit: 2000000 + }, extensions: fileExtensions().map((extensionItem) => { return { extension: extensionItem.extension, diff --git a/packages/web-pkg/src/apps/types.ts b/packages/web-pkg/src/apps/types.ts index 79fbb4a074e..07f24f3f134 100644 --- a/packages/web-pkg/src/apps/types.ts +++ b/packages/web-pkg/src/apps/types.ts @@ -74,6 +74,9 @@ export interface ApplicationInformation { iconFillType?: IconFillType iconColor?: string img?: string + meta?: { + fileSizeLimit?: number + } /** @deprecated */ isFileEditor?: boolean extensions?: ApplicationFileExtension[] diff --git a/packages/web-pkg/src/components/AppTemplates/AppWrapper.vue b/packages/web-pkg/src/components/AppTemplates/AppWrapper.vue index 82b4429bb12..f6f2ac0eff9 100644 --- a/packages/web-pkg/src/components/AppTemplates/AppWrapper.vue +++ b/packages/web-pkg/src/components/AppTemplates/AppWrapper.vue @@ -91,6 +91,8 @@ import { HttpError } from '@ownclouders/web-client' import { dirname } from 'path' import { useFileActionsOpenWithApp } from '../../composables/actions/files/useFileActionsOpenWithApp' import { UnsavedChangesModal } from '../Modals' +import { formatFileSize } from '../../helpers' +import toNumber from 'lodash-es/toNumber' export default defineComponent({ name: 'AppWrapper', @@ -126,7 +128,7 @@ export default defineComponent({ } }, setup(props) { - const { $gettext } = useGettext() + const { $gettext, current: currentLanguage } = useGettext() const appsStore = useAppsStore() const { showMessage, showErrorMessage } = useMessages() const router = useRouter() @@ -209,6 +211,10 @@ export default defineComponent({ const { applicationMeta } = useAppMeta({ applicationId: props.applicationId, appsStore }) + const fileSizeLimit = computed(() => { + return unref(applicationMeta).meta?.fileSizeLimit + }) + const pageTitle = computed(() => { const { name: appName } = unref(applicationMeta) @@ -264,17 +270,24 @@ export default defineComponent({ }) } - const loadFileTask = useTask(function* (signal) { + const loadResourceTask = useTask(function* (signal) { try { if (!unref(driveAliasAndItem)) { yield addMissingDriveAliasAndItem() } - space.value = unref(unref(currentFileContext).space) - resource.value = yield getFileInfo(currentFileContext) + resource.value = yield getFileInfo(currentFileContext, { signal }) resourcesStore.initResourceList({ currentFolder: null, resources: [unref(resource)] }) selectedResources.value = [unref(resource)] + } catch (e) { + console.error(e) + loadingError.value = e + loading.value = false + } + }).restartable() + const loadFileTask = useTask(function* (signal) { + try { const newExtension = props.importResourceWithExtension(unref(resource)) if (newExtension) { const timestamp = DateTime.local().toFormat('yyyyMMddHHmmss') @@ -318,19 +331,43 @@ export default defineComponent({ signal }) } - loading.value = false } catch (e) { console.error(e) loadingError.value = e + } finally { loading.value = false } }).restartable() watch( currentFileContext, - () => { + async () => { if (!unref(noResourceLoading)) { - loadFileTask.perform() + await loadResourceTask.perform() + + if (unref(fileSizeLimit) && toNumber(unref(resource).size) > unref(fileSizeLimit)) { + dispatchModal({ + title: $gettext('File exceeds %{threshold}', { + threshold: formatFileSize(unref(fileSizeLimit), currentLanguage) + }), + message: $gettext( + '%{resource} exceeds the recommended size of %{threshold} for editing, and may cause performance issues.', + { + resource: unref(resource).name, + threshold: formatFileSize(unref(fileSizeLimit), currentLanguage) + } + ), + confirmText: $gettext('Continue'), + onCancel: () => { + closeApp() + }, + onConfirm: () => { + loadFileTask.perform() + } + }) + } else { + loadFileTask.perform() + } } }, { immediate: true }