dialog: add fragment

Signed-off-by: Varun Patil <radialapps@gmail.com>
pull/888/head
Varun Patil 2023-10-24 12:26:12 -07:00
parent 0a7914d9b9
commit 8588a7d190
3 changed files with 71 additions and 47 deletions

View File

@ -1,4 +1,8 @@
import { translate as t, translatePlural as n } from '@nextcloud/l10n'; import { translate as t, translatePlural as n } from '@nextcloud/l10n';
import { FilePickerType, getFilePickerBuilder } from '@nextcloud/dialogs';
import { showError } from '@nextcloud/dialogs';
import { bus } from './event-bus';
import { fragment } from './fragment';
// https://github.com/nextcloud/server/blob/4b7ec0a0c18d4e2007565dc28ee214814940161e/core/src/OC/dialogs.js // https://github.com/nextcloud/server/blob/4b7ec0a0c18d4e2007565dc28ee214814940161e/core/src/OC/dialogs.js
const oc_dialogs = (<any>OC).dialogs; const oc_dialogs = (<any>OC).dialogs;
@ -20,6 +24,12 @@ type ConfirmOptions = {
modal?: boolean; modal?: boolean;
}; };
// Register fragment navigation
bus.on('memories:fragment:pop:dialog', () => {
const selectors = ['button.oc-dialog-close', '[role="dialog"]:last-of-type button.modal-container__close'].join(', ');
(document.querySelector(selectors) as HTMLElement)?.click?.();
});
export function confirmDestructive(options: ConfirmOptions): Promise<boolean> { export function confirmDestructive(options: ConfirmOptions): Promise<boolean> {
const opts: ConfirmOptions = Object.assign( const opts: ConfirmOptions = Object.assign(
{ {
@ -55,7 +65,10 @@ export function confirmDestructive(options: ConfirmOptions): Promise<boolean> {
// Watch changes to body // Watch changes to body
observer.observe(document.body, { childList: true }); observer.observe(document.body, { childList: true });
return new Promise((resolve) => oc_dialogs.confirmDestructive(opts.message, opts.title, opts, resolve)); return fragment.wrap(
new Promise((resolve) => oc_dialogs.confirmDestructive(opts.message, opts.title, opts, resolve)),
fragment.types.dialog,
);
} }
type PromptOptions = { type PromptOptions = {
@ -84,6 +97,50 @@ export async function prompt(opts: PromptOptions): Promise<string | null> {
}); });
} }
/**
* Choose a folder using the NC file picker
*
* @param title Title of the file picker
* @param initial Initial path
* @param type Type of the file picker
*
* @returns The path of the chosen folder
*/
export async function chooseNcFolder(
title: string,
initial: string = '/',
type: FilePickerType = FilePickerType.Choose,
) {
const picker = getFilePickerBuilder(title)
.setMultiSelect(false)
.setModal(true)
.setType(type)
.addMimeTypeFilter('httpd/unix-directory')
.allowDirectories()
.startAt(initial)
.build();
// Choose a folder
const promise = fragment.wrap(picker.pick(), fragment.types.dialog);
let folder = (await promise) || '/';
// Remove double slashes
folder = folder.replace(/\/+/g, '/');
// Look for any trailing or leading whitespace
if (folder.trim() !== folder) {
showError(
t(
'memories',
'The folder name "{folder}" has a leading or trailing whitespace. This may lead to errors and should be corrected.',
{ folder },
),
);
}
return folder;
}
/** Bespoke confirmation dialogs for re-use */ /** Bespoke confirmation dialogs for re-use */
export const dialogs = { export const dialogs = {
moveToTrash: (count: number) => moveToTrash: (count: number) =>

View File

@ -8,6 +8,7 @@ enum FragmentType {
sidebar = 'i', sidebar = 'i',
editor = 'e', editor = 'e',
settings = 'ss', settings = 'ss',
dialog = 'd',
} }
/** Names of fragments */ /** Names of fragments */
@ -160,6 +161,18 @@ export const fragment = {
else await this.pop(type); else await this.pop(type);
}, },
/**
* Wrap a promise as a route fragment.
*/
async wrap<T>(promise: Promise<T>, type: FragmentType, ...args: string[]): Promise<T> {
await this.push(type, ...args);
try {
return await promise;
} finally {
await this.pop(type);
}
},
get viewer() { get viewer() {
return this.get(FragmentType.viewer); return this.get(FragmentType.viewer);
}, },

View File

@ -1,7 +1,4 @@
import { FilePickerType, getFilePickerBuilder } from '@nextcloud/dialogs';
import { getCurrentUser } from '@nextcloud/auth'; import { getCurrentUser } from '@nextcloud/auth';
import { showError } from '@nextcloud/dialogs';
import { translate as t } from '@nextcloud/l10n';
import { API } from '../API'; import { API } from '../API';
import { constants as c } from './const'; import { constants as c } from './const';
@ -190,49 +187,6 @@ export function setupLivePhotoHooks(video: HTMLVideoElement) {
}; };
} }
/**
* Choose a folder using the NC file picker
*
* @param title Title of the file picker
* @param initial Initial path
* @param type Type of the file picker
*
* @returns The path of the chosen folder
*/
export async function chooseNcFolder(
title: string,
initial: string = '/',
type: FilePickerType = FilePickerType.Choose,
) {
const picker = getFilePickerBuilder(title)
.setMultiSelect(false)
.setModal(true)
.setType(type)
.addMimeTypeFilter('httpd/unix-directory')
.allowDirectories()
.startAt(initial)
.build();
// Choose a folder
let folder = (await picker.pick()) || '/';
// Remove double slashes
folder = folder.replace(/\/+/g, '/');
// Look for any trailing or leading whitespace
if (folder.trim() !== folder) {
showError(
t(
'memories',
'The folder name "{folder}" has a leading or trailing whitespace. This may lead to errors and should be corrected.',
{ folder },
),
);
}
return folder;
}
/** /**
* Check if the provided Axios Error is a network error. * Check if the provided Axios Error is a network error.
*/ */