Skip to content

Commit

Permalink
✨ use viewState to hold TFile in PreviewView
Browse files Browse the repository at this point in the history
  • Loading branch information
JichouP committed Feb 27, 2023
1 parent 019d0e3 commit a390409
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 42 deletions.
5 changes: 2 additions & 3 deletions src/export.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { exec } from 'child_process';
import { normalizePath, Notice } from 'obsidian';
import { fileState } from './fileState';
import { normalizePath, Notice, TFile } from 'obsidian';

export async function exportSlide(
file: TFile,
ext: 'html' | 'pdf' | 'pptx',
basePath: string,
themeDir: string,
) {
const exportDir = normalizePath(`${process.env.USERPROFILE}/Downloads`);
const file = fileState.getFile();
if (!file) return;
const filePath = normalizePath(`${basePath}/${file.path}`);
const cmd = `npx -y @marp-team/marp-cli@latest --stdin false --theme-set "${themeDir}" -o "${exportDir}/${file.basename}.${ext}" -- "${filePath}"`;
Expand Down
16 changes: 0 additions & 16 deletions src/fileState.ts

This file was deleted.

29 changes: 18 additions & 11 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { FileSystemAdapter, normalizePath, Notice, Plugin } from 'obsidian';
import { fileState } from './fileState';
import {
FileSystemAdapter,
normalizePath,
Notice,
Plugin,
TFile,
} from 'obsidian';
import { MARP_DEFAULT_SETTINGS, MarpPluginSettings } from './settings';
import { MARP_PREVIEW_VIEW_TYPE, PreviewView } from './preview';
import { MarpSettingTab } from './settingTab';
Expand All @@ -11,26 +16,24 @@ export default class MarpPlugin extends Plugin {

async onload() {
await this.loadSettings();
this.addRibbonIcon('presentation', 'Marp: Open Preview', _ => {
this.addRibbonIcon('presentation', 'Marp: Open Preview', async _ => {
const file = this.app.workspace.activeEditor?.file;
if (!file)
return new Notice(
'Please select the tab for the file you want to view in Marp , and then click this button again.',
10000,
);
fileState.setFile(file);
this.activateView();
await this.activateView(file);
});
// eslint-disable-next-line @typescript-eslint/no-this-alias
const that = this;
this.addCommand({
id: 'open-preview',
name: 'Open Preview',
editorCallback(_editor, ctx) {
async editorCallback(_editor, ctx) {
const file = ctx.file;
if (!file) return;
fileState.setFile(file);
that.activateView();
await that.activateView(file);
},
});
this.registerView(
Expand Down Expand Up @@ -69,21 +72,25 @@ export default class MarpPlugin extends Plugin {
this.app.workspace.detachLeavesOfType(MARP_PREVIEW_VIEW_TYPE);
}

async activateView() {
async activateView(file: TFile) {
this.app.workspace.detachLeavesOfType(MARP_PREVIEW_VIEW_TYPE);

if (this.settings.createNewSplitTab) {
// create a preview on a new split tab
this.app.workspace.getLeaf('split').setViewState({
const leaf = this.app.workspace.getLeaf('split');
await leaf.setViewState({

This comment has been minimized.

Copy link
@liamcain

liamcain Feb 27, 2023

You shouldn't have to call setState yourself. This should work:

setViewState({
    type: MARP_PREVIEW_VIEW_TYPE,
    active: true,
    state: { file }
});
type: MARP_PREVIEW_VIEW_TYPE,
active: true,
});
await (leaf.view as PreviewView).setState({ file }, {});
} else {
// do not create new split tab, just a new tab
this.app.workspace.getLeaf('tab').setViewState({
const leaf = this.app.workspace.getLeaf('tab');
await leaf.setViewState({
type: MARP_PREVIEW_VIEW_TYPE,
active: true,
});
await (leaf.view as PreviewView).setState({ file }, {});
}
}

Expand Down
52 changes: 40 additions & 12 deletions src/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,26 @@ import {
FileSystemAdapter,
ItemView,
normalizePath,
TFile,
ViewStateResult,
WorkspaceLeaf,
} from 'obsidian';
import { exportSlide } from './export';
import { fileState } from './fileState';
import { marp } from './marp';
import { MarpPluginSettings } from './settings';

export const MARP_PREVIEW_VIEW_TYPE = 'marp-preview-view';

export class PreviewView extends ItemView {
interface PreviewViewState {
file: TFile | null;
}

export class PreviewView extends ItemView implements PreviewViewState {
file: TFile | null;
settings: MarpPluginSettings;
constructor(leaf: WorkspaceLeaf, settings: MarpPluginSettings) {
super(leaf);
this.file = null;
this.settings = settings;
}

Expand All @@ -27,9 +34,8 @@ export class PreviewView extends ItemView {
}

async renderPreview() {
const file = fileState.getFile();
if (!file) return;
const content = await this.app.vault.cachedRead(file);
if (!this.file) return;
const content = await this.app.vault.cachedRead(this.file);
const { html, css } = marp.render(content);
const doc = new DOMParser().parseFromString(html, 'text/html');
const container = this.containerEl.children[1];
Expand All @@ -38,23 +44,31 @@ export class PreviewView extends ItemView {
container.createEl('style', { text: css });
}

async onOpen() {
this.registerEvent(this.app.vault.on('modify', this.onChange.bind(this)));
addActions() {
const basePath = (
this.app.vault.adapter as FileSystemAdapter
).getBasePath();
const themeDir = normalizePath(`${basePath}/${this.settings.themeDir}`);

this.addAction('download', 'Export as PDF', () => {
exportSlide('pdf', basePath, themeDir);
if (this.file) {
exportSlide(this.file, 'pdf', basePath, themeDir);
}
});
this.addAction('image', 'Export as PPTX', () => {
exportSlide('pptx', basePath, themeDir);
if (this.file) {
exportSlide(this.file, 'pptx', basePath, themeDir);
}
});
this.addAction('code-glyph', 'Export as HTML', () => {
exportSlide('html', basePath, themeDir);
if (this.file) {
exportSlide(this.file, 'html', basePath, themeDir);
}
});
await this.renderPreview();
}

async onOpen() {
this.registerEvent(this.app.vault.on('modify', this.onChange.bind(this)));
this.addActions();
}

async onClose() {
Expand All @@ -65,4 +79,18 @@ export class PreviewView extends ItemView {
if (!this.settings.autoReload) return;
this.renderPreview();
}

async setState(state: PreviewViewState, result: ViewStateResult) {
if (state.file) {
this.file = state.file;
}
await this.renderPreview();
return super.setState(state, result);
}

getState(): PreviewViewState {
return {
file: this.file,
};
}
}

0 comments on commit a390409

Please sign in to comment.