restructured vault settings

This commit is contained in:
2025-06-17 11:51:00 +02:00
parent 88493c959e
commit 066b8171bf
9 changed files with 191 additions and 158 deletions

View File

@ -84,7 +84,8 @@ export default defineNuxtConfig({
public: { public: {
haexVault: { haexVault: {
lastVaultFileName: 'lastVaults.json', lastVaultFileName: 'lastVaults.json',
//defaultDatabase: 'src/database/default.db', instanceFileName: 'instance.json',
defaultVaultName: 'HaexHub',
}, },
}, },
}, },

View File

@ -106,7 +106,9 @@ const onLoadDatabase = async () => {
const localePath = useLocalePath() const localePath = useLocalePath()
const { syncLocaleAsync, syncThemeAsync, syncVaultNameAsync } = useVaultStore() const { syncLocaleAsync, syncThemeAsync, syncVaultNameAsync } =
useVaultSettingsStore()
const onOpenDatabase = async () => { const onOpenDatabase = async () => {
try { try {
check.value = true check.value = true

View File

@ -3,6 +3,13 @@
<NuxtLayout name="app"> <NuxtLayout name="app">
<NuxtPage /> <NuxtPage />
</NuxtLayout> </NuxtLayout>
<UiDialog v-model:open="showInstanceDialog">
<div>
Das scheint das erste Mal zu sein, dass du auf diesem Gerät diese Vault
öffnest. Bitte gib diesem Gerät einen Namen
</div>
</UiDialog>
</div> </div>
</template> </template>
@ -10,4 +17,21 @@
definePageMeta({ definePageMeta({
middleware: 'database', middleware: 'database',
}) })
const showInstanceDialog = ref(false)
const { readNotificationsAsync } = useNotificationStore()
const { isFirstTimeAsync } = useVaultInstanceStore()
const { loadExtensionsAsync } = useExtensionsStore()
onMounted(async () => {
await loadExtensionsAsync()
await readNotificationsAsync()
if (await isFirstTimeAsync()) {
showInstanceDialog.value = true
}
})
onMounted(() => {})
</script> </script>

View File

@ -1,10 +1,12 @@
<template> <template>
<div class="h-full text-base-content flex bg-base-200 p-4"> <div>
<HaexExtensionCard <div class="h-full text-base-content flex bg-base-200 p-4">
v-for="extension in extensionStore.availableExtensions" <HaexExtensionCard
v-bind="extension" v-for="extension in extensionStore.availableExtensions"
:key="extension.id" v-bind="extension"
/> :key="extension.id"
/>
</div>
</div> </div>
</template> </template>
@ -14,10 +16,4 @@ definePageMeta({
}) })
const extensionStore = useExtensionsStore() const extensionStore = useExtensionsStore()
const { readNotificationsAsync } = useNotificationStore()
onMounted(async () => {
await extensionStore.loadExtensionsAsync()
await readNotificationsAsync()
})
</script> </script>

View File

@ -51,7 +51,7 @@ definePageMeta({
const { t, setLocale } = useI18n() const { t, setLocale } = useI18n()
const { currentVault, currentVaultName } = storeToRefs(useVaultStore()) const { currentVault, currentVaultName } = storeToRefs(useVaultStore())
const { updateVaultNameAsync } = useVaultStore() const { updateVaultNameAsync } = useVaultSettingsStore()
const onSelectLocaleAsync = async (locale: Locale) => { const onSelectLocaleAsync = async (locale: Locale) => {
await currentVault.value?.drizzle await currentVault.value?.drizzle

View File

@ -1,10 +1,8 @@
import * as schema from '@/../src-tauri/database/schemas/vault'
import { invoke } from '@tauri-apps/api/core'
import { exists } from '@tauri-apps/plugin-fs'
import { platform } from '@tauri-apps/plugin-os'
import { eq } from 'drizzle-orm'
import type { SqliteRemoteDatabase } from 'drizzle-orm/sqlite-proxy'
import { drizzle } from 'drizzle-orm/sqlite-proxy' import { drizzle } from 'drizzle-orm/sqlite-proxy'
import { invoke } from '@tauri-apps/api/core'
import { platform } from '@tauri-apps/plugin-os'
import * as schema from '@/../src-tauri/database/schemas/vault'
import type { SqliteRemoteDatabase } from 'drizzle-orm/sqlite-proxy'
interface IVault { interface IVault {
name: string name: string
@ -15,6 +13,10 @@ interface IOpenVaults {
} }
export const useVaultStore = defineStore('vaultStore', () => { export const useVaultStore = defineStore('vaultStore', () => {
const {
public: { haexVault },
} = useRuntimeConfig()
const currentVaultId = computed<string | undefined>({ const currentVaultId = computed<string | undefined>({
get: () => get: () =>
getSingleRouteParam(useRouter().currentRoute.value.params.vaultId), getSingleRouteParam(useRouter().currentRoute.value.params.vaultId),
@ -23,30 +25,7 @@ export const useVaultStore = defineStore('vaultStore', () => {
}, },
}) })
const defaultVaultName = ref('HaexHub') const currentVaultName = ref(haexVault.defaultVaultName || 'HaexHub')
const currentVaultName = ref(defaultVaultName.value)
const read_only = computed<boolean>({
get: () => {
console.log(
'query showSidebar',
useRouter().currentRoute.value.query.readonly,
)
return JSON.parse(
getSingleRouteParam(useRouter().currentRoute.value.query.readonly) ||
'false',
)
},
set: (readonly) => {
const router = useRouter()
router.replace({
query: {
...router.currentRoute.value.query,
readonly: JSON.stringify(readonly ? true : false),
},
})
},
})
const openVaults = ref<IOpenVaults>({}) const openVaults = ref<IOpenVaults>({})
@ -92,7 +71,6 @@ export const useVaultStore = defineStore('vaultStore', () => {
console.error('SQL select Error:', e, sql, params) console.error('SQL select Error:', e, sql, params)
return [] return []
}) })
console.log('select', rows)
} else { } else {
console.log('sql_execute', sql, params) console.log('sql_execute', sql, params)
// Otherwise, use the execute method // Otherwise, use the execute method
@ -125,13 +103,6 @@ export const useVaultStore = defineStore('vaultStore', () => {
} }
} }
const refreshDatabaseAsync = async () => {
console.log('refreshDatabaseAsync')
/* if (!currentVault.value?.database.close) {
return navigateTo(useLocaleRoute()({ name: 'vaultOpen' }));
} */
}
const createAsync = async ({ const createAsync = async ({
path, path,
password, password,
@ -139,109 +110,19 @@ export const useVaultStore = defineStore('vaultStore', () => {
path: string path: string
password: string password: string
}) => { }) => {
/* const existDb = await exists('default.db', { await invoke('create_encrypted_database', {
baseDir: BaseDirectory.Resource,
}); */
/* const existDb = await resolveResource('resources/default.db');
if (!existDb) throw new Error('Keine Datenbank da');
await copyFile(existDb, path); */
const result = await invoke('create_encrypted_database', {
path, path,
key: password, key: password,
}) })
console.log('create_encrypted_database', result)
return await openAsync({ path, password }) return await openAsync({ path, password })
} }
const closeAsync = async () => { const closeAsync = async () => {
if (!currentVaultId.value) return if (!currentVaultId.value) return
/* if (
typeof openVaults.value?.[currentVaultId.value]?.database?.close ===
'function'
) {
console.log('close db', openVaults.value?.[currentVaultId.value]);
return openVaults.value?.[currentVaultId.value]?.database?.close();
} */
delete openVaults.value?.[currentVaultId.value] delete openVaults.value?.[currentVaultId.value]
} }
const syncLocaleAsync = async () => {
try {
const app = useNuxtApp()
const currentLocaleRow = await currentVault.value?.drizzle
.select()
.from(schema.haexSettings)
.where(eq(schema.haexSettings.key, 'locale'))
if (currentLocaleRow?.[0]?.value) {
const currentLocale = app.$i18n.availableLocales.find(
(locale) => locale === currentLocaleRow[0].value,
)
await app.$i18n.setLocale(currentLocale ?? app.$i18n.defaultLocale)
} else {
await currentVault.value?.drizzle.insert(schema.haexSettings).values({
id: crypto.randomUUID(),
key: 'locale',
value: app.$i18n.locale.value,
})
}
} catch (error) {
console.log('ERROR syncLocaleAsync', error)
}
}
const syncThemeAsync = async () => {
const { availableThemes, defaultTheme, currentTheme } = storeToRefs(
useUiStore(),
)
const currentThemeRow = await currentVault.value?.drizzle
.select()
.from(schema.haexSettings)
.where(eq(schema.haexSettings.key, 'theme'))
if (currentThemeRow?.[0]?.value) {
const theme = availableThemes.value.find(
(theme) => theme.name === currentThemeRow[0].value,
)
currentTheme.value = theme ?? defaultTheme.value
} else {
await currentVault.value?.drizzle.insert(schema.haexSettings).values({
id: crypto.randomUUID(),
key: 'theme',
value: currentTheme.value.value,
})
}
}
const syncVaultNameAsync = async () => {
const currentVaultNameRow = await currentVault.value?.drizzle
.select()
.from(schema.haexSettings)
.where(eq(schema.haexSettings.key, 'vaultName'))
if (currentVaultNameRow?.[0]?.value) {
currentVaultName.value =
currentVaultNameRow.at(0)?.value ?? defaultVaultName.value
} else {
await currentVault.value?.drizzle.insert(schema.haexSettings).values({
id: crypto.randomUUID(),
key: 'vaultName',
value: currentVaultName.value,
})
}
}
const updateVaultNameAsync = async (newVaultName?: string | null) => {
console.log('set new vaultName', newVaultName)
return currentVault.value?.drizzle
.update(schema.haexSettings)
.set({ value: newVaultName ?? defaultVaultName.value })
.where(eq(schema.haexSettings.key, 'vaultName'))
}
return { return {
closeAsync, closeAsync,
createAsync, createAsync,
@ -250,12 +131,6 @@ export const useVaultStore = defineStore('vaultStore', () => {
currentVaultName, currentVaultName,
openAsync, openAsync,
openVaults, openVaults,
read_only,
refreshDatabaseAsync,
syncLocaleAsync,
syncThemeAsync,
syncVaultNameAsync,
updateVaultNameAsync,
} }
}) })
@ -264,9 +139,8 @@ const getVaultIdAsync = async (path: string) => {
const data = encoder.encode(path) const data = encoder.encode(path)
const hashBuffer = await crypto.subtle.digest('SHA-256', data) const hashBuffer = await crypto.subtle.digest('SHA-256', data)
const hashArray = Array.from(new Uint8Array(hashBuffer)) // convert buffer to byte array const hashArray = Array.from(new Uint8Array(hashBuffer))
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('') // convert bytes to hex string const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('')
console.log('vaultId', hashHex)
return hashHex return hashHex
} }

View File

@ -0,0 +1,47 @@
import { load } from '@tauri-apps/plugin-store'
export const useVaultInstanceStore = defineStore('vaultInstanceStore', () => {
const instanceId = ref<string>()
const getInstanceIdAsync = async () => {
const store = await getStoreAsync()
instanceId.value = await store.get<string>('id')
return instanceId.value
}
const getStoreAsync = async () => {
const {
public: { haexVault },
} = useRuntimeConfig()
return await load(haexVault.instanceFileName || 'instance.json')
}
const setInstanceIdAsync = async (id?: string) => {
const store = await getStoreAsync()
const _id = id || crypto.randomUUID()
await store.set('id', _id)
return _id
}
const setInstanceIdIfNotExistsAsync = async () => {
const id = await getInstanceIdAsync()
return id ?? (await setInstanceIdAsync())
}
const isFirstTimeAsync = async () => {
const { currentVault } = useVaultStore()
currentVault.drizzle.select
return !(await getInstanceIdAsync())
}
return {
instanceId,
isFirstTimeAsync,
setInstanceIdAsync,
setInstanceIdIfNotExistsAsync,
}
})

View File

@ -16,7 +16,7 @@ export const useLastVaultStore = defineStore('lastVaultStore', () => {
const keyName = 'lastVaults' const keyName = 'lastVaults'
const getStoreAsync = async () => { const getStoreAsync = async () => {
return await load(haexVault.lastVaultFileName) return await load(haexVault.lastVaultFileName || 'lastVaults.json')
} }
const syncLastVaultsAsync = async () => { const syncLastVaultsAsync = async () => {
@ -45,7 +45,6 @@ export const useLastVaultStore = defineStore('lastVaultStore', () => {
} }
const removeVaultAsync = async (vaultPath: string) => { const removeVaultAsync = async (vaultPath: string) => {
console.log('remove', vaultPath, lastVaults.value)
lastVaults.value = lastVaults.value.filter( lastVaults.value = lastVaults.value.filter(
(vault) => vault.path !== vaultPath, (vault) => vault.path !== vaultPath,
) )
@ -54,14 +53,11 @@ export const useLastVaultStore = defineStore('lastVaultStore', () => {
const saveLastVaultsAsync = async () => { const saveLastVaultsAsync = async () => {
const store = await getStoreAsync() const store = await getStoreAsync()
console.log('save lastVaults', keyName, lastVaults.value)
await store.set(keyName, lastVaults.value) await store.set(keyName, lastVaults.value)
await syncLastVaultsAsync() await syncLastVaultsAsync()
} }
const test = async () => console.log('test')
return { return {
test,
addVaultAsync, addVaultAsync,
syncLastVaultsAsync, syncLastVaultsAsync,
lastVaults, lastVaults,

View File

@ -0,0 +1,93 @@
import * as schema from '@/../src-tauri/database/schemas/vault'
import { eq } from 'drizzle-orm'
export const useVaultSettingsStore = defineStore('vaultSettingsStore', () => {
const { currentVault, currentVaultName } = storeToRefs(useVaultStore())
const {
public: { haexVault },
} = useRuntimeConfig()
const syncLocaleAsync = async () => {
try {
const app = useNuxtApp()
const currentLocaleRow = await currentVault.value?.drizzle
.select()
.from(schema.haexSettings)
.where(eq(schema.haexSettings.key, 'locale'))
if (currentLocaleRow?.[0]?.value) {
const currentLocale = app.$i18n.availableLocales.find(
(locale) => locale === currentLocaleRow[0].value,
)
await app.$i18n.setLocale(currentLocale ?? app.$i18n.defaultLocale)
} else {
await currentVault.value?.drizzle.insert(schema.haexSettings).values({
id: crypto.randomUUID(),
key: 'locale',
value: app.$i18n.locale.value,
})
}
} catch (error) {
console.log('ERROR syncLocaleAsync', error)
}
}
const syncThemeAsync = async () => {
const { availableThemes, defaultTheme, currentTheme } = storeToRefs(
useUiStore(),
)
const currentThemeRow = await currentVault.value?.drizzle
.select()
.from(schema.haexSettings)
.where(eq(schema.haexSettings.key, 'theme'))
if (currentThemeRow?.[0]?.value) {
const theme = availableThemes.value.find(
(theme) => theme.name === currentThemeRow[0].value,
)
currentTheme.value = theme ?? defaultTheme.value
} else {
await currentVault.value?.drizzle.insert(schema.haexSettings).values({
id: crypto.randomUUID(),
key: 'theme',
value: currentTheme.value.value,
})
}
}
const syncVaultNameAsync = async () => {
const currentVaultNameRow = await currentVault.value?.drizzle
.select()
.from(schema.haexSettings)
.where(eq(schema.haexSettings.key, 'vaultName'))
if (currentVaultNameRow?.[0]?.value) {
currentVaultName.value =
currentVaultNameRow.at(0)?.value ||
haexVault.defaultVaultName ||
'HaexHub'
} else {
await currentVault.value?.drizzle.insert(schema.haexSettings).values({
id: crypto.randomUUID(),
key: 'vaultName',
value: currentVaultName.value,
})
}
}
const updateVaultNameAsync = async (newVaultName?: string | null) => {
return currentVault.value?.drizzle
.update(schema.haexSettings)
.set({ value: newVaultName || haexVault.defaultVaultName || 'HaexHub' })
.where(eq(schema.haexSettings.key, 'vaultName'))
}
return {
syncLocaleAsync,
syncThemeAsync,
syncVaultNameAsync,
updateVaultNameAsync,
}
})