/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/main.ts var main_exports = {}; __export(main_exports, { default: () => DailyTaskPlugin }); module.exports = __toCommonJS(main_exports); var import_obsidian4 = require("obsidian"); // src/models/settings.ts var DEFAULT_TEMPLATE_ZH = `## {{date}}\uFF08{{weekday}}\uFF09 ### \u{1F9D8} \u4ECA\u65E5\u8BA1\u5212 --- - [ ] \u51A5\u60F3 10 \u5206\u949F - [ ] \u590D\u76D8\u524D\u4E00\u65E5\u8BA1\u5212 - [ ] \u9605\u8BFB 20 \u9875\u4E66 ### \u{1F4DD} \u5DE5\u4F5C\u4EFB\u52A1 --- - [ ] \u6574\u7406\u4ECA\u65E5\u5DE5\u4F5C\u8BA1\u5212 - [ ] \u5B8C\u6210\u91CD\u8981\u9879\u76EE\u8FDB\u5EA6 ### \u{1F319} \u665A\u95F4\u56DE\u987E --- - \u4ECA\u65E5\u5B8C\u6210\u5EA6: __% - \u660E\u65E5\u8BA1\u5212:`; var DEFAULT_TEMPLATE_EN = `## {{date}} ({{weekday}}) ### \u{1F9D8} Today's Plan --- - [ ] Meditate for 10 minutes - [ ] Review yesterday's plan - [ ] Read 20 pages ### \u{1F4DD} Work Tasks --- - [ ] Organize today's work schedule - [ ] Progress on important projects ### \u{1F319} Evening Review --- - Today's completion rate: __% - Tomorrow's plan:`; var DEFAULT_SETTINGS = { rootDir: "DailyTasks", autoGenerateMode: "none" /* NONE */, language: "auto" /* AUTO */, templateZh: DEFAULT_TEMPLATE_ZH, templateEn: DEFAULT_TEMPLATE_EN, successNotificationDuration: 3e3 }; // src/settings/settings.ts var import_obsidian3 = require("obsidian"); // src/i18n/i18n.ts var zhTranslations = { // 设置页面 "settings.title": "\u{1F4C5} \u6BCF\u65E5\u4EFB\u52A1\u81EA\u52A8\u751F\u6210\u5668", "settings.rootDir": "\u{1F4C1} \u4EFB\u52A1\u6587\u4EF6\u5B58\u653E\u76EE\u5F55", "settings.rootDir.desc": "\u751F\u6210\u7684\u4EFB\u52A1\u6587\u4EF6\u5C06\u4FDD\u5B58\u5728\u6B64\u76EE\u5F55\u4E0B", "settings.rootDir.saved": "\u2705 \u8DEF\u5F84\u8BBE\u7F6E\u5DF2\u4FDD\u5B58", "settings.save": "\u4FDD\u5B58", "settings.autoGenerate": "\u2699\uFE0F \u81EA\u52A8\u751F\u6210\u6A21\u5F0F", "settings.autoGenerate.desc": "\u8BBE\u7F6E\u4F55\u65F6\u81EA\u52A8\u751F\u6210\u4EFB\u52A1", "settings.mode.none": "\u5173\u95ED", "settings.mode.daily": "\u6BCF\u65E5\u81EA\u52A8\u751F\u6210", "settings.mode.workday": "\u4EC5\u5DE5\u4F5C\u65E5\u81EA\u52A8\u751F\u6210", "settings.language": "\u{1F310} \u754C\u9762\u8BED\u8A00", "settings.language.desc": "\u8BBE\u7F6E\u63D2\u4EF6\u754C\u9762\u8BED\u8A00\uFF08\u9700\u91CD\u542FObsidian\u751F\u6548\uFF09", "settings.language.auto": "\u81EA\u52A8\u68C0\u6D4B", "settings.language.zh": "\u4E2D\u6587", "settings.language.en": "\u82F1\u6587", "settings.animations": "UI\u52A8\u753B\u6548\u679C", "settings.animations.desc": "\u542F\u7528\u6216\u7981\u7528\u754C\u9762\u52A8\u753B\u6548\u679C", "settings.template": "\u{1F4DD} \u4EFB\u52A1\u6A21\u677F\u8BBE\u7F6E", "settings.template.zh": "\u4E2D\u6587\u6A21\u677F\uFF08\u5F53\u524D\u73AF\u5883\u4E3A\u4E2D\u6587\u65F6\u9ED8\u8BA4\u4F7F\u7528\uFF09", "settings.template.en": "\u82F1\u6587\u6A21\u677F\uFF08\u5F53\u524D\u73AF\u5883\u4E3A\u82F1\u6587\u65F6\u9ED8\u8BA4\u4F7F\u7528\uFF09", "settings.template.preview": "\u67E5\u770B\u9884\u89C8", "settings.template.hide": "\u6536\u8D77\u9884\u89C8", "settings.resetDefault": "\u6062\u590D\u9ED8\u8BA4", "settings.addTaskButton": "\u{1F4CB} \u624B\u52A8\u6DFB\u52A0\u4ECA\u65E5\u4EFB\u52A1", "settings.resetToDefault": "\u{1F504} \u6062\u590D\u9ED8\u8BA4\u8BBE\u7F6E", "settings.notificationDuration": "\u23F1\uFE0F \u901A\u77E5\u663E\u793A\u65F6\u95F4", "settings.notificationDuration.desc": "\u6210\u529F/\u5931\u8D25\u63D0\u793A\u663E\u793A\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09", // 通知 "notification.taskAdded": "\u5DF2\u6210\u529F\u6DFB\u52A0\u4ECA\u65E5\u4EFB\u52A1", "notification.taskExists": "\u4ECA\u65E5\u4EFB\u52A1\u5DF2\u5B58\u5728", "notification.error": "\u64CD\u4F5C\u51FA\u9519\uFF1A", // 星期 "weekday.mon": "\u661F\u671F\u4E00", "weekday.tue": "\u661F\u671F\u4E8C", "weekday.wed": "\u661F\u671F\u4E09", "weekday.thu": "\u661F\u671F\u56DB", "weekday.fri": "\u661F\u671F\u4E94", "weekday.sat": "\u661F\u671F\u516D", "weekday.sun": "\u661F\u671F\u65E5" }; var enTranslations = { // 设置页面 "settings.title": "\u{1F4C5} Daily Task Auto Generator", "settings.rootDir": "\u{1F4C1} Task Directory", "settings.rootDir.desc": "Generated tasks will be saved in this directory", "settings.rootDir.saved": "\u2705 Path settings saved", "settings.save": "Save", "settings.autoGenerate": "\u2699\uFE0F Auto Generate Mode", "settings.autoGenerate.desc": "Set when to automatically generate tasks", "settings.mode.none": "Off", "settings.mode.daily": "Daily", "settings.mode.workday": "Workdays Only", "settings.language": "\u{1F310} Language", "settings.language.desc": "Set plugin interface language (requires Obsidian restart)", "settings.language.auto": "Auto Detect", "settings.language.zh": "Chinese", "settings.language.en": "English", "settings.animations": "UI Animations", "settings.animations.desc": "Enable or disable interface animations", "settings.template": "\u{1F4DD} Task Template Settings", "settings.template.zh": "Chinese Template (used by default in Chinese environment)", "settings.template.en": "English Template (used by default in English environment)", "settings.template.preview": "Show Preview", "settings.template.hide": "Hide Preview", "settings.resetDefault": "Reset to Default", "settings.addTaskButton": "\u{1F4CB} Add Today's Tasks Manually", "settings.resetToDefault": "\u{1F504} Reset to Default Settings", "settings.notificationDuration": "\u23F1\uFE0F Notification Duration", "settings.notificationDuration.desc": "Duration to show success/failure notifications (milliseconds)", // 通知 "notification.taskAdded": "Today's tasks added successfully", "notification.taskExists": "Today's tasks already exist", "notification.error": "Error: ", // 星期 "weekday.mon": "Monday", "weekday.tue": "Tuesday", "weekday.wed": "Wednesday", "weekday.thu": "Thursday", "weekday.fri": "Friday", "weekday.sat": "Saturday", "weekday.sun": "Sunday" }; var translations = { "zh": zhTranslations, "en": enTranslations }; var currentLanguage = "en"; function setCurrentLanguage(language) { currentLanguage = language; } function getTranslation(key, fallbackLanguage) { var _a; const language = fallbackLanguage || currentLanguage; const translation = (_a = translations[language]) == null ? void 0 : _a[key]; if (!translation) { return translations["en"][key] || key; } return translation; } function getLocalizedWeekday(dayOfWeek) { const weekdayKeys = [ "weekday.sun", "weekday.mon", "weekday.tue", "weekday.wed", "weekday.thu", "weekday.fri", "weekday.sat" ]; const normalizedDayOfWeek = (dayOfWeek % 7 + 7) % 7; return getTranslation(weekdayKeys[normalizedDayOfWeek]); } // src/utils/dateUtils.ts function getCurrentYear() { return new Date().getFullYear().toString(); } function getCurrentMonth() { const month = (new Date().getMonth() + 1).toString(); return month.padStart(2, "0"); } function getLocalizedMonthName(isEnglish = false) { const monthIndex = new Date().getMonth(); const chineseMonths = [ "1\u6708", "2\u6708", "3\u6708", "4\u6708", "5\u6708", "6\u6708", "7\u6708", "8\u6708", "9\u6708", "10\u6708", "11\u6708", "12\u6708" ]; const englishMonths = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; return isEnglish ? englishMonths[monthIndex] : chineseMonths[monthIndex]; } function isEnglishEnvironment() { const mondayText = getTranslation("weekday.mon"); return mondayText === "Monday"; } function getCurrentDay() { const day = new Date().getDate().toString(); return day.padStart(2, "0"); } function getCurrentDate() { return `${getCurrentYear()}-${getCurrentMonth()}-${getCurrentDay()}`; } function isWorkday() { const day = new Date().getDay(); return day >= 1 && day <= 5; } function getCurrentWeekdayName() { const day = new Date().getDay(); return getLocalizedWeekday(day); } function getYearProgress() { const now = new Date(); const start = new Date(now.getFullYear(), 0, 1); const end = new Date(now.getFullYear() + 1, 0, 1); const totalDays = (end.getTime() - start.getTime()) / (1e3 * 60 * 60 * 24); const passedDays = (now.getTime() - start.getTime()) / (1e3 * 60 * 60 * 24); return Math.round(passedDays / totalDays * 100); } function getMonthProgress() { const now = new Date(); const start = new Date(now.getFullYear(), now.getMonth(), 1); const end = new Date(now.getFullYear(), now.getMonth() + 1, 1); const totalDays = (end.getTime() - start.getTime()) / (1e3 * 60 * 60 * 24); const passedDays = (now.getTime() - start.getTime()) / (1e3 * 60 * 60 * 24); return Math.round(passedDays / totalDays * 100); } // src/utils/templateEngine.ts function getDefaultTemplateVariables() { return { date: getCurrentDate(), weekday: getCurrentWeekdayName(), yearProgress: getYearProgress(), monthProgress: getMonthProgress(), time: new Date().toLocaleTimeString() }; } function renderTemplate(template, variables = getDefaultTemplateVariables()) { return template.replace(/\{\{([^}]+)\}\}/g, (match, variableName) => { const trimmedName = variableName.trim(); if (trimmedName in variables) { return String(variables[trimmedName]); } return match; }); } // src/taskGenerator.ts var import_obsidian2 = require("obsidian"); // src/utils/fileUtils.ts var import_obsidian = require("obsidian"); async function ensureFolderExists(vault, path) { try { path = path.endsWith("/") ? path : path + "/"; const folders = path.split("/").filter((p) => p.length > 0); let currentPath = ""; for (const folder of folders) { if (currentPath) { currentPath += "/" + folder; } else { currentPath = folder; } console.log(`\u68C0\u67E5\u76EE\u5F55: ${currentPath}`); const existingItem = vault.getAbstractFileByPath(currentPath); if (!existingItem) { console.log(`\u76EE\u5F55\u4E0D\u5B58\u5728\uFF0C\u6B63\u5728\u521B\u5EFA: ${currentPath}`); try { await vault.createFolder(currentPath); console.log(`\u76EE\u5F55\u521B\u5EFA\u6210\u529F: ${currentPath}`); } catch (e) { console.log(`\u521B\u5EFA\u76EE\u5F55\u65F6\u51FA\u73B0\u5F02\u5E38\uFF0C\u53EF\u80FD\u5DF2\u88AB\u5176\u4ED6\u8FDB\u7A0B\u521B\u5EFA: ${e}`); const folderAfterError = vault.getAbstractFileByPath(currentPath); if (!folderAfterError || !(folderAfterError instanceof import_obsidian.TFolder)) { console.error(`\u76EE\u5F55\u521B\u5EFA\u5931\u8D25\uFF0C\u4E14\u65E0\u6CD5\u786E\u8BA4\u76EE\u5F55\u5DF2\u5B58\u5728: ${currentPath}`); return false; } } } else if (!(existingItem instanceof import_obsidian.TFolder)) { console.error(`\u8DEF\u5F84 ${currentPath} \u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u6587\u4EF6\u5939\uFF0C\u800C\u662F: ${existingItem.constructor.name}`); return false; } else { console.log(`\u76EE\u5F55\u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u521B\u5EFA: ${currentPath}`); } } return true; } catch (error) { console.error(`\u521B\u5EFA\u76EE\u5F55\u65F6\u51FA\u73B0\u672A\u9884\u671F\u9519\u8BEF(${path}):`, error); return false; } } async function ensureFileExists(vault, path, content = "") { try { const existingItem = vault.getAbstractFileByPath(path); if (existingItem) { if (existingItem instanceof import_obsidian.TFile) { console.log(`\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u521B\u5EFA: ${path}`); return true; } else { console.error(`\u8DEF\u5F84 ${path} \u5B58\u5728\u4F46\u4E0D\u662F\u6587\u4EF6\uFF0C\u65E0\u6CD5\u521B\u5EFA\u6587\u4EF6\uFF0C\u53EF\u80FD\u662F\u540C\u540D\u76EE\u5F55`); return false; } } const lastSlashIndex = path.lastIndexOf("/"); if (lastSlashIndex > 0) { const parentPath = path.substring(0, lastSlashIndex); console.log(`\u68C0\u67E5\u6587\u4EF6\u7236\u76EE\u5F55: ${parentPath}`); const parentExists = await ensureFolderExists(vault, parentPath); if (!parentExists) { console.error(`\u65E0\u6CD5\u786E\u4FDD\u7236\u76EE\u5F55\u5B58\u5728: ${parentPath}`); return false; } } try { console.log(`\u5F00\u59CB\u521B\u5EFA\u6587\u4EF6: ${path}`); await vault.create(path, content); console.log(`\u6587\u4EF6\u521B\u5EFA\u6210\u529F: ${path}`); return true; } catch (e) { console.log(`\u521B\u5EFA\u6587\u4EF6\u65F6\u51FA\u73B0\u5F02\u5E38: ${e}`); const fileAfterError = vault.getAbstractFileByPath(path); if (fileAfterError && fileAfterError instanceof import_obsidian.TFile) { console.log(`\u5C3D\u7BA1\u51FA\u73B0\u5F02\u5E38\uFF0C\u4F46\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u53EF\u80FD\u88AB\u5176\u4ED6\u8FDB\u7A0B\u521B\u5EFA: ${path}`); return true; } console.error(`\u6587\u4EF6\u521B\u5EFA\u6700\u7EC8\u5931\u8D25: ${path}`); return false; } } catch (error) { console.error(`\u521B\u5EFA\u6587\u4EF6\u65F6\u51FA\u73B0\u672A\u9884\u671F\u9519\u8BEF(${path}):`, error); return false; } } async function appendToFile(vault, path, content) { try { const file = vault.getAbstractFileByPath(path); if (file && file instanceof import_obsidian.TFile) { try { const currentContent = await vault.read(file); await vault.modify(file, currentContent + "\n\n" + content); return true; } catch (e) { console.error(`\u8BFB\u53D6\u6216\u4FEE\u6539\u6587\u4EF6\u65F6\u51FA\u9519: ${e}`); return false; } } else { console.log(`\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u5C1D\u8BD5\u521B\u5EFA: ${path}`); return await ensureFileExists(vault, path, content); } } catch (error) { console.error(`Error appending to file at ${path}:`, error); return false; } } async function fileContains(vault, path, content) { try { const file = vault.getAbstractFileByPath(path); if (file && file instanceof import_obsidian.TFile) { try { const currentContent = await vault.read(file); return currentContent.includes(content); } catch (e) { console.error(`\u8BFB\u53D6\u6587\u4EF6\u5185\u5BB9\u65F6\u51FA\u9519: ${e}`); return false; } } console.log(`\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u65E0\u6CD5\u68C0\u67E5\u5185\u5BB9: ${path}`); return false; } catch (error) { console.error(`Error checking file content at ${path}:`, error); return false; } } function getTaskFilePath(rootDir) { const year = getCurrentYear(); const isEnglish = isEnglishEnvironment(); const monthName = getLocalizedMonthName(isEnglish); return (0, import_obsidian.normalizePath)(`${rootDir}/${year}/${monthName}.md`); } async function todayTaskExists(vault, rootDir) { const taskFilePath = getTaskFilePath(rootDir); const date = getCurrentDate(); try { console.log(`\u68C0\u67E5\u4ECA\u65E5\u4EFB\u52A1\u662F\u5426\u5B58\u5728\u4E8E: ${taskFilePath}`); return await fileContains(vault, taskFilePath, `## ${date}`); } catch (error) { console.error(`\u68C0\u67E5\u4ECA\u65E5\u4EFB\u52A1\u65F6\u51FA\u9519:`, error); return false; } } // src/taskGenerator.ts var TaskGenerator = class { constructor(app, settingsManager) { this.app = app; this.vault = app.vault; this.settingsManager = settingsManager; } /** * 生成每日任务 * @param openFile 是否打开文件 * @param quietMode 静默模式,减少日志输出 * @returns 成功或失败 */ async generateDailyTask(openFile = true, quietMode = false) { try { const settings = this.settingsManager.getSettings(); const rootDir = settings.rootDir.trim() || "DailyTasks"; const filePath = getTaskFilePath(rootDir); if (!quietMode) console.log(`\u751F\u6210\u4EFB\u52A1\u6587\u4EF6\u8DEF\u5F84: ${filePath}`); const pathParts = filePath.split("/"); const year = pathParts.length > 1 ? pathParts[1] : ""; const monthName = pathParts.length > 2 ? pathParts[2].replace(".md", "") : ""; const yearFolder = `${rootDir}/${year}`; if (!quietMode) console.log(`\u6B63\u5728\u786E\u4FDD\u6839\u76EE\u5F55\u5B58\u5728: ${rootDir}`); const rootCreated = await ensureFolderExists(this.vault, rootDir); if (!rootCreated) { console.error(`\u65E0\u6CD5\u8BBF\u95EE\u6216\u521B\u5EFA\u6839\u76EE\u5F55: ${rootDir}`); throw new Error(`\u65E0\u6CD5\u8BBF\u95EE\u6839\u76EE\u5F55: ${rootDir}\uFF0C\u53EF\u80FD\u662F\u5B58\u5728\u540C\u540D\u6587\u4EF6\u6216\u6743\u9650\u95EE\u9898`); } if (!quietMode) console.log(`\u6839\u76EE\u5F55\u786E\u8BA4: ${rootDir}`); if (!quietMode) console.log(`\u6B63\u5728\u786E\u4FDD\u5E74\u4EFD\u76EE\u5F55\u5B58\u5728: ${yearFolder}`); const yearCreated = await ensureFolderExists(this.vault, yearFolder); if (!yearCreated) { console.error(`\u65E0\u6CD5\u8BBF\u95EE\u6216\u521B\u5EFA\u5E74\u4EFD\u76EE\u5F55: ${yearFolder}`); throw new Error(`\u65E0\u6CD5\u8BBF\u95EE\u5E74\u4EFD\u76EE\u5F55: ${yearFolder}\uFF0C\u53EF\u80FD\u662F\u5B58\u5728\u540C\u540D\u6587\u4EF6\u6216\u6743\u9650\u95EE\u9898`); } if (!quietMode) console.log(`\u5E74\u4EFD\u76EE\u5F55\u786E\u8BA4: ${yearFolder}`); if (!quietMode) console.log(`\u6B63\u5728\u786E\u4FDD\u6708\u4EFD\u6587\u4EF6\u5B58\u5728: ${filePath} (${monthName})`); const fileCreated = await ensureFileExists(this.vault, filePath); if (!fileCreated) { console.error(`\u65E0\u6CD5\u8BBF\u95EE\u6216\u521B\u5EFA\u6708\u4EFD\u6587\u4EF6: ${filePath}`); throw new Error(`\u65E0\u6CD5\u8BBF\u95EE\u6708\u4EFD\u6587\u4EF6: ${filePath}\uFF0C\u8BF7\u68C0\u67E5\u662F\u5426\u5B58\u5728\u540C\u540D\u76EE\u5F55\u6216\u6743\u9650\u95EE\u9898`); } if (!quietMode) console.log(`\u6708\u4EFD\u6587\u4EF6\u786E\u8BA4: ${filePath}`); const date = getCurrentDate(); const existingTaskCheck = await fileContains(this.vault, filePath, `## ${date}`); if (existingTaskCheck) { console.log(`\u4ECA\u65E5(${date})\u4EFB\u52A1\u5DF2\u5B58\u5728\u4E8E\u6587\u4EF6\u4E2D\uFF0C\u8DF3\u8FC7\u521B\u5EFA`); if (openFile) { this.showWarningNotice(`\u{1F4CC} ${getTranslation("notification.taskExists")}`); const file = this.vault.getAbstractFileByPath(filePath); if (file && file instanceof import_obsidian2.TFile) { const leaf = this.app.workspace.getLeaf(); await leaf.openFile(file); } } return true; } const template = this.settingsManager.getCurrentTemplate(); const renderedContent = renderTemplate(template); if (!quietMode) console.log(`\u6B63\u5728\u5411\u6587\u4EF6\u8FFD\u52A0\u5185\u5BB9`); const success = await appendToFile(this.vault, filePath, renderedContent); if (success) { console.log(`\u2705 \u4EFB\u52A1\u5185\u5BB9\u8FFD\u52A0\u6210\u529F ${date}`); if (openFile) { const file = this.vault.getAbstractFileByPath(filePath); if (file && file instanceof import_obsidian2.TFile) { const leaf = this.app.workspace.getLeaf(); await leaf.openFile(file); setTimeout(() => { this.showSuccessNotice(`\u2728 ${getTranslation("notification.taskAdded")}`); }, 300); } else { throw new Error(`\u6587\u4EF6\u521B\u5EFA\u6210\u529F\u4F46\u65E0\u6CD5\u6253\u5F00: ${filePath}`); } } else { console.log(`\u2728 \u4ECA\u65E5(${date})\u4EFB\u52A1\u5DF2\u9759\u9ED8\u6DFB\u52A0\uFF0C\u65E0\u9700\u6253\u5F00\u6587\u4EF6`); } } else { throw new Error(`\u65E0\u6CD5\u5411\u6587\u4EF6\u8FFD\u52A0\u5185\u5BB9: ${filePath}`); } return success; } catch (error) { console.error("Error generating daily task:", error); const errorMsg = error instanceof Error ? error.message : String(error); this.showErrorNotice(`${getTranslation("notification.error")} ${errorMsg}`); return false; } } /** * 手动添加今日任务 * @returns 成功或失败 */ async addTaskManually() { try { const settings = this.settingsManager.getSettings(); const rootDir = settings.rootDir || "DailyTasks"; const exists = await todayTaskExists(this.vault, rootDir); if (exists) { this.showWarningNotice(`\u{1F4CC} ${getTranslation("notification.taskExists")}`); return false; } return await this.generateDailyTask(); } catch (error) { console.error("Error adding task manually:", error); const errorMsg = error instanceof Error ? error.message : String(error); this.showErrorNotice(`${getTranslation("notification.error")} ${errorMsg}`); return false; } } /** * 显示成功通知 * @param message 通知内容 */ showSuccessNotice(message) { const notice = new import_obsidian2.Notice( message, this.settingsManager.getSettings().successNotificationDuration ); if (notice.noticeEl) { notice.noticeEl.addClass("daily-task-success-notice"); } } /** * 显示警告通知 * @param message 通知内容 */ showWarningNotice(message) { const notice = new import_obsidian2.Notice( message, this.settingsManager.getSettings().successNotificationDuration ); if (notice.noticeEl) { notice.noticeEl.addClass("daily-task-warning-notice"); } } /** * 显示错误通知 * @param message 通知内容 */ showErrorNotice(message) { const notice = new import_obsidian2.Notice( message, this.settingsManager.getSettings().successNotificationDuration ); if (notice.noticeEl) { notice.noticeEl.addClass("daily-task-error-notice"); } } }; // src/settings/settings.ts var DailyTaskSettingTab = class extends import_obsidian3.PluginSettingTab { constructor(app, plugin) { super(app, plugin); this.previewEl = null; this.addTaskButton = null; // 模板预览元素 this.zhPreviewEl = null; this.enPreviewEl = null; // 目录输入框 this.rootDirInput = null; // 标记设置是否已修改但未保存 this.dirtySettings = false; this.plugin = plugin; this.settingsManager = plugin.settingsManager; this.taskGenerator = new TaskGenerator(app, this.settingsManager); } display() { const { containerEl } = this; containerEl.empty(); containerEl.classList.add("daily-task-setting-tab"); const settings = this.settingsManager.getSettings(); const topSpacing = containerEl.createEl("div"); topSpacing.style.marginTop = "30px"; const rootDirSetting = new import_obsidian3.Setting(containerEl).setName(getTranslation("settings.rootDir")).setDesc(getTranslation("settings.rootDir.desc")); const inputContainer = document.createElement("div"); inputContainer.style.display = "flex"; inputContainer.style.width = "100%"; inputContainer.style.position = "relative"; rootDirSetting.controlEl.appendChild(inputContainer); this.rootDirInput = new import_obsidian3.TextComponent(inputContainer).setValue(settings.rootDir).onChange(async (value) => { if (value.trim() !== "") { this.dirtySettings = true; this.autoSaveRootDir(value); } }); if (this.rootDirInput && this.rootDirInput.inputEl) { this.rootDirInput.inputEl.placeholder = "DailyTasks"; this.rootDirInput.inputEl.style.width = "100%"; this.rootDirInput.inputEl.style.borderRadius = "4px"; this.rootDirInput.inputEl.style.padding = "8px 35px 8px 10px"; this.rootDirInput.inputEl.style.transition = "all 0.3s ease"; } const saveIndicator = document.createElement("div"); saveIndicator.classList.add("save-indicator"); saveIndicator.style.position = "absolute"; saveIndicator.style.right = "10px"; saveIndicator.style.top = "50%"; saveIndicator.style.transform = "translateY(-50%)"; saveIndicator.style.opacity = "0"; saveIndicator.style.transition = "opacity 0.3s ease"; inputContainer.appendChild(saveIndicator); const saveSuccessIcon = createSpan({ cls: "svg-icon lucide-check" }); saveSuccessIcon.style.color = "#4CAF50"; saveSuccessIcon.style.width = "18px"; saveSuccessIcon.style.height = "18px"; saveIndicator.appendChild(saveSuccessIcon); let autoSaveTimer = null; this.autoSaveRootDir = async (value) => { if (autoSaveTimer !== null) { clearTimeout(autoSaveTimer); } autoSaveTimer = setTimeout(async () => { let pathToSave = value.trim(); if (pathToSave === "") { pathToSave = "DailyTasks"; } await this.settingsManager.updateSettings({ rootDir: pathToSave }); this.dirtySettings = false; saveIndicator.style.opacity = "1"; setTimeout(() => { saveIndicator.style.opacity = "0"; }, 2e3); }, 800); }; const autoGenSetting = new import_obsidian3.Setting(containerEl).setName(getTranslation("settings.autoGenerate")).setDesc(getTranslation("settings.autoGenerate.desc")); const toggleContainer = document.createElement("div"); toggleContainer.classList.add("mode-toggle-container"); toggleContainer.style.width = "20%"; toggleContainer.style.marginLeft = "auto"; const modes = [ { value: "none" /* NONE */, label: getTranslation("settings.mode.none") }, { value: "daily" /* DAILY */, label: getTranslation("settings.mode.daily") }, { value: "workday" /* WORKDAY */, label: getTranslation("settings.mode.workday") } ]; const slider = document.createElement("div"); slider.classList.add("mode-toggle-slider"); toggleContainer.appendChild(slider); const updateSlider = (index) => { slider.style.left = `${index * 33.33}%`; }; let currentModeIndex = modes.findIndex((mode) => mode.value === settings.autoGenerateMode); if (currentModeIndex === -1) { currentModeIndex = modes.findIndex((mode) => mode.value === "workday" /* WORKDAY */); this.settingsManager.updateSettings({ autoGenerateMode: "workday" /* WORKDAY */ }); } updateSlider(currentModeIndex); modes.forEach((mode, index) => { const option = document.createElement("div"); option.classList.add("mode-toggle-option"); option.textContent = mode.label; if (mode.value === settings.autoGenerateMode) { option.classList.add("active"); } option.addEventListener("click", async () => { toggleContainer.querySelectorAll(".mode-toggle-option").forEach((el) => { el.classList.remove("active"); }); option.classList.add("active"); updateSlider(index); await this.settingsManager.updateSettings({ autoGenerateMode: mode.value }); }); toggleContainer.appendChild(option); }); autoGenSetting.controlEl.appendChild(toggleContainer); new import_obsidian3.Setting(containerEl).setName(getTranslation("settings.language")).setDesc(getTranslation("settings.language.desc")).addDropdown((dropdown) => { dropdown.addOption("auto" /* AUTO */, getTranslation("settings.language.auto")).addOption("zh" /* ZH */, getTranslation("settings.language.zh")).addOption("en" /* EN */, getTranslation("settings.language.en")).setValue(settings.language).onChange(async (value) => { await this.settingsManager.updateSettings({ language: value }); this.display(); }); }); new import_obsidian3.Setting(containerEl).setName(getTranslation("settings.notificationDuration")).setDesc(getTranslation("settings.notificationDuration.desc")).addText((text) => { const component = text.setValue(settings.successNotificationDuration.toString()).onChange(async (value) => { const duration = parseInt(value); if (!isNaN(duration) && duration > 0) { await this.settingsManager.updateSettings({ successNotificationDuration: duration }); } }); component.inputEl.placeholder = "3000"; return component; }); containerEl.createEl("h3", { text: getTranslation("settings.template") }); const templateDescription = containerEl.createEl("p", { text: this.settingsManager.getCurrentLanguage() === "zh" ? "\u6CE8\u610F\uFF1A\u63D2\u4EF6\u4F1A\u6839\u636E\u5F53\u524D\u8BED\u8A00\u73AF\u5883\u81EA\u52A8\u9009\u62E9\u5BF9\u5E94\u8BED\u8A00\u7684\u4EFB\u52A1\u6A21\u677F\u3002\u5982\u679C\u60A8\u4FEE\u6539\u4E86\u4EFB\u4E00\u6A21\u677F\uFF0C\u5219\u4F1A\u4F7F\u7528\u60A8\u81EA\u5B9A\u4E49\u7684\u6A21\u677F\uFF0C\u4E0D\u518D\u533A\u5206\u8BED\u8A00\u3002" : "Note: The plugin automatically selects the template based on current language environment. If you modify either template, your customized template will be used regardless of language." }); templateDescription.style.fontSize = "0.85em"; templateDescription.style.opacity = "0.8"; templateDescription.style.marginBottom = "15px"; const zhTemplateSetting = new import_obsidian3.Setting(containerEl).setName(getTranslation("settings.template.zh")).setClass("template-setting"); const zhTemplateContainer = document.createElement("div"); zhTemplateContainer.style.width = "100%"; const zhTextarea = new import_obsidian3.TextAreaComponent(zhTemplateContainer).setValue(settings.templateZh).setPlaceholder("\u5728\u6B64\u5904\u8F93\u5165\u4E2D\u6587\u6A21\u677F...").onChange(async (value) => { await this.settingsManager.updateSettings({ templateZh: value }); this.updatePreview(this.zhPreviewEl, value); }); zhTextarea.inputEl.classList.add("template-editor"); const zhPreviewHeader = document.createElement("div"); zhPreviewHeader.classList.add("template-preview-header"); zhPreviewHeader.style.display = "flex"; zhPreviewHeader.style.justifyContent = "center"; const zhToggleButton = new import_obsidian3.ButtonComponent(zhPreviewHeader).setButtonText(getTranslation("settings.template.preview")); const eyeIcon = createSpan({ cls: "svg-icon lucide-eye" }); zhToggleButton.buttonEl.prepend(eyeIcon); zhToggleButton.buttonEl.style.display = "flex"; zhToggleButton.buttonEl.style.alignItems = "center"; zhToggleButton.buttonEl.style.justifyContent = "center"; zhToggleButton.buttonEl.style.textAlign = "center"; zhToggleButton.buttonEl.style.width = "120px"; zhToggleButton.onClick(() => { this.togglePreview(this.zhPreviewEl); if (this.zhPreviewEl && this.zhPreviewEl.classList.contains("visible")) { eyeIcon.className = "svg-icon lucide-eye-off"; zhToggleButton.setButtonText(getTranslation("settings.template.hide")); } else { eyeIcon.className = "svg-icon lucide-eye"; zhToggleButton.setButtonText(getTranslation("settings.template.preview")); } }); const zhResetBtn = new import_obsidian3.ButtonComponent(zhPreviewHeader).setButtonText(getTranslation("settings.resetDefault")).onClick(async () => { await this.settingsManager.updateSettings({ templateZh: DEFAULT_TEMPLATE_ZH }); zhTextarea.setValue(DEFAULT_TEMPLATE_ZH); this.updatePreview(this.zhPreviewEl, DEFAULT_TEMPLATE_ZH); }); zhResetBtn.buttonEl.prepend(createSpan({ cls: "svg-icon lucide-refresh-cw" })); zhResetBtn.buttonEl.style.display = "flex"; zhResetBtn.buttonEl.style.alignItems = "center"; zhResetBtn.buttonEl.style.justifyContent = "center"; zhResetBtn.buttonEl.style.textAlign = "center"; zhResetBtn.buttonEl.style.width = "120px"; zhTemplateContainer.appendChild(zhPreviewHeader); this.zhPreviewEl = document.createElement("div"); this.zhPreviewEl.classList.add("template-preview"); this.updatePreview(this.zhPreviewEl, settings.templateZh); zhTemplateContainer.appendChild(this.zhPreviewEl); zhTemplateSetting.controlEl.appendChild(zhTemplateContainer); const enTemplateSetting = new import_obsidian3.Setting(containerEl).setName(getTranslation("settings.template.en")).setClass("template-setting"); const enTemplateContainer = document.createElement("div"); enTemplateContainer.style.width = "100%"; const enTextarea = new import_obsidian3.TextAreaComponent(enTemplateContainer).setValue(settings.templateEn).setPlaceholder("Enter English template here...").onChange(async (value) => { await this.settingsManager.updateSettings({ templateEn: value }); this.updatePreview(this.enPreviewEl, value); }); enTextarea.inputEl.classList.add("template-editor"); const enPreviewHeader = document.createElement("div"); enPreviewHeader.classList.add("template-preview-header"); enPreviewHeader.style.display = "flex"; enPreviewHeader.style.justifyContent = "center"; const enToggleButton = new import_obsidian3.ButtonComponent(enPreviewHeader).setButtonText(getTranslation("settings.template.preview")); const enEyeIcon = createSpan({ cls: "svg-icon lucide-eye" }); enToggleButton.buttonEl.prepend(enEyeIcon); enToggleButton.buttonEl.style.display = "flex"; enToggleButton.buttonEl.style.alignItems = "center"; enToggleButton.buttonEl.style.justifyContent = "center"; enToggleButton.buttonEl.style.textAlign = "center"; enToggleButton.buttonEl.style.width = "120px"; enToggleButton.onClick(() => { this.togglePreview(this.enPreviewEl); if (this.enPreviewEl && this.enPreviewEl.classList.contains("visible")) { enEyeIcon.className = "svg-icon lucide-eye-off"; enToggleButton.setButtonText(getTranslation("settings.template.hide")); } else { enEyeIcon.className = "svg-icon lucide-eye"; enToggleButton.setButtonText(getTranslation("settings.template.preview")); } }); const enResetBtn = new import_obsidian3.ButtonComponent(enPreviewHeader).setButtonText(getTranslation("settings.resetDefault")).onClick(async () => { await this.settingsManager.updateSettings({ templateEn: DEFAULT_TEMPLATE_EN }); enTextarea.setValue(DEFAULT_TEMPLATE_EN); this.updatePreview(this.enPreviewEl, DEFAULT_TEMPLATE_EN); }); enResetBtn.buttonEl.prepend(createSpan({ cls: "svg-icon lucide-refresh-cw" })); enResetBtn.buttonEl.style.display = "flex"; enResetBtn.buttonEl.style.alignItems = "center"; enResetBtn.buttonEl.style.justifyContent = "center"; enResetBtn.buttonEl.style.textAlign = "center"; enResetBtn.buttonEl.style.width = "120px"; enTemplateContainer.appendChild(enPreviewHeader); this.enPreviewEl = document.createElement("div"); this.enPreviewEl.classList.add("template-preview"); this.updatePreview(this.enPreviewEl, settings.templateEn); enTemplateContainer.appendChild(this.enPreviewEl); enTemplateSetting.controlEl.appendChild(enTemplateContainer); const resetContainer = document.createElement("div"); resetContainer.style.display = "flex"; resetContainer.style.justifyContent = "flex-end"; resetContainer.style.marginTop = "20px"; resetContainer.style.marginBottom = "10px"; containerEl.appendChild(resetContainer); const resetDefaultBtn = new import_obsidian3.ButtonComponent(resetContainer).setButtonText(getTranslation("settings.resetToDefault")).onClick(async () => { await this.settingsManager.resetToDefaults(); this.display(); }); resetDefaultBtn.buttonEl.addClass("danger-button"); resetDefaultBtn.buttonEl.prepend(createSpan({ cls: "svg-icon lucide-refresh-cw" })); resetDefaultBtn.buttonEl.style.display = "flex"; resetDefaultBtn.buttonEl.style.alignItems = "center"; resetDefaultBtn.buttonEl.style.justifyContent = "center"; const addTaskContainer = document.createElement("div"); addTaskContainer.style.display = "flex"; addTaskContainer.style.justifyContent = "flex-end"; addTaskContainer.style.marginTop = "20px"; containerEl.appendChild(addTaskContainer); this.addTaskButton = new import_obsidian3.ButtonComponent(addTaskContainer).setButtonText(getTranslation("settings.addTaskButton")).setCta().onClick(async () => { var _a, _b; const rootDir = this.settingsManager.getSettings().rootDir; (_a = this.addTaskButton) == null ? void 0 : _a.buttonEl.classList.add("loading"); (_b = this.addTaskButton) == null ? void 0 : _b.setDisabled(true); try { await this.taskGenerator.addTaskManually(); } catch (e) { console.error("\u6DFB\u52A0\u4EFB\u52A1\u51FA\u9519:", e); new import_obsidian3.Notice(`\u6DFB\u52A0\u4EFB\u52A1\u5931\u8D25: ${e.message || e}`); } finally { setTimeout(() => { var _a2, _b2; (_a2 = this.addTaskButton) == null ? void 0 : _a2.buttonEl.classList.remove("loading"); (_b2 = this.addTaskButton) == null ? void 0 : _b2.setDisabled(false); }, 500); } }); this.addTaskButton.buttonEl.prepend(createSpan({ cls: "svg-icon lucide-calendar-plus" })); this.addTaskButton.buttonEl.classList.add("add-task-button"); this.addTaskButton.buttonEl.style.display = "flex"; this.addTaskButton.buttonEl.style.alignItems = "center"; this.addTaskButton.buttonEl.style.justifyContent = "center"; } /** * 更新模板预览 */ updatePreview(previewEl, template) { if (!previewEl) return; const renderedContent = renderTemplate(template); previewEl.innerHTML = renderedContent.replace(/\n/g, "
"); } /** * 切换预览的显示/隐藏 */ togglePreview(previewEl) { if (!previewEl) return; previewEl.classList.toggle("visible"); } }; var SettingsManager = class { constructor(plugin) { this.plugin = plugin; this.settings = Object.assign({}, DEFAULT_SETTINGS); } /** * 获取当前设置 */ getSettings() { return this.settings; } /** * 更新设置并保存 * @param settings 要更新的设置 */ async updateSettings(settings) { this.settings = { ...this.settings, ...settings }; await this.saveSettings(); this.updateCurrentLanguage(); } /** * 保存设置到数据存储 */ async saveSettings() { await this.plugin.saveData(this.settings); } /** * 加载设置 */ async loadSettings() { const loadedData = await this.plugin.loadData(); if (loadedData) { this.settings = { ...DEFAULT_SETTINGS, ...loadedData }; this.ensureSettingsCompleteness(); } else { this.settings = { ...DEFAULT_SETTINGS, autoGenerateMode: "workday" /* WORKDAY */ }; } this.updateCurrentLanguage(); } /** * 确保设置完整性,为新增的设置项提供默认值 */ ensureSettingsCompleteness() { const defaultKeys = Object.keys(DEFAULT_SETTINGS); defaultKeys.forEach((key) => { if (!(key in this.settings)) { this.settings[key] = DEFAULT_SETTINGS[key]; } }); } /** * 恢复默认设置 */ async resetToDefaults() { this.settings = Object.assign({}, DEFAULT_SETTINGS); await this.saveSettings(); this.updateCurrentLanguage(); } /** * 根据语言获取当前使用的模板 * 如果当前模板不是默认模板,则不再区分语言 */ getCurrentTemplate() { const language = this.getCurrentLanguage(); if (language === "zh") { if (this.settings.templateZh !== DEFAULT_TEMPLATE_ZH) { return this.settings.templateZh; } if (this.settings.templateEn !== DEFAULT_TEMPLATE_EN) { return this.settings.templateEn; } return this.settings.templateZh; } else { if (this.settings.templateEn !== DEFAULT_TEMPLATE_EN) { return this.settings.templateEn; } if (this.settings.templateZh !== DEFAULT_TEMPLATE_ZH) { return this.settings.templateZh; } return this.settings.templateEn; } } /** * 获取当前语言设置 */ getCurrentLanguage() { if (this.settings.language === "auto" /* AUTO */) { const systemLanguage = window.navigator.language.toLowerCase(); return systemLanguage.startsWith("zh") ? "zh" : "en"; } return this.settings.language; } /** * 更新当前语言 */ updateCurrentLanguage() { const language = this.getCurrentLanguage(); setCurrentLanguage(language); } }; // src/main.ts var ICON = ` `; var DailyTaskPlugin = class extends import_obsidian4.Plugin { /** * 插件加载时调用 */ async onload() { console.log("Loading Daily Task Auto Generator plugin"); (0, import_obsidian4.addIcon)("daily-task", ICON); this.settingsManager = new SettingsManager(this); await this.settingsManager.loadSettings(); this.taskGenerator = new TaskGenerator(this.app, this.settingsManager); setCurrentLanguage(this.settingsManager.getCurrentLanguage()); this.addSettingTab(new DailyTaskSettingTab(this.app, this)); this.addCommand({ id: "add-daily-task", name: "\u624B\u52A8\u6DFB\u52A0\u4ECA\u65E5\u4EFB\u52A1", callback: async () => { await this.taskGenerator.addTaskManually(); } }); console.log("\u8BA1\u5212\u572810\u79D2\u540E\u68C0\u67E5\u662F\u5426\u9700\u8981\u81EA\u52A8\u751F\u6210\u4EFB\u52A1"); setTimeout(async () => { console.log("\u5F00\u59CB\u68C0\u67E5\u662F\u5426\u9700\u8981\u81EA\u52A8\u751F\u6210\u4EFB\u52A1"); await this.checkAutoGenerate(); }, 1e4); } /** * 插件卸载时调用 */ onunload() { console.log("Unloading Daily Task Auto Generator plugin"); } /** * 检查是否需要自动生成任务 */ async checkAutoGenerate() { const settings = this.settingsManager.getSettings(); switch (settings.autoGenerateMode) { case "daily" /* DAILY */: console.log("\u6839\u636E\u8BBE\u7F6E\uFF0C\u6BCF\u5929\u81EA\u52A8\u751F\u6210\u4EFB\u52A1\uFF08\u9759\u9ED8\u6A21\u5F0F\uFF09"); await this.taskGenerator.generateDailyTask(false, true); break; case "workday" /* WORKDAY */: if (isWorkday()) { console.log("\u6839\u636E\u8BBE\u7F6E\uFF0C\u5DE5\u4F5C\u65E5\u81EA\u52A8\u751F\u6210\u4EFB\u52A1\uFF08\u9759\u9ED8\u6A21\u5F0F\uFF09"); await this.taskGenerator.generateDailyTask(false, true); } else { console.log("\u4ECA\u5929\u4E0D\u662F\u5DE5\u4F5C\u65E5\uFF0C\u8DF3\u8FC7\u81EA\u52A8\u751F\u6210\u4EFB\u52A1"); } break; case "none" /* NONE */: default: console.log("\u5DF2\u7981\u7528\u81EA\u52A8\u751F\u6210\u4EFB\u52A1\u529F\u80FD"); break; } } };