mirror of
https://github.com/gapmiss/substack-clipper.git
synced 2026-07-22 07:48:24 +00:00
feat: add open-after-save toggle, fix footnotes to [^N] syntax, rename Clip→Save in UI
This commit is contained in:
parent
8dacb96863
commit
d2c9ab36e9
3 changed files with 34 additions and 13 deletions
27
src/main.ts
27
src/main.ts
|
|
@ -1,4 +1,4 @@
|
|||
import { normalizePath, Notice, Plugin } from 'obsidian';
|
||||
import { normalizePath, Notice, Plugin, TFile } from 'obsidian';
|
||||
import { type SubstackClipperSettings, DEFAULT_SETTINGS } from './types';
|
||||
import type { ParsedArticle, DownloadResult } from './types';
|
||||
import { SettingsTab } from './settings';
|
||||
|
|
@ -18,10 +18,14 @@ export default class SubstackClipperPlugin extends Plugin {
|
|||
|
||||
this.addCommand({
|
||||
id: 'clip-post',
|
||||
name: 'Clip substack post',
|
||||
name: 'Save substack post',
|
||||
callback: () => {
|
||||
new ClipModal(this.app, (url) => {
|
||||
void this.clipPost(url);
|
||||
new ClipModal(this.app, this.settings.openAfterClip, (url, openAfterClip) => {
|
||||
if (openAfterClip !== this.settings.openAfterClip) {
|
||||
this.settings.openAfterClip = openAfterClip;
|
||||
void this.saveSettings();
|
||||
}
|
||||
void this.clipPost(url, openAfterClip);
|
||||
}).open();
|
||||
},
|
||||
});
|
||||
|
|
@ -35,8 +39,8 @@ export default class SubstackClipperPlugin extends Plugin {
|
|||
await this.saveData(this.settings);
|
||||
}
|
||||
|
||||
private async clipPost(url: string): Promise<void> {
|
||||
const notice = new Notice('Clipping...', 0);
|
||||
private async clipPost(url: string, openAfterClip: boolean): Promise<void> {
|
||||
const notice = new Notice('Saving...', 0);
|
||||
|
||||
try {
|
||||
const { username, slug, domain } = parseUrl(url);
|
||||
|
|
@ -189,12 +193,19 @@ export default class SubstackClipperPlugin extends Plugin {
|
|||
await this.writeFile(htmlPath, article.html);
|
||||
}
|
||||
|
||||
if (openAfterClip) {
|
||||
const file = this.app.vault.getAbstractFileByPath(notePath);
|
||||
if (file instanceof TFile) {
|
||||
await this.app.workspace.getLeaf(false).openFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
notice.hide();
|
||||
new Notice(`Clipped: ${article.title}`);
|
||||
new Notice(`Saved: ${article.title}`);
|
||||
|
||||
} catch (e) {
|
||||
notice.hide();
|
||||
new Notice(`Clip failed: ${e instanceof Error ? e.message : String(e)}`);
|
||||
new Notice(`Save failed: ${e instanceof Error ? e.message : String(e)}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
18
src/modal.ts
18
src/modal.ts
|
|
@ -2,17 +2,19 @@ import { App, Modal, Notice, Setting } from 'obsidian';
|
|||
|
||||
export class ClipModal extends Modal {
|
||||
private url = '';
|
||||
private onSubmit: (url: string) => void;
|
||||
private openAfterClip: boolean;
|
||||
private onSubmit: (url: string, openAfterClip: boolean) => void;
|
||||
|
||||
constructor(app: App, onSubmit: (url: string) => void) {
|
||||
constructor(app: App, openAfterClip: boolean, onSubmit: (url: string, openAfterClip: boolean) => void) {
|
||||
super(app);
|
||||
this.openAfterClip = openAfterClip;
|
||||
this.onSubmit = onSubmit;
|
||||
}
|
||||
|
||||
onOpen(): void {
|
||||
const { contentEl } = this;
|
||||
contentEl.addClass('substack-clipper-modal');
|
||||
contentEl.createEl('h2', { text: 'Clip substack post' });
|
||||
contentEl.createEl('h2', { text: 'Save substack post' });
|
||||
|
||||
new Setting(contentEl)
|
||||
.setName('Post URL')
|
||||
|
|
@ -29,9 +31,15 @@ export class ClipModal extends Modal {
|
|||
text.inputEl.setCssStyles({ width: '100%' });
|
||||
});
|
||||
|
||||
new Setting(contentEl)
|
||||
.setName('Open after saving')
|
||||
.addToggle(toggle => toggle
|
||||
.setValue(this.openAfterClip)
|
||||
.onChange(value => { this.openAfterClip = value; }));
|
||||
|
||||
new Setting(contentEl)
|
||||
.addButton(btn => btn
|
||||
.setButtonText('Clip')
|
||||
.setButtonText('Save')
|
||||
.setCta()
|
||||
.onClick(() => { this.submit(); }));
|
||||
}
|
||||
|
|
@ -42,7 +50,7 @@ export class ClipModal extends Modal {
|
|||
return;
|
||||
}
|
||||
this.close();
|
||||
this.onSubmit(this.url);
|
||||
this.onSubmit(this.url, this.openAfterClip);
|
||||
}
|
||||
|
||||
onClose(): void {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ export interface SubstackClipperSettings {
|
|||
saveRawJson: boolean;
|
||||
saveRawHtml: boolean;
|
||||
commentSort: 'most_recent_first' | 'oldest_first' | 'best_first';
|
||||
openAfterClip: boolean;
|
||||
}
|
||||
|
||||
export const DEFAULT_SETTINGS: SubstackClipperSettings = {
|
||||
|
|
@ -42,6 +43,7 @@ export const DEFAULT_SETTINGS: SubstackClipperSettings = {
|
|||
saveRawJson: false,
|
||||
saveRawHtml: false,
|
||||
commentSort: 'most_recent_first',
|
||||
openAfterClip: false,
|
||||
};
|
||||
|
||||
export interface DownloadResult {
|
||||
|
|
|
|||
Loading…
Reference in a new issue