mirror of
https://github.com/jxpeng98/obsidian-to-NotionNext
synced 2026-07-29 16:35:57 +08:00
Compare commits
6 Commits
v2.8.0-bet
...
v2.8.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9355aaf92 | ||
|
|
943ec6af6d | ||
|
|
bb4b75c82e | ||
|
|
ae4488546c | ||
|
|
7661bc94c7 | ||
|
|
e8a9594ea1 |
5
.github/workflows/release.yml
vendored
5
.github/workflows/release.yml
vendored
@@ -2,8 +2,11 @@ name: Release
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
tags:
|
tags:
|
||||||
- "*"
|
- "v*.*.*"
|
||||||
|
- "[0-9]+.[0-9]+.[0-9]+"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
PLUGIN_NAME: share-to-notionnext # Change this to match the id of your plugin.
|
PLUGIN_NAME: share-to-notionnext # Change this to match the id of your plugin.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## [Unreleased]
|
## v2.8.0-beta.1 (2025-10-31)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,21 @@ In the plugin settings, you can add and configure the Notion databases you want
|
|||||||
- [3️⃣ Custom Database](#3️⃣-custom-database)
|
- [3️⃣ Custom Database](#3️⃣-custom-database)
|
||||||
- [Finalizing Configuration](#finalizing-configuration)
|
- [Finalizing Configuration](#finalizing-configuration)
|
||||||
|
|
||||||
|
## Auto Sync Frontmatter Entry
|
||||||
|
|
||||||
|
If you enable auto sync, the plugin needs a frontmatter entry that lists which configured databases should receive updates. You can customise the name of this entry in **Settings → Auto Sync Frontmatter Key** (default: `autosync-database`). Use any text you like—letters, numbers, emojis, or other scripts are all supported.
|
||||||
|
|
||||||
|
In your note's frontmatter, add the configured key and list the database abbreviations you created in the settings:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: My Article
|
||||||
|
autosync-database: [blog, ideas]
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
The entry can be a YAML list or comma-separated string, and manual uploads will automatically add the current database abbreviation if it is missing. If you change the key name in settings, update your frontmatter to match the new value.
|
||||||
|
|
||||||
## 1️⃣ General Database
|
## 1️⃣ General Database
|
||||||
|
|
||||||
This is the most basic database type and is suitable for most users.
|
This is the most basic database type and is suitable for most users.
|
||||||
|
|||||||
@@ -22,6 +22,25 @@ The plugin supports automatic syncing that monitors your notes for changes and a
|
|||||||
3. Enable the toggle
|
3. Enable the toggle
|
||||||
4. Configure the "Auto Sync Delay" (default: 5 seconds, minimum: 2 seconds)
|
4. Configure the "Auto Sync Delay" (default: 5 seconds, minimum: 2 seconds)
|
||||||
|
|
||||||
|
### Prepare the Frontmatter
|
||||||
|
|
||||||
|
Auto sync reads the database list from the frontmatter key you configured in **Settings → Auto Sync Frontmatter Key** (default: `autosync-database`). To make sure your notes can sync automatically:
|
||||||
|
|
||||||
|
- Add the configured key to your note's frontmatter
|
||||||
|
- List one or more database abbreviations that you defined in the plugin settings
|
||||||
|
- Keep the list updated if you change the databases a note should sync to
|
||||||
|
|
||||||
|
Example with the default key:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: My Article
|
||||||
|
autosync-database: [blog, portfolio]
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
If you change the key name in the settings, update your frontmatter to match. The plugin will prompt you when the entry is missing.
|
||||||
|
|
||||||
### How Auto Sync Works
|
### How Auto Sync Works
|
||||||
|
|
||||||
When auto sync is enabled:
|
When auto sync is enabled:
|
||||||
@@ -32,7 +51,7 @@ When auto sync is enabled:
|
|||||||
|
|
||||||
### Auto Sync Scenarios
|
### Auto Sync Scenarios
|
||||||
|
|
||||||
#### Scenario A: New Document (Not Yet Synced)
|
#### Scenario A: Missing Auto Sync Entry
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
@@ -41,18 +60,34 @@ tags: [blog, tech]
|
|||||||
---
|
---
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Behavior:**
|
||||||
|
- ✅ Detects that the configured auto sync key is missing
|
||||||
|
- ✅ Shows notice: `⚠️ Auto sync skipped: Add a "{key}" entry in the frontmatter to choose databases`
|
||||||
|
- ✅ No sync operation performed
|
||||||
|
- 📝 **Action Required:** Add the configured key (default `autosync-database`) to the frontmatter with the database abbreviations
|
||||||
|
|
||||||
|
#### Scenario B: New Document (Not Yet Synced)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: My New Article
|
||||||
|
aytosync-database: [blog]
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
**Behavior:**
|
**Behavior:**
|
||||||
- ✅ Detects no NotionID present
|
- ✅ Detects no NotionID present
|
||||||
- ✅ Shows notice: "⚠️ Auto sync skipped: This document has not been synced to Notion, please upload manually first"
|
- ✅ Shows notice: "⚠️ Auto sync skipped: This document has not been synced to Notion, please upload manually first"
|
||||||
- ✅ No sync operation performed
|
- ✅ No sync operation performed
|
||||||
- 📝 **Action Required:** Manually sync the document first using the command palette
|
- 📝 **Action Required:** Manually sync the document first using the command palette
|
||||||
|
|
||||||
#### Scenario B: Synced to One Database
|
#### Scenario C: Synced to One Database
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
title: My Article
|
title: My Article
|
||||||
NotionID-blog: abc123
|
NotionID-blog: abc123
|
||||||
|
autosync-database: [blog]
|
||||||
---
|
---
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -62,7 +97,7 @@ NotionID-blog: abc123
|
|||||||
- ✅ Shows success/failure notification from the upload command
|
- ✅ Shows success/failure notification from the upload command
|
||||||
- 📝 **No Action Required:** Changes are automatically synced
|
- 📝 **No Action Required:** Changes are automatically synced
|
||||||
|
|
||||||
#### Scenario C: Synced to Multiple Databases
|
#### Scenario D: Synced to Multiple Databases
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
@@ -80,6 +115,21 @@ NotionID-notes: ghi789
|
|||||||
- ✅ Shows individual result notifications for each database
|
- ✅ Shows individual result notifications for each database
|
||||||
- 📝 **No Action Required:** Changes are automatically synced to all linked databases
|
- 📝 **No Action Required:** Changes are automatically synced to all linked databases
|
||||||
|
|
||||||
|
#### Scenario E: Custom Frontmatter Key
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: My Article
|
||||||
|
NotionID-blog: abc123
|
||||||
|
NotionID-portfolio: def456
|
||||||
|
🚀-sync-targets: [blog, portfolio]
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
**Behavior:**
|
||||||
|
- ✅ Uses your custom key (for example `🚀-sync-targets`) configured in settings
|
||||||
|
- ✅ Syncs to the listed databases when NotionIDs are present
|
||||||
|
- 📝 **Remember:** Update both the setting and your frontmatter if you rename the key
|
||||||
### Auto Sync Best Practices
|
### Auto Sync Best Practices
|
||||||
|
|
||||||
1. **First Sync Manually**: Always perform the first sync manually to establish the NotionID link
|
1. **First Sync Manually**: Always perform the first sync manually to establish the NotionID link
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ export const en = {
|
|||||||
NotionLinkDisplayDesc: "Default is ON, if you want to hide the link in the front matter, please turn it off",
|
NotionLinkDisplayDesc: "Default is ON, if you want to hide the link in the front matter, please turn it off",
|
||||||
AutoSync: "Auto Sync",
|
AutoSync: "Auto Sync",
|
||||||
AutoSyncDesc: "Automatically sync to Notion when frontmatter or content is modified (requires existing NotionID)",
|
AutoSyncDesc: "Automatically sync to Notion when frontmatter or content is modified (requires existing NotionID)",
|
||||||
|
AutoSyncFrontmatterKey: "Auto Sync Frontmatter Key",
|
||||||
|
AutoSyncFrontmatterKeyDesc: "Set the frontmatter property name that lists which databases should auto sync (defaults to autosync-database).",
|
||||||
AutoSyncDelay: "Auto Sync Delay (seconds)",
|
AutoSyncDelay: "Auto Sync Delay (seconds)",
|
||||||
AutoSyncDelayDesc: "How many seconds to wait after document modification before triggering auto sync (default: 5 seconds, minimum: 2 seconds)",
|
AutoSyncDelayDesc: "How many seconds to wait after document modification before triggering auto sync (default: 5 seconds, minimum: 2 seconds)",
|
||||||
AutoSyncDelayText: "Enter delay in seconds",
|
AutoSyncDelayText: "Enter delay in seconds",
|
||||||
@@ -86,6 +88,7 @@ export const en = {
|
|||||||
CheckConsole: "Check the console for more information \n opt+cmd+i/ctrl+shift+i",
|
CheckConsole: "Check the console for more information \n opt+cmd+i/ctrl+shift+i",
|
||||||
SettingsMigrated: "✨ Plugin settings updated! Auto sync feature added, check plugin settings",
|
SettingsMigrated: "✨ Plugin settings updated! Auto sync feature added, check plugin settings",
|
||||||
AutoSyncNoNotionID: "⚠️ Auto sync skipped: This document has not been synced to Notion, please upload manually first",
|
AutoSyncNoNotionID: "⚠️ Auto sync skipped: This document has not been synced to Notion, please upload manually first",
|
||||||
|
AutoSyncMissingDatabaseList: "⚠️ Auto sync skipped: Add a \"{key}\" entry in the frontmatter to choose databases",
|
||||||
AutoSyncMultipleSync: "🔄 Auto sync: Syncing to {count} database(s)...",
|
AutoSyncMultipleSync: "🔄 Auto sync: Syncing to {count} database(s)...",
|
||||||
AutoSyncFailed: "Auto sync to {database} failed: {error}",
|
AutoSyncFailed: "Auto sync to {database} failed: {error}",
|
||||||
AutoSyncError: "Auto sync failed for {filename}: {error}",
|
AutoSyncError: "Auto sync failed for {filename}: {error}",
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ export const ja = {
|
|||||||
NotionLinkDisplayDesc: "デフォルトはONです。front matterにリンクを非表示にしたい場合は、オフにしてください",
|
NotionLinkDisplayDesc: "デフォルトはONです。front matterにリンクを非表示にしたい場合は、オフにしてください",
|
||||||
AutoSync: "自動同期",
|
AutoSync: "自動同期",
|
||||||
AutoSyncDesc: "frontmatter またはコンテンツが変更されたときに自動的に Notion に同期します(NotionID が必要)",
|
AutoSyncDesc: "frontmatter またはコンテンツが変更されたときに自動的に Notion に同期します(NotionID が必要)",
|
||||||
|
AutoSyncFrontmatterKey: "自動同期 frontmatter キー",
|
||||||
|
AutoSyncFrontmatterKeyDesc: "自動同期するデータベースを列挙する frontmatter のプロパティ名を設定します(デフォルトは autosync-database)。",
|
||||||
AutoSyncDelay: "自動同期遅延時間(秒)",
|
AutoSyncDelay: "自動同期遅延時間(秒)",
|
||||||
AutoSyncDelayDesc: "ドキュメントの変更後、自動同期をトリガーするまでの待機時間(デフォルト:5秒、最小:2秒)",
|
AutoSyncDelayDesc: "ドキュメントの変更後、自動同期をトリガーするまでの待機時間(デフォルト:5秒、最小:2秒)",
|
||||||
AutoSyncDelayText: "遅延秒数を入力",
|
AutoSyncDelayText: "遅延秒数を入力",
|
||||||
@@ -78,6 +80,7 @@ export const ja = {
|
|||||||
CheckConsole: "詳細情報を確認するには、コンソールを開いてください \n opt+cmd+i/ctrl+shift+i",
|
CheckConsole: "詳細情報を確認するには、コンソールを開いてください \n opt+cmd+i/ctrl+shift+i",
|
||||||
SettingsMigrated: "✨ プラグイン設定が更新されました!自動同期機能が追加されました。設定を確認してください",
|
SettingsMigrated: "✨ プラグイン設定が更新されました!自動同期機能が追加されました。設定を確認してください",
|
||||||
AutoSyncNoNotionID: "⚠️ 自動同期をスキップ:このドキュメントは Notion に同期されていません。まず手動でアップロードしてください",
|
AutoSyncNoNotionID: "⚠️ 自動同期をスキップ:このドキュメントは Notion に同期されていません。まず手動でアップロードしてください",
|
||||||
|
AutoSyncMissingDatabaseList: "⚠️ 自動同期をスキップ:frontmatter に \"{key}\" 項目を追加してください",
|
||||||
AutoSyncMultipleSync: "🔄 自動同期:{count} 個のデータベースに同期中...",
|
AutoSyncMultipleSync: "🔄 自動同期:{count} 個のデータベースに同期中...",
|
||||||
AutoSyncFailed: "{database} への自動同期に失敗しました:{error}",
|
AutoSyncFailed: "{database} への自動同期に失敗しました:{error}",
|
||||||
AutoSyncError: "{filename} の自動同期に失敗しました:{error}",
|
AutoSyncError: "{filename} の自動同期に失敗しました:{error}",
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ export const zh = {
|
|||||||
NotionLinkDisplayDesc: "默认开启,如果你不想在front matter中显示链接,请关闭",
|
NotionLinkDisplayDesc: "默认开启,如果你不想在front matter中显示链接,请关闭",
|
||||||
AutoSync: "自动同步",
|
AutoSync: "自动同步",
|
||||||
AutoSyncDesc: "当检测到文档的 frontmatter 或内容发生修改时,自动同步到 Notion(需要文档已有 NotionID)",
|
AutoSyncDesc: "当检测到文档的 frontmatter 或内容发生修改时,自动同步到 Notion(需要文档已有 NotionID)",
|
||||||
|
AutoSyncFrontmatterKey: "自动同步 Frontmatter 键名",
|
||||||
|
AutoSyncFrontmatterKeyDesc: "设置用于列出自动同步数据库的 frontmatter 属性名称(默认 autosync-database)。",
|
||||||
AutoSyncDelay: "自动同步延迟时间(秒)",
|
AutoSyncDelay: "自动同步延迟时间(秒)",
|
||||||
AutoSyncDelayDesc: "文档修改后等待多少秒才触发自动同步,避免频繁同步(默认:5秒,最小:2秒)",
|
AutoSyncDelayDesc: "文档修改后等待多少秒才触发自动同步,避免频繁同步(默认:5秒,最小:2秒)",
|
||||||
AutoSyncDelayText: "输入延迟秒数",
|
AutoSyncDelayText: "输入延迟秒数",
|
||||||
@@ -81,6 +83,7 @@ export const zh = {
|
|||||||
CheckConsole: "opt+cmd+i/ctrl+shift+i,\n打开控制台查看更多信息",
|
CheckConsole: "opt+cmd+i/ctrl+shift+i,\n打开控制台查看更多信息",
|
||||||
SettingsMigrated: "✨ 插件设置已更新!新增自动同步功能,请在设置中查看",
|
SettingsMigrated: "✨ 插件设置已更新!新增自动同步功能,请在设置中查看",
|
||||||
AutoSyncNoNotionID: "⚠️ 自动同步跳过:此文档未同步到 Notion,请先手动上传",
|
AutoSyncNoNotionID: "⚠️ 自动同步跳过:此文档未同步到 Notion,请先手动上传",
|
||||||
|
AutoSyncMissingDatabaseList: "⚠️ 自动同步跳过:请在 frontmatter 中添加 \"{key}\" 项来指定数据库",
|
||||||
AutoSyncMultipleSync: "🔄 自动同步:正在同步到 {count} 个数据库...",
|
AutoSyncMultipleSync: "🔄 自动同步:正在同步到 {count} 个数据库...",
|
||||||
AutoSyncFailed: "自动同步到 {database} 失败:{error}",
|
AutoSyncFailed: "自动同步到 {database} 失败:{error}",
|
||||||
AutoSyncError: "自动同步 {filename} 失败:{error}",
|
AutoSyncError: "自动同步 {filename} 失败:{error}",
|
||||||
|
|||||||
65
src/main.ts
65
src/main.ts
@@ -4,6 +4,7 @@ import { i18nConfig } from "src/lang/I18n";
|
|||||||
import ribbonCommands from "src/commands/NotionCommands";
|
import ribbonCommands from "src/commands/NotionCommands";
|
||||||
import { ObsidianSettingTab, PluginSettings, DEFAULT_SETTINGS, DatabaseDetails } from "src/ui/settingTabs";
|
import { ObsidianSettingTab, PluginSettings, DEFAULT_SETTINGS, DatabaseDetails } from "src/ui/settingTabs";
|
||||||
import { uploadCommandNext, uploadCommandGeneral, uploadCommandCustom } from "src/upload/uploadCommand";
|
import { uploadCommandNext, uploadCommandGeneral, uploadCommandCustom } from "src/upload/uploadCommand";
|
||||||
|
import { DEFAULT_AUTO_SYNC_DATABASE_KEY, parseAutoSyncDatabaseList, resolveAutoSyncKey } from "src/utils/frontmatter";
|
||||||
|
|
||||||
// Remember to rename these classes and interfaces!
|
// Remember to rename these classes and interfaces!
|
||||||
|
|
||||||
@@ -17,6 +18,7 @@ export default class ObsidianSyncNotionPlugin extends Plugin {
|
|||||||
private syncingFiles: Set<string> = new Set();
|
private syncingFiles: Set<string> = new Set();
|
||||||
private lastFrontmatterCache: Map<string, any> = new Map();
|
private lastFrontmatterCache: Map<string, any> = new Map();
|
||||||
private lastContentHashCache: Map<string, string> = new Map();
|
private lastContentHashCache: Map<string, string> = new Map();
|
||||||
|
private missingAutoSyncNoticeShown: Set<string> = new Set();
|
||||||
|
|
||||||
async onload() {
|
async onload() {
|
||||||
await this.loadSettings();
|
await this.loadSettings();
|
||||||
@@ -67,6 +69,7 @@ export default class ObsidianSyncNotionPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
this.lastFrontmatterCache.clear();
|
this.lastFrontmatterCache.clear();
|
||||||
this.lastContentHashCache.clear();
|
this.lastContentHashCache.clear();
|
||||||
|
this.missingAutoSyncNoticeShown.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadSettings() {
|
async loadSettings() {
|
||||||
@@ -89,6 +92,10 @@ export default class ObsidianSyncNotionPlugin extends Plugin {
|
|||||||
if (typeof this.settings.NotionLinkDisplay !== 'boolean') {
|
if (typeof this.settings.NotionLinkDisplay !== 'boolean') {
|
||||||
this.settings.NotionLinkDisplay = DEFAULT_SETTINGS.NotionLinkDisplay;
|
this.settings.NotionLinkDisplay = DEFAULT_SETTINGS.NotionLinkDisplay;
|
||||||
}
|
}
|
||||||
|
if (typeof this.settings.autoSyncFrontmatterKey !== 'string') {
|
||||||
|
this.settings.autoSyncFrontmatterKey = DEFAULT_AUTO_SYNC_DATABASE_KEY;
|
||||||
|
}
|
||||||
|
this.settings.autoSyncFrontmatterKey = resolveAutoSyncKey(this.settings.autoSyncFrontmatterKey);
|
||||||
|
|
||||||
// Ensure databaseDetails exists
|
// Ensure databaseDetails exists
|
||||||
if (!this.settings.databaseDetails || typeof this.settings.databaseDetails !== 'object') {
|
if (!this.settings.databaseDetails || typeof this.settings.databaseDetails !== 'object') {
|
||||||
@@ -99,7 +106,8 @@ export default class ObsidianSyncNotionPlugin extends Plugin {
|
|||||||
const needsSave = !loadedData ||
|
const needsSave = !loadedData ||
|
||||||
loadedData.autoSync === undefined ||
|
loadedData.autoSync === undefined ||
|
||||||
loadedData.autoSyncDelay === undefined ||
|
loadedData.autoSyncDelay === undefined ||
|
||||||
loadedData.NotionLinkDisplay === undefined;
|
loadedData.NotionLinkDisplay === undefined ||
|
||||||
|
loadedData.autoSyncFrontmatterKey === undefined;
|
||||||
|
|
||||||
if (needsSave) {
|
if (needsSave) {
|
||||||
const migratedFields = [];
|
const migratedFields = [];
|
||||||
@@ -131,6 +139,7 @@ export default class ObsidianSyncNotionPlugin extends Plugin {
|
|||||||
autoSync: this.settings.autoSync,
|
autoSync: this.settings.autoSync,
|
||||||
autoSyncDelay: this.settings.autoSyncDelay,
|
autoSyncDelay: this.settings.autoSyncDelay,
|
||||||
NotionLinkDisplay: this.settings.NotionLinkDisplay,
|
NotionLinkDisplay: this.settings.NotionLinkDisplay,
|
||||||
|
autoSyncFrontmatterKey: this.settings.autoSyncFrontmatterKey,
|
||||||
databaseCount: Object.keys(this.settings.databaseDetails || {}).length
|
databaseCount: Object.keys(this.settings.databaseDetails || {}).length
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -153,6 +162,20 @@ export default class ObsidianSyncNotionPlugin extends Plugin {
|
|||||||
console.warn('[Settings] Invalid databaseDetails, resetting to empty object');
|
console.warn('[Settings] Invalid databaseDetails, resetting to empty object');
|
||||||
this.settings.databaseDetails = {};
|
this.settings.databaseDetails = {};
|
||||||
}
|
}
|
||||||
|
if (typeof this.settings.autoSyncFrontmatterKey !== 'string' || this.settings.autoSyncFrontmatterKey.trim().length === 0) {
|
||||||
|
console.warn('[Settings] Invalid autoSyncFrontmatterKey, resetting to default');
|
||||||
|
this.settings.autoSyncFrontmatterKey = DEFAULT_AUTO_SYNC_DATABASE_KEY;
|
||||||
|
} else {
|
||||||
|
this.settings.autoSyncFrontmatterKey = resolveAutoSyncKey(this.settings.autoSyncFrontmatterKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resetAutoSyncNoticeCache() {
|
||||||
|
this.missingAutoSyncNoticeShown.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
getAutoSyncFrontmatterKey(): string {
|
||||||
|
return resolveAutoSyncKey(this.settings.autoSyncFrontmatterKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
async addDatabaseDetails(dbDetails: DatabaseDetails) {
|
async addDatabaseDetails(dbDetails: DatabaseDetails) {
|
||||||
@@ -327,21 +350,52 @@ export default class ObsidianSyncNotionPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find all databases this file belongs to by checking for NotionID-{abName}
|
const autoSyncKey = this.getAutoSyncFrontmatterKey();
|
||||||
const foundDatabases: Array<{ dbDetails: DatabaseDetails, notionId: string }> = [];
|
const autoSyncTargets = parseAutoSyncDatabaseList(frontMatter[autoSyncKey]);
|
||||||
|
|
||||||
|
if (autoSyncTargets.length === 0) {
|
||||||
|
if (!this.missingAutoSyncNoticeShown.has(file.path)) {
|
||||||
|
const message = i18nConfig.AutoSyncMissingDatabaseList.replace('{key}', autoSyncKey);
|
||||||
|
new Notice(message, 10000);
|
||||||
|
this.missingAutoSyncNoticeShown.add(file.path);
|
||||||
|
}
|
||||||
|
console.log(`[AutoSync] No auto sync database list found in ${file.path} using key "${autoSyncKey}"`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.missingAutoSyncNoticeShown.delete(file.path);
|
||||||
|
|
||||||
|
const dbByShortName = new Map<string, DatabaseDetails>();
|
||||||
for (const key in this.settings.databaseDetails) {
|
for (const key in this.settings.databaseDetails) {
|
||||||
const dbDetails = this.settings.databaseDetails[key];
|
const dbDetails = this.settings.databaseDetails[key];
|
||||||
const notionIDKey = `NotionID-${dbDetails.abName}`;
|
dbByShortName.set(dbDetails.abName.toLowerCase(), dbDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
const foundDatabases: Array<{ dbDetails: DatabaseDetails, notionId: string }> = [];
|
||||||
|
const unresolvedTargets: string[] = [];
|
||||||
|
|
||||||
|
for (const target of autoSyncTargets) {
|
||||||
|
const lookupKey = target.toLowerCase();
|
||||||
|
const dbDetails = dbByShortName.get(lookupKey);
|
||||||
|
|
||||||
|
if (!dbDetails) {
|
||||||
|
unresolvedTargets.push(target);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const notionIDKey = `NotionID-${dbDetails.abName}`;
|
||||||
if (frontMatter[notionIDKey]) {
|
if (frontMatter[notionIDKey]) {
|
||||||
foundDatabases.push({
|
foundDatabases.push({
|
||||||
dbDetails: dbDetails,
|
dbDetails,
|
||||||
notionId: String(frontMatter[notionIDKey])
|
notionId: String(frontMatter[notionIDKey])
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unresolvedTargets.length > 0) {
|
||||||
|
console.log(`[AutoSync] Frontmatter auto sync targets not found in settings: ${unresolvedTargets.join(", ")}`);
|
||||||
|
}
|
||||||
|
|
||||||
// If no NotionID found, notify user to upload manually first
|
// If no NotionID found, notify user to upload manually first
|
||||||
if (foundDatabases.length === 0) {
|
if (foundDatabases.length === 0) {
|
||||||
console.log(`[AutoSync] No NotionID found in ${file.path}, skipping auto sync`);
|
console.log(`[AutoSync] No NotionID found in ${file.path}, skipping auto sync`);
|
||||||
@@ -403,4 +457,3 @@ export default class ObsidianSyncNotionPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { SettingModal } from "./settingModal";
|
|||||||
import { PreviewModal } from "./PreviewModal";
|
import { PreviewModal } from "./PreviewModal";
|
||||||
import { EditModal } from "./EditModal";
|
import { EditModal } from "./EditModal";
|
||||||
import { DeleteModal } from "./DeleteModal";
|
import { DeleteModal } from "./DeleteModal";
|
||||||
|
import { DEFAULT_AUTO_SYNC_DATABASE_KEY } from "src/utils/frontmatter";
|
||||||
|
|
||||||
export interface PluginSettings {
|
export interface PluginSettings {
|
||||||
NextButton: boolean;
|
NextButton: boolean;
|
||||||
@@ -15,6 +16,7 @@ export interface PluginSettings {
|
|||||||
NotionLinkDisplay: boolean;
|
NotionLinkDisplay: boolean;
|
||||||
autoSync: boolean;
|
autoSync: boolean;
|
||||||
autoSyncDelay: number;
|
autoSyncDelay: number;
|
||||||
|
autoSyncFrontmatterKey: string;
|
||||||
proxy: string;
|
proxy: string;
|
||||||
GeneralButton: boolean;
|
GeneralButton: boolean;
|
||||||
tagButton: boolean;
|
tagButton: boolean;
|
||||||
@@ -53,6 +55,7 @@ export const DEFAULT_SETTINGS: PluginSettings = {
|
|||||||
NotionLinkDisplay: true,
|
NotionLinkDisplay: true,
|
||||||
autoSync: false,
|
autoSync: false,
|
||||||
autoSyncDelay: 5,
|
autoSyncDelay: 5,
|
||||||
|
autoSyncFrontmatterKey: DEFAULT_AUTO_SYNC_DATABASE_KEY,
|
||||||
proxy: "",
|
proxy: "",
|
||||||
GeneralButton: true,
|
GeneralButton: true,
|
||||||
tagButton: true,
|
tagButton: true,
|
||||||
@@ -94,6 +97,20 @@ export class ObsidianSettingTab extends PluginSettingTab {
|
|||||||
|
|
||||||
this.createSettingEl(containerEl, i18nConfig.AutoSync, i18nConfig.AutoSyncDesc, 'toggle', i18nConfig.AutoSync, this.plugin.settings.autoSync, 'autoSync')
|
this.createSettingEl(containerEl, i18nConfig.AutoSync, i18nConfig.AutoSyncDesc, 'toggle', i18nConfig.AutoSync, this.plugin.settings.autoSync, 'autoSync')
|
||||||
|
|
||||||
|
new Setting(containerEl)
|
||||||
|
.setName(i18nConfig.AutoSyncFrontmatterKey)
|
||||||
|
.setDesc(i18nConfig.AutoSyncFrontmatterKeyDesc)
|
||||||
|
.addText((text) =>
|
||||||
|
text
|
||||||
|
.setPlaceholder(DEFAULT_AUTO_SYNC_DATABASE_KEY)
|
||||||
|
.setValue(this.plugin.settings.autoSyncFrontmatterKey ?? "")
|
||||||
|
.onChange(async (value) => {
|
||||||
|
this.plugin.settings.autoSyncFrontmatterKey = value;
|
||||||
|
await this.plugin.saveSettings();
|
||||||
|
this.plugin.resetAutoSyncNoticeCache();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
// Auto Sync Delay setting - only visible when autoSync is enabled
|
// Auto Sync Delay setting - only visible when autoSync is enabled
|
||||||
this.autoSyncDelayContainer = containerEl.createDiv();
|
this.autoSyncDelayContainer = containerEl.createDiv();
|
||||||
const delaySetting = new Setting(this.autoSyncDelayContainer)
|
const delaySetting = new Setting(this.autoSyncDelayContainer)
|
||||||
@@ -350,4 +367,3 @@ export class ObsidianSettingTab extends PluginSettingTab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { App, Notice, TFile } from "obsidian";
|
|||||||
import ObsidianSyncNotionPlugin from "../main";
|
import ObsidianSyncNotionPlugin from "../main";
|
||||||
import { DatabaseDetails } from "../ui/settingTabs";
|
import { DatabaseDetails } from "../ui/settingTabs";
|
||||||
import { i18nConfig } from "src/lang/I18n";
|
import { i18nConfig } from "src/lang/I18n";
|
||||||
|
import { ensureAutoSyncDatabaseEntry } from "src/utils/frontmatter";
|
||||||
|
|
||||||
export async function updateYamlInfo(
|
export async function updateYamlInfo(
|
||||||
yamlContent: string,
|
yamlContent: string,
|
||||||
@@ -17,6 +18,7 @@ export async function updateYamlInfo(
|
|||||||
const { abName } = dbDetails
|
const { abName } = dbDetails
|
||||||
const notionIDKey = `NotionID-${abName}`;
|
const notionIDKey = `NotionID-${abName}`;
|
||||||
const linkKey = `link-${abName}`;
|
const linkKey = `link-${abName}`;
|
||||||
|
const autoSyncKey = plugin.getAutoSyncFrontmatterKey();
|
||||||
|
|
||||||
if (notionUser !== "") {
|
if (notionUser !== "") {
|
||||||
// replace url str "www" to notionID
|
// replace url str "www" to notionID
|
||||||
@@ -33,6 +35,12 @@ export async function updateYamlInfo(
|
|||||||
// add new notionID and link
|
// add new notionID and link
|
||||||
yamlContent[notionIDKey] = id;
|
yamlContent[notionIDKey] = id;
|
||||||
(NotionLinkDisplay) ? yamlContent[linkKey] = url : null;
|
(NotionLinkDisplay) ? yamlContent[linkKey] = url : null;
|
||||||
|
|
||||||
|
// ensure auto sync database list contains current short name
|
||||||
|
yamlContent[autoSyncKey] = ensureAutoSyncDatabaseEntry(
|
||||||
|
yamlContent[autoSyncKey],
|
||||||
|
abName
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
63
src/utils/frontmatter.ts
Normal file
63
src/utils/frontmatter.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
export const DEFAULT_AUTO_SYNC_DATABASE_KEY = "autosync-database";
|
||||||
|
|
||||||
|
export function resolveAutoSyncKey(rawKey: unknown): string {
|
||||||
|
if (typeof rawKey === "string") {
|
||||||
|
const trimmed = rawKey.trim();
|
||||||
|
if (trimmed.length > 0) {
|
||||||
|
return trimmed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DEFAULT_AUTO_SYNC_DATABASE_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toCandidateList(value: unknown): string[] {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
return value.map(item => String(item ?? "").trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value === "string") {
|
||||||
|
if (value.includes(",")) {
|
||||||
|
return value.split(",").map(item => item.trim());
|
||||||
|
}
|
||||||
|
return [value.trim()];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseAutoSyncDatabaseList(value: unknown): string[] {
|
||||||
|
const candidates = toCandidateList(value)
|
||||||
|
.map(name => name.replace(/^\[|\]$/g, "").trim()) // strip stray brackets
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
|
const seen = new Map<string, string>();
|
||||||
|
for (const name of candidates) {
|
||||||
|
const key = name.toLowerCase();
|
||||||
|
if (!seen.has(key)) {
|
||||||
|
seen.set(key, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from(seen.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ensureAutoSyncDatabaseEntry(value: unknown, abName: string): string[] {
|
||||||
|
const current = parseAutoSyncDatabaseList(value);
|
||||||
|
const lower = abName.toLowerCase();
|
||||||
|
|
||||||
|
let contains = false;
|
||||||
|
const updated = current.map(name => {
|
||||||
|
if (name.toLowerCase() === lower) {
|
||||||
|
contains = true;
|
||||||
|
return abName;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!contains) {
|
||||||
|
updated.push(abName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user