From e4889654b49a5d033eb6756b318a91c6578ed679 Mon Sep 17 00:00:00 2001 From: kaiiiz Date: Thu, 21 Jul 2022 23:01:35 +0800 Subject: [PATCH 1/5] Sync article tags --- src/api.ts | 1 + src/assets/defaultTemplate.njk | 1 + src/renderer.ts | 4 +++- src/templates/templateInstructions.html | 1 + src/types.ts | 1 + 5 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/api.ts b/src/api.ts index fb13652..475decc 100644 --- a/src/api.ts +++ b/src/api.ts @@ -111,6 +111,7 @@ export class RaindropAPI { excerpt: raindrop['excerpt'], link: raindrop['link'], lastUpdate: new Date(raindrop['lastUpdate']), + tags: raindrop['tags'], }; return article; }); diff --git a/src/assets/defaultTemplate.njk b/src/assets/defaultTemplate.njk index 3ab4f34..792cf7d 100644 --- a/src/assets/defaultTemplate.njk +++ b/src/assets/defaultTemplate.njk @@ -1,6 +1,7 @@ {% if is_new_article %} # Metadata {% if link %}Source URL:: {{link}}{% endif %} +{% if tags|length %}Topics:: {{ tags | join(", ") }}{% endif %} --- # {{title}} diff --git a/src/renderer.ts b/src/renderer.ts index 85bc6f0..1718cae 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -20,6 +20,7 @@ type RenderTemplate = { excerpt: string; link: string; highlights: RenderHighlight[]; + tags: string[], }; export default class Renderer { @@ -40,7 +41,7 @@ export default class Renderer { } renderContent(article: RaindropArticle, newArticle = true) { - const { id , title, highlights, excerpt, link } = article; + const { id , title, highlights, excerpt, link, tags } = article; const dateTimeFormat = this.plugin.settings.dateTimeFormat; const renderHighlights: RenderHighlight[] = highlights.map(hl => { @@ -62,6 +63,7 @@ export default class Renderer { excerpt, link, highlights: renderHighlights, + tags, }; const template = this.plugin.settings.template; diff --git a/src/templates/templateInstructions.html b/src/templates/templateInstructions.html index 6f96a52..7e6d95d 100644 --- a/src/templates/templateInstructions.html +++ b/src/templates/templateInstructions.html @@ -13,6 +13,7 @@
  • {{excerpt}} - Article excerpt
  • {{link}} - Link to source
  • {{highlights}} - List of your Highlights
  • +
  • {{tags}} - List of tag
  • Highlight diff --git a/src/types.ts b/src/types.ts index 91b5489..58fd00f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -25,6 +25,7 @@ export interface RaindropArticle { // Remote state excerpt: string, link: string, lastUpdate: Date, + tags: string[], } // ---------- From de6e64f078ca11bef8c6515a85a6ebe836efa14c Mon Sep 17 00:00:00 2001 From: kaiiiz Date: Thu, 21 Jul 2022 23:12:03 +0800 Subject: [PATCH 2/5] Fix update collection settings bug --- src/main.ts | 21 ++++++++++++++++++++- src/settings.ts | 15 +-------------- src/sync.ts | 3 +++ 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/main.ts b/src/main.ts index 269b571..963660e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,7 +1,7 @@ import { Plugin } from 'obsidian'; import { RaindropSettingTab } from './settings'; import RaindropSync from './sync'; -import type { RaindropPluginSettings } from './types'; +import type { RaindropCollection, RaindropPluginSettings } from './types'; import DEFAULT_TEMPLATE from './assets/defaultTemplate.njk'; @@ -44,4 +44,23 @@ export default class RaindropPlugin extends Plugin { async saveSettings() { await this.saveData(this.settings); } + + async updateCollectionSettings(collections: RaindropCollection[]) { + const syncCollections = this.settings.syncCollections; + collections.forEach(async (collection) => { + const {id, title} = collection; + + if (!(id in syncCollections)) { + syncCollections[id] = { + id: id, + title: title, + sync: false, + lastSyncDate: undefined, + }; + } else { + syncCollections[id].title = title; + } + }); + await this.saveSettings(); + } } diff --git a/src/settings.ts b/src/settings.ts index 5b77939..5f9f89f 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -90,20 +90,7 @@ export class RaindropSettingTab extends PluginSettingTab { .onClick(async () => { // update for new collections const allCollections = await this.api.getCollections(); - const syncCollections = this.plugin.settings.syncCollections; - allCollections.forEach(async (collection) => { - const {id, title} = collection; - - if (!(id in syncCollections)) { - syncCollections[id] = { - id: id, - title: title, - sync: false, - lastSyncDate: undefined, - }; - } - }); - await this.plugin.saveSettings(); + this.plugin.updateCollectionSettings(allCollections); const collectionsModal = new CollectionsModal(this.app, this.plugin); this.display(); // rerender diff --git a/src/sync.ts b/src/sync.ts index b71a7a8..ae0ed93 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -19,6 +19,9 @@ export default class RaindropSync { } async sync() { + const allCollections = await this.api.getCollections(); + this.plugin.updateCollectionSettings(allCollections); + for (const id in this.plugin.settings.syncCollections) { const collection = this.plugin.settings.syncCollections[id]; if (collection.sync) { From 5125d01f0f6e6f23b8b9131d1ac0437df38eb192 Mon Sep 17 00:00:00 2001 From: kaiiiz Date: Thu, 21 Jul 2022 23:46:58 +0800 Subject: [PATCH 3/5] Add last sync in post front matter (to prevent unexpected import while resyncing) --- src/renderer.ts | 3 ++- src/sync.ts | 13 +++++++++++++ src/types.ts | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/renderer.ts b/src/renderer.ts index 1718cae..e6bfa8b 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -65,7 +65,7 @@ export default class Renderer { highlights: renderHighlights, tags, }; - + const template = this.plugin.settings.template; const content = nunjucks.renderString(template, context); return content; @@ -74,6 +74,7 @@ export default class Renderer { addFrontMatter(markdownContent: string, article: RaindropArticle) { const fm: ArticleFileFrontMatter = { raindrop_id: article.id, + raindrop_last_update: (new Date()).toISOString(), }; return matter.stringify(markdownContent, fm); } diff --git a/src/sync.ts b/src/sync.ts index ae0ed93..d7c4446 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -83,6 +83,19 @@ export default class RaindropSync { } async updateFile(file: TFile, article: RaindropArticle) { + const metadata = this.app.metadataCache.getFileCache(file); + if (metadata?.frontmatter && 'raindrop_last_update' in metadata.frontmatter) { + const localLastUpdate = new Date(metadata.frontmatter.raindrop_last_update); + if (localLastUpdate >= article.lastUpdate) { + console.debug('skip update file', file.path); + return; + } + + article.highlights = article.highlights.filter(hl => { + return localLastUpdate < hl.lastUpdate; + }); + } + console.debug("update file", file.path); const newMdContent = this.renderer.renderContent(article, false); const oldMdContent = await this.app.vault.cachedRead(file); diff --git a/src/types.ts b/src/types.ts index 58fd00f..c48a462 100644 --- a/src/types.ts +++ b/src/types.ts @@ -37,6 +37,7 @@ export interface ArticleFile { export interface ArticleFileFrontMatter { // use snake_case in front matter raindrop_id: number, + raindrop_last_update: string, } // ---------- From 07405472a45d3f65a6a27a4de79fbdc0f78dcc75 Mon Sep 17 00:00:00 2001 From: kaiiiz Date: Fri, 22 Jul 2022 00:03:28 +0800 Subject: [PATCH 4/5] Move token from storage to localStorage --- src/api.ts | 3 +-- src/main.ts | 6 ++++-- src/settings.ts | 7 +++++-- src/tokenManager.ts | 21 +++++++++++++++++++++ src/types.ts | 1 - 5 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 src/tokenManager.ts diff --git a/src/api.ts b/src/api.ts index 475decc..f1a8ee8 100644 --- a/src/api.ts +++ b/src/api.ts @@ -15,8 +15,7 @@ export class RaindropAPI { } async get(url: string, params: any) { - const token = this.plugin.settings.token; - + const token = this.plugin.tokenManager.get(); if (!token) { throw new Error("Invalid token"); } diff --git a/src/main.ts b/src/main.ts index 963660e..ceede28 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,10 +3,10 @@ import { RaindropSettingTab } from './settings'; import RaindropSync from './sync'; import type { RaindropCollection, RaindropPluginSettings } from './types'; import DEFAULT_TEMPLATE from './assets/defaultTemplate.njk'; +import TokenManager from './tokenManager'; const DEFAULT_SETTINGS: RaindropPluginSettings = { - token: '', highlightsFolder: '', syncCollections: {}, template: DEFAULT_TEMPLATE, @@ -15,11 +15,13 @@ const DEFAULT_SETTINGS: RaindropPluginSettings = { export default class RaindropPlugin extends Plugin { private raindropSync: RaindropSync; - settings: RaindropPluginSettings; + public settings: RaindropPluginSettings; + public tokenManager: TokenManager; async onload() { await this.loadSettings(); + this.tokenManager = new TokenManager(); this.raindropSync = new RaindropSync(this.app, this); this.addCommand({ diff --git a/src/settings.ts b/src/settings.ts index 5f9f89f..9de6b4e 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -63,14 +63,17 @@ export class RaindropSettingTab extends PluginSettingTab { .setDesc(tokenDescFragment) .addText(async (text) => { try { - text.setValue(this.plugin.settings.token); + const token = this.plugin.tokenManager.get(); + if (token) { + text.setValue(token); + } } catch (e) { /* Throw away read error if file does not exist. */ } text.onChange(async (value) => { try { - this.plugin.settings.token = value; + this.plugin.tokenManager.set(value); new Notice('Token saved'); } catch (e) { new Notice('Invalid token'); diff --git a/src/tokenManager.ts b/src/tokenManager.ts new file mode 100644 index 0000000..8fc272d --- /dev/null +++ b/src/tokenManager.ts @@ -0,0 +1,21 @@ +export default class TokenManager { + localStorage: any; + + constructor() { + this.localStorage = window.localStorage; + } + + get(): string|null { + const token = this.localStorage.getItem('raindrop_token'); + + if (token === null || token.length == 0) { + return null; + } + + return token; + } + + set(token: string) { + this.localStorage.setItem('raindrop_token', token); + } +} diff --git a/src/types.ts b/src/types.ts index c48a462..46ba938 100644 --- a/src/types.ts +++ b/src/types.ts @@ -52,7 +52,6 @@ export interface SyncCollection { // Local state export interface SyncCollectionSettings {[id: number]: SyncCollection} export interface RaindropPluginSettings { - token: string, highlightsFolder: string; syncCollections: SyncCollectionSettings; template: string; From d2ad1475a41a730025c0f2ba7ffb85f00b35e357 Mon Sep 17 00:00:00 2001 From: kaiiiz Date: Fri, 22 Jul 2022 00:06:56 +0800 Subject: [PATCH 5/5] Bump version to v0.0.3 --- manifest.json | 2 +- package.json | 2 +- versions.json | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/manifest.json b/manifest.json index 476b058..594be7f 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-raindrop-highlights", "name": "Raindrop Highlights", - "version": "0.0.2", + "version": "0.0.3", "minAppVersion": "0.14.0", "description": "Sync your Raindrop.io highlights.", "author": "kaiiiz", diff --git a/package.json b/package.json index 5d73237..401037b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsidian-raindrop-highlights", - "version": "0.0.2", + "version": "0.0.3", "description": "Sync your Raindrop.io highlights.", "main": "main.js", "scripts": { diff --git a/versions.json b/versions.json index df9c349..a13d9e6 100644 --- a/versions.json +++ b/versions.json @@ -1,4 +1,5 @@ { "0.0.1": "0.12.0", - "0.0.2": "0.14.0" + "0.0.2": "0.14.0", + "0.0.3": "0.14.0" }