Skip to content

Commit e8ce4bd

Browse files
xiaojunjunxiaojunjun
authored andcommitted
Fix web version compatibility - remove Tauri dependencies for web environment
1 parent ddcbfd8 commit e8ce4bd

File tree

7 files changed

+164
-35
lines changed

7 files changed

+164
-35
lines changed

src/App.vue

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ const isSettingsOpen = ref(false);
1212
const settingsStore = useSettingsStore();
1313
const tabsStore = useTabsStore();
1414
15+
// Check if we're running in a web environment
16+
const isWeb = typeof window !== 'undefined' && !window.__TAURI__;
17+
1518
// Watch for theme changes and apply them to the body element
1619
watchEffect(() => {
1720
document.body.dataset.theme = settingsStore.theme;
@@ -21,11 +24,13 @@ watchEffect(() => {
2124
onMounted(() => {
2225
tabsStore.setup_menu_listeners();
2326
24-
// Listen for menu events from native menu and system tray
25-
listen("menu-event", (event) => {
26-
const menuId = event.payload as string;
27-
handleMenuEvent(menuId);
28-
});
27+
// Listen for menu events from native menu and system tray (Tauri only)
28+
if (!isWeb) {
29+
listen("menu-event", (event) => {
30+
const menuId = event.payload as string;
31+
handleMenuEvent(menuId);
32+
});
33+
}
2934
});
3035
3136
const handleMenuEvent = (menuId: string) => {

src/components/EditorArea.vue

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ const editorRef = ref<HTMLTextAreaElement | null>(null);
1818
const lineNumbersRef = ref<HTMLDivElement | null>(null);
1919
let unlisten: UnlistenFn | null = null;
2020
21+
// Check if we're running in a web environment
22+
const isWeb = typeof window !== 'undefined' && !window.__TAURI__;
23+
2124
const activeTab = computed(() => tabsStore.activeTab);
2225
2326
const lineCount = computed(() => {
@@ -40,12 +43,14 @@ const syncScroll = () => {
4043
};
4144
4245
onMounted(async () => {
43-
// Listen for the custom file drop event from the Rust backend
44-
unlisten = await listen<string[]>("custom-file-drop", (event) => {
45-
for (const filePath of event.payload) {
46-
tabsStore.openSpecificFile(filePath);
47-
}
48-
});
46+
// Listen for the custom file drop event from the Rust backend (Tauri only)
47+
if (!isWeb) {
48+
unlisten = await listen<string[]>("custom-file-drop", (event) => {
49+
for (const filePath of event.payload) {
50+
tabsStore.openSpecificFile(filePath);
51+
}
52+
});
53+
}
4954
});
5055
5156
onBeforeUnmount(() => {

src/components/SettingsModal.vue

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import { invoke } from "@tauri-apps/api/tauri";
77
const { t, i18next } = useTranslation();
88
const settingsStore = useSettingsStore();
99
10+
// Check if we're running in a web environment
11+
const isWeb = typeof window !== 'undefined' && !window.__TAURI__;
12+
1013
// Local state for form values
1114
const localTheme = ref<Theme>("light");
1215
const localLanguage = ref("en");
@@ -67,7 +70,11 @@ const saveSettings = async () => {
6770
settingsStore.newNoteShortcut = getShortcutString(localShortcutKeys.value);
6871
settingsStore.closeTabShortcut = getShortcutString(localCloseTabShortcutKeys.value);
6972
settingsStore.toggleWindowShortcut = getShortcutString(localToggleWindowShortcutKeys.value);
70-
await settingsStore.save_all_settings();
73+
74+
if (!isWeb) {
75+
await settingsStore.save_all_settings();
76+
}
77+
7178
if (localLanguage.value !== i18next.language) {
7279
i18next.changeLanguage(localLanguage.value);
7380
}
@@ -80,7 +87,19 @@ const saveSettings = async () => {
8087
8188
const resetToDefaults = async () => {
8289
try {
83-
await settingsStore.reset_settings();
90+
if (!isWeb) {
91+
await settingsStore.reset_settings();
92+
} else {
93+
// In web environment, just reset the local state
94+
settingsStore.theme = "light";
95+
settingsStore.language = "en";
96+
settingsStore.defaultFormat = "txt";
97+
settingsStore.defaultPath = null;
98+
settingsStore.newNoteShortcut = "CmdOrCtrl+Option+T";
99+
settingsStore.closeTabShortcut = "CmdOrCtrl+Option+Y";
100+
settingsStore.toggleWindowShortcut = "CmdOrCtrl+Option+U";
101+
}
102+
84103
localTheme.value = settingsStore.theme;
85104
localLanguage.value = settingsStore.language;
86105
localDefaultFormat.value = settingsStore.defaultFormat;
@@ -99,6 +118,12 @@ const resetToDefaults = async () => {
99118
};
100119
101120
const browsePath = async () => {
121+
if (isWeb) {
122+
// In web environment, show a message that file operations are not available
123+
alert("File operations are not available in the web version. Please download the desktop app for full functionality.");
124+
return;
125+
}
126+
102127
try {
103128
const selectedPath = await invoke<string | null>("select_directory");
104129
if (selectedPath) {

src/components/TabBar.vue

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import { appWindow } from "@tauri-apps/api/window";
66
77
// Import Vue and utility functions
88
9+
// Check if we're running in a web environment
10+
const isWeb = typeof window !== 'undefined' && !window.__TAURI__;
11+
912
// Store reference to the tabs state
1013
const tabsStore = useTabsStore();
1114
const tabsContainer = ref<HTMLDivElement | null>(null);
@@ -44,7 +47,14 @@ const trafficLightSvg = (
4447
};
4548
4649
// Only close (red) button has click handler; minimize and maximize are UI only
47-
const handleClose = () => appWindow.hide();
50+
const handleClose = () => {
51+
if (!isWeb) {
52+
appWindow.hide();
53+
} else {
54+
// In web environment, show a message
55+
alert("This is a web demo. Please download the desktop app for full functionality.");
56+
}
57+
};
4858
4959
// Emit events for parent communication
5060
const emit = defineEmits<{

src/main.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@ async function main() {
1212
app.use(pinia);
1313
app.use(I18nextVue, { i18next });
1414

15-
// Initialize settings from the backend before mounting the app
16-
const settingsStore = useSettingsStore();
17-
await settingsStore.initialize_settings();
15+
// Check if we're running in a web environment
16+
const isWeb = typeof window !== 'undefined' && !window.__TAURI__;
17+
18+
if (!isWeb) {
19+
// Initialize settings from the backend before mounting the app (Tauri only)
20+
const settingsStore = useSettingsStore();
21+
await settingsStore.initialize_settings();
22+
}
1823

1924
app.mount("#app");
2025
}

src/stores/settings.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export interface SettingsState {
1414
loadError: boolean;
1515
}
1616

17+
// Check if we're running in a web environment
18+
const isWeb = typeof window !== 'undefined' && !window.__TAURI__;
19+
1720
export const useSettingsStore = defineStore("settings", {
1821
state: (): SettingsState => ({
1922
theme: "light",
@@ -31,6 +34,12 @@ export const useSettingsStore = defineStore("settings", {
3134
* Loads settings from the backend and initializes the store.
3235
*/
3336
async initialize_settings() {
37+
// Skip Tauri API calls in web environment
38+
if (isWeb) {
39+
console.log("Running in web environment, using default settings");
40+
return;
41+
}
42+
3443
try {
3544
const settings = await invoke<{
3645
theme: string;
@@ -68,6 +77,12 @@ export const useSettingsStore = defineStore("settings", {
6877
theme: Theme,
6978
) {
7079
this.theme = theme;
80+
81+
// Skip Tauri API calls in web environment
82+
if (isWeb) {
83+
return;
84+
}
85+
7186
try {
7287
await invoke("save_settings", {
7388
settings: {
@@ -89,6 +104,11 @@ export const useSettingsStore = defineStore("settings", {
89104
* Saves all settings to the backend.
90105
*/
91106
async save_all_settings() {
107+
// Skip Tauri API calls in web environment
108+
if (isWeb) {
109+
return;
110+
}
111+
92112
try {
93113
await invoke("save_settings", {
94114
settings: {
@@ -130,7 +150,9 @@ export const useSettingsStore = defineStore("settings", {
130150
this.closeTabShortcut = "CmdOrCtrl+Option+Y";
131151
this.toggleWindowShortcut = "CmdOrCtrl+Option+U";
132152

133-
await this.save_all_settings();
153+
if (!isWeb) {
154+
await this.save_all_settings();
155+
}
134156
},
135157
},
136158
});

src/stores/tabs.ts

Lines changed: 74 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ function extractFileName(path: string): string {
5555
return path.split(/[\\/]/).pop() || path;
5656
}
5757

58+
// Check if we're running in a web environment
59+
const isWeb = typeof window !== 'undefined' && !window.__TAURI__;
60+
5861
export const useTabsStore = defineStore("tabs", {
5962
state: () => {
6063
const firstTabId = generateId();
@@ -99,9 +102,11 @@ export const useTabsStore = defineStore("tabs", {
99102
this.tabs.push(newTab);
100103
this.activeTabId = newTab.id;
101104

102-
// Show and focus window when a new tab is created
103-
await appWindow.show();
104-
await appWindow.setFocus();
105+
// Show and focus window when a new tab is created (Tauri only)
106+
if (!isWeb) {
107+
await appWindow.show();
108+
await appWindow.setFocus();
109+
}
105110
},
106111

107112
/**
@@ -116,18 +121,30 @@ export const useTabsStore = defineStore("tabs", {
116121

117122
// If tab has unsaved changes, ask user before closing
118123
if (tabToClose.isUnsaved) {
119-
const result = await ask(`"${tabToClose.name}" has unsaved changes.`, {
120-
title: "Unsaved Changes",
121-
type: "warning",
122-
okLabel: "Save",
123-
cancelLabel: "Don't Save", // This will return `false`
124-
});
125-
126-
if (result) {
127-
// User clicked "Save", result is true
128-
const savedSuccessfully = await this.saveActiveFile();
129-
if (!savedSuccessfully) {
130-
return; // User cancelled the save dialog, so we abort closing the tab
124+
if (isWeb) {
125+
// In web environment, use browser confirm dialog
126+
const result = confirm(`"${tabToClose.name}" has unsaved changes. Do you want to save?`);
127+
if (result) {
128+
const savedSuccessfully = await this.saveActiveFile();
129+
if (!savedSuccessfully) {
130+
return; // User cancelled the save dialog, so we abort closing the tab
131+
}
132+
}
133+
} else {
134+
// In Tauri environment, use native dialog
135+
const result = await ask(`"${tabToClose.name}" has unsaved changes.`, {
136+
title: "Unsaved Changes",
137+
type: "warning",
138+
okLabel: "Save",
139+
cancelLabel: "Don't Save", // This will return `false`
140+
});
141+
142+
if (result) {
143+
// User clicked "Save", result is true
144+
const savedSuccessfully = await this.saveActiveFile();
145+
if (!savedSuccessfully) {
146+
return; // User cancelled the save dialog, so we abort closing the tab
147+
}
131148
}
132149
}
133150
// If user clicked "Don't Save" (result is false), we just proceed to close.
@@ -166,8 +183,8 @@ export const useTabsStore = defineStore("tabs", {
166183
}
167184
}
168185

169-
// Hide window if no tabs left
170-
if (this.tabs.length === 0) {
186+
// Hide window if no tabs left (Tauri only)
187+
if (!isWeb && this.tabs.length === 0) {
171188
appWindow.hide();
172189
}
173190
},
@@ -201,6 +218,12 @@ export const useTabsStore = defineStore("tabs", {
201218

202219
// === File operations using backend commands ===
203220
async openFileFromDialog() {
221+
if (isWeb) {
222+
// In web environment, show a message that file operations are not available
223+
alert("File operations are not available in the web version. Please download the desktop app for full functionality.");
224+
return;
225+
}
226+
204227
try {
205228
const results = await invoke<Array<{
206229
path: string;
@@ -232,6 +255,12 @@ export const useTabsStore = defineStore("tabs", {
232255
},
233256

234257
async openSpecificFile(path: string) {
258+
if (isWeb) {
259+
// In web environment, show a message that file operations are not available
260+
alert("File operations are not available in the web version. Please download the desktop app for full functionality.");
261+
return;
262+
}
263+
235264
try {
236265
// 如果已經有這個檔案的分頁,直接切換
237266
const existingTab = this.tabs.find((tab) => tab.path === path);
@@ -275,6 +304,12 @@ export const useTabsStore = defineStore("tabs", {
275304
return this.saveActiveFileAs();
276305
}
277306

307+
if (isWeb) {
308+
// In web environment, just mark as saved
309+
activeTab.isUnsaved = false;
310+
return true;
311+
}
312+
278313
try {
279314
await invoke("save_file", {
280315
path: activeTab.path,
@@ -293,6 +328,23 @@ export const useTabsStore = defineStore("tabs", {
293328
const activeTab = this.tabs.find((tab) => tab.id === this.activeTabId);
294329
if (!activeTab) return false;
295330

331+
if (isWeb) {
332+
// In web environment, create a download link
333+
const blob = new Blob([activeTab.content], { type: 'text/plain' });
334+
const url = URL.createObjectURL(blob);
335+
const a = document.createElement('a');
336+
a.href = url;
337+
a.download = activeTab.name || 'untitled.txt';
338+
document.body.appendChild(a);
339+
a.click();
340+
document.body.removeChild(a);
341+
URL.revokeObjectURL(url);
342+
343+
// Mark as saved
344+
activeTab.isUnsaved = false;
345+
return true;
346+
}
347+
296348
const settingsStore = useSettingsStore();
297349

298350
try {
@@ -316,6 +368,11 @@ export const useTabsStore = defineStore("tabs", {
316368

317369
// === Menu event listeners ===
318370
setup_menu_listeners() {
371+
if (isWeb) {
372+
// Skip menu listeners in web environment
373+
return;
374+
}
375+
319376
// Listen for shortcut-new-note event from backend
320377
listen("shortcut-new-note", () => {
321378
this.createTab();

0 commit comments

Comments
 (0)