aboutsummaryrefslogtreecommitdiff
path: root/src/stores/useTabsStore.ts
diff options
context:
space:
mode:
authorzwlucas <lucas.fariamo08@gmail.com>2026-06-05 20:52:54 +0000
committerzwlucas <lucas.fariamo08@gmail.com>2026-06-05 20:52:54 +0000
commit09f964451d7d92e9891430ec4595c1276d486aab (patch)
tree28da4483f5c28924a8c47fceb648b1baebe88224 /src/stores/useTabsStore.ts
downloadyace-master.tar.gz
yace-master.zip
feat: uploadHEADmaster
Signed-off-by: zwlucas <lucas.fariamo08@gmail.com>
Diffstat (limited to 'src/stores/useTabsStore.ts')
-rw-r--r--src/stores/useTabsStore.ts152
1 files changed, 152 insertions, 0 deletions
diff --git a/src/stores/useTabsStore.ts b/src/stores/useTabsStore.ts
new file mode 100644
index 0000000..eb9a03a
--- /dev/null
+++ b/src/stores/useTabsStore.ts
@@ -0,0 +1,152 @@
+import { create } from 'zustand'
+import type { Tab } from '@/types'
+import { readFile, writeFile, saveDialog, pickFile } from '@/lib/tauri'
+import { detectLanguage } from '@/lib/languageMap'
+
+interface TabsState {
+ tabs: Tab[]
+ activeTabId: string | null
+ cursorLine: number
+ cursorCol: number
+ savingId: string | null
+ statusMessage: string | null
+ untitledCounter: number
+
+ openFile: (path: string) => Promise<void>
+ pickAndOpenFile: () => Promise<void>
+ createUntitledFile: () => void
+ closeTab: (id: string) => void
+ setActiveTab: (id: string) => void
+ updateContent: (id: string, content: string) => void
+ saveFile: (id: string) => Promise<void>
+ setCursorPosition: (line: number, col: number) => void
+ clearStatusMessage: () => void
+}
+
+function isUntitled(id: string) {
+ return id.startsWith('untitled://')
+}
+
+export const useTabsStore = create<TabsState>((set, get) => ({
+ tabs: [],
+ activeTabId: null,
+ cursorLine: 1,
+ cursorCol: 1,
+ savingId: null,
+ statusMessage: null,
+ untitledCounter: 0,
+
+ openFile: async (path: string) => {
+ const { tabs } = get()
+ const existing = tabs.find((t) => t.path === path)
+ if (existing) {
+ set({ activeTabId: existing.id })
+ return
+ }
+
+ try {
+ const content = await readFile(path)
+ const name = path.split(/[\\/]/).pop() ?? 'untitled'
+ const id = path
+ const tab: Tab = {
+ id,
+ path,
+ name,
+ language: detectLanguage(name),
+ content,
+ modified: false,
+ }
+ set({ tabs: [...tabs, tab], activeTabId: id })
+ } catch (err) {
+ console.error('Failed to open file:', err)
+ }
+ },
+
+ pickAndOpenFile: async () => {
+ const path = await pickFile()
+ if (path) get().openFile(path)
+ },
+
+ createUntitledFile: () => {
+ const { tabs, untitledCounter } = get()
+ const n = untitledCounter + 1
+ const name = `Untitled-${n}`
+ const id = `untitled://${n}`
+ const tab: Tab = {
+ id,
+ path: id,
+ name,
+ language: 'plaintext',
+ content: '',
+ modified: false,
+ }
+ set({ tabs: [...tabs, tab], activeTabId: id, untitledCounter: n })
+ },
+
+ closeTab: (id: string) => {
+ const { tabs, activeTabId } = get()
+ const newTabs = tabs.filter((t) => t.id !== id)
+ let newActive = activeTabId
+ if (activeTabId === id) {
+ const idx = tabs.findIndex((t) => t.id === id)
+ newActive = newTabs[Math.min(idx, newTabs.length - 1)]?.id ?? null
+ }
+ set({ tabs: newTabs, activeTabId: newActive })
+ },
+
+ setActiveTab: (id: string) => {
+ set({ activeTabId: id })
+ },
+
+ updateContent: (id: string, content: string) => {
+ set((state) => ({
+ tabs: state.tabs.map((t) =>
+ t.id === id ? { ...t, content, modified: true } : t
+ ),
+ }))
+ },
+
+ saveFile: async (id: string) => {
+ const { tabs } = get()
+ const tab = tabs.find((t) => t.id === id)
+ if (!tab) return
+
+ set({ savingId: id, statusMessage: null })
+
+ try {
+ let targetPath = tab.path
+
+ if (isUntitled(targetPath)) {
+ const picked = await saveDialog(tab.name)
+ if (!picked) {
+ set({ savingId: null })
+ return
+ }
+ targetPath = picked
+ }
+
+ await writeFile(targetPath, tab.content)
+ const name = targetPath.split(/[\\/]/).pop() ?? tab.name
+ set({
+ tabs: tabs.map((t) =>
+ t.id === id
+ ? { ...t, path: targetPath, name, language: detectLanguage(name), modified: false }
+ : t
+ ),
+ savingId: null,
+ statusMessage: 'Saved',
+ })
+ } catch (err) {
+ set({ savingId: null, statusMessage: 'Save failed' })
+ console.error('Failed to save file:', err)
+ }
+ },
+
+ setCursorPosition: (line: number, col: number) => {
+ set({ cursorLine: line, cursorCol: col })
+ },
+
+ clearStatusMessage: () => {
+ set({ statusMessage: null })
+ },
+}))