diff --git a/manifest.json b/manifest.json index 3217682..b67d892 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "mdfriday", "name": "Friday", - "version": "0.1.1", + "version": "0.1.2", "minAppVersion": "0.15.0", "description": "Notes to Website. Friday helps you turn Markdown documents into websites in minutes.", "author": "sunwei", diff --git a/package.json b/package.json index 34abc38..784f338 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsidian-friday-plugin", - "version": "0.1.1", + "version": "0.1.2", "description": "Friday is an Obsidian plugin that empowers users to focus on content creation by writing Markdown files, while we handle the distribution. From creating websites to content deployment, Friday serves as a creative output assistant, helping users turn their work into publishable sites with ease.", "main": "main.js", "scripts": { diff --git a/src/fileinfo.ts b/src/fileinfo.ts index 3b27b1a..5d12f2d 100644 --- a/src/fileinfo.ts +++ b/src/fileinfo.ts @@ -45,7 +45,6 @@ export class FileInfo { this.content = this.extractContentWithoutFrontmatter(fileContent, this.frontMatter); // 存储去掉 frontmatter 的内容 callback(this); // 通知外部异步操作已完成 - console.log("fileInfo updated and callback"); } else { callback(this); // 没有文件的情况,直接回调 } @@ -100,7 +99,6 @@ export class FileInfo { hasContentConfigured(): boolean { const contentPath = this.getContentFolder(); if (contentPath !== FM_CONTENT_EMPTY && contentPath !== null && this.isContentFolderExists) { - console.log("has content configured: ", contentPath); return true } return false diff --git a/src/hugoverse.ts b/src/hugoverse.ts index 2023433..2620456 100644 --- a/src/hugoverse.ts +++ b/src/hugoverse.ts @@ -39,8 +39,6 @@ export class Hugoverse { projectDirPath(filepath: string): string { const projDirPath = path.join(path.dirname(filepath), "MDFriday"); - console.log("MDFriday projectDirPath: ", projDirPath); - return projDirPath; } @@ -50,7 +48,6 @@ export class Hugoverse { if (await this.plugin.app.vault.adapter.exists(manifestPath)) { const data = await this.app.vault.adapter.read(manifestPath); this.manifestConfig = JSON.parse(data); - console.log('Manifest configuration loaded successfully.'); } } catch (error) { console.error('Failed to load manifest.json', error); @@ -190,8 +187,6 @@ export class Hugoverse { // 定义请求的URL const url = `${this.apiUrl}/api/${action}?type=Site&id=${siteId}`; - console.log(`${action} URL: `, url); - // 创建 FormData 实例并添加 siteId 字段 let body = new FormData(); body.append("site", `${siteId}`); @@ -218,10 +213,7 @@ export class Hugoverse { // 解析返回的 JSON 数据,提取 ID const responseData = JSON.parse(response.text); - const actionUrl = responseData.data[0]; - console.log(`Site ${action} generated successfully. URL:`, actionUrl); - - return actionUrl; + return responseData.data[0]; } catch (error) { console.error(`Error generating site ${action}:`, error); new Notice(`Failed to ${action} site.`, 5000); @@ -252,7 +244,6 @@ export class Hugoverse { body.append("Params", this.plugin.fileInfo.getParams()); body.append("working_dir", ""); - console.log("create site url: ", createSiteUrl); // 将 FormData 转换为 ArrayBuffer const boundary = "----WebKitFormBoundary" + Math.random().toString(36).substring(2, 9); const arrayBufferBody = await this.formDataToArrayBuffer(body, boundary); @@ -276,8 +267,6 @@ export class Hugoverse { const responseData = JSON.parse(response.text); const siteId = responseData.data[0].id; // 假设`data`数组的第一个元素包含所需的`id` - console.log("Site created successfully. Site ID:", siteId); - return siteId; } catch (error) { console.error("Failed to create site:", error.toString()); @@ -302,7 +291,6 @@ export class Hugoverse { body.append("post", `/api/content?type=Post&id=${postId}`); body.append("path", path); - console.log("create site url: ", url); // 将 FormData 转换为 ArrayBuffer const boundary = "----WebKitFormBoundary" + Math.random().toString(36).substring(2, 9); const arrayBufferBody = await this.formDataToArrayBuffer(body, boundary); @@ -324,10 +312,8 @@ export class Hugoverse { // 解析返回的 JSON 数据,提取 ID const responseData = JSON.parse(response.text); - const sitePostId = responseData.data[0].id; // 假设`data`数组的第一个元素包含所需的`id` - console.log("Site post created successfully. SitePost Id: ", sitePostId); - - return sitePostId; + // 假设`data`数组的第一个元素包含所需的`id` + return responseData.data[0].id; } catch (error) { console.error("Error creating site post:", error); new Notice("Failed to create site post.", 5000); @@ -412,7 +398,6 @@ export class Hugoverse { imageResults.forEach((result, index) => { if (result) { body.append(`assets.${index}`, result.blob, result.imagePath); - console.log("image index:", index, result.imagePath, "Size:", result.blob.size); } }); @@ -432,17 +417,13 @@ export class Hugoverse { // 检查响应状态 if (response.status !== 200) { - console.log("create post response: ", response.text, file.name); throw new Error(`Post creation failed: ${response.text}`); } // 解析返回的 JSON 数据,提取 ID const responseData = JSON.parse(response.text); - const postId = responseData.data[0].id; // 假设`data`数组的第一个元素包含所需的`id` - - console.log("Post created successfully. Post ID:", postId, file.name); - - return postId; + // 假设`data`数组的第一个元素包含所需的`id` + return responseData.data[0].id; } catch (error) { console.error("Failed to create post:", error.toString()); new Notice("Failed to create post.", 5000); diff --git a/src/main.ts b/src/main.ts index 3430d71..cbc2986 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,16 +1,16 @@ -import {App, Notice, Plugin, TFile, TFolder, PluginSettingTab, Setting, FileSystemAdapter} from 'obsidian'; -import { getDefaultFrontMatter } from './frontmatter'; -import ServerView, { FRIDAY_SERVER_VIEW_TYPE } from './server'; +import {App, Notice, Plugin, PluginSettingTab, Setting, TFile, TFolder} from 'obsidian'; +import {getDefaultFrontMatter} from './frontmatter'; +import ServerView, {FRIDAY_SERVER_VIEW_TYPE} from './server'; import {User} from "./user"; import {Hugoverse} from "./hugoverse"; import {FileInfo} from "./fileinfo"; -interface MyPluginSettings { - mySetting: string; +interface FridaySettings { + netlifyToken: string; } -const DEFAULT_SETTINGS: MyPluginSettings = { - mySetting: 'default' +const DEFAULT_SETTINGS: FridaySettings = { + netlifyToken: '' } export const FRIDAY_ICON = 'dice-5'; @@ -18,7 +18,7 @@ export const API_URL_DEV = 'http://127.0.0.1:1314'; export const API_URL_PRO = 'https://mdfriday.sunwei.xyz'; export default class FridayPlugin extends Plugin { - settings: MyPluginSettings; + settings: FridaySettings; statusBar: HTMLElement fileInfo: FileInfo; @@ -37,7 +37,7 @@ export default class FridayPlugin extends Plugin { this.statusBar = this.addStatusBarItem(); - this.addSettingTab(new SampleSettingTab(this.app, this)); + this.addSettingTab(new FridaySettingTab(this.app, this)); this.registerView(FRIDAY_SERVER_VIEW_TYPE, leaf => new ServerView(leaf, this)) if (this.app.workspace.layoutReady) this.initLeaf() @@ -45,8 +45,6 @@ export default class FridayPlugin extends Plugin { } async initFriday(): Promise { - console.log("Init Friday...") - this.fileInfo = new FileInfo() this.apiUrl = process.env.NODE_ENV === 'production' ? API_URL_PRO : API_URL_DEV; this.user = new User(this); @@ -82,10 +80,7 @@ export default class FridayPlugin extends Plugin { : this.app.fileManager.getNewFileParent(this.app.workspace.getActiveFile()?.path || ''); try { - const fNote: TFile = await (this.app.fileManager as any).createNewMarkdownFile( - targetFolder, - 'Untitled Friday Site' - ); + const fNote: TFile = await this.createUniqueMarkdownFile(targetFolder.path, 'Untitled Friday Site'); await this.app.vault.modify(fNote, getDefaultFrontMatter()); await this.app.workspace.getLeaf().openFile(fNote); @@ -95,18 +90,37 @@ export default class FridayPlugin extends Plugin { } } - async status(text: string) { - this.statusBar.setText(text) + async createUniqueMarkdownFile(targetFolder: string, baseFileName: string): Promise { + let fileIndex = 0; + let newFile: TFile | null = null; + + while (!newFile) { + // 动态生成文件名:如 Untitled Friday Site, Untitled Friday Site 1, Untitled Friday Site 2 + const fileName = fileIndex === 0 ? `${baseFileName}.md` : `${baseFileName} ${fileIndex}.md`; + const filePath = `${targetFolder}/${fileName}`; + + try { + // 尝试创建文件 + newFile = await this.app.vault.create(filePath, ''); // 创建空文件 + } catch (error) { + // 如果文件已存在,则递增 fileIndex 并重试 + if (error.message.includes("File already exists")) { + fileIndex++; + } else { + throw error; // 其他错误直接抛出 + } + } + } + + return newFile; } - async loadUser() { - const response = await fetch('https://api.github.com/users/mdfriday'); - const data = await response.json(); - return data + async status(text: string) { + this.statusBar.setText(text) } } -class SampleSettingTab extends PluginSettingTab { +class FridaySettingTab extends PluginSettingTab { plugin: FridayPlugin; constructor(app: App, plugin: FridayPlugin) { @@ -120,13 +134,13 @@ class SampleSettingTab extends PluginSettingTab { containerEl.empty(); new Setting(containerEl) - .setName('Setting #1') - .setDesc('It\'s a secret') + .setName('Netlify Token') + .setDesc('Deploy to your own account') .addText(text => text - .setPlaceholder('Enter your secret') - .setValue(this.plugin.settings.mySetting) + .setPlaceholder('Enter your netlify token') + .setValue(this.plugin.settings.netlifyToken) .onChange(async (value) => { - this.plugin.settings.mySetting = value; + this.plugin.settings.netlifyToken = value; await this.plugin.saveSettings(); })); } diff --git a/src/preview.ts b/src/preview.ts index fe6a79b..cdf4fd0 100644 --- a/src/preview.ts +++ b/src/preview.ts @@ -1,4 +1,4 @@ -import { Modal, App } from 'obsidian'; +import {Modal, App} from 'obsidian'; export class WebPreviewModal extends Modal { private readonly url: string; @@ -9,34 +9,23 @@ export class WebPreviewModal extends Modal { } onOpen() { - const { contentEl, modalEl } = this; + const {contentEl, modalEl} = this; - // 设置 Modal 的宽度和高度 - modalEl.style.width = '900px'; - modalEl.style.height = `${window.innerHeight * 0.9}px`; // 设置 Modal 高度为屏幕的 90% + // Apply CSS class to modal + modalEl.classList.add('my-modal'); - // 创建 iframe 元素 + // Create and style the iframe with a CSS class const iframe = document.createElement('iframe'); - iframe.src = this.url; // 设置 iframe 的链接 + iframe.src = this.url; + iframe.classList.add('my-iframe'); - // 设置 iframe 的样式 - iframe.style.width = '100%'; // 让 iframe 填满 Modal 的宽度 - iframe.style.height = '100%'; // 让 iframe 填满 Modal 的高度 - iframe.style.border = 'none'; // 去除边框 - iframe.style.backgroundColor = 'white'; // 设置背景色为白色 - - // 将 iframe 插入到 modal 内容中 + // Insert the iframe into the modal content contentEl.appendChild(iframe); - - // 动态调整 iframe 的高度 - window.addEventListener('resize', () => { - modalEl.style.height = `${window.innerHeight * 0.9}px`; // 监听窗口调整事件,动态调整 Modal 高度 - iframe.style.height = `${window.innerHeight * 0.9}px`; // 同时调整 iframe 的高度 - }); } + onClose() { - const { contentEl } = this; + const {contentEl} = this; contentEl.empty(); // 关闭时清空内容 } } diff --git a/src/server.ts b/src/server.ts index 56f092b..5593b06 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,4 +1,4 @@ -import {ItemView, WorkspaceLeaf} from 'obsidian'; +import {ItemView, WorkspaceLeaf, TFile} from 'obsidian'; import FridayPlugin, {FRIDAY_ICON} from "./main"; import Server from './svelte/Server.svelte'; import {FileInfo} from "./fileinfo"; @@ -46,7 +46,7 @@ export default class ServerView extends ItemView { async onOpen(): Promise { await this.updateFileInfo(); // 初始化时获取 fileInfo this._app = new Server({ - target: (this as any).contentEl, + target: this.contentEl, props: { fileInfo: this.plugin.fileInfo, app: this.app, @@ -61,7 +61,6 @@ export default class ServerView extends ItemView { await fileInfo.updateFileInfo(this.app, (updatedFileInfo) => { this.plugin.fileInfo = updatedFileInfo; // 更新 fileInfo if (this._app) { - // 重新设置 Svelte 组件的 props this._app.$set({ fileInfo: this.plugin.fileInfo }); } }); diff --git a/src/svelte/Service.svelte b/src/svelte/Service.svelte index fa1c1fe..b1353ab 100644 --- a/src/svelte/Service.svelte +++ b/src/svelte/Service.svelte @@ -54,19 +54,20 @@ const downloadFile = async () => { await refreshDownloadStatus() + if (!displayDownload){ + return + } + if (themeZipFileExists) { downloadProgress = 100; await extractFile(themePath, themeProjPath); await fileInfo.updateFrontMatter(FM_CONTENT, themeContentPath); - displayDownload = false; return } isDownloading = true; downloadProgress = 0; - console.log("Downloading from:", themeDownloadUrl); - // 每个块的大小(以字节为单位) const chunkSize = 1024 * 1024; // 1MB let receivedLength = 0; // 已接收的字节数 @@ -108,20 +109,16 @@ // 更新下载进度 downloadProgress = Math.floor((receivedLength / contentLength) * 100); - console.log(`Downloaded ${downloadProgress}%`); } // 将文件写入到 Obsidian 插件目录中 await this.app.vault.adapter.writeBinary(themePath, fileContent); // 写入完整文件 - console.log(`File downloaded to: ${themePath}`); isDownloading = false; await extractFile(themePath, themeProjPath); await fileInfo.updateFrontMatter(FM_CONTENT, themeContentPath); - displayDownload = false; } catch (error) { - console.error('Download error:', error); isDownloading = false; } }; @@ -151,7 +148,6 @@ // Write the extracted file to the specified output directory await app.vault.adapter.writeBinary(outputFilePath, content); - console.log(`Extracted file: ${outputFilePath}`); } } } catch (error) { @@ -190,7 +186,6 @@
{#if Platform.isDesktop} {#if themeDownloadFilename !== '' && fileInfo.hasFridayPluginEnabled()} - {#if displayDownload}
Content structure example provided for theme: {fileInfo.getThemeName()}
@@ -202,7 +197,6 @@ {/if}
- {/if} {/if} {/if}
diff --git a/src/user.ts b/src/user.ts index 5236e71..c6fe399 100644 --- a/src/user.ts +++ b/src/user.ts @@ -79,7 +79,6 @@ export class User { this.token = data.token; } catch (error) { console.error("Failed to load user data:", error); - // 可以选择在此处处理文件未找到的情况 } } diff --git a/styles.css b/styles.css index 71cc60f..1a7cafb 100644 --- a/styles.css +++ b/styles.css @@ -1,8 +1,19 @@ -/* +/* styles.css */ +.my-modal { + width: 80vw; + height: 100vh; + max-height: 100%; + overflow: hidden; /* 避免 iframe 超出 modal */ + background-color: white; + position: fixed; + top: 0; + left: 10vw; + box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2); +} -This CSS file will be included with your plugin, and -available in the app when your plugin is enabled. - -If your plugin does not need CSS, delete this file. - -*/ +.my-iframe { + width: 100%; + height: 100%; + border: none; + background-color: white; +} diff --git a/versions.json b/versions.json index 2ce835e..ff0516b 100644 --- a/versions.json +++ b/versions.json @@ -1,3 +1,4 @@ { - "0.1.1": "0.15.0" + "0.1.1": "0.15.0", + "0.1.2": "0.15.0" } \ No newline at end of file