Merge branch 'feature/enableAutomaticFileSync' into dev

This commit is contained in:
Grol Grol 2025-04-25 03:25:54 +03:00
commit d1a76ae87c
4 changed files with 62 additions and 37 deletions

View file

@ -24,10 +24,10 @@ export class FileLoadEventHandler {
//запуск плагина при открытии файла
this.plugin.registerEvent(
this.app.workspace.on("file-open", async (file) => {
if (file) {
if (file && file.extension === "md") {
console.log(`file-open ${file.path}`);
const isUpdate = await this.fileStateHolder.initIfNeeded(file);
if (isUpdate) {
if (isUpdate && this.plugin.settings.enableAutomaticFileSync) {
await this.syncController.syncFile(file);
}
}
@ -38,9 +38,9 @@ export class FileLoadEventHandler {
// console.log(`MarkdownPostProcessor "${ctx.sourcePath}"`);
await this.markdownPostProcessorMutex.runExclusive(async () => {
const file = this.app.vault.getAbstractFileByPath(ctx.sourcePath);
if (file instanceof TFile) {
if (file instanceof TFile && file.extension === "md") {
const isUpdate = await this.fileStateHolder.initIfNeeded(file);
if (isUpdate) {
if (isUpdate && this.plugin.settings.enableAutomaticFileSync) {
await this.syncController.syncFile(file);
}
}
@ -49,9 +49,11 @@ export class FileLoadEventHandler {
this.plugin.registerEvent(
this.app.workspace.on('quick-preview', async (file: TFile, data: string) => {
const isUpdate = await this.fileStateHolder.initIfNeeded(file, data);
if (isUpdate) {
await this.syncController.syncFile(file);
if (file && file.extension === "md") {
const isUpdate = await this.fileStateHolder.initIfNeeded(file, data);
if (isUpdate && this.plugin.settings.enableAutomaticFileSync) {
await this.syncController.syncFile(file);
}
}
})
);
@ -78,21 +80,25 @@ export class FileLoadEventHandler {
await this.findEmbedsRecursive(file, filesToInitialize);
for (const fileToInit of filesToInitialize) {
try {
const isUpdateNeeded = await this.fileStateHolder.initIfNeeded(fileToInit);
// Синхронизируем только если инициализация это потребовала,
// ИЛИ если это основной файл, открытый в редакторе (на всякий случай)
if (isUpdateNeeded || (fileToInit === file && view.getMode() === 'source')) {
// Если основной файл в редакторе, лучше вызвать syncEditor для него
if (fileToInit === file && view.getMode() === 'source') {
await this.syncController.syncEditor(view.editor, view);
} else {
await this.syncController.syncFile(fileToInit);
}
}
} catch (error) {
console.error(`Error processing file ${fileToInit.path} during initial load:`, error);
try {
const isUpdateNeeded = await this.fileStateHolder.initIfNeeded(fileToInit);
//skip if settings enableAutomaticFileSync === false
if(this.plugin.settings.enableAutomaticFileSync === false){
continue;
}
// Синхронизируем только если инициализация это потребовала,
// ИЛИ если это основной файл, открытый в редакторе (на всякий случай)
if (isUpdateNeeded || (fileToInit === file && view.getMode() === 'source')) {
// Если основной файл в редакторе, лучше вызвать syncEditor для него
if (fileToInit === file && view.getMode() === 'source') {
await this.syncController.syncEditor(view.editor, view);
} else {
await this.syncController.syncFile(fileToInit);
}
}
} catch (error) {
console.error(`Error processing file ${fileToInit.path} during initial load:`, error);
}
}
}
@ -102,16 +108,16 @@ export class FileLoadEventHandler {
if (!cache?.embeds) return;
for (const embed of cache.embeds) {
const embedFile = this.app.metadataCache.getFirstLinkpathDest(embed.link, file.path);
if (!embedFile) continue;
const embedFile = this.app.metadataCache.getFirstLinkpathDest(embed.link, file.path);
if (!embedFile) continue;
if (embedFile instanceof TFile && embedFile.extension === 'md') {
// Если файл еще не посещали, добавляем и ищем его внедрения
if (!visited.has(embedFile)) {
visited.add(embedFile);
await this.findEmbedsRecursive(embedFile, visited);
}
if (embedFile instanceof TFile && embedFile.extension === 'md') {
// Если файл еще не посещали, добавляем и ищем его внедрения
if (!visited.has(embedFile)) {
visited.add(embedFile);
await this.findEmbedsRecursive(embedFile, visited);
}
}
}
}
}
}

View file

@ -41,12 +41,15 @@ export default class CheckboxSyncPlugin extends Plugin {
async updateSettings(callback: (settings: CheckboxSyncPluginSettings) => void | Promise<void>) {
await callback(this._settings);
await this.saveData(this.settings);
//надо пересинхронизировать все файлы в кеше
const allFile = this.fileStateHolder.getAllFiles();
await Promise.all(
allFile.map(async (file: TFile) => {
await this.syncController.syncFile(file);
})
);
if (this.settings.enableAutomaticFileSync) {
//надо пересинхронизировать все файлы в кеше
const allFile = this.fileStateHolder.getAllFiles();
await Promise.all(
allFile.map(async (file: TFile) => {
await this.syncController.syncFile(file);
})
);
}
}
}

View file

@ -5,6 +5,7 @@ export interface CheckboxSyncPluginSettings {
uncheckedSymbols: string[];
ignoreSymbols: string[];
unknownSymbolPolicy: CheckboxState;
enableAutomaticFileSync: boolean;
}
export enum CheckboxState {
@ -20,4 +21,5 @@ export const DEFAULT_SETTINGS: CheckboxSyncPluginSettings = {
uncheckedSymbols: [' '],
ignoreSymbols: [],
unknownSymbolPolicy: CheckboxState.Checked,
enableAutomaticFileSync: false,
};

View file

@ -12,6 +12,7 @@ export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
private unknownPolicyDropdown: DropdownComponent;
private parentToggle: ToggleComponent;
private childToggle: ToggleComponent;
private enableAutomaticFileSyncToggle: ToggleComponent;
private applyButton: ButtonComponent;
private resetToDefaultButton: ButtonComponent;
private errorDisplayEl: HTMLElement;
@ -177,6 +178,16 @@ export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
.onChange(() => this.settingChanged())
});
new Setting(containerEl)
.setName("Enable automatic file synchronization")
.setDesc("If enabled (requires restart or settings reload), automatically syncs checkbox states when files are loaded/opened and after settings changes. If disabled (default), sync only occurs when you manually change a checkbox.")
.addToggle(toggle => {
this.enableAutomaticFileSyncToggle = toggle;
toggle
.setValue(this.plugin.settings.enableAutomaticFileSync)
.onChange(() => this.settingChanged());
});
// --- Область для вывода ошибок ---
this.errorDisplayEl = containerEl.createDiv({ cls: 'checkbox-sync-settings-error' });
@ -265,6 +276,7 @@ export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
this.unknownPolicyDropdown.setValue(settings.unknownSymbolPolicy);
this.parentToggle.setValue(settings.enableAutomaticParentState);
this.childToggle.setValue(settings.enableAutomaticChildState);
this.enableAutomaticFileSyncToggle.setValue(settings.enableAutomaticFileSync);
// Очищаем ошибку и сбрасываем состояние "грязный"
this.errorDisplayEl?.setText('');
@ -353,6 +365,7 @@ export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
const policyValue = this.unknownPolicyDropdown.getValue() as CheckboxState;
const parentValue = this.parentToggle.getValue();
const childValue = this.childToggle.getValue();
const automaticFileSyncValue = this.enableAutomaticFileSyncToggle.getValue();
// 2. Парсим JSON
const parsedChecked = this.parseJsonStringArray(checkedValue);
@ -404,6 +417,7 @@ export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
settings.unknownSymbolPolicy = policyValue;
settings.enableAutomaticParentState = parentValue;
settings.enableAutomaticChildState = childValue;
settings.enableAutomaticFileSync = automaticFileSyncValue;
});
}
}