add desktop

This commit is contained in:
2025-10-16 20:56:21 +02:00
parent 033c9135c6
commit a291619f63
27 changed files with 1755 additions and 124 deletions

170
src/stores/vault/desktop.ts Normal file
View File

@ -0,0 +1,170 @@
import { eq } from 'drizzle-orm'
import { haexDesktopItems } from '~~/src-tauri/database/schemas'
import type {
InsertHaexDesktopItems,
SelectHaexDesktopItems,
} from '~~/src-tauri/database/schemas'
export type DesktopItemType = 'extension' | 'file' | 'folder'
export interface IDesktopItem extends SelectHaexDesktopItems {
label?: string
icon?: string
}
export const useDesktopStore = defineStore('desktopStore', () => {
const { currentVault } = storeToRefs(useVaultStore())
const desktopItems = ref<IDesktopItem[]>([])
const loadDesktopItemsAsync = async () => {
if (!currentVault.value?.drizzle) {
console.error('Kein Vault geöffnet')
return
}
try {
const items = await currentVault.value.drizzle
.select()
.from(haexDesktopItems)
desktopItems.value = items
} catch (error) {
console.error('Fehler beim Laden der Desktop-Items:', error)
throw error
}
}
const addDesktopItemAsync = async (
itemType: DesktopItemType,
referenceId: string,
positionX: number = 0,
positionY: number = 0,
) => {
if (!currentVault.value?.drizzle) {
throw new Error('Kein Vault geöffnet')
}
try {
const newItem: InsertHaexDesktopItems = {
itemType: itemType,
referenceId: referenceId,
positionX: positionX,
positionY: positionY,
}
const result = await currentVault.value.drizzle
.insert(haexDesktopItems)
.values(newItem)
.returning()
if (result.length > 0 && result[0]) {
desktopItems.value.push(result[0])
return result[0]
}
} catch (error) {
console.error('Fehler beim Hinzufügen des Desktop-Items:', error)
throw error
}
}
const updateDesktopItemPositionAsync = async (
id: string,
positionX: number,
positionY: number,
) => {
if (!currentVault.value?.drizzle) {
throw new Error('Kein Vault geöffnet')
}
try {
const result = await currentVault.value.drizzle
.update(haexDesktopItems)
.set({
positionX: positionX,
positionY: positionY,
})
.where(eq(haexDesktopItems.id, id))
.returning()
if (result.length > 0 && result[0]) {
const index = desktopItems.value.findIndex((item) => item.id === id)
if (index !== -1) {
desktopItems.value[index] = result[0]
}
}
} catch (error) {
console.error('Fehler beim Aktualisieren der Position:', error)
throw error
}
}
const removeDesktopItemAsync = async (id: string) => {
if (!currentVault.value?.drizzle) {
throw new Error('Kein Vault geöffnet')
}
try {
// Soft delete using haexTombstone
await currentVault.value.drizzle
.delete(haexDesktopItems)
.where(eq(haexDesktopItems.id, id))
desktopItems.value = desktopItems.value.filter((item) => item.id !== id)
} catch (error) {
console.error('Fehler beim Entfernen des Desktop-Items:', error)
throw error
}
}
const getDesktopItemByReference = (
itemType: DesktopItemType,
referenceId: string,
) => {
return desktopItems.value.find(
(item) => item.itemType === itemType && item.referenceId === referenceId,
)
}
const getContextMenuItems = (
id: string,
itemType: DesktopItemType,
referenceId: string,
onOpen: () => void,
onUninstall: () => void,
) => {
return [
[
{
label: 'Öffnen',
icon: 'i-heroicons-arrow-top-right-on-square',
click: onOpen,
},
],
[
{
label: 'Von Desktop entfernen',
icon: 'i-heroicons-x-mark',
click: async () => {
await removeDesktopItemAsync(id)
},
},
{
label: 'Deinstallieren',
icon: 'i-heroicons-trash',
click: onUninstall,
},
],
]
}
return {
desktopItems,
loadDesktopItemsAsync,
addDesktopItemAsync,
updateDesktopItemPositionAsync,
removeDesktopItemAsync,
getDesktopItemByReference,
getContextMenuItems,
}
})

View File

@ -51,11 +51,12 @@ export const useDeviceStore = defineStore('vaultInstanceStore', () => {
const readDeviceNameAsync = async (id?: string) => {
const { readDeviceNameAsync } = useVaultSettingsStore()
const _id = id ?? deviceId.value
const _id = id || deviceId.value
console.log('readDeviceNameAsync id', _id)
if (!_id) return
deviceName.value = (await readDeviceNameAsync(_id))?.value ?? ''
return deviceName.value
}

View File

@ -3,7 +3,10 @@
import { drizzle } from 'drizzle-orm/sqlite-proxy'
import { invoke } from '@tauri-apps/api/core'
import { schema } from '@/../src-tauri/database/index'
import type { SqliteRemoteDatabase } from 'drizzle-orm/sqlite-proxy'
import type {
AsyncRemoteCallback,
SqliteRemoteDatabase,
} from 'drizzle-orm/sqlite-proxy'
interface IVault {
name: string
@ -55,40 +58,10 @@ export const useVaultStore = defineStore('vaultStore', () => {
...openVaults.value,
[vaultId]: {
name: fileName,
drizzle: drizzle<typeof schema>(
async (sql, params: unknown[], method) => {
let rows: any[] = []
let results: any[] = []
// If the query is a SELECT, use the select method
if (isSelectQuery(sql)) {
console.log('sql_select', sql, params, method)
rows = await invoke<unknown[]>('sql_select', {
sql,
params,
}).catch((e) => {
console.error('SQL select Error:', e, sql, params)
return []
})
} else {
console.log('sql_execute', sql, params, method)
// Otherwise, use the execute method
rows = await invoke<unknown[]>('sql_execute', {
sql,
params,
}).catch((e) => {
console.error('SQL execute Error:', e, sql, params)
return []
})
return { rows: [] }
}
results = method === 'all' ? rows : rows[0]
return { rows: results }
},
{ schema: schema, logger: true },
),
drizzle: drizzle<typeof schema>(drizzleCallback, {
schema: schema,
logger: false,
}),
},
}
@ -141,7 +114,34 @@ const getVaultIdAsync = async (path: string) => {
}
const isSelectQuery = (sql: string) => {
console.log('check isSelectQuery', sql)
const selectRegex = /^\s*SELECT\b/i
return selectRegex.test(sql)
}
const drizzleCallback = (async (
sql: string,
params: unknown[],
method: 'get' | 'run' | 'all' | 'values',
) => {
let rows: unknown[] = []
if (isSelectQuery(sql)) {
rows = await invoke<unknown[]>('sql_select', { sql, params }).catch((e) => {
console.error('SQL select Error:', e, sql, params)
return []
})
} else {
rows = await invoke<unknown[]>('sql_execute', { sql, params }).catch(
(e) => {
console.error('SQL execute Error:', e, sql, params)
return []
},
)
}
if (method === 'get') {
return { rows: rows.length > 0 ? [rows[0]] : [] }
} else {
return { rows }
}
}) satisfies AsyncRemoteCallback

View File

@ -128,7 +128,7 @@ export const useVaultSettingsStore = defineStore('vaultSettingsStore', () => {
eq(schema.haexSettings.key, id),
),
})
console.log('readDeviceNameAsync', deviceName)
console.log('store: readDeviceNameAsync', deviceName)
return deviceName
}