refactor: extract batch folder prompt dialog to src/batch.ts

Move the inline Modal dialog for batch folder selection into a reusable
promptForBatchFolder function. Removes Modal import from main.ts.
main.ts now 775 lines.

Change-Id: I7a5c62b7df95635dcbe0ac814007838ff83eded4
This commit is contained in:
fancivez 2026-04-27 13:16:13 +08:00 committed by wujunchen
parent 50a3c4bec3
commit ba6e44194a
3 changed files with 50 additions and 46 deletions

44
main.js

File diff suppressed because one or more lines are too long

27
main.ts
View file

@ -1,5 +1,5 @@
'use strict';
import { MarkdownView, Modal, Notice, Plugin, TFile } from 'obsidian';
import { MarkdownView, Notice, Plugin, TFile } from 'obsidian';
import {
type BatchRunState,
batchProgressVars,
@ -8,6 +8,7 @@ import {
hasUnsafeBatchFolderSegments,
markBatchFileRunning,
normalizeBatchFolderInput,
promptForBatchFolder,
recordBatchError,
recordBatchProcessed,
recordBatchSkip,
@ -552,29 +553,7 @@ class ParallelReaderPlugin extends Plugin {
new Notice(this.t('batchAlreadyRunning'));
return;
}
const selectFolderText = this.t('batchSelectFolder');
const folderPromptText = this.t('batchFolderPrompt');
const folderPath = await new Promise<string | null>((resolve) => {
const modal = new Modal(this.app);
modal.onOpen = () => {
modal.contentEl.createEl('p', { text: selectFolderText });
const field = modal.contentEl.createDiv({ cls: 'parallel-reader-modal-field' });
const input = field.createEl('input', { type: 'text' });
input.placeholder = folderPromptText;
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
resolve(input.value.trim());
modal.close();
}
});
modal.contentEl.createEl('button', { text: 'OK' }).addEventListener('click', () => {
resolve(input.value.trim());
modal.close();
});
};
modal.onClose = () => resolve(null);
modal.open();
});
const folderPath = await promptForBatchFolder(this.app, this.t('batchSelectFolder'), this.t('batchFolderPrompt'));
if (folderPath === null) return;
const validation = validateBatchFolderInput(folderPath, (path) => {
const target = this.app.vault.getAbstractFileByPath(path);

View file

@ -1,5 +1,6 @@
'use strict';
import { type App, Modal } from 'obsidian';
import { cacheEntryMatches } from './settings';
import type { CacheEntry, PluginSettings } from './types';
@ -102,3 +103,27 @@ export function requestBatchCancel(state: BatchRunState | null): boolean {
state.cancelled = true;
return true;
}
export function promptForBatchFolder(app: App, selectText: string, promptText: string): Promise<string | null> {
return new Promise<string | null>((resolve) => {
const modal = new Modal(app);
modal.onOpen = () => {
modal.contentEl.createEl('p', { text: selectText });
const field = modal.contentEl.createDiv({ cls: 'parallel-reader-modal-field' });
const input = field.createEl('input', { type: 'text' });
input.placeholder = promptText;
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
resolve(input.value.trim());
modal.close();
}
});
modal.contentEl.createEl('button', { text: 'OK' }).addEventListener('click', () => {
resolve(input.value.trim());
modal.close();
});
};
modal.onClose = () => resolve(null);
modal.open();
});
}