import { App, ButtonComponent, DropdownComponent, Modal, SearchComponent, Setting, TextComponent, ValueComponent, } from "obsidian"; import DoubanPlugin from "../../main"; import {i18nHelper} from "src/org/wanxp/lang/helper"; import HandleContext from "../data/model/HandleContext"; import { DEFAULT_SETTINGS_ARRAY_INPUT_SIZE, SupportType, SyncConditionType, SyncConditionTypeRecords, SyncType, SyncTypeRecords } from "../../constant/Constsant"; import { ALL, DoubanSubjectState, DoubanSubjectStateRecords, DoubanSubjectStateRecords_BOOK_SYNC, DoubanSubjectStateRecords_BROADCAST_SYNC, DoubanSubjectStateRecords_GAME_SYNC, DoubanSubjectStateRecords_MOVIE_SYNC, DoubanSubjectStateRecords_MUSIC_SYNC, DoubanSubjectStateRecords_NOTE_SYNC, DoubanSubjectStateRecords_TELEPLAY_SYNC } from "../../constant/DoubanUserState"; import {SyncConfig} from "../sync/model/SyncConfig"; import {clearInterval} from "timers"; import {FolderSuggest} from "../setting/model/FolderSuggest"; import {DEFAULT_SETTINGS} from "../../constant/DefaultSettings"; import {createFileSelectionSetting} from "../setting/TemplateSettingHelper"; import {FileSuggest} from "../setting/model/FileSuggest"; import {getDefaultTemplateContent} from "../../constant/DefaultTemplateContent"; import TimeUtil from "../../utils/TimeUtil"; import SettingsManager from "../setting/SettingsManager"; import {ArraySetting, DEFAULT_SETTINGS_ARRAY_NAME} from "../setting/model/ArraySetting"; import {arraySettingDisplay} from "../setting/ArrayDisplayTypeSettingsHelper"; import {DatePickComponent} from "./DatePickComponent"; import {NumberComponent} from "./NumberComponent"; import {log} from "../../utils/Logutil"; export class DoubanSyncModal extends Modal { plugin: DoubanPlugin; context: HandleContext timer: any; constructor(app: App, plugin: DoubanPlugin, context: HandleContext) { super(app); this.plugin = plugin; this.context = context; } onOpen() { let {contentEl} = this; this.show(contentEl); } private show(contentEl: HTMLElement) { contentEl.empty(); if (this.plugin.statusHolder.syncing()) { this.showSyncStatus(contentEl); } else { this.showSyncConfig(contentEl); } } private showSyncStatus(contentEl: HTMLElement) { const {syncStatus} = this.plugin.statusHolder; const {syncConfig} = syncStatus; contentEl.createEl("h3", {text: i18nHelper.getMessage('500002')}); this.showConfigPan(contentEl.createDiv('config'), syncConfig, true); const sliderDiv = contentEl.createEl('div'); sliderDiv.addClass('obsidian_douban_sync_slider'); const controls = contentEl.createDiv("controls"); const stopButton = new ButtonComponent(controls) .setButtonText(i18nHelper.getMessage('110009')) .onClick(async () => { this.close(); await this.plugin.statusHolder.stopSync(); }) const backgroundButton = new ButtonComponent(controls) .setButtonText(i18nHelper.getMessage('110010')) .onClick(() => { this.close(); }); this.showProgress(sliderDiv, backgroundButton, stopButton); this.timer = setInterval(() => { this.showProgress(sliderDiv,backgroundButton, stopButton); }, 1000); backgroundButton.setClass("obsidian_douban_status_button"); stopButton.setClass("obsidian_douban_status_button"); } private showProgress(sliderDiv: HTMLDivElement, backgroundButton:ButtonComponent, stopButton:ButtonComponent) { sliderDiv.empty(); new Setting(sliderDiv); let progress = sliderDiv.createDiv('progress'); const {syncStatus} = this.plugin.statusHolder; if (!this.plugin.statusHolder.syncStarted) { progress.innerHTML = `

${syncStatus.getHasHandle()}/${syncStatus.getTotal()}:${i18nHelper.getMessage('110036')}

${i18nHelper.getMessage('110090', syncStatus.getTypeName(), syncStatus.getScopeName(), syncStatus.getAllTotal(), syncStatus.getTotal())}

${syncStatus.getMessage()}

` backgroundButton.setDisabled(true); stopButton.setButtonText(i18nHelper.getMessage('110036')) return; } progress.innerHTML = `

${syncStatus.getTotal() == 0 ? i18nHelper.getMessage('110043') : syncStatus.getHasHandle() + '/' + syncStatus.getTotal()} ${syncStatus.getHandle() == 0? '...' : i18nHelper.getMessage('110042') + ':' + TimeUtil.estimateTimeMsg(syncStatus.getNeedHandled()-syncStatus.getHandle(), syncStatus.getOverSize())}

${i18nHelper.getMessage('110090', syncStatus.getTypeName(), syncStatus.getScopeName(), syncStatus.getAllTotal(), syncStatus.getTotal())}

${syncStatus.getMessage()}

`} private showSyncConfig(contentEl: HTMLElement) { if (this.timer != null) { clearInterval(this.timer) } contentEl.createEl("h3", {text: i18nHelper.getMessage('500001')}); const {settings} = this.plugin; let syncConfig:SyncConfig = {syncType: SyncType.movie, scope: ALL, force: false, dataFilePath: (settings.dataFilePath == '' || settings.dataFilePath == null) ? DEFAULT_SETTINGS.dataFilePath : settings.dataFilePath, dataFileNamePath: (settings.dataFileNamePath == '' || settings.dataFileNamePath == null) ? DEFAULT_SETTINGS.dataFileNamePath : settings.dataFileNamePath, cacheImage: ( settings.cacheImage == null) ? DEFAULT_SETTINGS.cacheImage : settings.cacheImage, cacheHighQuantityImage: ( settings.cacheHighQuantityImage == null) ? DEFAULT_SETTINGS.cacheHighQuantityImage : settings.cacheHighQuantityImage, attachmentPath: (settings.attachmentPath == '' || settings.attachmentPath == null) ? DEFAULT_SETTINGS.attachmentPath : settings.attachmentPath, attachmentFileName: (settings.attachmentFileName == '' || settings.attachmentFileName == null) ? DEFAULT_SETTINGS.attachmentFileName : settings.attachmentFileName, templateFile: (settings.movieTemplateFile == '' || settings.movieTemplateFile == null) ? DEFAULT_SETTINGS.movieTemplateFile : settings.movieTemplateFile, incrementalUpdate: true, syncConditionType: SyncConditionType.ALL, syncConditionDateFromValue: TimeUtil.getLastMonth(), syncConditionDateToValue: new Date(), syncConditionCountFromValue: 1, syncConditionCountToValue: 30 }; this.showConfigPan(contentEl.createDiv('config'), syncConfig, false); const controls = contentEl.createDiv("controls"); const cancelButton = new ButtonComponent(controls) .setButtonText(i18nHelper.getMessage('110005')) .onClick(() => { this.close(); }); const syncButton = new ButtonComponent(controls) .setButtonText(i18nHelper.getMessage('110007')) .onClick(async () => { if(!await this.plugin.checkLogin(this.context)) { return; } syncButton.setDisabled(true); if(!this.plugin.statusHolder.startSync(syncConfig)) { return; } this.updateContextByConfig(syncConfig); this.show(contentEl); await this.plugin.sync(this.context); }) syncButton.setClass("obsidian_douban_search_button"); cancelButton.setClass("obsidian_douban_search_button"); } private updateContextByConfig(syncConfig: SyncConfig) { const { context} = this; context.syncConfig = syncConfig; context.syncActive = true; } private showConfigPan(contentEl: HTMLElement, config:SyncConfig, disable:boolean) { new Setting(contentEl); this.showTypeDropdown(contentEl, config, disable); this.showCondition(contentEl, config, disable); // this.showOutputFolderSelections(contentEl, config, disable); // this.showOutiFleName(contentEl, config, disable); // this.showAttachmentsFileConfig(contentEl, config, disable); this.showUpdateAllConfig(contentEl, config, disable); this.showForceUpdateConfig(contentEl, config, disable); } async onClose() { let {contentEl} = this; contentEl.empty(); if (this.timer != null) { clearInterval(this.timer); } } private openScopeDropdown(contentEl:HTMLDivElement, config: SyncConfig, disable:boolean) { switch (config.syncType) { case SyncType.movie: this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_MOVIE_SYNC, config, disable); break; case SyncType.book: this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_BOOK_SYNC, config, disable); break; case SyncType.broadcast: this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_BROADCAST_SYNC, config, disable); break; case SyncType.note: this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_NOTE_SYNC, config, disable); break; case SyncType.music: this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_MUSIC_SYNC, config, disable); break; case SyncType.teleplay: this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_TELEPLAY_SYNC, config, disable); break; case SyncType.game: config.scope = DoubanSubjectState.collect; this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_GAME_SYNC, config, disable); break; } } private showTypeDropdown(containerEl:HTMLElement, config: SyncConfig, disable:boolean) { const settings = new Setting(containerEl); const scopeSelections = containerEl.createDiv("scope-selection"); // const templateFile:HTMLDivElement = containerEl.createDiv('template-file-path-selection'); settings .setName(i18nHelper.getMessage('110030')) .addDropdown((dropdown) => { dropdown.addOptions(SyncTypeRecords) .setValue(config.syncType) .onChange((value) => { config.syncType = value; config.templateFile = this.getDefaultTemplatePath(value); this.openScopeDropdown(scopeSelections, config, disable); // this.showTemplateFileSelectionSetting(templateFile, config, disable); }); }).setDisabled(disable); this.openScopeDropdown(scopeSelections, config, disable); // this.showTemplateFileSelectionSetting(templateFile, config, disable); } private getDefaultTemplatePath(value: string) { let result:string = ""; const {settings} = this.plugin; switch (value) { case SyncType.movie: result = (settings.movieTemplateFile == '' || settings.movieTemplateFile == null) ? DEFAULT_SETTINGS.movieTemplateFile : settings.movieTemplateFile break; case SyncType.book: result = (settings.bookTemplateFile == '' || settings.bookTemplateFile == null) ? DEFAULT_SETTINGS.bookTemplateFile : settings.bookTemplateFile break; case SyncType.music: result = (settings.musicTemplateFile == '' || settings.musicTemplateFile == null) ? DEFAULT_SETTINGS.musicTemplateFile : settings.musicTemplateFile break; case SyncType.teleplay: result = (settings.teleplayTemplateFile == '' || settings.teleplayTemplateFile == null) ? DEFAULT_SETTINGS.teleplayTemplateFile : settings.teleplayTemplateFile break; case SyncType.game: result = (settings.gameTemplateFile == '' || settings.gameTemplateFile == null) ? DEFAULT_SETTINGS.gameTemplateFile : settings.gameTemplateFile break; } return result; } private showScopeDropdown(containerEl:HTMLDivElement, scopeSelections: Record, config: SyncConfig, disable:boolean) { containerEl.empty(); new Setting(containerEl) .setName(i18nHelper.getMessage('110032')) .addDropdown((dropdown) => { dropdown.addOptions(scopeSelections) dropdown.setValue(config.scope) .onChange(async (value: string) => { config.scope = value; }); }).setDisabled(disable); } private showOutiFleName(containerEl: HTMLElement, config: SyncConfig, disable:boolean) { const dataFilePathSetting = new Setting(containerEl) .setName(i18nHelper.getMessage('121601')) .setDesc(i18nHelper.getMessage('121602')) .addText((textField) => { textField.setPlaceholder(i18nHelper.getMessage('121602')) .setValue(config.dataFileNamePath) .onChange(async (value) => { config.dataFileNamePath = value }); }) .setDisabled(disable); } showOutputFolderSelections(containerEl: HTMLElement, config: SyncConfig, disable:boolean) { new Setting(containerEl) .setName( i18nHelper.getMessage('121501')) .setDesc( i18nHelper.getMessage('121502')) .addSearch(async (search: SearchComponent) => { new FolderSuggest(this.app, search.inputEl); // @ts-ignore search.setValue(config.dataFilePath) // @ts-ignore .setPlaceholder(i18nHelper.getMessage('121503')) .onChange(async (value: string) => { config.dataFilePath = value; }); }) .setDisabled(disable); } showTemplateFileSelectionSetting(containerEl: HTMLElement, config: SyncConfig, disable:boolean) { containerEl.empty(); const key:string = this.getKey(config.syncType); // @ts-ignore let setting = new Setting(containerEl) .setName(i18nHelper.getMessage('121101')) .setDesc(i18nHelper.getMessage('121102')) .addSearch(async (search: SearchComponent) => { new FileSuggest(this.app, search.inputEl); // @ts-ignore search.setValue(config.templateFile) // @ts-ignore .onChange(async (value: string) => { config.templateFile = value; }); }) .setDisabled(disable); setting.addExtraButton((button) => { button .setIcon('copy') .setTooltip(i18nHelper.getMessage('121903')) .onClick(async () => { // @ts-ignore navigator.clipboard.writeText(getDefaultTemplateContent(key)); }); }); setting.addExtraButton((button) => { button .setIcon('document') .setTooltip(i18nHelper.getMessage('121901')) .onClick(async () => { // @ts-ignore navigator.clipboard.writeText(getDefaultTemplateContent(key, false)) }); }); } private getKey(supportType: string) { return supportType + 'TemplateFile'; } showForceUpdateConfig(containerEl: HTMLElement, config: SyncConfig, disable:boolean) { new Setting(containerEl) .setName(i18nHelper.getMessage('110031')) .setDesc(i18nHelper.getMessage('500110')) .addToggle((toggleComponent) => { toggleComponent // .setTooltip(i18nHelper.getMessage('121403')) .setValue(config.force) .onChange(async (value) => { config.force = value; }); }) .setDisabled(disable); } showAttachmentsFileConfig(containerEl: HTMLElement, config: SyncConfig, disable:boolean) { const settings = new Setting(containerEl); let attachmentFileEl = containerEl.createDiv('attachment-file-path-selection'); settings.setName(i18nHelper.getMessage('121430')) .setDesc(i18nHelper.getMessage('121431')) .addToggle((toggleComponent) => { toggleComponent // .setTooltip(i18nHelper.getMessage('121403')) .setValue(config.cacheImage) .onChange(async (value) => { config.cacheImage = value; this.showAttachmentPathSelections(value, attachmentFileEl, config, disable); }); }) .setDisabled(disable); this.showAttachmentPathSelections(config.cacheImage, attachmentFileEl, config, disable); } showAttachmentPathSelections(show:boolean, containerEl: HTMLElement, config: SyncConfig, disable:boolean) { containerEl.empty(); if (!show) { return; } new Setting(containerEl) .setName( i18nHelper.getMessage('121432')) .setDesc( i18nHelper.getMessage('121433')) .addSearch(async (search: SearchComponent) => { new FolderSuggest(this.plugin.app, search.inputEl); // @ts-ignore search.setValue(config.attachmentPath) // @ts-ignore .setPlaceholder(i18nHelper.getMessage('121434')) .onChange(async (value: string) => { config.attachmentPath = value; }); }) .setDisabled(disable); new Setting(containerEl) .setName( i18nHelper.getMessage('121452')) .setDesc( i18nHelper.getMessage('121453')) .addSearch(async (search: SearchComponent) => { new FolderSuggest(this.plugin.app, search.inputEl); // @ts-ignore search.setValue(config.attachmentFileName) // @ts-ignore .setPlaceholder(i18nHelper.getMessage('121454')) .onChange(async (value: string) => { config.attachmentFileName = value; }); }) .setDisabled(disable); new Setting(containerEl) .setName(i18nHelper.getMessage('121435')) .setDesc(i18nHelper.getMessage('121438')) .addToggle((toggleComponent) => { toggleComponent .setValue(config.cacheHighQuantityImage) .onChange(async (value) => { config.cacheHighQuantityImage = value; }); }) .setDisabled(disable); } showUpdateAllConfig(containerEl: HTMLElement, config: SyncConfig, disable:boolean) { new Setting(containerEl) .setName(i18nHelper.getMessage('110039')) .setDesc(i18nHelper.getMessage('110040')) .addToggle((toggleComponent) => { toggleComponent .setTooltip(i18nHelper.getMessage('110040')) .setValue(config.incrementalUpdate) .onChange(async (value) => { config.incrementalUpdate = value; }); }) .setDisabled(disable); } private showCondition(contentEl: HTMLElement, config: SyncConfig, disable: boolean) { showConditionItem(contentEl.createDiv("sync-douban-condition"), this.plugin.settingsManager, config, disable); } } function showConditionItem(containerEl: HTMLElement, manager: SettingsManager, config: SyncConfig, disable: boolean) { containerEl.empty(); const condition = new Setting(containerEl).setName(i18nHelper.getMessage('110070')) const conditionDesc = condition.descEl.createDiv('sync-douban-condition-desc'); new DropdownComponent(conditionDesc).addOptions(SyncConditionTypeRecords) .setValue(config.syncConditionType) .onChange((value) => { config.syncConditionType = value; showConditionItem(containerEl, manager, config, disable); }).setDisabled(disable); showConditionItemInput(conditionDesc, config, disable); } function showConditionItemInput(containerEl: HTMLElement, config: SyncConfig, disable: boolean) { if (config.syncConditionType == SyncConditionType.CUSTOM_ITEM) { showCustomInputCount(containerEl, config, disable); }else if (config.syncConditionType == SyncConditionType.CUSTOM_TIME) { showCustomInputTime(containerEl, config, disable); } } function showCustomInputCount(containerEl: HTMLElement, config: SyncConfig, disable: boolean) { containerEl.createEl('span', { text: ' ' }) containerEl.createEl('span', { text: i18nHelper.getMessage('110077') }) containerEl.createEl('span', { text: i18nHelper.getMessage('110078') }) const fromField = new TextComponent(containerEl); fromField.setPlaceholder(i18nHelper.getMessage('110080')) .setValue(config.syncConditionCountFromValue + '') .onChange(async (value) => { if (!value) { config.syncConditionCountFromValue = 1; return; } try { config.syncConditionCountFromValue = parseInt(value); }catch (e) { log.notice(i18nHelper.getMessage('112080')) } }).setDisabled(disable); let fromEl = fromField.inputEl; fromEl.addClass('obsidian_douban_settings_input') fromEl.style.width ='20%'; containerEl.appendChild(fromEl); const lang = window.localStorage.getItem('language'); if (lang == 'zh') { containerEl.createEl('span', {text: i18nHelper.getMessage('110073')}) } containerEl.createEl('span', { text: i18nHelper.getMessage('110079') }) containerEl.createEl('span', { text: i18nHelper.getMessage('110078') }) const toField = new TextComponent(containerEl); toField.setPlaceholder(i18nHelper.getMessage('110080')) .setValue(config.syncConditionCountToValue + '') .onChange(async (value) => { if (!value) { config.syncConditionCountToValue = 30; return; } try { config.syncConditionCountToValue = parseInt(value); }catch (e) { log.notice(i18nHelper.getMessage('112080')) } }).setDisabled(disable); let toEl = toField.inputEl; toEl.addClass('obsidian_douban_settings_input') toEl.style.width ='20%'; containerEl.appendChild(toEl); if (lang == 'zh') { containerEl.createEl('span', {text: i18nHelper.getMessage('110073')}) } containerEl.createEl('span', {text: ' '}) const buttopn = new ButtonComponent(containerEl).setIcon('help').setTooltip(i18nHelper.getMessage('110095')) containerEl.appendChild(buttopn.buttonEl); } function showCustomInputTime(containerEl: HTMLElement, config: SyncConfig, disable: boolean) { containerEl.createEl('span', { text: i18nHelper.getMessage('110077') }) const fromDateField = new TextComponent(containerEl); const fromDateEl = fromDateField.inputEl; fromDateEl.type = 'date'; fromDateEl.value = config.syncConditionDateFromValue ? config.syncConditionDateFromValue.toISOString().substring(0, 10) : TimeUtil.getLastMonth().toISOString().substring(0, 10); fromDateField.setPlaceholder(i18nHelper.getMessage('110075')) .setValue(config.syncConditionDateFromValue ? config.syncConditionDateFromValue.toISOString().substring(0, 10) : TimeUtil.getLastMonth().toISOString().substring(0, 10)) .onChange(async (value) => { if (!value) { return; } try { config.syncConditionDateFromValue = new Date(value); }catch (e) { log.notice(i18nHelper.getMessage('110082')) } }).setDisabled(disable); fromDateEl.addClass('obsidian_douban_settings_input') containerEl.appendChild(fromDateEl); containerEl.createEl('span', { text: i18nHelper.getMessage('110079') }) const toDateField = new TextComponent(containerEl); let toDateEl = toDateField.inputEl; toDateEl.type = 'date'; toDateEl.value = config.syncConditionDateToValue ? config.syncConditionDateToValue.toISOString().substring(0, 10) : new Date().toISOString().substring(0, 10); toDateField.setPlaceholder(i18nHelper.getMessage('110075')) .setValue(config.syncConditionDateToValue ? config.syncConditionDateToValue.toISOString().substring(0, 10) : new Date().toISOString().substring(0, 10)) .onChange(async (value) => { if (!value) { return; } try { config.syncConditionDateToValue = new Date(value); }catch (e) { log.notice(i18nHelper.getMessage('110082')) } }).setDisabled(disable); toDateEl.addClass('obsidian_douban_settings_input') containerEl.appendChild(toDateEl); new ButtonComponent(containerEl).setIcon('help').setTooltip(i18nHelper.getMessage('110095')) }