diff --git a/electron/main.js b/electron/main.js index d37065d..aed9986 100644 --- a/electron/main.js +++ b/electron/main.js @@ -85,6 +85,28 @@ ipcMain.handle('dialog:saveFile', async (_event, options) => { return null }) +ipcMain.handle('dialog:showMessage', async (_event, options) => { + const result = await dialog.showMessageBox(mainWindow, { + type: options?.type || 'info', + buttons: options?.buttons || ['确定'], + title: options?.title || 'Web2App', + message: options?.message || '' + }) + return result.response +}) + +ipcMain.handle('dialog:showConfirm', async (_event, options) => { + const result = await dialog.showMessageBox(mainWindow, { + type: 'question', + buttons: ['取消', '确定'], + defaultId: 1, + cancelId: 0, + title: options?.title || 'Web2App', + message: options?.message || '确认?' + }) + return result.response === 1 +}) + ipcMain.handle('dir:readTree', async (_event, dirPath) => { return readDirectoryTree(dirPath) }) diff --git a/electron/preload.js b/electron/preload.js index d4414b3..8d623f6 100644 --- a/electron/preload.js +++ b/electron/preload.js @@ -5,7 +5,9 @@ contextBridge.exposeInMainWorld('api', { selectDirectory: () => ipcRenderer.invoke('dialog:selectDirectory'), selectFile: (options) => ipcRenderer.invoke('dialog:selectFile', options), selectIcon: () => ipcRenderer.invoke('dialog:selectIcon'), - saveFile: (options) => ipcRenderer.invoke('dialog:saveFile', options) + saveFile: (options) => ipcRenderer.invoke('dialog:saveFile', options), + showMessage: (options) => ipcRenderer.invoke('dialog:showMessage', options), + showConfirm: (options) => ipcRenderer.invoke('dialog:showConfirm', options) }, dir: { readTree: (dirPath) => ipcRenderer.invoke('dir:readTree', dirPath) diff --git a/package.json b/package.json index 0b0719a..4e5ca97 100644 --- a/package.json +++ b/package.json @@ -2,12 +2,19 @@ "name": "web2app", "version": "1.0.0", "description": "将网站转化为独立运行的桌面应用", + "homepage": "https://github.com/web2app/web2app", + "author": { + "name": "Web2App Team", + "email": "team@web2app.dev" + }, "main": "electron/main.js", "scripts": { "dev": "vite", "build": "vite build", "electron:dev": "concurrently \"vite\" \"wait-on http://localhost:5173 && electron .\"", "electron:build": "vite build && electron-builder --config", + "electron:build:linux": "vite build && electron-builder --config --linux", + "electron:build:deb": "vite build && electron-builder --config --linux deb", "preview": "vite preview" }, "build": { @@ -55,7 +62,8 @@ } ], "icon": null, - "category": "Utility" + "category": "Utility", + "maintainer": "Web2App Team " } }, "dependencies": { diff --git a/site/index.html b/site/index.html index db10f07..5f1fb85 100644 --- a/site/index.html +++ b/site/index.html @@ -344,23 +344,25 @@
🪟

Windows

v1.0.0 · x64

- + - 下载便携版 + 下载安装包 -
可执行安装包请通过 npm run electron:build 构建
+
Windows 7+ / x64 · 含安装向导
🍎

macOS

v1.0.0 · Intel / Apple Silicon

即将发布 +
可通过源码自行构建
🐧

Linux

-

v1.0.0 · .AppImage

+

v1.0.0 · .AppImage / .deb

即将发布 +
可通过源码自行构建
@@ -409,7 +411,7 @@ diff --git a/src/components/InputDialog.vue b/src/components/InputDialog.vue new file mode 100644 index 0000000..3636c89 --- /dev/null +++ b/src/components/InputDialog.vue @@ -0,0 +1,100 @@ + + + + + diff --git a/src/views/Home.vue b/src/views/Home.vue index ace07a0..e763d99 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -42,6 +42,15 @@ + + @@ -49,25 +58,40 @@ import { ref } from 'vue' import { useRouter } from 'vue-router' import { useProjectStore } from '../stores/project' +import InputDialog from '../components/InputDialog.vue' const router = useRouter() const store = useProjectStore() const recentProjects = ref(loadRecentProjects()) +const showInput = ref(false) +const pendingDir = ref('') async function createNewProject() { const dir = await window.api.dialog.selectDirectory() if (!dir) return - const name = prompt('请输入项目名称:') - if (!name) return + pendingDir.value = dir + showInput.value = true +} + +async function onNameConfirmed(name) { + showInput.value = false try { - await store.createProject(name, dir) - addRecentProject(dir, name) + await store.createProject(name, pendingDir.value) + addRecentProject(pendingDir.value, name) router.push('/editor') } catch (err) { - alert('创建失败: ' + err.message) + await window.api.dialog.showMessage({ + type: 'error', + title: '创建失败', + message: err.message + }) } } +function onNameCancelled() { + showInput.value = false +} + async function openExistingProject() { const dir = await window.api.dialog.selectDirectory() if (!dir) return @@ -80,7 +104,11 @@ async function openProject(dir) { addRecentProject(dir, store.config.name) router.push('/editor') } catch (err) { - alert('打开失败: ' + err.message) + await window.api.dialog.showMessage({ + type: 'error', + title: '打开失败', + message: err.message + }) } } diff --git a/src/views/ProjectEditor.vue b/src/views/ProjectEditor.vue index 32002b4..b786a43 100644 --- a/src/views/ProjectEditor.vue +++ b/src/views/ProjectEditor.vue @@ -74,7 +74,11 @@ async function importFromFiles() { } async function handleDelete(relativePath) { - if (confirm(`确定删除 "${relativePath}"?`)) { + const ok = await window.api.dialog.showConfirm({ + title: '删除确认', + message: `确定要删除 "${relativePath}" 吗?` + }) + if (ok) { await store.removeFile(relativePath) } }