From f01c54946de3d7ab6c6af5cdd69dc2a777e49626 Mon Sep 17 00:00:00 2001 From: Ola Rubaj <52197250+olayway@users.noreply.github.com> Date: Fri, 14 Feb 2025 16:04:53 +0100 Subject: [PATCH] feat!: refactor for cloud Flowershow version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Changes - replace `isDraft: true` with Obsidian-publish-compatible `publish: false`, - adjust notes syncing to mirror the vault 1-to-1 with the repo (no longer adds content to `/content` and assets to `/public`), - improve publish manager modal styles a bit and add: link to repo, refresh button and settings button - adjust usage instructions in `README.md` (almost the same as added here: https://github.com/datopian/datahub-next/pull/689 to `/obsidian-quickstart`) - add short info at the top with a link to the `/obsidian-quickstart?ref=obsidian` (with ref param that we can use for analytics, but needs to be tested if this is enough) - replace the old, temporary icon 🌱 with our Flowershow icon in Obsidian ribbon - add notice at the top of the `README.md` about breaking change - bump major version from `1.0.0` to `2.0.0` --- README.md | 69 ++++++++++++++++++++----------- main.ts | 4 +- manifest.json | 2 +- package.json | 2 +- src/PublishStatusModal.ts | 85 ++++++++++++++++++++++++++++++++++----- src/Publisher.ts | 45 +++++++++------------ src/SettingView.ts | 23 ++++++----- src/SiteManager.ts | 14 +++---- src/Validator.ts | 6 +-- src/constants.ts | 4 +- 10 files changed, 170 insertions(+), 84 deletions(-) diff --git a/README.md b/README.md index 0690165..bafcd5e 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,59 @@ # 🌷 Obsidian Flowershow Plugin +> ⚠️ **IMPORTANT**: This plugin is no longer compatible with self-hosted Flowershow sites. It is now exclusively used as a tool for Flowershow Cloud. [Sign up for Flowershow Cloud here](https://cloud.flowershow.app) + Obsidian Flowershow plugin for publishing with [Flowershow](https://github.com/datopian/flowershow) direct from your Obsidian vault. -## Docs +## Getting Started ### Initial Setup -1. Firstly, you will need a GitHub account. If you don't have it yet, create one [here](https://github.com/signup). -2. You'll also need a Vercel account. You can sign up using your GitHub account [here](https://vercel.com/signup) -3. Open [this repo](https://github.com/datopian/flowershow), and click the blue "Deploy" button under "Quick clone and deploy" section. This will open Vercel's "Create Git Repository" page. Pick a name for your site's repository and click "Create", to create a copy of the template repository in your GitHub account and deploy it to Vercel. -4. Now you need to create a personal access token on GitHub, so that the plugin can add/delete notes to/from the repo. Go to [this page](https://github.com/settings/tokens/new?scopes=repo) while logged in to GitHub. The correct settings should already be applied. If you don't want to generate this every few months, choose the "No expiration" option. Click the "Generate token" button, and copy the token you are presented with on the next page. -5. In Obsidian open Flowershow plugin settings. Fill in your GitHub username, the name of the repo with your notes which you created in step 3. Lastly paste the token you created in step 4. -6. Now, let's publish your first note! Create a new note in Obsidian. -7. Open your command pallete by pressing CTRL+P on Windows/Linux (CMD+P on Mac) and find the "Flowershow: Publish Single Note" command. Press enter. -8. Go to your site's URL which you should find on [Vercel](https://vercel.com/dashboard). If nothing shows up yet, wait a minute and refresh. Your Flowershow site with the note you just created should now be up and running. +1. First, you will need a GitHub account. If you don't have one yet, create one [here](https://github.com/signup). + +2. Go to our [GitHub template](https://github.com/datopian/flowershow) and click on the green "Use this template" button. Then, select "Create a new repository" option from the dropdown. + +3. Give your repository a name and choose whether you want to keep it private or public. + +4. Once the repository is created, click on the "Create New Site" button in your dashboard and choose the newly created GitHub repository to use as a base for your site. + +5. Wait for your repository to finish syncing with the content. Once done, you can click on the "Visit" button to see your created site. + +6. Now you need to create a personal access token on GitHub, so that the plugin can sync your notes with the repository. Go to [this page](https://github.com/settings/tokens/new?scopes=repo) while logged in to GitHub. The correct settings should already be applied. If you don't want to generate this every few months, choose the "No expiration" option. Click the "Generate token" button, and copy the token you are presented with on the next page. + +### Publishing Your Notes + +1. Install and enable the Obsidian Flowershow plugin in your vault. -Congratulations, you now have your own Flowershow site, hosted free of charge! -You can now start adding links as you usually would in Obisidan, with double square brackets like this: [[Some Other Note]], to the note that you just published. You can also link to a specific header by using the syntax [[Some Other Note#A Header]]. Remember to also publish the notes your are linking to as this will not happen automatically. +2. Open the plugin settings and provide: + - Your GitHub username + - The name of the GitHub repository you created earlier + - The personal access token you generated -### Commands +3. Close the settings and click on the Flowershow icon in the ribbon. -* `Flowershow: Publish Single Note` - Publishes the current note to your Flowershow site. -* `Flowershow: Publish All Notes` - Publishes all notes in your vault to your Flowershow site. +4. Click on "Sync all" to fully synchronize your site's content with your vault. -### Ribbon commands +Done! Your notes are ready to be shared with the world! 💐 -After installing the plugin, you'll see a new icon added to your Obsidian ribbon - 🌱. -Clicking on it will pull up the Publication Status panel, which includes: +You can now start adding links as you usually would in Obsidian, with double square brackets like this: [[Some Other Note]]. You can also link to a specific header by using the syntax [[Some Other Note#A Header]]. + +### Publication Status Panel + +The Flowershow icon in your ribbon opens the Publication Status panel, which shows: * **Published**: the total number of notes that has been published to your Flowershow site * **Changed**: the total number of __published__ notes that has been edited locally (+ button to publish them) * **Unpublished**: the total number of new notes in your Obsidian vault, that has not yet been published to your site (+ button to publish them) * **Deleted**: the total number of notes that has been deleted from your Obsidian vault, but are still published on your site (+ button to unpublish them) +### Available Commands + +* `Flowershow: Publish Single Note` - Publishes the current note to your Flowershow site +* `Flowershow: Publish All Notes` - Publishes all notes in your vault to your Flowershow site + ### Frontmatter settings -* `isDraft` - Set to `true` to keep the note unpublished from your Flowershow site (or unpublish it if it was published before). Default: `false`. +* `publish` - Set to `false` to keep the note unpublished from your Flowershow site (or unpublish it if it was published before). ## Development @@ -44,15 +62,19 @@ Clicking on it will pull up the Publication Status panel, which includes: 1. Clone the repository. 2. Run `npm i` to install dependencies. 3. Run `npm run build`. -4. Create symlinks to the `main.js`, `manifest.json`, and `styles.css` files in your Obsidian plugins folder: +4. Create the plugins directory in your Obsidian vault if it doesn't exist: +```sh +mkdir -p /path/to/obsidian-vault/.obsidian/plugins/flowershow +``` +5. Create symlinks to the `main.js`, `manifest.json`, and `styles.css` files in your Obsidian plugins folder: -``` sh +```sh ln -s /path/to/obsidian-flowershow/main.js /path/to/obsidian-vault/.obsidian/plugins/flowershow/main.js ln -s /path/to/obsidian-flowershow/manifest.json /path/to/obsidian-vault/.obsidian/plugins/flowershow/manifest.json ln -s /path/to/obsidian-flowershow/styles.css /path/to/obsidian-vault/.obsidian/plugins/flowershow/styles.css ``` -5. Reload Obsidian, go to Settings > Community Plugins, and enable the plugin. +6. Reload Obsidian, go to Settings > Community Plugins, and enable the plugin. ### Rebuild on change @@ -66,13 +88,13 @@ If you want true hot reloading, i.e. without needing to disable/enable the plugi - download the .zip file from the latest release - extract the .zip file into your Obsidian vault's `.obsidian/plugins` folder - go to Settings > Community Plugins and enable the plugin -2. Instead of creating symlinks like in step 4 above, copy the plugin files directly into your Obsidian vault's `.obsidian/plugins` folder: +2. Instead of creating symlinks like in step 4 above, copy/clone the plugin project directly into your Obsidian vault's `.obsidian/plugins` folder: ``` sh mv /path/to/obsidian-flowershow /path/to/obsidian-vault/.obsidian/plugins/ ``` -3. Run `npm run dev` to start the server. +3. Run `npm i && npm run dev` in the plugin folder to start the development server. Now, whenever you make any changes to the source code, two things will happen: 1. The plugin will be rebuilt automatically. @@ -81,4 +103,3 @@ Now, whenever you make any changes to the source code, two things will happen: ## Shoutout Big thanks to [Ole Eskild Steensen](https://github.com/oleeskild) for [his obsidian-digital-garden plugin](https://github.com/oleeskild/obsidian-digital-garden/tree/main) which inspired us and we got to build on. - diff --git a/main.ts b/main.ts index 755c9cd..144eb59 100644 --- a/main.ts +++ b/main.ts @@ -8,7 +8,7 @@ import PublishStatusModal from 'src/PublishStatusModal'; import SettingView from 'src/SettingView'; import SiteManager, { ISiteManager } from 'src/SiteManager'; -import { seedling } from 'src/constants'; +import { flowershowIcon } from 'src/constants'; export default class Flowershow extends Plugin { @@ -32,7 +32,7 @@ export default class Flowershow extends Plugin { this.addSettingTab(new FlowershowSettingTab(this.app, this)); await this.addCommands(); - addIcon('flowershow-icon', seedling); + addIcon('flowershow-icon', flowershowIcon); this.addRibbonIcon("flowershow-icon", "Publish with Flowershow", async () => { this.openPublishStatusModal(); }); diff --git a/manifest.json b/manifest.json index ec2a1e5..c1fc172 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "flowershow", "name": "Flowershow", - "version": "1.0.0", + "version": "2.0.0", "minAppVersion": "0.0.1", "description": "Publish with Flowershow directly from your Obsidian vault.", "author": "Rufus Pollock", diff --git a/package.json b/package.json index 140d5bb..5cff9d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "flowershow", - "version": "1.0.0", + "version": "2.0.0", "description": "Obsidian Flowershow plugin for publishing with flowershow direct from your obsidian vault.", "main": "main.js", "scripts": { diff --git a/src/PublishStatusModal.ts b/src/PublishStatusModal.ts index 911c59d..fb90e0a 100644 --- a/src/PublishStatusModal.ts +++ b/src/PublishStatusModal.ts @@ -11,8 +11,9 @@ export interface IPublishStatusModal { export default class PublishStatusModal implements IPublishStatusModal { private modal: Modal; - // private settings: FlowershowSettings; + private settings: FlowershowSettings; private publishStatusManager: IPublishStatusManager; + private app: App; private publisher: IPublisher; private publishStatus: PublishStatus; @@ -28,7 +29,8 @@ export default class PublishStatusModal implements IPublishStatusModal { constructor(app: App, publishStatusManager: IPublishStatusManager, publisher: IPublisher, settings: FlowershowSettings) { this.modal = new Modal(app); - // this.settings = settings; + this.app = app; + this.settings = settings; this.publishStatusManager = publishStatusManager; this.publisher = publisher; @@ -42,15 +44,68 @@ export default class PublishStatusModal implements IPublishStatusModal { // DONE private async initialize() { - this.modal.titleEl.innerText = "🌷 Flowershow"; this.modal.contentEl.addClass("digital-garden-publish-status-view"); - this.modal.contentEl.createEl("h2", { text: "Publication Status" }); + + // Add GitHub repository header with link + const headerEl = this.modal.contentEl.createEl("div", { cls: "publish-header" }); + headerEl.style.display = "flex"; + headerEl.style.justifyContent = "space-between"; + headerEl.style.alignItems = "center"; + headerEl.style.marginBottom = "20px"; + headerEl.style.padding = "10px"; + headerEl.style.borderBottom = "1px solid var(--background-modifier-border)"; + + const headerLeft = headerEl.createEl("div"); + const repoUrl = `https://github.com/${this.settings.githubUserName}/${this.settings.githubRepo}`; + const headerText = headerLeft.createEl("p", { cls: "publish-header-text" }); + headerText.style.margin = "0"; + headerText.setText("Publishing to "); + + const link = headerText.createEl("a", { + text: `${this.settings.githubUserName}/${this.settings.githubRepo}`, + href: repoUrl + }); + link.style.color = "var(--text-accent)"; + link.style.textDecoration = "none"; + + // Add icons container + const iconsContainer = headerEl.createEl("div"); + iconsContainer.style.display = "flex"; + iconsContainer.style.gap = "8px"; + + // Add sync icon + const syncIcon = iconsContainer.createEl("div", { cls: "clickable-icon" }); + syncIcon.innerHTML = ``; + syncIcon.style.cursor = "pointer"; + syncIcon.addEventListener("click", async () => { + this.progressContainer.innerText = `⌛ Refreshing status...`; + await this.refreshStatus(); + this.progressContainer.innerText = `✅ Status refreshed`; + setTimeout(() => { + this.progressContainer.innerText = ""; + }, 2000); + }); + + // Add settings icon + const settingsIcon = iconsContainer.createEl("div", { cls: "clickable-icon" }); + settingsIcon.innerHTML = ``; + settingsIcon.style.cursor = "pointer"; + settingsIcon.addEventListener("click", () => { + this.modal.close(); + // @ts-ignore + this.app.setting?.open(); + // @ts-ignore + this.app.setting?.openTabById("obsidian-flowershow"); + }); + this.progressContainer = this.modal.contentEl.createEl("div"); this.progressContainer.addClass("progress-container"); + this.progressContainer.style.padding = "0 10px"; + this.progressContainer.style.marginBottom = "8px"; [this.publishedCounter, this.publishedList] = this.createSection("Published", null, null); - [this.changedCounter, this.changedList] = this.createSection("Changed", "Update changed notes", async () => this.publishChangedNotes()); - [this.unpublishedCounter, this.unpublishedList] = this.createSection("Unpublished", "Publish unpublished notes", async () => this.publishUnpublishedNotes()); + [this.changedCounter, this.changedList] = this.createSection("Changed", "Update notes", async () => this.publishChangedNotes()); + [this.unpublishedCounter, this.unpublishedList] = this.createSection("Unpublished", "Publish notes", async () => this.publishUnpublishedNotes()); [this.deletedCounter, this.deletedList] = this.createSection("Deleted", "Delete notes from site", async () => this.unpublishNotes()); this.modal.onOpen = () => this.initView(); @@ -61,10 +116,18 @@ export default class PublishStatusModal implements IPublishStatusModal { private createSection(title: string, buttonText: string, buttonCallback: () => Promise): Array { const headerContainer = this.modal.contentEl.createEl("div"); headerContainer.addClass("header-container"); + headerContainer.style.marginBottom = "8px"; // Add smaller margin between sections const collapsableList = this.modal.contentEl.createEl("ul"); + collapsableList.style.padding = "4px 0 4px 20px"; + collapsableList.style.margin = "0"; const titleContainer = headerContainer.createEl("div"); titleContainer.addClass("title-container"); - const toggleHeader = titleContainer.createEl("h3", { text: `➕️ ${title}`, attr: { class: "collapsable collapsed" } }); + const toggleHeader = titleContainer.createEl("h3", { + text: `▶ ${title}`, + attr: { class: "collapsable collapsed" }, + cls: "small-chevron" + }); + toggleHeader.style.fontSize = "1em"; const counter = titleContainer.createEl("span"); counter.addClass("count"); @@ -83,12 +146,12 @@ export default class PublishStatusModal implements IPublishStatusModal { headerContainer.onClickEvent(() => { if (collapsableList.isShown()) { - toggleHeader.textContent = `➕️ ${title}`; + toggleHeader.textContent = `▶ ${title}`; collapsableList.hide(); toggleHeader.removeClass("open"); toggleHeader.addClass("collapsed"); } else { - toggleHeader.textContent = `➖ ${title}`; + toggleHeader.textContent = `▼ ${title}`; collapsableList.show() toggleHeader.removeClass("collapsed"); toggleHeader.addClass("open"); @@ -109,6 +172,7 @@ export default class PublishStatusModal implements IPublishStatusModal { publishedNotes.forEach(file => { const li = document.createElement('li'); li.textContent = file.path; + li.style.padding = "2px 0"; this.publishedList.appendChild(li); }); @@ -118,6 +182,7 @@ export default class PublishStatusModal implements IPublishStatusModal { unpublishedNotes.forEach(file => { const li = document.createElement('li'); li.textContent = file.path; + li.style.padding = "2px 0"; this.unpublishedList.appendChild(li); }); @@ -127,6 +192,7 @@ export default class PublishStatusModal implements IPublishStatusModal { changedNotes.forEach(file => { const li = document.createElement('li'); li.textContent = file.path; + li.style.padding = "2px 0"; this.changedList.appendChild(li); }); @@ -136,6 +202,7 @@ export default class PublishStatusModal implements IPublishStatusModal { deletedNotePaths.forEach(path => { const li = document.createElement('li'); li.textContent = path; + li.style.padding = "2px 0"; this.deletedList.appendChild(li); }); } diff --git a/src/Publisher.ts b/src/Publisher.ts index 41bad36..fcd8634 100644 --- a/src/Publisher.ts +++ b/src/Publisher.ts @@ -23,8 +23,8 @@ export default class Publisher implements IPublisher { private metadataCache: MetadataCache; private settings: FlowershowSettings; - private notesRepoPath = "content"; - private assetsRepoPath = "public"; + private notesRepoPath = ""; + private assetsRepoPath = ""; constructor(vault: Vault, metadataCache: MetadataCache, settings: FlowershowSettings) { this.vault = vault; @@ -60,7 +60,7 @@ export default class Publisher implements IPublisher { for (const file of files) { const frontMatter = this.metadataCache.getCache(file.path).frontmatter - if (!frontMatter || !frontMatter["isDraft"]) { + if (!frontMatter || frontMatter["publish"] !== false) { notesToPublish.push(file); const text = await this.vault.read(file); const images = await this.extractEmbeddedImageFiles(text, file.path); @@ -77,26 +77,21 @@ export default class Publisher implements IPublisher { private async uploadMarkdown(content: string, filePath: string) { content = Base64.encode(content); - const path = `${this.notesRepoPath}/${filePath}` - await this.uploadToGithub(path, content) + await this.uploadToGithub(filePath, content) } private async deleteMarkdown(filePath: string) { - const path = `${this.notesRepoPath}/${filePath}` - await this.deleteFromGithub(path) + await this.deleteFromGithub(filePath) } - private async uploadAssets(assets: any) { - // TODO types - // TODO can there be anything else in assets obj than assets.images? - // TODO check if assets already published? + private async uploadAssets(assets: { images: Array<{ path: string, content: string }> }) { for (let idx = 0; idx < assets.images.length; idx++) { const image = assets.images[idx]; await this.uploadImage(image.path, image.content); } } - private async deleteAssets(assets: any) { + private async deleteAssets(assets: { images: Array<{ path: string }> }) { for (let idx = 0; idx < assets.images.length; idx++) { const image = assets.images[idx]; await this.deleteImage(image.path); @@ -104,18 +99,11 @@ export default class Publisher implements IPublisher { } private async uploadImage(filePath: string, content: string) { - const publicPath = `${this.assetsRepoPath}/${filePath}` - await this.uploadToGithub(publicPath, content) - // TODO temporarily we also need to upload the image to the content folder - // so that shortened Obsidian image embeds can be resolved - // in the future, copying the image to the public folder could be done when building the site - const contentPath = `${this.notesRepoPath}/${filePath}` - await this.uploadToGithub(contentPath, content) + await this.uploadToGithub(filePath, content) } private async deleteImage(filePath: string) { - const path = `${this.assetsRepoPath}/${filePath}` - return await this.deleteFromGithub(path); + return await this.deleteFromGithub(filePath); } private async uploadToGithub(path: string, content: string) { @@ -139,9 +127,13 @@ export default class Publisher implements IPublisher { repo: this.settings.githubRepo, path }); - if (response.status === 200 && response.data.type === "file") { + + // Handle both single file and directory responses + const fileData = Array.isArray(response.data) ? null : response.data; + + if (response.status === 200 && fileData?.type === "file") { payload.message = `Update content ${path}`; - payload.sha = response.data.sha; + payload.sha = fileData.sha; } } catch { @@ -170,8 +162,11 @@ export default class Publisher implements IPublisher { path }); - if (response.status === 200 && response.data.type === "file") { - payload.sha = response.data.sha; + // Handle both single file and directory responses + const fileData = Array.isArray(response.data) ? null : response.data; + + if (response.status === 200 && fileData?.type === "file") { + payload.sha = fileData.sha; } await octokit.request('DELETE /repos/{owner}/{repo}/contents/{path}', payload); diff --git a/src/SettingView.ts b/src/SettingView.ts index c1e3528..7c8a390 100644 --- a/src/SettingView.ts +++ b/src/SettingView.ts @@ -22,12 +22,15 @@ export default class SettingView { this.settingsRootElement.createEl('h1', { text: 'Flowershow Settings' }); const linkDiv = this.settingsRootElement.createEl('div'); linkDiv.addClass("pr-link"); - linkDiv.createEl('span', { text: 'Remember to read the setup guide if you haven\'t already. It can be found ' }); - linkDiv.createEl('a', { text: 'here.', href: "https://github.com/datopian/obsidian-flowershow" }); + linkDiv.createEl('span', { text: "Sign up to " }); + linkDiv.createEl('a', { text: 'Flowershow ', href: "https://cloud.flowershow.app/" }); + linkDiv.createEl('span', { text: "and follow " }); + linkDiv.createEl('a', { text: 'the instructions ', href: "https://cloud.flowershow.app/obsidian-quickstart?ref=obsidian" }); + linkDiv.createEl('span', { text: "for publishing an Obsidian vault on Flowershow." }); - this.settingsRootElement.createEl('h3', { text: 'GitHub Authentication (required)' }).prepend(getIcon("github")); - this.initializeGitHubRepoSetting(); + this.settingsRootElement.createEl('h3', { text: 'GitHub Authentication' }).prepend(getIcon("github")); this.initializeGitHubUserNameSetting(); + this.initializeGitHubRepoSetting(); this.initializeGitHubTokenSetting(); } @@ -49,8 +52,8 @@ export default class SettingView { private initializeGitHubRepoSetting() { new Setting(this.settingsRootElement) - .setName('GitHub repo name') - .setDesc('The name of the GitHub repository') + .setName('Repository name') + .setDesc('Name of the GitHub repository linked to your Flowershow site') .addText(text => text .setPlaceholder('mygithubrepo') .setValue(this.settings.githubRepo) @@ -63,8 +66,8 @@ export default class SettingView { private initializeGitHubUserNameSetting() { new Setting(this.settingsRootElement) - .setName('GitHub Username') - .setDesc('Your GitHub Username') + .setName('Username') + .setDesc('Your GitHub username') .addText(text => text .setPlaceholder('myusername') .setValue(this.settings.githubUserName) @@ -79,7 +82,7 @@ export default class SettingView { const desc = document.createDocumentFragment(); desc.createEl("span", null, (span) => { span.innerText = - "A GitHub token with repo permissions. You can generate it "; + "GitHub personal access token with repository permissions. You can generate one "; span.createEl("a", null, (link) => { link.href = "https://github.com/settings/tokens/new?scopes=repo"; link.innerText = "here!"; @@ -87,7 +90,7 @@ export default class SettingView { }); new Setting(this.settingsRootElement) - .setName('GitHub token') + .setName('Personal Access Token') .setDesc(desc) .addText(text => text .setPlaceholder('Secret Token') diff --git a/src/SiteManager.ts b/src/SiteManager.ts index 0c7e2ca..29ebcfd 100644 --- a/src/SiteManager.ts +++ b/src/SiteManager.ts @@ -1,5 +1,5 @@ import { FlowershowSettings } from "src/FlowershowSettings"; -import { MetadataCache, TFile } from "obsidian"; +import { MetadataCache } from "obsidian"; import { Octokit } from "@octokit/core"; @@ -42,11 +42,10 @@ export default class SiteManager implements ISiteManager { const files = response.data.tree; const notes: Array<{ path: string, sha: string }> = files.filter( - (file: { path: string; type: string; }) => file.path.startsWith("content/") && file.type === "blob" && file.path !== "content/config.mjs"); + (file: { path: string; type: string; }) => file.type === "blob" && file.path.endsWith(".md")); const hashes: PathToHashDict = notes.reduce((dict: PathToHashDict, note) => { - const vaultPath = note.path.replace("content/", ""); - dict[vaultPath] = note.sha; + dict[note.path] = note.sha; return dict }, {}); @@ -65,11 +64,12 @@ export default class SiteManager implements ISiteManager { const files = response.data.tree; const images: Array<{ path: string, sha: string }> = files.filter( - (file: { path: string; type: string; }) => file.path.startsWith("public/") && file.type === "blob"); + (file: { path: string; type: string; }) => + file.type === "blob" && + /\.(png|jpg|jpeg|gif|svg|webp|bmp)$/i.test(file.path)); const hashes: PathToHashDict = images.reduce((dict: PathToHashDict, img) => { - const vaultPath = decodeURI(img.path.replace("public/", "")); // TODO why do we need to decodeURI for images? - dict[vaultPath] = img.sha; + dict[decodeURI(img.path)] = img.sha; return dict }, {}); diff --git a/src/Validator.ts b/src/Validator.ts index 02cf167..35b085d 100644 --- a/src/Validator.ts +++ b/src/Validator.ts @@ -4,8 +4,8 @@ import { FlowershowSettings } from "./FlowershowSettings"; export function validatePublishFrontmatter(frontMatter: FrontMatterCache): boolean { - if (frontMatter && frontMatter["isDraft"]) { - new Notice("Note is marked as draft. Please remove `isDraft` from the frontmatter and again.") + if (frontMatter && frontMatter["publish"] === false) { + new Notice("Note is marked as not publishable.") return false; } return true; @@ -25,4 +25,4 @@ export function validateSettings(settings: FlowershowSettings): boolean { return false; } return true; -} +} \ No newline at end of file diff --git a/src/constants.ts b/src/constants.ts index ebe3588..5c38bb4 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,4 +1,4 @@ -export const seedling = `Layer 1` +export const flowershowIcon = `` export const excaliDrawBundle = ``; -export let excalidraw = (excaliDrawJson:string , drawingId:string):string => `
`; +export const excalidraw = (excaliDrawJson:string , drawingId:string):string => `
`;