Skip to content

Commit 5ec5385

Browse files
feature: add advanced settings w/ book ID frontmatter population
1 parent a551c1e commit 5ec5385

File tree

1 file changed

+115
-2
lines changed

1 file changed

+115
-2
lines changed

src/main.ts

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
Plugin,
1010
PluginSettingTab,
1111
Setting,
12+
TFile,
1213
Vault
1314
} from 'obsidian';
1415
import * as zip from "@zip.js/zip.js";
@@ -47,6 +48,7 @@ interface ReadwisePluginSettings {
4748
booksToRefresh: Array<string>;
4849
booksIDsMap: { [key: string]: string; };
4950
reimportShowConfirmation: boolean;
51+
frontmatterBookIdKey?: string;
5052
}
5153

5254
// define our initial settings
@@ -65,6 +67,73 @@ const DEFAULT_SETTINGS: ReadwisePluginSettings = {
6567
reimportShowConfirmation: true,
6668
};
6769

70+
class AdvancedModal extends Modal {
71+
plugin: ReadwisePlugin;
72+
73+
constructor(app: App, plugin: ReadwisePlugin) {
74+
super(app);
75+
this.plugin = plugin;
76+
}
77+
78+
onOpen() {
79+
const { titleEl, contentEl } = this;
80+
81+
titleEl.setText('Advanced settings');
82+
83+
// add new setting that allows text input
84+
new Setting(contentEl)
85+
.setName('Book ID frontmatter key')
86+
.setDesc('The frontmatter key used to store the Readwise book_id. If set, will be preferred for syncs.')
87+
.addText(text => text
88+
.setPlaceholder('readwise-book-id')
89+
.setValue(this.plugin.settings.frontmatterBookIdKey)
90+
.onChange(async value => {
91+
console.log('Readwise Official plugin: setting frontmatter book ID key to', value);
92+
this.plugin.settings.frontmatterBookIdKey = value;
93+
this.plugin.saveSettings();
94+
95+
// enable/disable populate button depending on whether the key is set
96+
const populateButton = contentEl.querySelector('.rw-setting-populate-book-id');
97+
if (populateButton instanceof HTMLButtonElement) {
98+
populateButton.disabled = !value;
99+
}
100+
}));
101+
102+
// button to populate the frontmatter with using
103+
// the frontmatterBookIdKey and matching it
104+
// with whatever's saved in booksIDsMap
105+
return new Setting(contentEl)
106+
.setName('Populate frontmatter key')
107+
.setDesc('If the book ID frontmatter key is configured above, this will populate the frontmatter key setting with the first key found in the booksIDsMap. This will not overwrite existing keys.')
108+
.addButton(button => button
109+
.setButtonText('Populate')
110+
.setClass('rw-setting-populate-book-id')
111+
.setDisabled(!this.plugin.settings.frontmatterBookIdKey)
112+
.onClick(async () => {
113+
this.plugin.notice("Populating frontmatter with book IDs...", true);
114+
console.log(`Readwise Official plugin: populating frontmatter key ${this.plugin.settings.frontmatterBookIdKey} with matching value from booksIDsMap...`);
115+
116+
const readwiseExports = this.plugin.app.vault.getMarkdownFiles();
117+
for (const file of readwiseExports) {
118+
console.log('Readwise Official plugin: checking file for frontmatter', file.path);
119+
120+
const bookId = this.plugin.settings.booksIDsMap[file.path];
121+
if (!bookId) continue;
122+
123+
await this.plugin.writeBookIdToFrontmatter(file, bookId);
124+
}
125+
126+
this.plugin.notice("Frontmatter populated with book IDs", true);
127+
})
128+
);
129+
}
130+
131+
onClose() {
132+
const { contentEl } = this;
133+
contentEl.empty();
134+
}
135+
}
136+
68137
export default class ReadwisePlugin extends Plugin {
69138
settings: ReadwisePluginSettings;
70139
fs: DataAdapter;
@@ -293,6 +362,7 @@ export default class ReadwisePlugin extends Plugin {
293362
contentToSave = existingContent + contents;
294363
}
295364
await this.fs.write(originalName, contentToSave);
365+
this.app.metadataCache.trigger('readwise:write');
296366
await this.saveSettings();
297367
} catch (e) {
298368
console.log(`Readwise Official plugin: error writing ${processedFileName}:`, e);
@@ -407,8 +477,10 @@ export default class ReadwisePlugin extends Plugin {
407477
let booksToRefresh = this.settings.booksToRefresh;
408478
this.settings.booksToRefresh = booksToRefresh.filter(n => ![bookId].includes(n));
409479
this.saveSettings();
410-
vault.delete(vault.getAbstractFileByPath(fileName));
411-
this.startSync();
480+
vault.delete(vault.getAbstractFileByPath(fileName)).then(() => {
481+
this.startSync();
482+
this.app.metadataCache.trigger('readwise:write');
483+
});
412484
} else {
413485
this.notice("Failed to reimport. Please try again", true);
414486
}
@@ -445,6 +517,7 @@ export default class ReadwisePlugin extends Plugin {
445517
);
446518

447519
this.refreshBookExport(this.settings.booksToRefresh);
520+
448521
this.app.vault.on("delete", async (file) => {
449522
const bookId = this.settings.booksIDsMap[file.path];
450523
if (bookId) {
@@ -454,6 +527,7 @@ export default class ReadwisePlugin extends Plugin {
454527
delete this.settings.booksIDsMap[file.path];
455528
this.saveSettings();
456529
});
530+
457531
this.app.vault.on("rename", (file, oldPath) => {
458532
const bookId = this.settings.booksIDsMap[oldPath];
459533
if (!bookId) {
@@ -463,6 +537,13 @@ export default class ReadwisePlugin extends Plugin {
463537
delete this.settings.booksIDsMap[oldPath];
464538
this.saveSettings();
465539
});
540+
541+
this.app.metadataCache.on('changed', async (file) => {
542+
if (file.path.startsWith(this.settings.readwiseDir)) {
543+
await this.writeBookIdToFrontmatter(file, this.settings.booksIDsMap[file.path]);
544+
}
545+
});
546+
466547
if (this.settings.isSyncing) {
467548
if (this.settings.currentSyncStatusID) {
468549
await this.getExportStatus();
@@ -617,6 +698,27 @@ export default class ReadwisePlugin extends Plugin {
617698
await this.saveSettings();
618699
return true;
619700
}
701+
702+
async writeBookIdToFrontmatter(file: TFile, bookId: string) {
703+
console.log('Readwise Official plugin: checking file for frontmatter', file.path);
704+
705+
if (!this.settings.frontmatterBookIdKey) return;
706+
707+
const cache = this.app.metadataCache.getFileCache(file);
708+
if (!cache) return;
709+
710+
const frontmatter = cache.frontmatter;
711+
if (!frontmatter) return;
712+
713+
// don't overwrite existing book ID in frontmatter
714+
const existingBookId = frontmatter[this.settings.frontmatterBookIdKey];
715+
if (existingBookId) return;
716+
717+
await this.app.fileManager.processFrontMatter(file, frontmatter => {
718+
console.log(`Readwise Official plugin: setting frontmatter key for "${file.path}" to ${bookId}`);
719+
frontmatter[this.settings.frontmatterBookIdKey] = bookId;
720+
});
721+
}
620722
}
621723

622724
class ReadwiseSettingTab extends PluginSettingTab {
@@ -734,6 +836,17 @@ class ReadwiseSettingTab extends PluginSettingTab {
734836
}
735837
);
736838

839+
new Setting(containerEl)
840+
.setName('Advanced settings')
841+
.setDesc('Customize additional settings for the Readwise plugin')
842+
.addButton(button => {
843+
button
844+
.setButtonText('Open')
845+
.onClick(() => {
846+
new AdvancedModal(this.app, this.plugin).open();
847+
});
848+
});
849+
737850
if (this.plugin.settings.lastSyncFailed) {
738851
this.plugin.showInfoStatus(containerEl.find(".rw-setting-sync .rw-info-container").parentElement, "Last sync failed", "rw-error");
739852
}

0 commit comments

Comments
 (0)