From ccb5a20abe4e0fbb4587eb2a08a93410ae9fa64e Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Thu, 23 Nov 2023 22:11:04 +0000 Subject: [PATCH 01/11] add custom frontmatter --- README.md | 3 + src/lang/locale/en.ts | 3 + src/lang/locale/ja.ts | 3 + src/lang/locale/zh.ts | 3 + src/ui/settingTabs.ts | 25 ++- src/upload/uploadCommand.ts | 35 ++++ .../upoload_custom/BaseUpload2NotionCustom.ts | 90 ++++++++++ .../upoload_custom/Upload2NotionCustom.ts | 157 ++++++++++++++++++ .../upoload_custom/getMarkdownCustom.ts | 43 +++++ 9 files changed, 360 insertions(+), 2 deletions(-) create mode 100644 src/upload/upoload_custom/BaseUpload2NotionCustom.ts create mode 100644 src/upload/upoload_custom/Upload2NotionCustom.ts create mode 100644 src/upload/upoload_custom/getMarkdownCustom.ts diff --git a/README.md b/README.md index 71e3aba..6c3851a 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,9 @@ Thus, based on the [original author's work](https://github.com/EasyChris/obsidia **Now, support both NotionNext and General databases.** ## Update + +### 1.2.0 + ### 1.1.1 - Fix the setting display bug in Japanese. - Add Japanese translation. diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index e109408..c54cfde 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -31,6 +31,9 @@ export const en = { NotionCustomTitleName: "Preferred title name", NotionCustomTitleNameDesc: "Enter the preferred title name for the first column of the Notion database (default: title)", NotionCustomTitleText: "Enter the name", + NotionCustomValues: "Customise values property", + NotionCustomValuesDesc: "Modify the column name of the Notion database,one per line", + NotionCustomValuesText: "Enter all properties that you want to sync", NotYetFinish: "Not finished. This function will be available in the next version", PlaceHolder: "Enter database Name", diff --git a/src/lang/locale/ja.ts b/src/lang/locale/ja.ts index 875e543..e2d6362 100644 --- a/src/lang/locale/ja.ts +++ b/src/lang/locale/ja.ts @@ -29,6 +29,9 @@ export const ja = { NotionCustomTitleName: "希望のタイトル名", NotionCustomTitleNameDesc: "Notionデータベースの最初の列のための希望のタイトル名を入力(デフォルト:title)", NotionCustomTitleText: "名前を入力", + NotionCustomValues: "値のカスタマイズ", + NotionCustomValuesDesc: "Notionデータベースの列名を変更、1行に1つ", + NotionCustomValuesText: "同期したいすべてのプロパティを入力", NotYetFinish: "未完了。この機能は次のバージョンで利用可能になります", PlaceHolder: "データベース名を入力", "notion-logo": "NotionNextで共有", diff --git a/src/lang/locale/zh.ts b/src/lang/locale/zh.ts index 56ff64b..a525aba 100644 --- a/src/lang/locale/zh.ts +++ b/src/lang/locale/zh.ts @@ -31,6 +31,9 @@ export const zh = { NotionCustomTitleName: "想要修改的表头名", NotionCustomTitleNameDesc: "输入你想要修改的notion数据库的表头名(默认:title)", NotionCustomTitleText: "输入表头名", + NotionCustomValues: "自定义Notion 数据库表头", + NotionCustomValuesDesc: "自定义Notion 数据库表头,每行一个", + NotionCustomValuesText: "输入你想要同步的所有属性", NotYetFinish: "未完成。此功能将在之后版本中提供", PlaceHolder: "输入数据库名称", "notion-logo": "分享到NotionNext", diff --git a/src/ui/settingTabs.ts b/src/ui/settingTabs.ts index 67862ba..4478cfc 100644 --- a/src/ui/settingTabs.ts +++ b/src/ui/settingTabs.ts @@ -10,12 +10,13 @@ export interface PluginSettings { notionUser: string; proxy: string; GeneralButton: boolean; - tagButton: boolean; + tagButton: boolean; CustomTitleButton: boolean; CustomTitleName: string; notionAPIGeneral: string; databaseIDGeneral: string; CustomButton: boolean; + CustomValues: string; notionAPICustom: string; databaseIDCustom: string; [key: string]: any; @@ -29,12 +30,13 @@ export const DEFAULT_SETTINGS: PluginSettings = { notionUser: "", proxy: "", GeneralButton: true, - tagButton: true, + tagButton: true, CustomTitleButton: false, CustomTitleName: "", notionAPIGeneral: "", databaseIDGeneral: "", CustomButton: false, + CustomValues: "", notionAPICustom: "", databaseIDCustom: "", }; @@ -108,8 +110,10 @@ export class ObsidianSettingTab extends PluginSettingTab { // name should follow the result of the title button if (value) { this.updateSettingEl(CustomNameEl, this.plugin.settings.CustomTitleButton) + this.updateSettingEl(CustomValuesEl, this.plugin.settings.CustomTitleButton) } else { this.updateSettingEl(CustomNameEl, value) + this.updateSettingEl(CustomValuesEl, value) } this.updateSettingEl(notionAPIGeneralEl, value) @@ -139,6 +143,8 @@ export class ObsidianSettingTab extends PluginSettingTab { this.updateSettingEl(CustomNameEl, value) + this.updateSettingEl(CustomValuesEl, value) + await this.plugin.saveSettings(); await this.plugin.commands.updateCommand(); }) @@ -148,6 +154,21 @@ export class ObsidianSettingTab extends PluginSettingTab { const CustomNameEl = this.createStyleDiv('custom-name', (this.plugin.settings.CustomTitleButton && this.plugin.settings.GeneralButton)); this.createSettingEl(CustomNameEl, i18nConfig.NotionCustomTitleName, i18nConfig.NotionCustomTitleNameDesc, 'text', i18nConfig.NotionCustomTitleText, this.plugin.settings.CustomTitleName, 'CustomTitleName') + // Custom database properties + const CustomValuesEl = this.createStyleDiv('custom-values', (this.plugin.settings.CustomTitleButton && this.plugin.settings.GeneralButton)); + new Setting(CustomValuesEl) + .setName(i18nConfig.NotionCustomValues) + .setDesc(i18nConfig.NotionCustomValuesDesc) + .addTextArea((text) => + text + .setPlaceholder(i18nConfig.NotionCustomValuesText) + .setValue(this.plugin.settings.CustomValues) + .onChange(async (value) => { + this.plugin.settings.CustomValues = value; + await this.plugin.saveSettings(); + await this.plugin.commands.updateCommand(); + }) + ); // new Setting(containerEl) // .setName("Convert tags(optional)") // .setDesc("Transfer the Obsidian tags to the Notion table. It requires the column with the name 'Tags'") diff --git a/src/upload/uploadCommand.ts b/src/upload/uploadCommand.ts index fbd2c78..0230fff 100644 --- a/src/upload/uploadCommand.ts +++ b/src/upload/uploadCommand.ts @@ -2,10 +2,12 @@ import { i18nConfig } from "../lang/I18n"; import { App, Notice } from "obsidian"; import { Upload2NotionNext } from "./upload_next/Upload2NotionNext"; import { Upload2NotionGeneral } from "./upload_general/Upload2NotionGeneral"; +import { Upload2NotionCustom } from "./upoload_custom/Upload2NotionCustom"; import { PluginSettings } from "../ui/settingTabs"; import ObsidianSyncNotionPlugin from "../main"; import { getNowFileMarkdownContentNext } from "./upload_next/getMarkdownNext"; import { getNowFileMarkdownContentGeneral } from "./upload_general/getMarkdownGeneral"; +import {getNowFileMarkdownContentCustom} from "./upoload_custom/getMarkdownCustom"; export async function uploadCommandNext( plugin: ObsidianSyncNotionPlugin, @@ -78,3 +80,36 @@ export async function uploadCommandGeneral( } } + + +export async function uploadCommandCustom( + plugin: ObsidianSyncNotionPlugin, + settings: PluginSettings, + app: App, +) { + + const { notionAPIGeneral, databaseIDGeneral } = settings; + + // Check if the user has set up the Notion API and database ID + if (notionAPIGeneral === "" || databaseIDGeneral === "") { + const setAPIMessage = i18nConfig["set-api-id"]; + new Notice(setAPIMessage); + return; + } + + const { markDownData, nowFile, cover, tags ,customValues} = await getNowFileMarkdownContentCustom(app, settings) + + if (markDownData) { + const { basename } = nowFile; + + const upload = new Upload2NotionCustom(plugin); + const res = await upload.syncMarkdownToNotionCustom(basename, cover, tags, customValues, markDownData, nowFile, this.app); + + if (res.status === 200) { + new Notice(`${i18nConfig["sync-success"]}${basename}`); + } else { + new Notice(`${i18nConfig["sync-fail"]}${basename}`, 5000); + } + + } +} diff --git a/src/upload/upoload_custom/BaseUpload2NotionCustom.ts b/src/upload/upoload_custom/BaseUpload2NotionCustom.ts new file mode 100644 index 0000000..cf135ac --- /dev/null +++ b/src/upload/upoload_custom/BaseUpload2NotionCustom.ts @@ -0,0 +1,90 @@ +import {App, Notice, requestUrl, TFile} from "obsidian"; +import {Client} from '@notionhq/client'; +import {markdownToBlocks,} from "@tryfabric/martian"; +import * as yamlFrontMatter from "yaml-front-matter"; +// import * as yaml from "yaml" +import MyPlugin from "src/main"; + +export class UploadBaseCustom { + plugin: MyPlugin; + notion: Client; + agent: any; + + constructor(plugin: MyPlugin) { + this.plugin = plugin; + } + + async deletePage(notionID: string) { + return requestUrl({ + url: `https://api.notion.com/v1/blocks/${notionID}`, + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer ' + this.plugin.settings.notionAPINext, + 'Notion-Version': '2022-06-28', + }, + body: '' + }); + } + + async getDataBase(databaseID: string) { + const response = await requestUrl({ + url: `https://api.notion.com/v1/databases/${databaseID}`, + method: 'GET', + headers: { + 'Authorization': 'Bearer ' + this.plugin.settings.notionAPINext, + 'Notion-Version': '2022-06-28', + } + } + ) + + // Check if cover is present in the JSON response and then get the URL + if (response.json.cover && response.json.cover.external) { + return response.json.cover.external.url; + } else { + return null; // or some other default value, if you prefer + } + } + + // async updateYamlInfo(yamlContent: string, nowFile: TFile, res: any, app: App, settings: any) { + // let {url, id} = res.json + // // replace www to notionID + // const {notionUser} = this.plugin.settings; + // + // if (notionUser !== "") { + // // replace url str "www" to notionID + // url = url.replace("www.notion.so", `${notionUser}.notion.site`) + // } + // + // await app.fileManager.processFrontMatter(nowFile, yamlContent => { + // if (yamlContent['notionID']) { + // delete yamlContent['notionID'] + // } + // if (yamlContent['link']) { + // delete yamlContent['link'] + // } + // // add new notionID and link + // yamlContent.notionID = id; + // yamlContent.link = url; + // }); + // + // try { + // await navigator.clipboard.writeText(url) + // } catch (error) { + // new Notice(`复制链接失败,请手动复制${error}`) + // } + // // const __content = yamlContent.__content; + // // delete yamlContent.__content + // // const yamlhead = yaml.stringify(yamlContent) + // // // if yamlhead hava last \n remove it + // // const yamlhead_remove_n = yamlhead.replace(/\n$/, '') + // // // if __content have start \n remove it + // // const __content_remove_n = __content.replace(/^\n/, '') + // // const content = '---\n' +yamlhead_remove_n +'\n---\n' + __content_remove_n; + // // try { + // // await nowFile.vault.modify(nowFile, content) + // // } catch (error) { + // // new Notice(`write file error ${error}`) + // // } + // } +} diff --git a/src/upload/upoload_custom/Upload2NotionCustom.ts b/src/upload/upoload_custom/Upload2NotionCustom.ts new file mode 100644 index 0000000..f84d92e --- /dev/null +++ b/src/upload/upoload_custom/Upload2NotionCustom.ts @@ -0,0 +1,157 @@ +import { App, Notice, requestUrl, TFile } from "obsidian"; +import { Client } from "@notionhq/client"; +import { markdownToBlocks } from "@tryfabric/martian"; +import * as yamlFrontMatter from "yaml-front-matter"; +// import * as yaml from "yaml" +import MyPlugin from "src/main"; +import { PluginSettings } from "../../ui/settingTabs"; +import { updateYamlInfo } from "../updateYaml"; +import {UploadBaseCustom} from "./BaseUpload2NotionCustom"; + +export class Upload2NotionCustom extends UploadBaseCustom { + settings: PluginSettings; + + constructor(plugin: MyPlugin) { + super(plugin); + } + + // 因为需要解析notion的block进行对比,非常的麻烦, + // 暂时就直接删除,新建一个page + async updatePage( + notionID: string, + title: string, + cover: string, + tags: string[], + customValues: Record, + childArr: any, + ) { + await this.deletePage(notionID); + + const databasecover = await this.getDataBase( + this.plugin.settings.databaseIDGeneral, + ); + + if (cover == null) { + cover = databasecover; + } + + return await this.createPage(title, cover, tags, customValues, childArr); + } + + async createPage( + title: string, + cover: string, + tags: string[], + customValues: Record, + childArr: any, + ) { + const bodyString: any = { + parent: { + database_id: this.plugin.settings.databaseIDGeneral, + }, + properties: { + [this.plugin.settings.CustomTitleButton + ? this.plugin.settings.CustomTitleName + : "title"]: { + title: [ + { + text: { + content: title, + }, + }, + ], + }, + ...(Object.keys(customValues).reduce((acc, key) => { + acc[key] = { + rich_text: [ + { + text: { + content: customValues[key] || '', + }, + }, + ], + }; + return acc; + }, {} as Record)), + }, + children: childArr, + }; + + if (cover) { + bodyString.cover = { + type: "external", + external: { + url: cover, + }, + }; + } + + if (!bodyString.cover && this.plugin.settings.bannerUrl) { + bodyString.cover = { + type: "external", + external: { + url: this.plugin.settings.bannerUrl, + }, + }; + } + + try { + return await requestUrl({ + url: `https://api.notion.com/v1/pages`, + method: "POST", + headers: { + "Content-Type": "application/json", + // 'User-Agent': 'obsidian.md', + Authorization: + "Bearer " + this.plugin.settings.notionAPIGeneral, + "Notion-Version": "2022-06-28", + }, + body: JSON.stringify(bodyString), + }); + } catch (error) { + new Notice(`network error ${error}`); + } + } + + async syncMarkdownToNotionCustom( + title: string, + cover: string, + tags: string[], + customValues: Record, + markdown: string, + nowFile: TFile, + app: App, + ): Promise { + const options = { + notionLimits: { + truncate: false, + } + } + let res: any; + const yamlContent: any = yamlFrontMatter.loadFront(markdown); + const __content = yamlContent.__content; + const file2Block = markdownToBlocks(__content, options); + const frontmasster = + app.metadataCache.getFileCache(nowFile)?.frontmatter; + const notionID = frontmasster ? frontmasster.notionID : null; + + if (notionID) { + res = await this.updatePage( + notionID, + title, + cover, + tags, + customValues, + file2Block, + ); + } else { + res = await this.createPage(title, cover, tags, customValues, file2Block); + } + if (res.status === 200) { + await updateYamlInfo(markdown, nowFile, res, app, this.plugin); + } else { + new Notice(`${res.text}`); + } + return res; + } +} diff --git a/src/upload/upoload_custom/getMarkdownCustom.ts b/src/upload/upoload_custom/getMarkdownCustom.ts new file mode 100644 index 0000000..ad0b323 --- /dev/null +++ b/src/upload/upoload_custom/getMarkdownCustom.ts @@ -0,0 +1,43 @@ +import {App, Notice} from "obsidian"; +import {i18nConfig} from "../../lang/I18n"; +import {PluginSettings} from "../../ui/settingTabs"; + +export async function getNowFileMarkdownContentCustom( + app: App, + settings: PluginSettings, +) { + const nowFile = app.workspace.getActiveFile(); + let cover = ''; + let tags = []; + let customValues: Record = {}; + + const FileCache = app.metadataCache.getFileCache(nowFile); + try { + cover = FileCache.frontmatter.coverurl; + tags = FileCache.frontmatter.tags; + + // split the CustomValues into an array + const customValuesNames = settings.CustomValues.split('\n').map(value => value.trim()); + + // get the custom values from the frontmatter + customValuesNames.forEach(valueName => { + customValues[valueName] = FileCache.frontmatter[valueName]; + }); + } catch (error) { + new Notice(i18nConfig["set-tags-fail"]); + } + + if (nowFile) { + const markDownData = await nowFile.vault.read(nowFile); + return { + markDownData, + nowFile, + cover, + tags, + customValues, + }; + } else { + new Notice(i18nConfig["open-file"]); + return; + } +} From 6c30d0c2b4ced89eff60308fc68ad1b85501094b Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Wed, 6 Dec 2023 14:40:15 +0000 Subject: [PATCH 02/11] adjust the limitation of blocks --- README.html | 632 -------------------- src/upload/upload_next/Upload2NotionNext.ts | 22 + 2 files changed, 22 insertions(+), 632 deletions(-) delete mode 100644 README.html diff --git a/README.html b/README.html deleted file mode 100644 index 164eb46..0000000 --- a/README.html +++ /dev/null @@ -1,632 +0,0 @@ - - - - - - - - - -readme - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-

Obsidian to NotionNext

-

test.yml Release Obsidian plugin Github all releases GitLab latest release

-

中文文档

-

Thanks to the original author for developing such a useful plugin that can synchronize Obsidian to Notion. However, the original repository can only sync Name and Tags information. For those like me who use NotionNext to set up their website, this presents some limitations. Every time I import, I need to make a lot of modifications.

-

Thus, based on the original author’s work, I’ve added a feature to match the NotionNext template. This way, you can edit directly in Obsidian and publish with a single click after organizing.

-

Now, support both NotionNext and General databases.

-
-

Update

-
-

1.0.1

-
    -
  • Fix the custom name element display bug in the settings.
  • -
-
-
-

1.0.0 (Big Update)

-
    -
  • From this version, you can modify the first column name (title column, default: ‘title’) as you want. (Note: You need to have the ‘tags’ column in your Notion General database, and add tags: in your markdown frontmatter. If not, you will receive network error 400. But you can leave the tags: blank.)
  • -
-

Like this:

-
    -
  • Add a switch button to control whether display the setting tabs in the plugin settings for both NotionNext and Notion General databases.
  • -
-

-
-
-

0.2.6

-
    -
  • Add a switch button to control whether to show the upload command in the command palette.
  • -
-

If you turn off the button for the General database, you won’t see the option for the General database in the upload command list.

-

If you turn off the button for the NotionNext database, you won’t see the option for the NotionNext database in the upload command list.

-

-
-
-

0.2.3

-
    -
  • Fix the bug, now you can update normally.
  • -
-
-
-

0.2.2

-
    -
  • Support both NotionNext and General Notion database.
  • -
  • You can have one NotionNext and one General Notion database.
  • -
  • General Notion database can only have title and tags columns, and tags columns should be the multi-selected property. the name of the columns is case sensitive. You should use small letter.
  • -
-

-

-
-
-

0.2.1

-
    -
  • Restructure the code
  • -
-
-
-

0.2.0

-
    -
  • From this version, the interactive logic has been rewritten. When you click the ribbon icon, it will display the sync command for all presetting NotionNext databases. You can choose the database you want to sync to. However, only NotionNext database is supported for now.
  • -
-
-
-

0.1.10

-
    -
  • Fix the Chinese support in the settings.
  • -
-
-
-

0.1.8

-
    -
  • Rebuild the uploadCommand function, and add one button to select the different databases. However, only NotionNext database is supported for now.
  • -
-
-
-

0.1.7

-
    -
  • Removed the convert tag option. Now, you can directly add tags in the YAML front matter. If you don’t want to add tags, you can delete the tags in the YAML front matter or leave the tags blank.
  • -
-
-
-
-

How to Use

-
-

Precautions

-

For now, this plugin is exclusively for NotionNext. If you’re not using this template, you’ll keep receiving error 400.

-

For those without a NotionNext requirement, please use the original Obsidian-to-notion.

-
-
-

Pre-Installation Steps

-

Before installing the plugin, you must have set up the following:

-
    -
  1. Your NotionNext database.
  2. -
  3. According to the original author’s readme.md, set up the Notion API, and it should already be associated with your NotionNext repository.
  4. -
  5. NotionNext Database ID
  6. -
  7. Your NotionNext database should have the following contents: -
      -
    • type
    • -
    • title
    • -
    • slug
    • -
    • category
    • -
    • tags
    • -
    • date
    • -
    • status
    • -
    • summary
    • -
    • password
    • -
    • icon
    • -
  8. -
-

From version 0.0.6, I also add the following contents: - titleicon: the unique icon for each post, it can only support emoji currently. - cover url: the cover image for each post, it should be end with a type of image, such as .jpg, .png, .gif, etc.

-

If you’ve directly copied the NotionNext template, these contents should already exist. I’ve made changes to this plugin based on the original author’s work. All you need to ensure is that your database has the above content, and every letter is in lowercase!!!

-

⚠️⚠️⚠️: All headers are in lowercase!!! The order doesn’t matter!

-
-
-

Plugin Installation

-
-

Install via Community Plugins

-

Open Obsidian settings -> Community Plugins -> Browse -> NotionNext -> Share to NotionNext

-
-
-

Mannually Install

-
    -
  1. Close Obsidian.
  2. -
  3. Download the plugin file from Release and unzip it into your Obsidian plugin directory.
  4. -
  5. Re-open Obsidian, go to settings, and enable the plugin.
  6. -
  7. In the settings, find Obsidian to NotionNext, and enter your NotionNext Database ID and API token.
  8. -
-
-
-
-

How to Use

-
-
-

Using the Plugin

-

In the repository, I have uploaded a template which you can directly copy into your template folder. After that, use Obsidian’s template feature to create a new note with one click.

-

If you don’t want to use the template, you can also directly create a new file in Obsidian and then copy the content below. Then save it.

-
---
-# default value has been set.
-# for any unwanted value, you can delete it or set it to empty.
-# for example, if you donot want to set password, you can delete password: "1234" or set it to password: ""
-# 我已经在插件中设置了默认值,如果有不需要的选项,可以直接删除。
-# 例如你不需要密码选项,你可以将password: "1234"删除,或者将它设置为空。
-# !!!!!!!!!!!!
-# 现在阶段一定不要修改表头的名字, please do not change the name of the header in YAML front matter
-# !!!!!!!!!!!!
-titleicon: 📎 # emoji icon, default is 📜, 默认是📜
-date: 2023-07-23 # default is today, 默认是今天。 Format is YYYY-MM-DD, 格式是YYYY-MM-DD
-coverurl: https://img.jxpeng.dev/2023/08/843e27a210847f05a0f7cfb121fec100.jpg # default is empty, 默认是空
-type: Post # Post or Page, default is Post, 默认是Post
-slug: test # slug for url, default is empty, 默认是空
-stats: Draft # Draft, Invisible, Published, default is Draft, 默认是Draft
-category: test # default is 'Obsidian', 默认是'Obsidian'
-summary: this is a summary for test post # default is empty, 默认是空
-icon: fa-solid fa-camera # you can ignore this, default is empty, 默认是空,可直接删除
-password: "1234" # if you donot want to set password, you can delete this line, default is empty, 默认是空,可直接删除
-# 现在必须开启tags选项,否则会报错
-tags:
-  - test  # tags for post
-  - web # add more tags if you want
----
-
-Contents Below
-

Usage of the template is as follows:

-

Plugin preview is shown below

-
-

Original README.md

-

Many Thanks for the original author’s work. I’ve only made some changes to the original author’s work. If you find this plugin useful, please give the original author a star.

-
-
-
-
-

Obsidian to Notion

-

Release Obsidian plugin GitHub license Github all releases GitLab latest release

-

Share of obsidian to Notion 中文文档

-

Sharing files from Obsidian to Notion with a single click, and Obsidian will automatically add the Notion share link

-

You are welcome to offer it a star if it can benefit you.

-

-
-
-

TODO

-
-

TODO Board

-
    -
  • support for custom page banner
  • -
  • update the exsit page
  • -
  • support for mult language
  • -
  • support for auto copy the share link to clipboard
  • -
  • support for mobile
  • -
  • support tags thank for @jannikbuscha
  • -
  • transfer the bi-link format like [[]] into the format that Notion supports.
  • -
-
-
-
-

How to use

-
-

Install the plugin

-
-

Marketplace download

-

Open obsidian setting -> Add plugin -> Search -> notion

-

-
-
-

BRAT

-

Enter BRAT into the plugin market center to find it. Add EasyChris/obsidian-to-notion to the list of BRAT plugins that have been installed. Return to the plugin center and turn it on.

-
-
-

Manual installation

-
cd YOUR_OBSIDIAN_FOLDER/.obsidian/plugins/
-git clone https://github.com/EasyChris/obsidian-to-notion.git
-
-
-
-

Apply Notion API

-

Official reference documentation: https://developers.notion.com/docs

-
-

Step 1: Create integration

-

Go to https://www.notion.com/my-integrations Once created, copy secrets toekn

-
-

Note

-

database first custom name must be “Name”, otherwise sync to notion will be failed

-

-
-
-
-

Step 2: Share a database with your integration

-

Create a new page (with public permissions) Create a new database in the page -> you need full page database

-

Add integration to your new database

-

-
-
-

Step 3: Copy the database ID

-
https://www.notion.so/myworkspace/a8aec43384f447ed84390e8e42c2e089?v=...
-                                  | --------- Database ID --------|
-
-
-
-
-

Open the plugin configuration

-

Fill the configuration with the NOTION_API_KEY and DATABASE_ID you got

-
-
-

Upload file content to notion

-

Click the uploadCommand notion button A share link will be automatically generated after successful uploadCommand

-
- -
-

Convert Tags [option]

-

Transfer the Obsidian tags to the Notion table. It requires the column with the name ‘Tags’.

-

Add tags to your notion page

-

-
    -
  • open plugin convert tags
  • -
-

-
    -
  • add tags in the head
  • -
-
---
-tags: [tag1,tag2]
----
-
-this is test tags
-
---
-tags:
-  - tag4
----
-
-this is test tags
-

-

Thanks for @jannikbuscha contribution

-
-
-

Notion ID [option]

-

Notion ID is the your notion site ID that you want to share the file to. if you don’t write it, notion will share to the default link like: https://www.notion.so/myworkspace/a8aec43384f447ed84390 that visit this page need to redirect to your site url if you write the Notion ID, it will share to the page link like: https://your_user_name.notion.site/myworkspace/a8aec43384f447ed84390. The visiter don’t need to redirect url.

-
-
-

Sync image to Notion

-

To sync images to your oss or cos bucket, use the Obsidian Image Auto Upload Plugin.

-
-
-
-

Development

-
git clone https://github.com/EasyChris/obsidian-to-notion.git
-yarn install
-yarn dev
-
-

Release

-
node update-version.js
-./release.sh
-

```

-
-
-
-

Thanks

-

Development Process | Obsidian Plugin Development Documentation

-

GitHub - devbean/obsidian-wordpress: An obsidian plugin for publishing docs to WordPress.

-

GitHub - obsidianmd/obsidian-api

-

GitHub - Easychris/obsidian-to-notion: Obsidian Weread Plugin is an plugin to sync Weread(微信读书) hightlights and annotations into your Obsidian Vault.

-

GitHub - Quorafind/Obsidian-Memos: A quick capture plugin for Obsidian, all data from your notes.

-

https://github.com/jannikbuscha/obsidian-to-notion

-
-
-

License

-

GNU GPLv3

-
- -
- - -
- - - - \ No newline at end of file diff --git a/src/upload/upload_next/Upload2NotionNext.ts b/src/upload/upload_next/Upload2NotionNext.ts index e1069ca..480c962 100644 --- a/src/upload/upload_next/Upload2NotionNext.ts +++ b/src/upload/upload_next/Upload2NotionNext.ts @@ -7,6 +7,7 @@ import * as yamlFrontMatter from "yaml-front-matter"; import MyPlugin from "src/main"; import { PluginSettings } from "../../ui/settingTabs"; import { updateYamlInfo } from "../updateYaml"; +import {LIMITS, paragraph} from "@tryfabric/martian/src/notion"; export class Upload2NotionNext extends UploadBaseNext { settings: PluginSettings; @@ -217,6 +218,27 @@ export class Upload2NotionNext extends UploadBaseNext { const frontmasster = app.metadataCache.getFileCache(nowFile)?.frontmatter const notionID = frontmasster ? frontmasster.notionID : null + // increase the limits + // Motivated by https://github.com/tryfabric/martian/issues/51 + file2Block.forEach((block,index) => { + if ( + block.type === 'paragraph' && + block.paragraph.rich_text.length > LIMITS.RICH_TEXT_ARRAYS + ) { + + const newParagraphBlocks: any[] = [] + const chunk:any = [] + const richTextChunks = chunk(block.paragraph.rich_text, 100) + + richTextChunks.forEach((chunk: any) => { + newParagraphBlocks.push(paragraph(chunk)) + }) + + file2Block.splice(index, 1, ...newParagraphBlocks) + + } + }) + if (notionID) { res = await this.updatePage( notionID, From f3fb251cf76b47ecef50ca58590c0dcce27ab141 Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Mon, 25 Dec 2023 22:43:11 +0000 Subject: [PATCH 03/11] set the class next tabs --- src/ui/settingGeneralTabs.ts | 0 src/ui/settingModal.ts | 86 ++++++++++++++++++++++++++++++++++ src/ui/settingNextTabs.ts | 48 +++++++++++++++++++ src/ui/settingTabs.ts | 91 +++++++++++++++++++++++++----------- 4 files changed, 199 insertions(+), 26 deletions(-) create mode 100644 src/ui/settingGeneralTabs.ts create mode 100644 src/ui/settingModal.ts create mode 100644 src/ui/settingNextTabs.ts diff --git a/src/ui/settingGeneralTabs.ts b/src/ui/settingGeneralTabs.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/ui/settingModal.ts b/src/ui/settingModal.ts new file mode 100644 index 0000000..a464a42 --- /dev/null +++ b/src/ui/settingModal.ts @@ -0,0 +1,86 @@ +import { + Modal, + Setting, + PluginSettingTab, + ButtonComponent +} from 'obsidian'; + +import { i18nConfig } from "../lang/I18n"; +import ObsidianSyncNotionPlugin from "../main"; + +export class SettingModal extends Modal { + plugin: ObsidianSyncNotionPlugin; + + constructor(plugin: ObsidianSyncNotionPlugin) { + super(plugin.app); + this.plugin = plugin; + } + + onOpen() { + let {contentEl} = this; + contentEl.addClass('sync-to-notion-modal'); + + new Setting(contentEl) + .setName(i18nConfig.GeneralSetting) + .setDesc(i18nConfig.GeneralSetting) + .addToggle((toggle) => { + toggle + .setValue(this.plugin.settings.enableNotionNext) + .onChange(async (value) => { + this.plugin.settings.enableNotionNext = value; + await this.plugin.saveSettings(); + }); + }) + .addToggle((toggle) => { + toggle + .setValue(this.plugin.settings.enableNotionGeneral) + .onChange(async (value) => { + this.plugin.settings.enableNotionGeneral = value; + await this.plugin.saveSettings(); + }); + }); + + new Setting(contentEl) + .setName(i18nConfig.NotionNextSettingHeader) + .setDesc(i18nConfig.NotionNextSettingHeader) + .addText((text) => { + text + .setPlaceholder(i18nConfig.NotionAPI) + .setValue(this.plugin.settings.notionAPI) + .onChange(async (value) => { + this.plugin.settings.notionAPI = value; + await this.plugin.saveSettings(); + }); + }) + .addText((text) => { + text + .setPlaceholder(i18nConfig.DatabaseID) + .setValue(this.plugin.settings.databaseIDNext) + .onChange(async (value) => { + this.plugin.settings.databaseIDNext = value; + await this.plugin.saveSettings(); + }); + }) + .addText((text) => { + text + .setPlaceholder(i18nConfig.BannerUrl) + .setValue(this.plugin.settings.bannerUrl) + .onChange(async (value) => { + this.plugin.settings.bannerUrl = value; + await this.plugin.saveSettings(); + }); + }) + .addText((text) => { + text + .setPlaceholder(i18nConfig.NotionUser) + .setValue(this.plugin.settings.notionUser) + .onChange(async (value) => { + this.plugin.settings.notionUser = value; + await this.plugin.saveSettings(); + }); + }); + + new Setting(contentEl) + } + +} diff --git a/src/ui/settingNextTabs.ts b/src/ui/settingNextTabs.ts new file mode 100644 index 0000000..5de4f83 --- /dev/null +++ b/src/ui/settingNextTabs.ts @@ -0,0 +1,48 @@ +import {App, PluginSettingTab, Setting} from "obsidian"; +import ObsidianSyncNotionPlugin from "../main"; +import {i18nConfig} from "../lang/I18n"; +import {ObsidianSettingTab} from "./settingTabs"; + +export class SettingNextTab extends PluginSettingTab { + plugin: ObsidianSyncNotionPlugin; + private settingTab: ObsidianSettingTab; + + constructor(app: App, plugin: ObsidianSyncNotionPlugin, settingTab: ObsidianSettingTab) { + super(app, plugin); + this.plugin = plugin; + this.settingTab = settingTab; + } + + display(): void { + + // notion next database settings + + this.settingTab.containerEl.createEl('h2', { text: i18nConfig.NotionNextSettingHeader }) + + new Setting(this.settingTab.containerEl) + .setName(i18nConfig.NotionNextButton) + .setDesc(i18nConfig.NotionNextButtonDesc) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.NextButton) + .onChange(async (value) => { + this.plugin.settings.NextButton = value; + + this.settingTab.updateSettingEl(notionAPINextEl, value) + + this.settingTab.updateSettingEl(databaseIDNextEl, value) + + await this.plugin.saveSettings(); + await this.plugin.commands.updateCommand(); + }) + ); + + + const notionAPINextEl = this.settingTab.createStyleDiv('api-next', this.plugin.settings.NextButton) + this.settingTab.createSettingEl(notionAPINextEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPINext, 'notionAPINext') + + const databaseIDNextEl = this.settingTab.createStyleDiv('databaseID-next', this.plugin.settings.NextButton) + this.settingTab.createSettingEl(databaseIDNextEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDNext, 'databaseIDNext') + } + +} diff --git a/src/ui/settingTabs.ts b/src/ui/settingTabs.ts index 4478cfc..f9cbf02 100644 --- a/src/ui/settingTabs.ts +++ b/src/ui/settingTabs.ts @@ -1,6 +1,8 @@ -import { App, PluginSettingTab, Setting } from "obsidian"; -import { i18nConfig } from "../lang/I18n"; +import {App, ButtonComponent, PluginSettingTab, Setting} from "obsidian"; +import {i18nConfig} from "../lang/I18n"; import ObsidianSyncNotionPlugin from "../main"; +import {SettingModal} from "./settingModal"; +import {SettingNextTab} from "./settingNextTabs"; export interface PluginSettings { NextButton: boolean; @@ -62,33 +64,70 @@ export class ObsidianSettingTab extends PluginSettingTab { this.createSettingEl(containerEl, i18nConfig.NotionUser, i18nConfig.NotionUserDesc, 'text', i18nConfig.NotionUserText, this.plugin.settings.notionUser, 'notionUser') - containerEl.createEl('h2', { text: i18nConfig.NotionNextSettingHeader }) + + // add new button + + new Setting(containerEl) + .setName("Add New Database") + .setDesc("Add New Database") + .addButton((button: ButtonComponent): ButtonComponent => { + return button + .setTooltip("Add New Database") + .setIcon("plus") + .onClick(async () => { + let modal = new SettingModal(this.plugin); + + modal.onClose = () => { + // if (modal.saved) { + // const database = { + // + // } + // this.plugin.addDatabase(database); + // + // this.plugin.calloutManager.addDatabase(database); + // + // this.display(); + // } + } + + modal.open(); + }); + }); - new Setting(containerEl) - .setName(i18nConfig.NotionNextButton) - .setDesc(i18nConfig.NotionNextButtonDesc) - .addToggle((toggle) => - toggle - .setValue(this.plugin.settings.NextButton) - .onChange(async (value) => { - this.plugin.settings.NextButton = value; - this.updateSettingEl(notionAPINextEl, value) + // notion next database settings - this.updateSettingEl(databaseIDNextEl, value) + const NextTabs = new SettingNextTab(this.app, this.plugin, this); - await this.plugin.saveSettings(); - await this.plugin.commands.updateCommand(); - }) - ); + NextTabs.display(); - - const notionAPINextEl = this.createStyleDiv('api-next', this.plugin.settings.NextButton) - this.createSettingEl(notionAPINextEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPINext, 'notionAPINext') - - const databaseIDNextEl = this.createStyleDiv('databaseID-next', this.plugin.settings.NextButton) - this.createSettingEl(databaseIDNextEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDNext, 'databaseIDNext') + // containerEl.createEl('h2', { text: i18nConfig.NotionNextSettingHeader }) + // + // new Setting(containerEl) + // .setName(i18nConfig.NotionNextButton) + // .setDesc(i18nConfig.NotionNextButtonDesc) + // .addToggle((toggle) => + // toggle + // .setValue(this.plugin.settings.NextButton) + // .onChange(async (value) => { + // this.plugin.settings.NextButton = value; + // + // this.updateSettingEl(notionAPINextEl, value) + // + // this.updateSettingEl(databaseIDNextEl, value) + // + // await this.plugin.saveSettings(); + // await this.plugin.commands.updateCommand(); + // }) + // ); + // + // + // const notionAPINextEl = this.createStyleDiv('api-next', this.plugin.settings.NextButton) + // this.createSettingEl(notionAPINextEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPINext, 'notionAPINext') + // + // const databaseIDNextEl = this.createStyleDiv('databaseID-next', this.plugin.settings.NextButton) + // this.createSettingEl(databaseIDNextEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDNext, 'databaseIDNext') // General Database Settings @@ -206,13 +245,13 @@ export class ObsidianSettingTab extends PluginSettingTab { } // create a function to create a div with a style for pop over elements - private createStyleDiv(className: string, commandValue: boolean = false) { + public createStyleDiv(className: string, commandValue: boolean = false) { return this.containerEl.createDiv(className, (div) => { this.updateSettingEl(div, commandValue); }); } // update the setting display style in the setting tab - private updateSettingEl(element: HTMLElement, commandValue: boolean) { + public updateSettingEl(element: HTMLElement, commandValue: boolean) { element.style.borderTop = commandValue ? "1px solid var(--background-modifier-border)" : "none"; element.style.paddingTop = commandValue ? "0.75em" : "0"; element.style.display = commandValue ? "block" : "none"; @@ -220,7 +259,7 @@ export class ObsidianSettingTab extends PluginSettingTab { } // function to add one setting element in the setting tab. - private createSettingEl(containerEl: HTMLElement, name: string, desc: string, type: string, placeholder: string, holderValue: any, settingsKey: string) { + public createSettingEl(containerEl: HTMLElement, name: string, desc: string, type: string, placeholder: string, holderValue: any, settingsKey: string) { if (type === 'password') { return new Setting(containerEl) .setName(name) From 11aaf14c0b53e9229d38db2c157995391d8da900 Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Mon, 25 Dec 2023 22:47:24 +0000 Subject: [PATCH 04/11] update general tabs --- src/ui/settingGeneralTabs.ts | 116 +++++++++++++++++++++ src/ui/settingNextTabs.ts | 2 +- src/ui/settingTabs.ts | 196 ++++++++++++++++++----------------- 3 files changed, 218 insertions(+), 96 deletions(-) diff --git a/src/ui/settingGeneralTabs.ts b/src/ui/settingGeneralTabs.ts index e69de29..394d0f2 100644 --- a/src/ui/settingGeneralTabs.ts +++ b/src/ui/settingGeneralTabs.ts @@ -0,0 +1,116 @@ +import {App, PluginSettingTab, Setting} from "obsidian"; +import ObsidianSyncNotionPlugin from "../main"; +import {i18nConfig} from "../lang/I18n"; +import {ObsidianSettingTab} from "./settingTabs"; + +export class SettingGeneralTabs extends PluginSettingTab { + plugin: ObsidianSyncNotionPlugin; + private settingTab: ObsidianSettingTab; + + constructor(app: App, plugin: ObsidianSyncNotionPlugin, settingTab: ObsidianSettingTab) { + super(app, plugin); + this.plugin = plugin; + this.settingTab = settingTab; + } + + display(): void { + + // General Database Settings + this.settingTab.containerEl.createEl('h2', { text: i18nConfig.NotionGeneralSettingHeader }); + + // new Setting(containerEl) + // .setName(i18nConfig.NotYetFinish) + new Setting(this.settingTab.containerEl) + .setName(i18nConfig.NotionGeneralButton) + .setDesc(i18nConfig.NotionGeneralButtonDesc) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.GeneralButton) + .onChange(async (value) => { + this.plugin.settings.GeneralButton = value; + + this.settingTab.updateSettingEl(tagButtonEl, value) + this.settingTab.updateSettingEl(CustomTitleEl, value) + // name should follow the result of the title button + if (value) { + this.settingTab.updateSettingEl(CustomNameEl, this.plugin.settings.CustomTitleButton) + this.settingTab.updateSettingEl(CustomValuesEl, this.plugin.settings.CustomTitleButton) + } else { + this.settingTab.updateSettingEl(CustomNameEl, value) + this.settingTab.updateSettingEl(CustomValuesEl, value) + } + + this.settingTab.updateSettingEl(notionAPIGeneralEl, value) + this.settingTab.updateSettingEl(databaseIDGeneralEl, value) + + + await this.plugin.saveSettings(); + await this.plugin.commands.updateCommand(); + + }) + ); + + // add the tagButton to control whether to add tags to the general database + const tagButtonEl = this.settingTab.createStyleDiv('tag-button', (this.plugin.settings.GeneralButton && this.plugin.settings.CustomTitleButton)); + this.settingTab.createSettingEl(tagButtonEl, i18nConfig.NotionTagButton, i18nConfig.NotionTagButtonDesc, 'toggle', i18nConfig.NotionCustomTitleText, this.plugin.settings.tagButton, 'tagButton') + + // Custom Title Button + const CustomTitleEl = this.settingTab.createStyleDiv('custom-title', this.plugin.settings.GeneralButton); + new Setting(CustomTitleEl) + .setName(i18nConfig.NotionCustomTitle) + .setDesc(i18nConfig.NotionCustomTitleDesc) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.CustomTitleButton) + .onChange(async (value) => { + this.plugin.settings.CustomTitleButton = value; + + this.settingTab.updateSettingEl(CustomNameEl, value) + + this.settingTab.updateSettingEl(CustomValuesEl, value) + + await this.plugin.saveSettings(); + await this.plugin.commands.updateCommand(); + }) + ); + + // Custom Title Name + const CustomNameEl = this.settingTab.createStyleDiv('custom-name', (this.plugin.settings.CustomTitleButton && this.plugin.settings.GeneralButton)); + this.settingTab.createSettingEl(CustomNameEl, i18nConfig.NotionCustomTitleName, i18nConfig.NotionCustomTitleNameDesc, 'text', i18nConfig.NotionCustomTitleText, this.plugin.settings.CustomTitleName, 'CustomTitleName') + + // Custom database properties + const CustomValuesEl = this.settingTab.createStyleDiv('custom-values', (this.plugin.settings.CustomTitleButton && this.plugin.settings.GeneralButton)); + new Setting(CustomValuesEl) + .setName(i18nConfig.NotionCustomValues) + .setDesc(i18nConfig.NotionCustomValuesDesc) + .addTextArea((text) => + text + .setPlaceholder(i18nConfig.NotionCustomValuesText) + .setValue(this.plugin.settings.CustomValues) + .onChange(async (value) => { + this.plugin.settings.CustomValues = value; + await this.plugin.saveSettings(); + await this.plugin.commands.updateCommand(); + }) + ); + // new Setting(containerEl) + // .setName("Convert tags(optional)") + // .setDesc("Transfer the Obsidian tags to the Notion table. It requires the column with the name 'Tags'") + // .addToggle((toggle) => + // toggle + // .setValue(this.plugin.settings.allowTags) + // .onChange(async (value) => { + // this.plugin.settings.allowTags = value; + // await this.plugin.saveSettings(); + // }) + // ); + + const notionAPIGeneralEl = this.settingTab.createStyleDiv('api-general', this.plugin.settings.GeneralButton); + this.settingTab.createSettingEl(notionAPIGeneralEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPIGeneral, 'notionAPIGeneral') + + + const databaseIDGeneralEl = this.settingTab.createStyleDiv('databaseID-general', this.plugin.settings.GeneralButton); + this.settingTab.createSettingEl(databaseIDGeneralEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDGeneral, 'databaseIDGeneral') + } + +} diff --git a/src/ui/settingNextTabs.ts b/src/ui/settingNextTabs.ts index 5de4f83..e0a8c8e 100644 --- a/src/ui/settingNextTabs.ts +++ b/src/ui/settingNextTabs.ts @@ -3,7 +3,7 @@ import ObsidianSyncNotionPlugin from "../main"; import {i18nConfig} from "../lang/I18n"; import {ObsidianSettingTab} from "./settingTabs"; -export class SettingNextTab extends PluginSettingTab { +export class SettingNextTabs extends PluginSettingTab { plugin: ObsidianSyncNotionPlugin; private settingTab: ObsidianSettingTab; diff --git a/src/ui/settingTabs.ts b/src/ui/settingTabs.ts index f9cbf02..ec5b71d 100644 --- a/src/ui/settingTabs.ts +++ b/src/ui/settingTabs.ts @@ -2,7 +2,8 @@ import {App, ButtonComponent, PluginSettingTab, Setting} from "obsidian"; import {i18nConfig} from "../lang/I18n"; import ObsidianSyncNotionPlugin from "../main"; import {SettingModal} from "./settingModal"; -import {SettingNextTab} from "./settingNextTabs"; +import {SettingNextTabs} from "./settingNextTabs"; +import {SettingGeneralTabs} from "./settingGeneralTabs"; export interface PluginSettings { NextButton: boolean; @@ -98,7 +99,7 @@ export class ObsidianSettingTab extends PluginSettingTab { // notion next database settings - const NextTabs = new SettingNextTab(this.app, this.plugin, this); + const NextTabs = new SettingNextTabs(this.app, this.plugin, this); NextTabs.display(); @@ -131,101 +132,106 @@ export class ObsidianSettingTab extends PluginSettingTab { // General Database Settings - containerEl.createEl('h2', { text: i18nConfig.NotionGeneralSettingHeader }); + const GeneralTabs = new SettingGeneralTabs(this.app, this.plugin, this); + GeneralTabs.display(); + + + // containerEl.createEl('h2', { text: i18nConfig.NotionGeneralSettingHeader }); + // + // // new Setting(containerEl) + // // .setName(i18nConfig.NotYetFinish) // new Setting(containerEl) - // .setName(i18nConfig.NotYetFinish) - new Setting(containerEl) - .setName(i18nConfig.NotionGeneralButton) - .setDesc(i18nConfig.NotionGeneralButtonDesc) - .addToggle((toggle) => - toggle - .setValue(this.plugin.settings.GeneralButton) - .onChange(async (value) => { - this.plugin.settings.GeneralButton = value; - - this.updateSettingEl(tagButtonEl, value) - this.updateSettingEl(CustomTitleEl, value) - // name should follow the result of the title button - if (value) { - this.updateSettingEl(CustomNameEl, this.plugin.settings.CustomTitleButton) - this.updateSettingEl(CustomValuesEl, this.plugin.settings.CustomTitleButton) - } else { - this.updateSettingEl(CustomNameEl, value) - this.updateSettingEl(CustomValuesEl, value) - } - - this.updateSettingEl(notionAPIGeneralEl, value) - this.updateSettingEl(databaseIDGeneralEl, value) - - - await this.plugin.saveSettings(); - await this.plugin.commands.updateCommand(); - - }) - ); - - // add the tagButton to control whether to add tags to the general database - const tagButtonEl = this.createStyleDiv('tag-button', (this.plugin.settings.GeneralButton && this.plugin.settings.CustomTitleButton)); - this.createSettingEl(tagButtonEl, i18nConfig.NotionTagButton, i18nConfig.NotionTagButtonDesc, 'toggle', i18nConfig.NotionCustomTitleText, this.plugin.settings.tagButton, 'tagButton') - - // Custom Title Button - const CustomTitleEl = this.createStyleDiv('custom-title', this.plugin.settings.GeneralButton); - new Setting(CustomTitleEl) - .setName(i18nConfig.NotionCustomTitle) - .setDesc(i18nConfig.NotionCustomTitleDesc) - .addToggle((toggle) => - toggle - .setValue(this.plugin.settings.CustomTitleButton) - .onChange(async (value) => { - this.plugin.settings.CustomTitleButton = value; - - this.updateSettingEl(CustomNameEl, value) - - this.updateSettingEl(CustomValuesEl, value) - - await this.plugin.saveSettings(); - await this.plugin.commands.updateCommand(); - }) - ); - - // Custom Title Name - const CustomNameEl = this.createStyleDiv('custom-name', (this.plugin.settings.CustomTitleButton && this.plugin.settings.GeneralButton)); - this.createSettingEl(CustomNameEl, i18nConfig.NotionCustomTitleName, i18nConfig.NotionCustomTitleNameDesc, 'text', i18nConfig.NotionCustomTitleText, this.plugin.settings.CustomTitleName, 'CustomTitleName') - - // Custom database properties - const CustomValuesEl = this.createStyleDiv('custom-values', (this.plugin.settings.CustomTitleButton && this.plugin.settings.GeneralButton)); - new Setting(CustomValuesEl) - .setName(i18nConfig.NotionCustomValues) - .setDesc(i18nConfig.NotionCustomValuesDesc) - .addTextArea((text) => - text - .setPlaceholder(i18nConfig.NotionCustomValuesText) - .setValue(this.plugin.settings.CustomValues) - .onChange(async (value) => { - this.plugin.settings.CustomValues = value; - await this.plugin.saveSettings(); - await this.plugin.commands.updateCommand(); - }) - ); - // new Setting(containerEl) - // .setName("Convert tags(optional)") - // .setDesc("Transfer the Obsidian tags to the Notion table. It requires the column with the name 'Tags'") - // .addToggle((toggle) => - // toggle - // .setValue(this.plugin.settings.allowTags) - // .onChange(async (value) => { - // this.plugin.settings.allowTags = value; - // await this.plugin.saveSettings(); - // }) - // ); - - const notionAPIGeneralEl = this.createStyleDiv('api-general', this.plugin.settings.GeneralButton); - this.createSettingEl(notionAPIGeneralEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPIGeneral, 'notionAPIGeneral') - - - const databaseIDGeneralEl = this.createStyleDiv('databaseID-general', this.plugin.settings.GeneralButton); - this.createSettingEl(databaseIDGeneralEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDGeneral, 'databaseIDGeneral') + // .setName(i18nConfig.NotionGeneralButton) + // .setDesc(i18nConfig.NotionGeneralButtonDesc) + // .addToggle((toggle) => + // toggle + // .setValue(this.plugin.settings.GeneralButton) + // .onChange(async (value) => { + // this.plugin.settings.GeneralButton = value; + // + // this.updateSettingEl(tagButtonEl, value) + // this.updateSettingEl(CustomTitleEl, value) + // // name should follow the result of the title button + // if (value) { + // this.updateSettingEl(CustomNameEl, this.plugin.settings.CustomTitleButton) + // this.updateSettingEl(CustomValuesEl, this.plugin.settings.CustomTitleButton) + // } else { + // this.updateSettingEl(CustomNameEl, value) + // this.updateSettingEl(CustomValuesEl, value) + // } + // + // this.updateSettingEl(notionAPIGeneralEl, value) + // this.updateSettingEl(databaseIDGeneralEl, value) + // + // + // await this.plugin.saveSettings(); + // await this.plugin.commands.updateCommand(); + // + // }) + // ); + // + // // add the tagButton to control whether to add tags to the general database + // const tagButtonEl = this.createStyleDiv('tag-button', (this.plugin.settings.GeneralButton && this.plugin.settings.CustomTitleButton)); + // this.createSettingEl(tagButtonEl, i18nConfig.NotionTagButton, i18nConfig.NotionTagButtonDesc, 'toggle', i18nConfig.NotionCustomTitleText, this.plugin.settings.tagButton, 'tagButton') + // + // // Custom Title Button + // const CustomTitleEl = this.createStyleDiv('custom-title', this.plugin.settings.GeneralButton); + // new Setting(CustomTitleEl) + // .setName(i18nConfig.NotionCustomTitle) + // .setDesc(i18nConfig.NotionCustomTitleDesc) + // .addToggle((toggle) => + // toggle + // .setValue(this.plugin.settings.CustomTitleButton) + // .onChange(async (value) => { + // this.plugin.settings.CustomTitleButton = value; + // + // this.updateSettingEl(CustomNameEl, value) + // + // this.updateSettingEl(CustomValuesEl, value) + // + // await this.plugin.saveSettings(); + // await this.plugin.commands.updateCommand(); + // }) + // ); + // + // // Custom Title Name + // const CustomNameEl = this.createStyleDiv('custom-name', (this.plugin.settings.CustomTitleButton && this.plugin.settings.GeneralButton)); + // this.createSettingEl(CustomNameEl, i18nConfig.NotionCustomTitleName, i18nConfig.NotionCustomTitleNameDesc, 'text', i18nConfig.NotionCustomTitleText, this.plugin.settings.CustomTitleName, 'CustomTitleName') + // + // // Custom database properties + // const CustomValuesEl = this.createStyleDiv('custom-values', (this.plugin.settings.CustomTitleButton && this.plugin.settings.GeneralButton)); + // new Setting(CustomValuesEl) + // .setName(i18nConfig.NotionCustomValues) + // .setDesc(i18nConfig.NotionCustomValuesDesc) + // .addTextArea((text) => + // text + // .setPlaceholder(i18nConfig.NotionCustomValuesText) + // .setValue(this.plugin.settings.CustomValues) + // .onChange(async (value) => { + // this.plugin.settings.CustomValues = value; + // await this.plugin.saveSettings(); + // await this.plugin.commands.updateCommand(); + // }) + // ); + // // new Setting(containerEl) + // // .setName("Convert tags(optional)") + // // .setDesc("Transfer the Obsidian tags to the Notion table. It requires the column with the name 'Tags'") + // // .addToggle((toggle) => + // // toggle + // // .setValue(this.plugin.settings.allowTags) + // // .onChange(async (value) => { + // // this.plugin.settings.allowTags = value; + // // await this.plugin.saveSettings(); + // // }) + // // ); + // + // const notionAPIGeneralEl = this.createStyleDiv('api-general', this.plugin.settings.GeneralButton); + // this.createSettingEl(notionAPIGeneralEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPIGeneral, 'notionAPIGeneral') + // + // + // const databaseIDGeneralEl = this.createStyleDiv('databaseID-general', this.plugin.settings.GeneralButton); + // this.createSettingEl(databaseIDGeneralEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDGeneral, 'databaseIDGeneral') // Custom Database Settings From 370444fb9492f815dc578d8b3a84abfc5a10345b Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Tue, 26 Dec 2023 09:03:29 +0000 Subject: [PATCH 05/11] basic display of modal --- src/lang/locale/en.ts | 5 + src/lang/locale/ja.ts | 5 + src/lang/locale/zh.ts | 5 + src/ui/settingModal.ts | 186 ++++++++++++++++++++++++-------------- src/ui/settingNextTabs.ts | 21 +++-- src/ui/settingTabs.ts | 148 +++--------------------------- 6 files changed, 158 insertions(+), 212 deletions(-) diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index c54cfde..db91ea8 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -1,4 +1,9 @@ export const en = { + databaseFormat: "Database Format", + databaseFormatDesc: "Select the database format you want to sync to NotionNext or General", + databaseNext: "NotionNext", + databaseGeneral: "General", + databaseCustom: "Custom", ribbonIcon: "Share to NotionNext", GeneralSetting: "General information Settings", CommandID: "share-to-notionnext", diff --git a/src/lang/locale/ja.ts b/src/lang/locale/ja.ts index e2d6362..4c23ae8 100644 --- a/src/lang/locale/ja.ts +++ b/src/lang/locale/ja.ts @@ -1,4 +1,9 @@ export const ja = { + databaseFormat: "データベース形式", + databaseFormatDesc: "同期したいデータベース形式を選択してください", + databaseNext: "NotionNext", + databaseGeneral: "一般的なNotion", + databaseCustom: "カスタム", ribbonIcon: "NotionNextで共有", GeneralSetting: "一般設定", CommandID: "share-to-notionnext", diff --git a/src/lang/locale/zh.ts b/src/lang/locale/zh.ts index a525aba..774dab2 100644 --- a/src/lang/locale/zh.ts +++ b/src/lang/locale/zh.ts @@ -1,4 +1,9 @@ export const zh = { + databaseFormat: "数据库格式", + databaseFormatDesc: "选择你想要同步的数据库格式Next 或者 普通", + databaseNext: "NotionNext", + databaseGeneral: "普通", + databaseCustom: "自定义", ribbonIcon: "分享到 NotionNext", GeneralSetting: "通用设置", CommandID: "share-to-notionnext", diff --git a/src/ui/settingModal.ts b/src/ui/settingModal.ts index a464a42..6a5ef63 100644 --- a/src/ui/settingModal.ts +++ b/src/ui/settingModal.ts @@ -2,85 +2,137 @@ import { Modal, Setting, PluginSettingTab, - ButtonComponent + ButtonComponent, App } from 'obsidian'; import { i18nConfig } from "../lang/I18n"; import ObsidianSyncNotionPlugin from "../main"; +import {ObsidianSettingTab} from "./settingTabs"; +import {SettingNextTabs} from "./settingNextTabs"; +import {SettingGeneralTabs} from "./settingGeneralTabs"; + export class SettingModal extends Modal { plugin: ObsidianSyncNotionPlugin; + settingTab: ObsidianSettingTab; - constructor(plugin: ObsidianSyncNotionPlugin) { - super(plugin.app); + constructor(app: App, plugin: ObsidianSyncNotionPlugin, settingTab: ObsidianSettingTab) { + super(app); this.plugin = plugin; + this.settingTab = settingTab; } + display(): void { + this.containerEl.addClass("settings-modal"); + + // create the dropdown button to select the database format + let { contentEl } = this; + contentEl.empty(); + + const settingDiv = contentEl.createDiv('setting-div'); + const nextTabs = contentEl.createDiv('next-tabs'); + + + new Setting(settingDiv) + .setName(i18nConfig.databaseFormat) + .setDesc(i18nConfig.databaseFormatDesc) + .addDropdown((component) => { + component + .addOption('none', '') + .addOption('general', i18nConfig.databaseGeneral) + .addOption('next', i18nConfig.databaseNext) + .addOption('custom', i18nConfig.databaseCustom) + .setValue(this.plugin.settings.databaseFormat) + .onChange(async (value) => { + this.updateContentBasedOnSelection(value, nextTabs); + }); + + // Initialize content based on the current dropdown value + this.updateContentBasedOnSelection(this.plugin.settings.databaseFormat, nextTabs); + }); + } + + updateContentBasedOnSelection(value: string, nextTabs: HTMLElement): void { + // Clear existing content + nextTabs.empty(); + + // Generate content based on the selected value + if (value === 'general') { + nextTabs.createEl('h2', { text: i18nConfig.NotionGeneralSettingHeader }); + // Additional content for 'general'... + } else if (value === 'next') { + nextTabs.createEl('h2', { text: i18nConfig.NotionNextSettingHeader }); + // Additional content for 'next'... + } + // Implement for 'custom' if needed + } + + + onOpen() { - let {contentEl} = this; - contentEl.addClass('sync-to-notion-modal'); - - new Setting(contentEl) - .setName(i18nConfig.GeneralSetting) - .setDesc(i18nConfig.GeneralSetting) - .addToggle((toggle) => { - toggle - .setValue(this.plugin.settings.enableNotionNext) - .onChange(async (value) => { - this.plugin.settings.enableNotionNext = value; - await this.plugin.saveSettings(); - }); - }) - .addToggle((toggle) => { - toggle - .setValue(this.plugin.settings.enableNotionGeneral) - .onChange(async (value) => { - this.plugin.settings.enableNotionGeneral = value; - await this.plugin.saveSettings(); - }); - }); - - new Setting(contentEl) - .setName(i18nConfig.NotionNextSettingHeader) - .setDesc(i18nConfig.NotionNextSettingHeader) - .addText((text) => { - text - .setPlaceholder(i18nConfig.NotionAPI) - .setValue(this.plugin.settings.notionAPI) - .onChange(async (value) => { - this.plugin.settings.notionAPI = value; - await this.plugin.saveSettings(); - }); - }) - .addText((text) => { - text - .setPlaceholder(i18nConfig.DatabaseID) - .setValue(this.plugin.settings.databaseIDNext) - .onChange(async (value) => { - this.plugin.settings.databaseIDNext = value; - await this.plugin.saveSettings(); - }); - }) - .addText((text) => { - text - .setPlaceholder(i18nConfig.BannerUrl) - .setValue(this.plugin.settings.bannerUrl) - .onChange(async (value) => { - this.plugin.settings.bannerUrl = value; - await this.plugin.saveSettings(); - }); - }) - .addText((text) => { - text - .setPlaceholder(i18nConfig.NotionUser) - .setValue(this.plugin.settings.notionUser) - .onChange(async (value) => { - this.plugin.settings.notionUser = value; - await this.plugin.saveSettings(); - }); - }); - - new Setting(contentEl) + // add console log to check if the modal is opened + this.display() } + + + // create a function to create a div with a style for pop over elements + public createStyleDiv(className: string, commandValue: boolean = false) { + return this.contentEl.createDiv(className, (div) => { + this.updateSettingEl(div, commandValue); + }); + } + // update the setting display style in the setting tab + public updateSettingEl(element: HTMLElement, commandValue: boolean) { + element.style.borderTop = commandValue ? "1px solid var(--background-modifier-border)" : "none"; + element.style.paddingTop = commandValue ? "0.75em" : "0"; + element.style.display = commandValue ? "block" : "none"; + element.style.alignItems = "center"; + } + + // function to add one setting element in the setting tab. + public createSettingEl(contentEl: HTMLElement, name: string, desc: string, type: string, placeholder: string, holderValue: any, settingsKey: string) { + if (type === 'password') { + return new Setting(contentEl) + .setName(name) + .setDesc(desc) + .addText((text) => { + text.inputEl.type = type; + return text + .setPlaceholder(placeholder) + .setValue(holderValue) + .onChange(async (value) => { + this.plugin.settings[settingsKey] = value; // Update the plugin settings directly + await this.plugin.saveSettings(); + }) + }); + } else if (type === 'toggle') { + return new Setting(contentEl) + .setName(name) + .setDesc(desc) + .addToggle((toggle) => + toggle + .setValue(holderValue) + .onChange(async (value) => { + this.plugin.settings[settingsKey] = value; // Update the plugin settings directly + await this.plugin.saveSettings(); + await this.plugin.commands.updateCommand(); + }) + ); + } else if (type === 'text') { + return new Setting(contentEl) + .setName(name) + .setDesc(desc) + .addText((text) => + text + .setPlaceholder(placeholder) + .setValue(holderValue) + .onChange(async (value) => { + this.plugin.settings[settingsKey] = value; // Update the plugin settings directly + await this.plugin.saveSettings(); + await this.plugin.commands.updateCommand(); + }) + ); + } + } } diff --git a/src/ui/settingNextTabs.ts b/src/ui/settingNextTabs.ts index e0a8c8e..ed96ec1 100644 --- a/src/ui/settingNextTabs.ts +++ b/src/ui/settingNextTabs.ts @@ -2,24 +2,25 @@ import {App, PluginSettingTab, Setting} from "obsidian"; import ObsidianSyncNotionPlugin from "../main"; import {i18nConfig} from "../lang/I18n"; import {ObsidianSettingTab} from "./settingTabs"; +import {SettingModal} from "./settingModal"; export class SettingNextTabs extends PluginSettingTab { plugin: ObsidianSyncNotionPlugin; - private settingTab: ObsidianSettingTab; + settingModal: SettingModal; constructor(app: App, plugin: ObsidianSyncNotionPlugin, settingTab: ObsidianSettingTab) { super(app, plugin); this.plugin = plugin; - this.settingTab = settingTab; } display(): void { // notion next database settings + this.containerEl.createEl('h2', { text: i18nConfig.NotionNextSettingHeader }); - this.settingTab.containerEl.createEl('h2', { text: i18nConfig.NotionNextSettingHeader }) + const NextButtonEl = this.containerEl.createDiv(); - new Setting(this.settingTab.containerEl) + new Setting(NextButtonEl) .setName(i18nConfig.NotionNextButton) .setDesc(i18nConfig.NotionNextButtonDesc) .addToggle((toggle) => @@ -28,9 +29,9 @@ export class SettingNextTabs extends PluginSettingTab { .onChange(async (value) => { this.plugin.settings.NextButton = value; - this.settingTab.updateSettingEl(notionAPINextEl, value) + this.settingModal.updateSettingEl(notionAPINextEl, value) - this.settingTab.updateSettingEl(databaseIDNextEl, value) + this.settingModal.updateSettingEl(databaseIDNextEl, value) await this.plugin.saveSettings(); await this.plugin.commands.updateCommand(); @@ -38,11 +39,11 @@ export class SettingNextTabs extends PluginSettingTab { ); - const notionAPINextEl = this.settingTab.createStyleDiv('api-next', this.plugin.settings.NextButton) - this.settingTab.createSettingEl(notionAPINextEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPINext, 'notionAPINext') + const notionAPINextEl = this.settingModal.createStyleDiv('api-next', this.plugin.settings.NextButton) + this.settingModal.createSettingEl(notionAPINextEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPINext, 'notionAPINext') - const databaseIDNextEl = this.settingTab.createStyleDiv('databaseID-next', this.plugin.settings.NextButton) - this.settingTab.createSettingEl(databaseIDNextEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDNext, 'databaseIDNext') + const databaseIDNextEl = this.settingModal.createStyleDiv('databaseID-next', this.plugin.settings.NextButton) + this.settingModal.createSettingEl(databaseIDNextEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDNext, 'databaseIDNext') } } diff --git a/src/ui/settingTabs.ts b/src/ui/settingTabs.ts index ec5b71d..48bafe4 100644 --- a/src/ui/settingTabs.ts +++ b/src/ui/settingTabs.ts @@ -66,6 +66,7 @@ export class ObsidianSettingTab extends PluginSettingTab { this.createSettingEl(containerEl, i18nConfig.NotionUser, i18nConfig.NotionUserDesc, 'text', i18nConfig.NotionUserText, this.plugin.settings.notionUser, 'notionUser') + // add new button new Setting(containerEl) @@ -76,7 +77,7 @@ export class ObsidianSettingTab extends PluginSettingTab { .setTooltip("Add New Database") .setIcon("plus") .onClick(async () => { - let modal = new SettingModal(this.plugin); + let modal = new SettingModal(this.app, this.plugin, this); modal.onClose = () => { // if (modal.saved) { @@ -97,141 +98,18 @@ export class ObsidianSettingTab extends PluginSettingTab { - // notion next database settings + // // notion next database settings + // + // const NextTabs = new SettingNextTabs(this.app, this.plugin, this); + // + // NextTabs.display(); + // + // + // // General Database Settings + // const GeneralTabs = new SettingGeneralTabs(this.app, this.plugin, this); + // + // GeneralTabs.display(); - const NextTabs = new SettingNextTabs(this.app, this.plugin, this); - - NextTabs.display(); - - // containerEl.createEl('h2', { text: i18nConfig.NotionNextSettingHeader }) - // - // new Setting(containerEl) - // .setName(i18nConfig.NotionNextButton) - // .setDesc(i18nConfig.NotionNextButtonDesc) - // .addToggle((toggle) => - // toggle - // .setValue(this.plugin.settings.NextButton) - // .onChange(async (value) => { - // this.plugin.settings.NextButton = value; - // - // this.updateSettingEl(notionAPINextEl, value) - // - // this.updateSettingEl(databaseIDNextEl, value) - // - // await this.plugin.saveSettings(); - // await this.plugin.commands.updateCommand(); - // }) - // ); - // - // - // const notionAPINextEl = this.createStyleDiv('api-next', this.plugin.settings.NextButton) - // this.createSettingEl(notionAPINextEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPINext, 'notionAPINext') - // - // const databaseIDNextEl = this.createStyleDiv('databaseID-next', this.plugin.settings.NextButton) - // this.createSettingEl(databaseIDNextEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDNext, 'databaseIDNext') - - - // General Database Settings - const GeneralTabs = new SettingGeneralTabs(this.app, this.plugin, this); - - GeneralTabs.display(); - - - // containerEl.createEl('h2', { text: i18nConfig.NotionGeneralSettingHeader }); - // - // // new Setting(containerEl) - // // .setName(i18nConfig.NotYetFinish) - // new Setting(containerEl) - // .setName(i18nConfig.NotionGeneralButton) - // .setDesc(i18nConfig.NotionGeneralButtonDesc) - // .addToggle((toggle) => - // toggle - // .setValue(this.plugin.settings.GeneralButton) - // .onChange(async (value) => { - // this.plugin.settings.GeneralButton = value; - // - // this.updateSettingEl(tagButtonEl, value) - // this.updateSettingEl(CustomTitleEl, value) - // // name should follow the result of the title button - // if (value) { - // this.updateSettingEl(CustomNameEl, this.plugin.settings.CustomTitleButton) - // this.updateSettingEl(CustomValuesEl, this.plugin.settings.CustomTitleButton) - // } else { - // this.updateSettingEl(CustomNameEl, value) - // this.updateSettingEl(CustomValuesEl, value) - // } - // - // this.updateSettingEl(notionAPIGeneralEl, value) - // this.updateSettingEl(databaseIDGeneralEl, value) - // - // - // await this.plugin.saveSettings(); - // await this.plugin.commands.updateCommand(); - // - // }) - // ); - // - // // add the tagButton to control whether to add tags to the general database - // const tagButtonEl = this.createStyleDiv('tag-button', (this.plugin.settings.GeneralButton && this.plugin.settings.CustomTitleButton)); - // this.createSettingEl(tagButtonEl, i18nConfig.NotionTagButton, i18nConfig.NotionTagButtonDesc, 'toggle', i18nConfig.NotionCustomTitleText, this.plugin.settings.tagButton, 'tagButton') - // - // // Custom Title Button - // const CustomTitleEl = this.createStyleDiv('custom-title', this.plugin.settings.GeneralButton); - // new Setting(CustomTitleEl) - // .setName(i18nConfig.NotionCustomTitle) - // .setDesc(i18nConfig.NotionCustomTitleDesc) - // .addToggle((toggle) => - // toggle - // .setValue(this.plugin.settings.CustomTitleButton) - // .onChange(async (value) => { - // this.plugin.settings.CustomTitleButton = value; - // - // this.updateSettingEl(CustomNameEl, value) - // - // this.updateSettingEl(CustomValuesEl, value) - // - // await this.plugin.saveSettings(); - // await this.plugin.commands.updateCommand(); - // }) - // ); - // - // // Custom Title Name - // const CustomNameEl = this.createStyleDiv('custom-name', (this.plugin.settings.CustomTitleButton && this.plugin.settings.GeneralButton)); - // this.createSettingEl(CustomNameEl, i18nConfig.NotionCustomTitleName, i18nConfig.NotionCustomTitleNameDesc, 'text', i18nConfig.NotionCustomTitleText, this.plugin.settings.CustomTitleName, 'CustomTitleName') - // - // // Custom database properties - // const CustomValuesEl = this.createStyleDiv('custom-values', (this.plugin.settings.CustomTitleButton && this.plugin.settings.GeneralButton)); - // new Setting(CustomValuesEl) - // .setName(i18nConfig.NotionCustomValues) - // .setDesc(i18nConfig.NotionCustomValuesDesc) - // .addTextArea((text) => - // text - // .setPlaceholder(i18nConfig.NotionCustomValuesText) - // .setValue(this.plugin.settings.CustomValues) - // .onChange(async (value) => { - // this.plugin.settings.CustomValues = value; - // await this.plugin.saveSettings(); - // await this.plugin.commands.updateCommand(); - // }) - // ); - // // new Setting(containerEl) - // // .setName("Convert tags(optional)") - // // .setDesc("Transfer the Obsidian tags to the Notion table. It requires the column with the name 'Tags'") - // // .addToggle((toggle) => - // // toggle - // // .setValue(this.plugin.settings.allowTags) - // // .onChange(async (value) => { - // // this.plugin.settings.allowTags = value; - // // await this.plugin.saveSettings(); - // // }) - // // ); - // - // const notionAPIGeneralEl = this.createStyleDiv('api-general', this.plugin.settings.GeneralButton); - // this.createSettingEl(notionAPIGeneralEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPIGeneral, 'notionAPIGeneral') - // - // - // const databaseIDGeneralEl = this.createStyleDiv('databaseID-general', this.plugin.settings.GeneralButton); - // this.createSettingEl(databaseIDGeneralEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDGeneral, 'databaseIDGeneral') // Custom Database Settings From 59c15f12064dc2ce28b769e46565226b842d9d18 Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Tue, 26 Dec 2023 21:19:24 +0000 Subject: [PATCH 06/11] modify setting modal --- src/lang/locale/en.ts | 3 + src/lang/locale/ja.ts | 3 + src/lang/locale/zh.ts | 3 + src/ui/settingModal.ts | 151 ++++++++++++++++++++++++++++++++++++++--- 4 files changed, 149 insertions(+), 11 deletions(-) diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index db91ea8..8306035 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -4,6 +4,9 @@ export const en = { databaseNext: "NotionNext", databaseGeneral: "General", databaseCustom: "Custom", + databaseAbbreviateName: "Database Abbreviate Name", + databaseAbbreviateNameDesc: "Please give a nick name for your database", + databaseAbbreviateNameText: "Enter your database nick name", ribbonIcon: "Share to NotionNext", GeneralSetting: "General information Settings", CommandID: "share-to-notionnext", diff --git a/src/lang/locale/ja.ts b/src/lang/locale/ja.ts index 4c23ae8..34e64b4 100644 --- a/src/lang/locale/ja.ts +++ b/src/lang/locale/ja.ts @@ -4,6 +4,9 @@ export const ja = { databaseNext: "NotionNext", databaseGeneral: "一般的なNotion", databaseCustom: "カスタム", + databaseAbbreviateName: "データベースの略称", + databaseAbbreviateNameDesc: "データベースの略称を入力してください", + databaseAbbreviateNameText: "データベースの略称を入力", ribbonIcon: "NotionNextで共有", GeneralSetting: "一般設定", CommandID: "share-to-notionnext", diff --git a/src/lang/locale/zh.ts b/src/lang/locale/zh.ts index 774dab2..5198943 100644 --- a/src/lang/locale/zh.ts +++ b/src/lang/locale/zh.ts @@ -4,6 +4,9 @@ export const zh = { databaseNext: "NotionNext", databaseGeneral: "普通", databaseCustom: "自定义", + databaseAbbreviateName: "数据库简称", + databaseAbbreviateNameDesc: "给你的数据库起一个简称", + databaseAbbreviateNameText: "输入你的数据库简称", ribbonIcon: "分享到 NotionNext", GeneralSetting: "通用设置", CommandID: "share-to-notionnext", diff --git a/src/ui/settingModal.ts b/src/ui/settingModal.ts index 6a5ef63..764a90b 100644 --- a/src/ui/settingModal.ts +++ b/src/ui/settingModal.ts @@ -13,6 +13,11 @@ import {SettingGeneralTabs} from "./settingGeneralTabs"; export class SettingModal extends Modal { + databaseFormat: string = 'none'; + databaseAbbreviateName: string = ''; + notionAPINext: string = ''; + databaseIDNext: string = ''; + GeneralButton: boolean = false; plugin: ObsidianSyncNotionPlugin; settingTab: ObsidianSettingTab; @@ -20,6 +25,7 @@ export class SettingModal extends Modal { super(app); this.plugin = plugin; this.settingTab = settingTab; + } display(): void { @@ -42,8 +48,9 @@ export class SettingModal extends Modal { .addOption('general', i18nConfig.databaseGeneral) .addOption('next', i18nConfig.databaseNext) .addOption('custom', i18nConfig.databaseCustom) - .setValue(this.plugin.settings.databaseFormat) + .setValue(this.databaseFormat) .onChange(async (value) => { + this.databaseFormat = value; this.updateContentBasedOnSelection(value, nextTabs); }); @@ -58,11 +65,135 @@ export class SettingModal extends Modal { // Generate content based on the selected value if (value === 'general') { - nextTabs.createEl('h2', { text: i18nConfig.NotionGeneralSettingHeader }); - // Additional content for 'general'... + nextTabs.createEl('h3', { text: i18nConfig.NotionGeneralSettingHeader }); + + // add abbreviate name + new Setting(nextTabs) + .setName(i18nConfig.databaseAbbreviateName) + .setDesc(i18nConfig.databaseAbbreviateNameDesc) + .addText((text) => + text + .setPlaceholder(i18nConfig.databaseAbbreviateNameText) + .setValue(this.databaseAbbreviateName) + .onChange(async (value) => { + this.databaseAbbreviateName = value; + }) + ); + + + new Setting(nextTabs) + .setName(i18nConfig.NotionGeneralButton) + .setDesc(i18nConfig.NotionGeneralButtonDesc) + .addToggle((toggle) => + toggle + .setValue(this.GeneralButton) + .onChange(async (value) => { + this.GeneralButton = value; + + this.updateSettingEl(notionAPIGeneralEl, value) + this.updateSettingEl(databaseIDGeneralEl, value) + + + }) + ); + + + const notionAPIGeneralEl = this.createStyleDiv('api-general', this.plugin.settings.GeneralButton); + + new Setting(notionAPIGeneralEl) + .setName(i18nConfig.NotionAPI) + .setDesc(i18nConfig.NotionAPIDesc) + .addText((text) => { + text.inputEl.type = 'password'; + return text + .setPlaceholder(i18nConfig.NotionAPIText) + .setValue(this.notionAPINext) + .onChange(async (value) => { + this.notionAPINext = value; // Update the plugin settings directly + }) + }); + + + const databaseIDGeneralEl = this.createStyleDiv('databaseID-general', this.plugin.settings.GeneralButton); + + new Setting(databaseIDGeneralEl) + .setName(i18nConfig.DatabaseID) + .setDesc(i18nConfig.NotionAPIDesc) + .addText((text) => { + text.inputEl.type = 'password'; + return text + .setPlaceholder(i18nConfig.DatabaseIDText) + .setValue(this.databaseIDNext) + .onChange(async (value) => { + this.databaseIDNext = value; // Update the plugin settings directly + }) + }); + + + } else if (value === 'next') { - nextTabs.createEl('h2', { text: i18nConfig.NotionNextSettingHeader }); - // Additional content for 'next'... + nextTabs.createEl('h3', { text: i18nConfig.NotionNextSettingHeader }); + // add abbreviate name + this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.databaseAbbreviateName) + + new Setting(nextTabs) + .setName(i18nConfig.databaseAbbreviateName) + .setDesc(i18nConfig.databaseAbbreviateNameDesc) + .addText((text) => + text + .setPlaceholder(i18nConfig.databaseAbbreviateNameText) + .setValue(this.databaseAbbreviateName) + .onChange(async (value) => { + this.databaseAbbreviateName = value; + }) + ); + + // add api key + const notionAPINextEl = this.createStyleDiv('api-next', this.plugin.settings.NextButton) + + new Setting(notionAPINextEl) + .setName(i18nConfig.NotionAPI) + .setDesc(i18nConfig.NotionAPIDesc) + .addText((text) => { + text.inputEl.type = 'password'; + return text + .setPlaceholder(i18nConfig.NotionAPIText) + .setValue(this.notionAPINext) + .onChange(async (value) => { + this.notionAPINext = value; // Update the plugin settings directly + }) + }); + + // add database id + const databaseIDNextEl = this.createStyleDiv('databaseID-next', this.plugin.settings.NextButton) + + new Setting(databaseIDNextEl) + .setName(i18nConfig.DatabaseID) + .setDesc(i18nConfig.NotionAPIDesc) + .addText((text) => { + text.inputEl.type = 'password'; + return text + .setPlaceholder(i18nConfig.DatabaseIDText) + .setValue(this.databaseIDNext) + .onChange(async (value) => { + this.databaseIDNext = value; // Update the plugin settings directly + }) + }); + + // // test button + // new Setting(nextTabs) + // .setName(i18nConfig.NotionNextButton) + // .setDesc(i18nConfig.NotionNextButtonDesc) + // .addToggle((toggle) => + // toggle + // .setValue(this.plugin.settings.NextButton) + // .onChange(async (value) => { + // this.plugin.settings.NextButton = value; + // }) + // ); + + } else if (value === 'custom') { + } // Implement for 'custom' if needed } @@ -91,7 +222,7 @@ export class SettingModal extends Modal { } // function to add one setting element in the setting tab. - public createSettingEl(contentEl: HTMLElement, name: string, desc: string, type: string, placeholder: string, holderValue: any, settingsKey: string) { + public createSettingEl(contentEl: HTMLElement, name: string, desc: string, type: string, placeholder: string, holderValue: any) { if (type === 'password') { return new Setting(contentEl) .setName(name) @@ -102,7 +233,7 @@ export class SettingModal extends Modal { .setPlaceholder(placeholder) .setValue(holderValue) .onChange(async (value) => { - this.plugin.settings[settingsKey] = value; // Update the plugin settings directly + holderValue = value; // Update the plugin settings directly await this.plugin.saveSettings(); }) }); @@ -114,9 +245,8 @@ export class SettingModal extends Modal { toggle .setValue(holderValue) .onChange(async (value) => { - this.plugin.settings[settingsKey] = value; // Update the plugin settings directly + holderValue = value; // Update the plugin settings directly await this.plugin.saveSettings(); - await this.plugin.commands.updateCommand(); }) ); } else if (type === 'text') { @@ -128,9 +258,8 @@ export class SettingModal extends Modal { .setPlaceholder(placeholder) .setValue(holderValue) .onChange(async (value) => { - this.plugin.settings[settingsKey] = value; // Update the plugin settings directly + holderValue = value; // Update the plugin settings directly await this.plugin.saveSettings(); - await this.plugin.commands.updateCommand(); }) ); } From fb5f7b502df825593edace8d59b885b1b7fc2ebb Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Wed, 27 Dec 2023 00:27:32 +0000 Subject: [PATCH 07/11] finish some command coding --- src/commands/NotionCommands.ts | 73 +++-- src/main.ts | 11 +- src/ui/settingModal.ts | 254 +++++++++--------- src/ui/settingNextTabs.ts | 4 +- src/ui/settingTabs.ts | 44 ++- src/upload/uploadCommand.ts | 16 +- .../upload_general/Upload2NotionGeneral.ts | 13 +- src/upload/upload_next/Upload2NotionNext.ts | 14 +- 8 files changed, 235 insertions(+), 194 deletions(-) diff --git a/src/commands/NotionCommands.ts b/src/commands/NotionCommands.ts index 2ca4b2b..13a7bad 100644 --- a/src/commands/NotionCommands.ts +++ b/src/commands/NotionCommands.ts @@ -1,8 +1,9 @@ import { i18nConfig } from "src/lang/I18n"; -import { Editor, MarkdownView } from "obsidian"; +import {Editor, MarkdownView, setTooltip} from "obsidian"; import { FuzzySuggester, DatabaseList } from "./FuzzySuggester"; import { uploadCommandGeneral, uploadCommandNext } from "../upload/uploadCommand"; import ObsidianSyncNotionPlugin from "src/main"; +import {DatabaseDetails} from "../ui/settingTabs"; interface Command { @@ -21,26 +22,11 @@ export default class RibbonCommands { constructor(plugin: ObsidianSyncNotionPlugin) { this.plugin = plugin; - // Check if NextButton is true, then include the corresponding command - if (this.plugin.settings.NextButton) { - this.Ncommand.push({ - id: "share-to-notionnext", - name: i18nConfig.CommandName, // Use the translated text from i18nConfig - editorCallback: async (editor: Editor, view: MarkdownView) => { - await uploadCommandNext(this.plugin, this.plugin.settings, this.plugin.app); - } - }); - } + // iterate through the database detail - // Check if GeneralButton is true, then include the corresponding command - if (this.plugin.settings.GeneralButton) { - this.Ncommand.push({ - id: "share-to-notion", - name: i18nConfig.CommandNameGeneral, // Use the translated text from i18nConfig - editorCallback: async (editor: Editor, view: MarkdownView) => { - await uploadCommandGeneral(this.plugin, this.plugin.settings, this.plugin.app); - } - }); + for (let key in this.plugin.settings.databaseDetails) { + let dbDetails = this.plugin.settings.databaseDetails[key]; + this.addCommandForDatabase(dbDetails); } // Register all the commands @@ -77,24 +63,9 @@ export default class RibbonCommands { this.Ncommand = []; - if (this.plugin.settings.NextButton) { - this.Ncommand.push({ - id: "share-to-notionnext", - name: i18nConfig.CommandName, // Use the translated text from i18nConfig - editorCallback: async (editor: Editor, view: MarkdownView) => { - await uploadCommandNext(this.plugin, this.plugin.settings, this.plugin.app); - } - }); - } - - if (this.plugin.settings.GeneralButton) { - this.Ncommand.push({ - id: "share-to-notion", - name: i18nConfig.CommandNameGeneral, // Use the translated text from i18nConfig - editorCallback: async (editor: Editor, view: MarkdownView) => { - await uploadCommandGeneral(this.plugin, this.plugin.settings, this.plugin.app); - } - }); + for (let key in this.plugin.settings.databaseDetails) { + let dbDetails = this.plugin.settings.databaseDetails[key]; + this.addCommandForDatabase(dbDetails); } this.Ncommand.forEach(command => { @@ -107,4 +78,30 @@ export default class RibbonCommands { ); }); } + + private addCommandForDatabase(dbDetails: DatabaseDetails) { + // Example logic - adjust based on your specific requirements + let commandId = `share-to-${dbDetails.abName}`; + let commandName = `Share to ${dbDetails.abName}`; // or use a translated name + + let editorCallback: (editor: Editor, view: MarkdownView) => Promise; + if (dbDetails.format === 'next') { + editorCallback = async (editor, view) => { + await uploadCommandNext(this.plugin, this.plugin.settings, dbDetails, this.plugin.app); + }; + } else if (dbDetails.format === 'general') { + editorCallback = async (editor, view) => { + await uploadCommandGeneral(this.plugin, this.plugin.settings, dbDetails, this.plugin.app); + }; + } + // else if (dbDetails.format === 'custom') { + // editorCallback = async (editor, view) => { + // await uploadCommandGeneral(this.plugin, dbDetails, this.plugin.app); + // }; + // } + + this.Ncommand.push({ id: commandId, name: commandName, editorCallback }); + } + + } diff --git a/src/main.ts b/src/main.ts index 5352417..8263f0c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,7 +4,7 @@ import { Upload2NotionGeneral } from "src/upload/upload_general/Upload2NotionGen import { Upload2NotionNext } from "src/upload/upload_next/Upload2NotionNext"; import { i18nConfig } from "src/lang/I18n"; import ribbonCommands from "src/commands/NotionCommands"; -import { ObsidianSettingTab, PluginSettings, DEFAULT_SETTINGS } from "src/ui/settingTabs"; +import { ObsidianSettingTab, PluginSettings, DEFAULT_SETTINGS, DatabaseDetails } from "src/ui/settingTabs"; // Remember to rename these classes and interfaces! @@ -55,6 +55,15 @@ export default class ObsidianSyncNotionPlugin extends Plugin { await this.saveData(this.settings); } + async addDatabaseDetails(dbDetails: DatabaseDetails) { + this.settings.databaseDetails = { + ...this.settings.databaseDetails, + [dbDetails.abName]: dbDetails, + }; + + await this.saveSettings(); + } + } diff --git a/src/ui/settingModal.ts b/src/ui/settingModal.ts index 764a90b..d16e3c4 100644 --- a/src/ui/settingModal.ts +++ b/src/ui/settingModal.ts @@ -7,29 +7,46 @@ import { import { i18nConfig } from "../lang/I18n"; import ObsidianSyncNotionPlugin from "../main"; -import {ObsidianSettingTab} from "./settingTabs"; +import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs"; import {SettingNextTabs} from "./settingNextTabs"; import {SettingGeneralTabs} from "./settingGeneralTabs"; export class SettingModal extends Modal { - databaseFormat: string = 'none'; - databaseAbbreviateName: string = ''; - notionAPINext: string = ''; - databaseIDNext: string = ''; - GeneralButton: boolean = false; + data: Record = { + databaseFormat: 'none', + databaseAbbreviateName: '', + notionAPI: '', + databaseID: '', + tagButton: true, + customTitleButton: false, + customTitleName: '', + // customValues: '', + saved: false, + }; plugin: ObsidianSyncNotionPlugin; settingTab: ObsidianSettingTab; - constructor(app: App, plugin: ObsidianSyncNotionPlugin, settingTab: ObsidianSettingTab) { + constructor(app: App, plugin: ObsidianSyncNotionPlugin, settingTab: ObsidianSettingTab, dbDetails?: DatabaseDetails) { super(app); this.plugin = plugin; this.settingTab = settingTab; + if (dbDetails) { + this.data.databaseFormat = dbDetails.format; + this.data.databaseAbbreviateName = dbDetails.abName; + this.data.notionAPI = dbDetails.notionAPI; + this.data.databaseID = dbDetails.databaseID; + this.data.tagButton = dbDetails.tagButton; + this.data.customTitleButton = dbDetails.customTitleButton; + this.data.customTitleName = dbDetails.customTitleName; + // this.data.customValues = dbDetails.customValues; + } } display(): void { this.containerEl.addClass("settings-modal"); + this.titleEl.setText('Add new database'); // create the dropdown button to select the database format let { contentEl } = this; @@ -48,15 +65,41 @@ export class SettingModal extends Modal { .addOption('general', i18nConfig.databaseGeneral) .addOption('next', i18nConfig.databaseNext) .addOption('custom', i18nConfig.databaseCustom) - .setValue(this.databaseFormat) + .setValue(this.data.databaseFormat) .onChange(async (value) => { - this.databaseFormat = value; + this.data.databaseFormat = value; + nextTabs.empty(); this.updateContentBasedOnSelection(value, nextTabs); }); // Initialize content based on the current dropdown value this.updateContentBasedOnSelection(this.plugin.settings.databaseFormat, nextTabs); }); + + // add save button + + let footerEl = contentEl.createDiv('save-button'); + let saveButton = new Setting(footerEl) + saveButton.addButton((button: ButtonComponent) => { + return button + .setTooltip('Save') + .setIcon('checkmark') + .onClick(async () => { + this.data.saved = true; + this.close(); + }); + } + ); + saveButton.addExtraButton((button) => { + return button + .setTooltip('Cancel') + .setIcon('cross') + .onClick(() => { + this.data.saved = false; + this.close(); + }); + } + ); } updateContentBasedOnSelection(value: string, nextTabs: HTMLElement): void { @@ -68,134 +111,92 @@ export class SettingModal extends Modal { nextTabs.createEl('h3', { text: i18nConfig.NotionGeneralSettingHeader }); // add abbreviate name - new Setting(nextTabs) - .setName(i18nConfig.databaseAbbreviateName) - .setDesc(i18nConfig.databaseAbbreviateNameDesc) - .addText((text) => - text - .setPlaceholder(i18nConfig.databaseAbbreviateNameText) - .setValue(this.databaseAbbreviateName) - .onChange(async (value) => { - this.databaseAbbreviateName = value; - }) - ); + this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.data.databaseAbbreviateName, 'databaseAbbreviateName') + + // tag button + this.createSettingEl(nextTabs, i18nConfig.NotionTagButton, i18nConfig.NotionTagButtonDesc, 'toggle', i18nConfig.NotionCustomTitleText, this.data.tagButton, 'tagButton') - new Setting(nextTabs) - .setName(i18nConfig.NotionGeneralButton) - .setDesc(i18nConfig.NotionGeneralButtonDesc) - .addToggle((toggle) => - toggle - .setValue(this.GeneralButton) - .onChange(async (value) => { - this.GeneralButton = value; - - this.updateSettingEl(notionAPIGeneralEl, value) - this.updateSettingEl(databaseIDGeneralEl, value) - - - }) - ); - - - const notionAPIGeneralEl = this.createStyleDiv('api-general', this.plugin.settings.GeneralButton); - - new Setting(notionAPIGeneralEl) - .setName(i18nConfig.NotionAPI) - .setDesc(i18nConfig.NotionAPIDesc) - .addText((text) => { - text.inputEl.type = 'password'; - return text - .setPlaceholder(i18nConfig.NotionAPIText) - .setValue(this.notionAPINext) - .onChange(async (value) => { - this.notionAPINext = value; // Update the plugin settings directly - }) - }); - - - const databaseIDGeneralEl = this.createStyleDiv('databaseID-general', this.plugin.settings.GeneralButton); - - new Setting(databaseIDGeneralEl) - .setName(i18nConfig.DatabaseID) - .setDesc(i18nConfig.NotionAPIDesc) - .addText((text) => { - text.inputEl.type = 'password'; - return text - .setPlaceholder(i18nConfig.DatabaseIDText) - .setValue(this.databaseIDNext) - .onChange(async (value) => { - this.databaseIDNext = value; // Update the plugin settings directly - }) - }); + // add api key + this.createSettingEl(nextTabs, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.data.notionAPI, 'notionAPI') + // add database id + this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.data.databaseID, 'databaseID') } else if (value === 'next') { + nextTabs.createEl('h3', { text: i18nConfig.NotionNextSettingHeader }); + // add abbreviate name - this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.databaseAbbreviateName) + this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.data.databaseAbbreviateName, 'databaseAbbreviateName') + + // add api key + this.createSettingEl(nextTabs, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.data.notionAPI, 'notionAPI') + + + // add database id + this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.data.databaseID, 'databaseID') + + } else if (value === 'custom') { + nextTabs.createEl('h3', { text: i18nConfig.NotionCustomSettingHeader}); + + // add abbreviate name + this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.data.databaseAbbreviateName, 'databaseAbbreviateName') + + // tag button + this.createSettingEl(nextTabs, i18nConfig.NotionTagButton, i18nConfig.NotionTagButtonDesc, 'toggle', i18nConfig.NotionCustomTitleText, this.data.tagButton, 'tagButton') + + // add custom title button new Setting(nextTabs) - .setName(i18nConfig.databaseAbbreviateName) - .setDesc(i18nConfig.databaseAbbreviateNameDesc) - .addText((text) => - text - .setPlaceholder(i18nConfig.databaseAbbreviateNameText) - .setValue(this.databaseAbbreviateName) + .setName(i18nConfig.NotionCustomTitle) + .setDesc(i18nConfig.NotionCustomTitleDesc) + .addToggle((toggle) => + toggle + .setValue(this.data.CustomTitleButton) .onChange(async (value) => { - this.databaseAbbreviateName = value; + this.data.CustomTitleButton = value; + + this.updateSettingEl(CustomNameEl, value) + + // this.updateSettingEl(CustomValuesEl, value) + + await this.plugin.saveSettings(); + await this.plugin.commands.updateCommand(); }) ); - // add api key - const notionAPINextEl = this.createStyleDiv('api-next', this.plugin.settings.NextButton) - new Setting(notionAPINextEl) - .setName(i18nConfig.NotionAPI) - .setDesc(i18nConfig.NotionAPIDesc) - .addText((text) => { - text.inputEl.type = 'password'; - return text - .setPlaceholder(i18nConfig.NotionAPIText) - .setValue(this.notionAPINext) - .onChange(async (value) => { - this.notionAPINext = value; // Update the plugin settings directly - }) - }); + // add custom title name + const CustomNameEl = this.createStyleDiv('custom-name', (this.data.CustomTitleButton), nextTabs); + this.createSettingEl(CustomNameEl, i18nConfig.NotionCustomTitleName, i18nConfig.NotionCustomTitleNameDesc, 'text', i18nConfig.NotionCustomTitleText, this.data.CustomTitleName, 'CustomTitleName') + + // // add custom values + // const CustomValuesEl = this.createStyleDiv('custom-values', (this.data.CustomTitleButton), nextTabs); + // new Setting(CustomValuesEl) + // .setName(i18nConfig.NotionCustomValues) + // .setDesc(i18nConfig.NotionCustomValuesDesc) + // .addTextArea((text) => { + // return text + // .setPlaceholder(i18nConfig.NotionCustomValuesText) + // .setValue(this.data.CustomValues) + // .onChange(async (value) => { + // this.data.CustomValues = value; + // await this.plugin.saveSettings(); + // }); + // }); + + + // add api key + const notionAPIGeneralEl = this.createStyleDiv('api-general', this.plugin.settings.GeneralButton, nextTabs); + this.createSettingEl(notionAPIGeneralEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.data.notionAPI, 'notionAPI') // add database id - const databaseIDNextEl = this.createStyleDiv('databaseID-next', this.plugin.settings.NextButton) - - new Setting(databaseIDNextEl) - .setName(i18nConfig.DatabaseID) - .setDesc(i18nConfig.NotionAPIDesc) - .addText((text) => { - text.inputEl.type = 'password'; - return text - .setPlaceholder(i18nConfig.DatabaseIDText) - .setValue(this.databaseIDNext) - .onChange(async (value) => { - this.databaseIDNext = value; // Update the plugin settings directly - }) - }); - - // // test button - // new Setting(nextTabs) - // .setName(i18nConfig.NotionNextButton) - // .setDesc(i18nConfig.NotionNextButtonDesc) - // .addToggle((toggle) => - // toggle - // .setValue(this.plugin.settings.NextButton) - // .onChange(async (value) => { - // this.plugin.settings.NextButton = value; - // }) - // ); - - } else if (value === 'custom') { - + const databaseIDGeneralEl = this.createStyleDiv('databaseID-general', this.plugin.settings.GeneralButton, nextTabs); + this.createSettingEl(databaseIDGeneralEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.data.databaseID, 'databaseID') } - // Implement for 'custom' if needed + } @@ -208,8 +209,8 @@ export class SettingModal extends Modal { // create a function to create a div with a style for pop over elements - public createStyleDiv(className: string, commandValue: boolean = false) { - return this.contentEl.createDiv(className, (div) => { + public createStyleDiv(className: string, commandValue: boolean = false,parentEl: HTMLElement ) { + return parentEl.createDiv(className, (div) => { this.updateSettingEl(div, commandValue); }); } @@ -222,7 +223,7 @@ export class SettingModal extends Modal { } // function to add one setting element in the setting tab. - public createSettingEl(contentEl: HTMLElement, name: string, desc: string, type: string, placeholder: string, holderValue: any) { + public createSettingEl(contentEl: HTMLElement, name: string, desc: string, type: string, placeholder: string, holderValue: any,settingsKey: string) { if (type === 'password') { return new Setting(contentEl) .setName(name) @@ -233,8 +234,7 @@ export class SettingModal extends Modal { .setPlaceholder(placeholder) .setValue(holderValue) .onChange(async (value) => { - holderValue = value; // Update the plugin settings directly - await this.plugin.saveSettings(); + this.data[settingsKey] = value; // Update the settings dictionary await this.plugin.saveSettings(); }) }); } else if (type === 'toggle') { @@ -245,8 +245,7 @@ export class SettingModal extends Modal { toggle .setValue(holderValue) .onChange(async (value) => { - holderValue = value; // Update the plugin settings directly - await this.plugin.saveSettings(); + this.data[settingsKey] = value; // Update the settings dictionary await this.plugin.saveSettings(); }) ); } else if (type === 'text') { @@ -258,8 +257,7 @@ export class SettingModal extends Modal { .setPlaceholder(placeholder) .setValue(holderValue) .onChange(async (value) => { - holderValue = value; // Update the plugin settings directly - await this.plugin.saveSettings(); + this.data[settingsKey] = value; // Update the settings dictionary await this.plugin.saveSettings(); }) ); } diff --git a/src/ui/settingNextTabs.ts b/src/ui/settingNextTabs.ts index ed96ec1..faa1c34 100644 --- a/src/ui/settingNextTabs.ts +++ b/src/ui/settingNextTabs.ts @@ -40,10 +40,10 @@ export class SettingNextTabs extends PluginSettingTab { const notionAPINextEl = this.settingModal.createStyleDiv('api-next', this.plugin.settings.NextButton) - this.settingModal.createSettingEl(notionAPINextEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPINext, 'notionAPINext') + this.settingModal.createSettingEl(notionAPINextEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPINext) const databaseIDNextEl = this.settingModal.createStyleDiv('databaseID-next', this.plugin.settings.NextButton) - this.settingModal.createSettingEl(databaseIDNextEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDNext, 'databaseIDNext') + this.settingModal.createSettingEl(databaseIDNextEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDNext) } } diff --git a/src/ui/settingTabs.ts b/src/ui/settingTabs.ts index 48bafe4..96959d8 100644 --- a/src/ui/settingTabs.ts +++ b/src/ui/settingTabs.ts @@ -23,6 +23,18 @@ export interface PluginSettings { notionAPICustom: string; databaseIDCustom: string; [key: string]: any; + databaseDetails: Record +} + +export interface DatabaseDetails { + format: string; + abName: string; + notionAPI: string; + databaseID: string; + tagButton: boolean; + customTitleButton: boolean; + customTitleName: string; + // customValues: string; } export const DEFAULT_SETTINGS: PluginSettings = { @@ -42,6 +54,7 @@ export const DEFAULT_SETTINGS: PluginSettings = { CustomValues: "", notionAPICustom: "", databaseIDCustom: "", + databaseDetails: {}, }; @@ -80,16 +93,24 @@ export class ObsidianSettingTab extends PluginSettingTab { let modal = new SettingModal(this.app, this.plugin, this); modal.onClose = () => { - // if (modal.saved) { - // const database = { - // - // } - // this.plugin.addDatabase(database); - // - // this.plugin.calloutManager.addDatabase(database); - // - // this.display(); - // } + if (modal.data.saved) { + const dbDetails = { + format: modal.data.databaseFormat, + abName: modal.data.databaseAbbreviateName, + notionAPI: modal.data.notionAPI, + databaseID: modal.data.databaseID, + tagButton: modal.data.tagButton, + customTitleButton: modal.data.customTitleButton, + customTitleName: modal.data.customTitleName, + // customValues: modal.data.customValues, + } + + this.plugin.addDatabaseDetails(dbDetails); + + this.plugin.commands.updateCommand(); + + this.display() + } } modal.open(); @@ -97,6 +118,9 @@ export class ObsidianSettingTab extends PluginSettingTab { }); + // list all created database + + // // notion next database settings // diff --git a/src/upload/uploadCommand.ts b/src/upload/uploadCommand.ts index 0230fff..58ed18e 100644 --- a/src/upload/uploadCommand.ts +++ b/src/upload/uploadCommand.ts @@ -3,7 +3,7 @@ import { App, Notice } from "obsidian"; import { Upload2NotionNext } from "./upload_next/Upload2NotionNext"; import { Upload2NotionGeneral } from "./upload_general/Upload2NotionGeneral"; import { Upload2NotionCustom } from "./upoload_custom/Upload2NotionCustom"; -import { PluginSettings } from "../ui/settingTabs"; +import {DatabaseDetails, PluginSettings} from "../ui/settingTabs"; import ObsidianSyncNotionPlugin from "../main"; import { getNowFileMarkdownContentNext } from "./upload_next/getMarkdownNext"; import { getNowFileMarkdownContentGeneral } from "./upload_general/getMarkdownGeneral"; @@ -12,10 +12,11 @@ import {getNowFileMarkdownContentCustom} from "./upoload_custom/getMarkdownCusto export async function uploadCommandNext( plugin: ObsidianSyncNotionPlugin, settings: PluginSettings, + dbDetails: DatabaseDetails, app: App, ) { - const { notionAPINext, databaseIDNext } = settings; + const { notionAPI, databaseID } = dbDetails; // Check if NNon exists // if (NNon === undefined) { @@ -25,7 +26,7 @@ export async function uploadCommandNext( // } // Check if the user has set up the Notion API and database ID - if (notionAPINext === "" || databaseIDNext === "") { + if (notionAPI === "" || databaseID === "") { const setAPIMessage = i18nConfig["set-api-id"]; new Notice(setAPIMessage); return; @@ -35,7 +36,7 @@ export async function uploadCommandNext( if (markDownData) { const { basename } = nowFile; - const upload = new Upload2NotionNext(plugin); + const upload = new Upload2NotionNext(plugin, dbDetails); const res = await upload.syncMarkdownToNotionNext(basename, emoji, cover, tags, type, slug, stats, category, summary, paword, favicon, datetime, markDownData, nowFile, this.app); if (res.status === 200) { @@ -52,13 +53,14 @@ export async function uploadCommandNext( export async function uploadCommandGeneral( plugin: ObsidianSyncNotionPlugin, settings: PluginSettings, + dbDetails: DatabaseDetails, app: App, ) { - const { notionAPIGeneral, databaseIDGeneral } = settings; + const { notionAPI, databaseID } = settings; // Check if the user has set up the Notion API and database ID - if (notionAPIGeneral === "" || databaseIDGeneral === "") { + if (notionAPI === "" || databaseID === "") { const setAPIMessage = i18nConfig["set-api-id"]; new Notice(setAPIMessage); return; @@ -69,7 +71,7 @@ export async function uploadCommandGeneral( if (markDownData) { const { basename } = nowFile; - const upload = new Upload2NotionGeneral(plugin); + const upload = new Upload2NotionGeneral(plugin, dbDetails); const res = await upload.syncMarkdownToNotionGeneral(basename, cover, tags, markDownData, nowFile, this.app); if (res.status === 200) { diff --git a/src/upload/upload_general/Upload2NotionGeneral.ts b/src/upload/upload_general/Upload2NotionGeneral.ts index 18c707a..71f8dc0 100644 --- a/src/upload/upload_general/Upload2NotionGeneral.ts +++ b/src/upload/upload_general/Upload2NotionGeneral.ts @@ -4,14 +4,15 @@ import { markdownToBlocks } from "@tryfabric/martian"; import * as yamlFrontMatter from "yaml-front-matter"; // import * as yaml from "yaml" import MyPlugin from "src/main"; -import { PluginSettings } from "../../ui/settingTabs"; +import {DatabaseDetails, PluginSettings} from "../../ui/settingTabs"; import { UploadBaseGeneral } from "./BaseUpload2NotionGeneral"; import { updateYamlInfo } from "../updateYaml"; export class Upload2NotionGeneral extends UploadBaseGeneral { settings: PluginSettings; + dbDetails: DatabaseDetails; - constructor(plugin: MyPlugin) { + constructor(plugin: MyPlugin, dbDetails: DatabaseDetails) { super(plugin); } @@ -26,8 +27,9 @@ export class Upload2NotionGeneral extends UploadBaseGeneral { ) { await this.deletePage(notionID); + const { databaseID } = this.dbDetails; const databasecover = await this.getDataBase( - this.plugin.settings.databaseIDGeneral, + databaseID, ); if (cover == null) { @@ -125,7 +127,10 @@ export class Upload2NotionGeneral extends UploadBaseGeneral { const file2Block = markdownToBlocks(__content, options); const frontmasster = app.metadataCache.getFileCache(nowFile)?.frontmatter; - const notionID = frontmasster ? frontmasster.notionID : null; + const {abName} = this.dbDetails + const notionIDKey = `${abName}-NotionID`; + const notionID = frontmasster ? frontmasster[notionIDKey] : null; + if (notionID) { res = await this.updatePage( diff --git a/src/upload/upload_next/Upload2NotionNext.ts b/src/upload/upload_next/Upload2NotionNext.ts index 480c962..a1e0d2f 100644 --- a/src/upload/upload_next/Upload2NotionNext.ts +++ b/src/upload/upload_next/Upload2NotionNext.ts @@ -5,14 +5,15 @@ import { markdownToBlocks, } from "@tryfabric/martian"; import * as yamlFrontMatter from "yaml-front-matter"; // import * as yaml from "yaml" import MyPlugin from "src/main"; -import { PluginSettings } from "../../ui/settingTabs"; +import {DatabaseDetails, PluginSettings} from "../../ui/settingTabs"; import { updateYamlInfo } from "../updateYaml"; import {LIMITS, paragraph} from "@tryfabric/martian/src/notion"; export class Upload2NotionNext extends UploadBaseNext { settings: PluginSettings; + dbDetails: DatabaseDetails - constructor(plugin: MyPlugin) { + constructor(plugin: MyPlugin, dbDetails: DatabaseDetails) { super(plugin); } @@ -36,7 +37,9 @@ export class Upload2NotionNext extends UploadBaseNext { ) { await this.deletePage(notionID) - const databasecover = await this.getDataBase(this.plugin.settings.databaseIDNext) + const { databaseID} = this.dbDetails + + const databasecover = await this.getDataBase(databaseID) if (cover == null) { cover = databasecover @@ -216,7 +219,10 @@ export class Upload2NotionNext extends UploadBaseNext { const __content = yamlContent.__content const file2Block = markdownToBlocks(__content, options); const frontmasster = app.metadataCache.getFileCache(nowFile)?.frontmatter - const notionID = frontmasster ? frontmasster.notionID : null + const {abName} = this.dbDetails + const notionIDKey = `${abName}-NotionID`; + const notionID = frontmasster ? frontmasster[notionIDKey] : null; + // increase the limits // Motivated by https://github.com/tryfabric/martian/issues/51 From 306573d81e56c5781849d8522edf7e1e205fe16a Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Wed, 27 Dec 2023 00:37:54 +0000 Subject: [PATCH 08/11] merge 1.1.2 --- package.json | 8 +-- src/ui/settingNextTabs.ts | 8 +-- yarn.lock | 120 ++++++++++++++++++++++---------------- 3 files changed, 78 insertions(+), 58 deletions(-) diff --git a/package.json b/package.json index 9f28b0a..e1ebb37 100644 --- a/package.json +++ b/package.json @@ -15,9 +15,9 @@ "devDependencies": { "@types/node": "^20.5.7", "@types/yaml-front-matter": "^4.1.3", - "@typescript-eslint/eslint-plugin": "^6.11.0", - "@typescript-eslint/parser": "^6.11.0", - "builtin-modules": "^3.2.0", + "@typescript-eslint/eslint-plugin": "^6.16.0", + "@typescript-eslint/parser": "^6.16.0", + "builtin-modules": "^3.3.0", "esbuild": "0.19.5", "obsidian": "latest", "tslib": "2.6.2", @@ -31,4 +31,4 @@ "yaml": "^2.3.4", "yaml-front-matter": "^4.1.1" } -} \ No newline at end of file +} diff --git a/src/ui/settingNextTabs.ts b/src/ui/settingNextTabs.ts index faa1c34..c844fe4 100644 --- a/src/ui/settingNextTabs.ts +++ b/src/ui/settingNextTabs.ts @@ -39,11 +39,11 @@ export class SettingNextTabs extends PluginSettingTab { ); - const notionAPINextEl = this.settingModal.createStyleDiv('api-next', this.plugin.settings.NextButton) - this.settingModal.createSettingEl(notionAPINextEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPINext) + const notionAPINextEl = this.settingModal.createStyleDiv('api-next', this.plugin.settings.NextButton,NextButtonEl) + this.settingModal.createSettingEl(notionAPINextEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPINext,'notionAPINext') - const databaseIDNextEl = this.settingModal.createStyleDiv('databaseID-next', this.plugin.settings.NextButton) - this.settingModal.createSettingEl(databaseIDNextEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDNext) + const databaseIDNextEl = this.settingModal.createStyleDiv('databaseID-next', this.plugin.settings.NextButton,NextButtonEl) + this.settingModal.createSettingEl(databaseIDNextEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDNext,'databaseIDNext') } } diff --git a/yarn.lock b/yarn.lock index fc5a713..3ab31c4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -269,16 +269,16 @@ "@types/js-yaml" "*" "@types/node" "*" -"@typescript-eslint/eslint-plugin@^6.11.0": - version "6.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.11.0.tgz#52aae65174ff526576351f9ccd41cea01001463f" - integrity sha512-uXnpZDc4VRjY4iuypDBKzW1rz9T5YBBK0snMn8MaTSNd2kMlj50LnLBABELjJiOL5YHk7ZD8hbSpI9ubzqYI0w== +"@typescript-eslint/eslint-plugin@^6.16.0": + version "6.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.16.0.tgz#cc29fbd208ea976de3db7feb07755bba0ce8d8bc" + integrity sha512-O5f7Kv5o4dLWQtPX4ywPPa+v9G+1q1x8mz0Kr0pXUtKsevo+gIJHLkGc8RxaZWtP8RrhwhSNIWThnW42K9/0rQ== dependencies: "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.11.0" - "@typescript-eslint/type-utils" "6.11.0" - "@typescript-eslint/utils" "6.11.0" - "@typescript-eslint/visitor-keys" "6.11.0" + "@typescript-eslint/scope-manager" "6.16.0" + "@typescript-eslint/type-utils" "6.16.0" + "@typescript-eslint/utils" "6.16.0" + "@typescript-eslint/visitor-keys" "6.16.0" debug "^4.3.4" graphemer "^1.4.0" ignore "^5.2.4" @@ -286,72 +286,73 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/parser@^6.11.0": - version "6.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.11.0.tgz#9640d9595d905f3be4f278bf515130e6129b202e" - integrity sha512-+whEdjk+d5do5nxfxx73oanLL9ghKO3EwM9kBCkUtWMRwWuPaFv9ScuqlYfQ6pAD6ZiJhky7TZ2ZYhrMsfMxVQ== +"@typescript-eslint/parser@^6.16.0": + version "6.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.16.0.tgz#36f39f63b126aa25af2ad2df13d9891e9fd5b40c" + integrity sha512-H2GM3eUo12HpKZU9njig3DF5zJ58ja6ahj1GoHEHOgQvYxzoFJJEvC1MQ7T2l9Ha+69ZSOn7RTxOdpC/y3ikMw== dependencies: - "@typescript-eslint/scope-manager" "6.11.0" - "@typescript-eslint/types" "6.11.0" - "@typescript-eslint/typescript-estree" "6.11.0" - "@typescript-eslint/visitor-keys" "6.11.0" + "@typescript-eslint/scope-manager" "6.16.0" + "@typescript-eslint/types" "6.16.0" + "@typescript-eslint/typescript-estree" "6.16.0" + "@typescript-eslint/visitor-keys" "6.16.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@6.11.0": - version "6.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.11.0.tgz#621f603537c89f4d105733d949aa4d55eee5cea8" - integrity sha512-0A8KoVvIURG4uhxAdjSaxy8RdRE//HztaZdG8KiHLP8WOXSk0vlF7Pvogv+vlJA5Rnjj/wDcFENvDaHb+gKd1A== +"@typescript-eslint/scope-manager@6.16.0": + version "6.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.16.0.tgz#f3e9a00fbc1d0701356359cd56489c54d9e37168" + integrity sha512-0N7Y9DSPdaBQ3sqSCwlrm9zJwkpOuc6HYm7LpzLAPqBL7dmzAUimr4M29dMkOP/tEwvOCC/Cxo//yOfJD3HUiw== dependencies: - "@typescript-eslint/types" "6.11.0" - "@typescript-eslint/visitor-keys" "6.11.0" + "@typescript-eslint/types" "6.16.0" + "@typescript-eslint/visitor-keys" "6.16.0" -"@typescript-eslint/type-utils@6.11.0": - version "6.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.11.0.tgz#d0b8b1ab6c26b974dbf91de1ebc5b11fea24e0d1" - integrity sha512-nA4IOXwZtqBjIoYrJcYxLRO+F9ri+leVGoJcMW1uqr4r1Hq7vW5cyWrA43lFbpRvQ9XgNrnfLpIkO3i1emDBIA== +"@typescript-eslint/type-utils@6.16.0": + version "6.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.16.0.tgz#5f21c3e49e540ad132dc87fc99af463c184d5ed1" + integrity sha512-ThmrEOcARmOnoyQfYkHw/DX2SEYBalVECmoldVuH6qagKROp/jMnfXpAU/pAIWub9c4YTxga+XwgAkoA0pxfmg== dependencies: - "@typescript-eslint/typescript-estree" "6.11.0" - "@typescript-eslint/utils" "6.11.0" + "@typescript-eslint/typescript-estree" "6.16.0" + "@typescript-eslint/utils" "6.16.0" debug "^4.3.4" ts-api-utils "^1.0.1" -"@typescript-eslint/types@6.11.0": - version "6.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.11.0.tgz#8ad3aa000cbf4bdc4dcceed96e9b577f15e0bf53" - integrity sha512-ZbEzuD4DwEJxwPqhv3QULlRj8KYTAnNsXxmfuUXFCxZmO6CF2gM/y+ugBSAQhrqaJL3M+oe4owdWunaHM6beqA== +"@typescript-eslint/types@6.16.0": + version "6.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.16.0.tgz#a3abe0045737d44d8234708d5ed8fef5d59dc91e" + integrity sha512-hvDFpLEvTJoHutVl87+MG/c5C8I6LOgEx05zExTSJDEVU7hhR3jhV8M5zuggbdFCw98+HhZWPHZeKS97kS3JoQ== -"@typescript-eslint/typescript-estree@6.11.0": - version "6.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.11.0.tgz#7b52c12a623bf7f8ec7f8a79901b9f98eb5c7990" - integrity sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ== +"@typescript-eslint/typescript-estree@6.16.0": + version "6.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.16.0.tgz#d6e0578e4f593045f0df06c4b3a22bd6f13f2d03" + integrity sha512-VTWZuixh/vr7nih6CfrdpmFNLEnoVBF1skfjdyGnNwXOH1SLeHItGdZDHhhAIzd3ACazyY2Fg76zuzOVTaknGA== dependencies: - "@typescript-eslint/types" "6.11.0" - "@typescript-eslint/visitor-keys" "6.11.0" + "@typescript-eslint/types" "6.16.0" + "@typescript-eslint/visitor-keys" "6.16.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" + minimatch "9.0.3" semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/utils@6.11.0": - version "6.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.11.0.tgz#11374f59ef4cea50857b1303477c08aafa2ca604" - integrity sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g== +"@typescript-eslint/utils@6.16.0": + version "6.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.16.0.tgz#1c291492d34670f9210d2b7fcf6b402bea3134ae" + integrity sha512-T83QPKrBm6n//q9mv7oiSvy/Xq/7Hyw9SzSEhMHJwznEmQayfBM87+oAlkNAMEO7/MjIwKyOHgBJbxB0s7gx2A== dependencies: "@eslint-community/eslint-utils" "^4.4.0" "@types/json-schema" "^7.0.12" "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.11.0" - "@typescript-eslint/types" "6.11.0" - "@typescript-eslint/typescript-estree" "6.11.0" + "@typescript-eslint/scope-manager" "6.16.0" + "@typescript-eslint/types" "6.16.0" + "@typescript-eslint/typescript-estree" "6.16.0" semver "^7.5.4" -"@typescript-eslint/visitor-keys@6.11.0": - version "6.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.11.0.tgz#d991538788923f92ec40d44389e7075b359f3458" - integrity sha512-+SUN/W7WjBr05uRxPggJPSzyB8zUpaYo2hByKasWbqr3PM8AXfZt8UHdNpBS1v9SA62qnSSMF3380SwDqqprgQ== +"@typescript-eslint/visitor-keys@6.16.0": + version "6.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.16.0.tgz#d50da18a05d91318ed3e7e8889bda0edc35f3a10" + integrity sha512-QSFQLruk7fhs91a/Ep/LqRdbJCZ1Rq03rqBdKT5Ky17Sz8zRLUksqIe9DW0pKtg/Z35/ztbLQ6qpOCN6rOC11A== dependencies: - "@typescript-eslint/types" "6.11.0" + "@typescript-eslint/types" "6.16.0" eslint-visitor-keys "^3.4.1" agent-base@^7.0.2: @@ -388,6 +389,18 @@ bail@^2.0.0: resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d" integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -1146,6 +1159,13 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +minimatch@9.0.3: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + moment@2.29.4: version "2.29.4" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" From fb463ceaae76382e0c3559d3af033d8fb073cd4f Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Wed, 27 Dec 2023 00:48:39 +0000 Subject: [PATCH 09/11] modify language map --- tsconfig.json | 2 ++ yarn.lock | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index a5f9a05..54cb87c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,8 @@ "baseUrl": ".", "inlineSourceMap": true, "inlineSources": true, + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, "module": "ESNext", "target": "ES6", "allowJs": true, diff --git a/yarn.lock b/yarn.lock index 3ab31c4..19370ae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -408,7 +408,7 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" -builtin-modules@^3.2.0: +builtin-modules@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== From cf08703fea19daa3991cdf89fc863e79aa221b14 Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Thu, 28 Dec 2023 00:55:06 +0000 Subject: [PATCH 10/11] complete the basic notionnext function --- src/lang/locale/en.ts | 3 + src/lang/locale/ja.ts | 3 + src/lang/locale/zh.ts | 3 + src/main.ts | 17 +++++ src/ui/settingModal.ts | 11 +++ src/ui/settingTabs.ts | 76 +++++++++++++++++++++ src/upload/updateYaml.ts | 18 +++-- src/upload/uploadCommand.ts | 2 +- src/upload/upload_next/Upload2NotionNext.ts | 3 +- 9 files changed, 127 insertions(+), 9 deletions(-) diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index 8306035..aaa3877 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -4,6 +4,9 @@ export const en = { databaseNext: "NotionNext", databaseGeneral: "General", databaseCustom: "Custom", + databaseFullName: "Database Full Name", + databaseFullNameDesc: "Please give a full name for your database", + databaseFullNameText: "Enter your database full name", databaseAbbreviateName: "Database Abbreviate Name", databaseAbbreviateNameDesc: "Please give a nick name for your database", databaseAbbreviateNameText: "Enter your database nick name", diff --git a/src/lang/locale/ja.ts b/src/lang/locale/ja.ts index 34e64b4..ac48ae5 100644 --- a/src/lang/locale/ja.ts +++ b/src/lang/locale/ja.ts @@ -4,6 +4,9 @@ export const ja = { databaseNext: "NotionNext", databaseGeneral: "一般的なNotion", databaseCustom: "カスタム", + databaseFullName: "データベースの全称", + databaseFullNameDesc: "データベースの全称を入力してください", + databaseFullNameText: "データベースの全称を入力", databaseAbbreviateName: "データベースの略称", databaseAbbreviateNameDesc: "データベースの略称を入力してください", databaseAbbreviateNameText: "データベースの略称を入力", diff --git a/src/lang/locale/zh.ts b/src/lang/locale/zh.ts index 5198943..d049627 100644 --- a/src/lang/locale/zh.ts +++ b/src/lang/locale/zh.ts @@ -4,6 +4,9 @@ export const zh = { databaseNext: "NotionNext", databaseGeneral: "普通", databaseCustom: "自定义", + databaseFullName: "数据库全称", + databaseFullNameDesc: "给你的数据库起一个全称", + databaseFullNameText: "输入你的数据库全称", databaseAbbreviateName: "数据库简称", databaseAbbreviateNameDesc: "给你的数据库起一个简称", databaseAbbreviateNameText: "输入你的数据库简称", diff --git a/src/main.ts b/src/main.ts index 8263f0c..21805bc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -64,6 +64,23 @@ export default class ObsidianSyncNotionPlugin extends Plugin { await this.saveSettings(); } + async deleteDatabaseDetails(dbDetails: DatabaseDetails) { + delete this.settings.databaseDetails[dbDetails.abName]; + + await this.saveSettings(); + } + + async updateDatabaseDetails(dbDetails: DatabaseDetails) { + // delete the old database details + delete this.settings.databaseDetails[dbDetails.abName]; + + this.settings.databaseDetails = { + ...this.settings.databaseDetails, + [dbDetails.abName]: dbDetails, + }; + + await this.saveSettings(); + } } diff --git a/src/ui/settingModal.ts b/src/ui/settingModal.ts index d16e3c4..42e4a1c 100644 --- a/src/ui/settingModal.ts +++ b/src/ui/settingModal.ts @@ -15,6 +15,7 @@ import {SettingGeneralTabs} from "./settingGeneralTabs"; export class SettingModal extends Modal { data: Record = { databaseFormat: 'none', + databaseFullName: '', databaseAbbreviateName: '', notionAPI: '', databaseID: '', @@ -33,6 +34,7 @@ export class SettingModal extends Modal { this.settingTab = settingTab; if (dbDetails) { this.data.databaseFormat = dbDetails.format; + this.data.databaseFullName = dbDetails.fullName; this.data.databaseAbbreviateName = dbDetails.abName; this.data.notionAPI = dbDetails.notionAPI; this.data.databaseID = dbDetails.databaseID; @@ -110,6 +112,9 @@ export class SettingModal extends Modal { if (value === 'general') { nextTabs.createEl('h3', { text: i18nConfig.NotionGeneralSettingHeader }); + // add full name + this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.data.databaseFullName, 'databaseFullName') + // add abbreviate name this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.data.databaseAbbreviateName, 'databaseAbbreviateName') @@ -128,6 +133,9 @@ export class SettingModal extends Modal { nextTabs.createEl('h3', { text: i18nConfig.NotionNextSettingHeader }); + // add full name + this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.data.databaseFullName, 'databaseFullName') + // add abbreviate name this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.data.databaseAbbreviateName, 'databaseAbbreviateName') @@ -141,6 +149,9 @@ export class SettingModal extends Modal { } else if (value === 'custom') { nextTabs.createEl('h3', { text: i18nConfig.NotionCustomSettingHeader}); + // add full name + this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.data.databaseFullName, 'databaseFullName') + // add abbreviate name this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.data.databaseAbbreviateName, 'databaseAbbreviateName') diff --git a/src/ui/settingTabs.ts b/src/ui/settingTabs.ts index 96959d8..8800a42 100644 --- a/src/ui/settingTabs.ts +++ b/src/ui/settingTabs.ts @@ -4,6 +4,7 @@ import ObsidianSyncNotionPlugin from "../main"; import {SettingModal} from "./settingModal"; import {SettingNextTabs} from "./settingNextTabs"; import {SettingGeneralTabs} from "./settingGeneralTabs"; +import {set} from "yaml/dist/schema/yaml-1.1/set"; export interface PluginSettings { NextButton: boolean; @@ -28,6 +29,7 @@ export interface PluginSettings { export interface DatabaseDetails { format: string; + fullName: string; abName: string; notionAPI: string; databaseID: string; @@ -60,6 +62,7 @@ export const DEFAULT_SETTINGS: PluginSettings = { export class ObsidianSettingTab extends PluginSettingTab { plugin: ObsidianSyncNotionPlugin; + databaseEl: HTMLDivElement; constructor(app: App, plugin: ObsidianSyncNotionPlugin) { super(app, plugin); @@ -96,6 +99,7 @@ export class ObsidianSettingTab extends PluginSettingTab { if (modal.data.saved) { const dbDetails = { format: modal.data.databaseFormat, + fullName: modal.data.databaseFullName, abName: modal.data.databaseAbbreviateName, notionAPI: modal.data.notionAPI, databaseID: modal.data.databaseID, @@ -117,8 +121,14 @@ export class ObsidianSettingTab extends PluginSettingTab { }); }); + // new section to display all created database + containerEl.createEl('h2', {text: "Database List"}); + this.databaseEl = containerEl.createDiv('database-list'); // list all created database + this.showDatabase(); + + @@ -212,4 +222,70 @@ export class ObsidianSettingTab extends PluginSettingTab { } } + // function to show all the database details + showDatabase() { + this.databaseEl.empty(); + + for (let key in this.plugin.settings.databaseDetails) { + let dbDetails = this.plugin.settings.databaseDetails[key]; + + const databaseDiv = this.databaseEl.createDiv('database-div'); + + let settingEl = new Setting(databaseDiv) + .setName(`${dbDetails.fullName} (${dbDetails.abName})`) + .setDesc(dbDetails.format) + + // settingEl + // .addButton((button: ButtonComponent): ButtonComponent => { + // return button + // .setTooltip("Edit Database") + // .setIcon("pencil") + // .onClick(async () => { + // let modal = new SettingModal(this.app, this.plugin, this, dbDetails); + // + // modal.onClose = () => { + // if (modal.data.saved) { + // const dbDetails = { + // format: modal.data.databaseFormat, + // fullName: modal.data.databaseFullName, + // abName: modal.data.databaseAbbreviateName, + // notionAPI: modal.data.notionAPI, + // databaseID: modal.data.databaseID, + // tagButton: modal.data.tagButton, + // customTitleButton: modal.data.customTitleButton, + // customTitleName: modal.data.customTitleName, + // // customValues: modal.data.customValues, + // } + // + // this.plugin.updateDatabaseDetails(dbDetails); + // + // this.plugin.commands.updateCommand(); + // + // this.display() + // } + // } + // + // modal.open(); + // }); + // }); + + settingEl + .addButton((button: ButtonComponent): ButtonComponent => { + return button + .setTooltip("Delete Database") + .setIcon("trash") + .onClick(async () => { + await this.plugin.deleteDatabaseDetails(dbDetails); + + await this.plugin.commands.updateCommand(); + + this.display() + }); + }); + } + } } +function addExtraButton(arg0: (button: ButtonComponent) => ButtonComponent): any { + throw new Error("Function not implemented."); +} + diff --git a/src/upload/updateYaml.ts b/src/upload/updateYaml.ts index 5e90a85..2a91687 100644 --- a/src/upload/updateYaml.ts +++ b/src/upload/updateYaml.ts @@ -1,6 +1,6 @@ import { App, Notice, TFile } from "obsidian"; import ObsidianSyncNotionPlugin from "../main"; -import { PluginSettings } from "../ui/settingTabs"; +import {DatabaseDetails, PluginSettings} from "../ui/settingTabs"; export async function updateYamlInfo( yamlContent: string, @@ -8,10 +8,14 @@ export async function updateYamlInfo( res: any, app: App, plugin: ObsidianSyncNotionPlugin, + dbDetails: DatabaseDetails, ) { let { url, id } = res.json // replace www to notionID const { notionUser } = plugin.settings; + const { abName } = dbDetails + const notionIDKey = `NotionID-${abName}`; + const linkKey = `link-${abName}`; if (notionUser !== "") { // replace url str "www" to notionID @@ -19,15 +23,15 @@ export async function updateYamlInfo( } await app.fileManager.processFrontMatter(nowFile, yamlContent => { - if (yamlContent['notionID']) { - delete yamlContent['notionID'] + if (yamlContent[notionIDKey]) { + delete yamlContent[notionIDKey] } - if (yamlContent['link']) { - delete yamlContent['link'] + if (yamlContent[linkKey]) { + delete yamlContent[linkKey] } // add new notionID and link - yamlContent.notionID = id; - yamlContent.link = url; + yamlContent[notionIDKey] = id; + yamlContent[linkKey] = url; }); try { diff --git a/src/upload/uploadCommand.ts b/src/upload/uploadCommand.ts index 58ed18e..06b9b45 100644 --- a/src/upload/uploadCommand.ts +++ b/src/upload/uploadCommand.ts @@ -57,7 +57,7 @@ export async function uploadCommandGeneral( app: App, ) { - const { notionAPI, databaseID } = settings; + const { notionAPI, databaseID } = dbDetails; // Check if the user has set up the Notion API and database ID if (notionAPI === "" || databaseID === "") { diff --git a/src/upload/upload_next/Upload2NotionNext.ts b/src/upload/upload_next/Upload2NotionNext.ts index a1e0d2f..1558441 100644 --- a/src/upload/upload_next/Upload2NotionNext.ts +++ b/src/upload/upload_next/Upload2NotionNext.ts @@ -15,6 +15,7 @@ export class Upload2NotionNext extends UploadBaseNext { constructor(plugin: MyPlugin, dbDetails: DatabaseDetails) { super(plugin); + this.dbDetails = dbDetails } // 因为需要解析notion的block进行对比,非常的麻烦, @@ -280,7 +281,7 @@ export class Upload2NotionNext extends UploadBaseNext { ); } if (res.status === 200) { - await updateYamlInfo(markdown, nowFile, res, app, this.plugin) + await updateYamlInfo(markdown, nowFile, res, app, this.plugin, this.dbDetails) } else { new Notice(`${res.text}`) } From 3123d91e97a34e9e16481717501595a9e3eee4dc Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Fri, 29 Dec 2023 00:21:21 +0000 Subject: [PATCH 11/11] complete the new version for add button --- README.md | 31 +++++++++++++++++++ src/commands/NotionCommands.ts | 2 +- src/main.ts | 4 +++ src/ui/settingModal.ts | 27 +++++++++++++++- src/ui/settingTabs.ts | 12 +++++++ src/upload/uploadCommand.ts | 7 +++-- .../upload_general/Upload2NotionGeneral.ts | 27 +++++++++++----- src/upload/upload_next/Upload2NotionNext.ts | 15 ++++++--- .../upoload_custom/Upload2NotionCustom.ts | 31 +++++++++++++------ 9 files changed, 130 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 6c3851a..f3c4fe6 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,38 @@ Thus, based on the [original author's work](https://github.com/EasyChris/obsidia **Now, support both NotionNext and General databases.** +**现在支持NotionNext和普通Notion数据库。** + +## TODO List + +- [ ] Support custom properties for Notion General database. 支持自定义属性 +- [ ] Support preview for database details in plugin settings. 支持预览数据库详情 +- [ ] Support edit for database details in plugin settings. 支持编辑数据库详情 + ## Update +### 2.0.0 (Big Update) + +- redesign the plugin settings UI. From this version, the settings UI will be separated into two parts: + - one for general settings: bannerUrl and your notion username (ID) + - one for database list: You can add new database or delete the database. +- 重新设计了插件设置界面。从这个版本开始,设置界面将被分成两部分: + - 一部分是通用设置:bannerUrl和你的notion用户名(ID) + - 一部分是数据库列表:你可以添加新的数据库或者删除数据库。 + +![](https://minioapi.pjx.ac.cn/img1/2023/12/f7e89241f45cfee6b902ec4b69dd6f63.png) + +- You can add more databases in the plugin settings. +- 你可以在插件设置中添加更多的数据库。 +![](https://minioapi.pjx.ac.cn/img1/2023/12/023bf46ebbc92c3991d2c443c575bc80.gif) + +- You can sync one note to multiple databases. +- 你可以将一个笔记同步到多个数据库中。 + +![](https://minioapi.pjx.ac.cn/img1/2023/12/75f793bad756162e46bf41e54166eb32.png) + +**Note: You need to add your previous database in the new template.** +**注意:你需要将之前的数据库添加到新的模板中。** + ### 1.2.0 diff --git a/src/commands/NotionCommands.ts b/src/commands/NotionCommands.ts index 13a7bad..4e5979e 100644 --- a/src/commands/NotionCommands.ts +++ b/src/commands/NotionCommands.ts @@ -82,7 +82,7 @@ export default class RibbonCommands { private addCommandForDatabase(dbDetails: DatabaseDetails) { // Example logic - adjust based on your specific requirements let commandId = `share-to-${dbDetails.abName}`; - let commandName = `Share to ${dbDetails.abName}`; // or use a translated name + let commandName = `Share to ${dbDetails.fullName} (${dbDetails.abName})`; // or use a translated name let editorCallback: (editor: Editor, view: MarkdownView) => Promise; if (dbDetails.format === 'next') { diff --git a/src/main.ts b/src/main.ts index 21805bc..585041e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -81,6 +81,10 @@ export default class ObsidianSyncNotionPlugin extends Plugin { await this.saveSettings(); } + + // previewDatabase(dbDetails: DatabaseDetails) { + // + // } } diff --git a/src/ui/settingModal.ts b/src/ui/settingModal.ts index 42e4a1c..8448bf4 100644 --- a/src/ui/settingModal.ts +++ b/src/ui/settingModal.ts @@ -66,7 +66,7 @@ export class SettingModal extends Modal { .addOption('none', '') .addOption('general', i18nConfig.databaseGeneral) .addOption('next', i18nConfig.databaseNext) - .addOption('custom', i18nConfig.databaseCustom) + // .addOption('custom', i18nConfig.databaseCustom) .setValue(this.data.databaseFormat) .onChange(async (value) => { this.data.databaseFormat = value; @@ -121,6 +121,31 @@ export class SettingModal extends Modal { // tag button this.createSettingEl(nextTabs, i18nConfig.NotionTagButton, i18nConfig.NotionTagButtonDesc, 'toggle', i18nConfig.NotionCustomTitleText, this.data.tagButton, 'tagButton') + // add custom title button + + new Setting(nextTabs) + .setName(i18nConfig.NotionCustomTitle) + .setDesc(i18nConfig.NotionCustomTitleDesc) + .addToggle((toggle) => + toggle + .setValue(this.data.CustomTitleButton) + .onChange(async (value) => { + this.data.CustomTitleButton = value; + + this.updateSettingEl(CustomNameEl, value) + + // this.updateSettingEl(CustomValuesEl, value) + + await this.plugin.saveSettings(); + await this.plugin.commands.updateCommand(); + }) + ); + + + // add custom title name + const CustomNameEl = this.createStyleDiv('custom-name', (this.data.CustomTitleButton), nextTabs); + this.createSettingEl(CustomNameEl, i18nConfig.NotionCustomTitleName, i18nConfig.NotionCustomTitleNameDesc, 'text', i18nConfig.NotionCustomTitleText, this.data.CustomTitleName, 'CustomTitleName') + // add api key this.createSettingEl(nextTabs, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.data.notionAPI, 'notionAPI') diff --git a/src/ui/settingTabs.ts b/src/ui/settingTabs.ts index 8800a42..cc692bc 100644 --- a/src/ui/settingTabs.ts +++ b/src/ui/settingTabs.ts @@ -235,6 +235,18 @@ export class ObsidianSettingTab extends PluginSettingTab { .setName(`${dbDetails.fullName} (${dbDetails.abName})`) .setDesc(dbDetails.format) + + // add a button for preview data + // settingEl + // .addButton((button: ButtonComponent): ButtonComponent => { + // return button + // .setTooltip("Preview Database") + // .setIcon("eye") + // .onClick(async () => { + // this.plugin.previewDatabase(dbDetails); + // }); + // }); + // settingEl // .addButton((button: ButtonComponent): ButtonComponent => { // return button diff --git a/src/upload/uploadCommand.ts b/src/upload/uploadCommand.ts index 06b9b45..55c951e 100644 --- a/src/upload/uploadCommand.ts +++ b/src/upload/uploadCommand.ts @@ -87,13 +87,14 @@ export async function uploadCommandGeneral( export async function uploadCommandCustom( plugin: ObsidianSyncNotionPlugin, settings: PluginSettings, + dbDetails: DatabaseDetails, app: App, ) { - const { notionAPIGeneral, databaseIDGeneral } = settings; + const { notionAPI, databaseID } = settings; // Check if the user has set up the Notion API and database ID - if (notionAPIGeneral === "" || databaseIDGeneral === "") { + if (notionAPI === "" || databaseID === "") { const setAPIMessage = i18nConfig["set-api-id"]; new Notice(setAPIMessage); return; @@ -104,7 +105,7 @@ export async function uploadCommandCustom( if (markDownData) { const { basename } = nowFile; - const upload = new Upload2NotionCustom(plugin); + const upload = new Upload2NotionCustom(plugin,dbDetails); const res = await upload.syncMarkdownToNotionCustom(basename, cover, tags, customValues, markDownData, nowFile, this.app); if (res.status === 200) { diff --git a/src/upload/upload_general/Upload2NotionGeneral.ts b/src/upload/upload_general/Upload2NotionGeneral.ts index 71f8dc0..e2f6a02 100644 --- a/src/upload/upload_general/Upload2NotionGeneral.ts +++ b/src/upload/upload_general/Upload2NotionGeneral.ts @@ -14,6 +14,7 @@ export class Upload2NotionGeneral extends UploadBaseGeneral { constructor(plugin: MyPlugin, dbDetails: DatabaseDetails) { super(plugin); + this.dbDetails = dbDetails; } // 因为需要解析notion的block进行对比,非常的麻烦, @@ -28,12 +29,13 @@ export class Upload2NotionGeneral extends UploadBaseGeneral { await this.deletePage(notionID); const { databaseID } = this.dbDetails; - const databasecover = await this.getDataBase( + + const databaseCover = await this.getDataBase( databaseID, ); if (cover == null) { - cover = databasecover; + cover = databaseCover; } return await this.createPage(title, cover, tags, childArr); @@ -45,13 +47,22 @@ export class Upload2NotionGeneral extends UploadBaseGeneral { tags: string[], childArr: any, ) { + + const { + databaseID, + customTitleButton, + customTitleName, + tagButton, + notionAPI + } = this.dbDetails; + const bodyString: any = { parent: { - database_id: this.plugin.settings.databaseIDGeneral, + database_id: databaseID, }, properties: { - [this.plugin.settings.CustomTitleButton - ? this.plugin.settings.CustomTitleName + [customTitleButton + ? customTitleName : "title"]: { title: [ { @@ -61,7 +72,7 @@ export class Upload2NotionGeneral extends UploadBaseGeneral { }, ], }, - ...(this.plugin.settings.tagsButton + ...(tagButton ? { tags: { multi_select: tags && true ? tags.map((tag) => ({ name: tag })) : [], @@ -98,7 +109,7 @@ export class Upload2NotionGeneral extends UploadBaseGeneral { "Content-Type": "application/json", // 'User-Agent': 'obsidian.md', Authorization: - "Bearer " + this.plugin.settings.notionAPIGeneral, + "Bearer " + notionAPI, "Notion-Version": "2022-06-28", }, body: JSON.stringify(bodyString), @@ -144,7 +155,7 @@ export class Upload2NotionGeneral extends UploadBaseGeneral { res = await this.createPage(title, cover, tags, file2Block); } if (res.status === 200) { - await updateYamlInfo(markdown, nowFile, res, app, this.plugin); + await updateYamlInfo(markdown, nowFile, res, app, this.plugin, this.dbDetails); } else { new Notice(`${res.text}`); } diff --git a/src/upload/upload_next/Upload2NotionNext.ts b/src/upload/upload_next/Upload2NotionNext.ts index 1558441..f56ed93 100644 --- a/src/upload/upload_next/Upload2NotionNext.ts +++ b/src/upload/upload_next/Upload2NotionNext.ts @@ -40,10 +40,10 @@ export class Upload2NotionNext extends UploadBaseNext { const { databaseID} = this.dbDetails - const databasecover = await this.getDataBase(databaseID) + const databaseCover = await this.getDataBase(databaseID) if (cover == null) { - cover = databasecover + cover = databaseCover } return await this.createPage( @@ -77,9 +77,16 @@ export class Upload2NotionNext extends UploadBaseNext { datetime: string, childArr: any ) { + + const { + databaseID, + notionAPI + } = this.dbDetails + + const bodyString: any = { parent: { - database_id: this.plugin.settings.databaseIDNext + database_id: databaseID, }, icon: { emoji: emoji || '📜' @@ -183,7 +190,7 @@ export class Upload2NotionNext extends UploadBaseNext { headers: { 'Content-Type': 'application/json', // 'User-Agent': 'obsidian.md', - 'Authorization': 'Bearer ' + this.plugin.settings.notionAPINext, + 'Authorization': 'Bearer ' + notionAPI, 'Notion-Version': '2022-06-28', }, body: JSON.stringify(bodyString), diff --git a/src/upload/upoload_custom/Upload2NotionCustom.ts b/src/upload/upoload_custom/Upload2NotionCustom.ts index f84d92e..7d9dbe4 100644 --- a/src/upload/upoload_custom/Upload2NotionCustom.ts +++ b/src/upload/upoload_custom/Upload2NotionCustom.ts @@ -4,15 +4,17 @@ import { markdownToBlocks } from "@tryfabric/martian"; import * as yamlFrontMatter from "yaml-front-matter"; // import * as yaml from "yaml" import MyPlugin from "src/main"; -import { PluginSettings } from "../../ui/settingTabs"; +import {DatabaseDetails, PluginSettings} from "../../ui/settingTabs"; import { updateYamlInfo } from "../updateYaml"; import {UploadBaseCustom} from "./BaseUpload2NotionCustom"; export class Upload2NotionCustom extends UploadBaseCustom { settings: PluginSettings; + dbDetails: DatabaseDetails; - constructor(plugin: MyPlugin) { + constructor(plugin: MyPlugin, dbDetails: DatabaseDetails) { super(plugin); + this.dbDetails = dbDetails; } // 因为需要解析notion的block进行对比,非常的麻烦, @@ -27,12 +29,14 @@ export class Upload2NotionCustom extends UploadBaseCustom { ) { await this.deletePage(notionID); - const databasecover = await this.getDataBase( - this.plugin.settings.databaseIDGeneral, + const { databaseID } = this.dbDetails; + + const databaseCover = await this.getDataBase( + databaseID ); if (cover == null) { - cover = databasecover; + cover = databaseCover; } return await this.createPage(title, cover, tags, customValues, childArr); @@ -45,13 +49,22 @@ export class Upload2NotionCustom extends UploadBaseCustom { customValues: Record, childArr: any, ) { + + const { + databaseID, + customTitleButton, + customTitleName, + tagButton, + notionAPI + } = this.dbDetails; + const bodyString: any = { parent: { - database_id: this.plugin.settings.databaseIDGeneral, + database_id: databaseID, }, properties: { - [this.plugin.settings.CustomTitleButton - ? this.plugin.settings.CustomTitleName + [customTitleButton + ? customTitleName : "title"]: { title: [ { @@ -148,7 +161,7 @@ export class Upload2NotionCustom extends UploadBaseCustom { res = await this.createPage(title, cover, tags, customValues, file2Block); } if (res.status === 200) { - await updateYamlInfo(markdown, nowFile, res, app, this.plugin); + await updateYamlInfo(markdown, nowFile, res, app, this.plugin, this.dbDetails); } else { new Notice(`${res.text}`); }