diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json
index d4da637..d6eafae 100644
--- a/src-tauri/tauri.conf.json
+++ b/src-tauri/tauri.conf.json
@@ -64,7 +64,7 @@
},
"assetProtocol": {
"enable": true,
- "scope": ["$APPDATA", "$RESOURCE"]
+ "scope": ["$APPDATA", "$RESOURCE", "$APPLOCALDATA/**"]
}
}
},
diff --git a/src/components/haex/desktop/index.vue b/src/components/haex/desktop/index.vue
index e63d624..68dbe8f 100644
--- a/src/components/haex/desktop/index.vue
+++ b/src/components/haex/desktop/index.vue
@@ -23,191 +23,198 @@
:key="workspace.id"
class="w-full h-full"
>
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- windowManager.updateWindowPosition(window.id, x, y)
- "
- @size-changed="
- (width, height) =>
- windowManager.updateWindowSize(window.id, width, height)
- "
- @drag-start="handleWindowDragStart(window.id)"
- @drag-end="handleWindowDragEnd"
- >
-
-
+
+
-
-
-
-
-
+
-
-
+
+
+
+
+
+
+
+ windowManager.updateWindowPosition(window.id, x, y)
- "
- @size-changed="
- (width, height) =>
- windowManager.updateWindowSize(window.id, width, height)
- "
- @drag-start="handleWindowDragStart(window.id)"
- @drag-end="handleWindowDragEnd"
- >
-
-
+ @position-changed="handlePositionChanged"
+ @drag-start="handleDragStart"
+ @drag-end="handleDragEnd"
+ />
-
-
+
+
+
+
+
+ windowManager.updateWindowPosition(window.id, x, y)
+ "
+ @size-changed="
+ (width, height) =>
+ windowManager.updateWindowSize(window.id, width, height)
+ "
+ @drag-start="handleWindowDragStart(window.id)"
+ @drag-end="handleWindowDragEnd"
+ >
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+ v-show="windowManager.showWindowOverview || !window.isMinimized"
+ :id="window.id"
+ v-model:x="window.x"
+ v-model:y="window.y"
+ v-model:width="window.width"
+ v-model:height="window.height"
+ :title="window.title"
+ :icon="window.icon"
+ :is-active="windowManager.isWindowActive(window.id)"
+ :source-x="window.sourceX"
+ :source-y="window.sourceY"
+ :source-width="window.sourceWidth"
+ :source-height="window.sourceHeight"
+ :is-opening="window.isOpening"
+ :is-closing="window.isClosing"
+ :warning-level="
+ window.type === 'extension' &&
+ availableExtensions.find((ext) => ext.id === window.sourceId)
+ ?.devServerUrl
+ ? 'warning'
+ : undefined
+ "
+ class="no-swipe"
+ @close="windowManager.closeWindow(window.id)"
+ @minimize="windowManager.minimizeWindow(window.id)"
+ @activate="windowManager.activateWindow(window.id)"
+ @position-changed="
+ (x, y) => windowManager.updateWindowPosition(window.id, x, y)
+ "
+ @size-changed="
+ (width, height) =>
+ windowManager.updateWindowSize(window.id, width, height)
+ "
+ @drag-start="handleWindowDragStart(window.id)"
+ @drag-end="handleWindowDragEnd"
+ >
+
+
+
+
+
+
+
+
+
@@ -239,6 +246,8 @@ const {
allowSwipe,
isOverviewMode,
} = storeToRefs(workspaceStore)
+const { getWorkspaceBackgroundStyle, getWorkspaceContextMenuItems } =
+ workspaceStore
const { x: mouseX } = useMouse()
diff --git a/src/components/haex/extension/launcher.vue b/src/components/haex/extension/launcher.vue
index 9c7407f..f7b4cb5 100644
--- a/src/components/haex/extension/launcher.vue
+++ b/src/components/haex/extension/launcher.vue
@@ -4,6 +4,9 @@
direction="right"
:title="t('launcher.title')"
:description="t('launcher.description')"
+ :overlay="false"
+ :modal="false"
+ :handle-only="true"
:ui="{
content: 'w-dvw max-w-md sm:max-w-fit',
}"
@@ -30,7 +33,7 @@
size="lg"
variant="ghost"
:ui="{
- base: 'size-24 flex flex-wrap text-sm items-center justify-center overflow-visible cursor-grab active:cursor-grabbing',
+ base: 'size-24 flex flex-wrap text-sm items-center justify-center overflow-visible cursor-grab',
leadingIcon: 'size-10',
label: 'w-full',
}"
@@ -241,10 +244,6 @@ const handleDragStart = (event: DragEvent, item: LauncherItem) => {
event.dataTransfer.setDragImage(dragImage, 20, 20)
}
}
-
-const handleDragEnd = () => {
- // Cleanup if needed
-}
diff --git a/src/components/haex/system/settings.vue b/src/components/haex/system/settings.vue
index 8ebece3..fb1b050 100644
--- a/src/components/haex/system/settings.vue
+++ b/src/components/haex/system/settings.vue
@@ -33,6 +33,20 @@
/>
+ {{ t('workspaceBackground.label') }}
+
+
+
+
+
@@ -40,6 +54,9 @@
@@ -112,6 +199,16 @@ de:
update:
success: Gerätename wurde erfolgreich aktualisiert
error: Gerätename konnte nich aktualisiert werden
+ workspaceBackground:
+ label: Workspace-Hintergrund
+ choose: Bild auswählen
+ update:
+ success: Hintergrund erfolgreich aktualisiert
+ error: Fehler beim Aktualisieren des Hintergrunds
+ remove:
+ label: Hintergrund entfernen
+ success: Hintergrund erfolgreich entfernt
+ error: Fehler beim Entfernen des Hintergrunds
en:
language: Language
design: Design
@@ -129,4 +226,14 @@ en:
update:
success: Device name has been successfully updated
error: Device name could not be updated
+ workspaceBackground:
+ label: Workspace Background
+ choose: Choose Image
+ update:
+ success: Background successfully updated
+ error: Error updating background
+ remove:
+ label: Remove Background
+ success: Background successfully removed
+ error: Error removing background
diff --git a/src/database/schemas/haex.ts b/src/database/schemas/haex.ts
index 0497a00..e6bb163 100644
--- a/src/database/schemas/haex.ts
+++ b/src/database/schemas/haex.ts
@@ -8,7 +8,7 @@ import {
type AnySQLiteColumn,
type SQLiteColumnBuilderBase,
} from 'drizzle-orm/sqlite-core'
-import tableNames from '~/database/tableNames.json'
+import tableNames from '@/database/tableNames.json'
const crdtColumnNames = {
haexTimestamp: 'haex_timestamp',
@@ -137,6 +137,7 @@ export const haexWorkspaces = sqliteTable(
position: integer(tableNames.haex.workspaces.columns.position)
.notNull()
.default(0),
+ background: text(),
}),
(table) => [unique().on(table.position)],
)
diff --git a/src/stores/desktop/workspace.ts b/src/stores/desktop/workspace.ts
index 47d334e..03d3c9f 100644
--- a/src/stores/desktop/workspace.ts
+++ b/src/stores/desktop/workspace.ts
@@ -4,6 +4,7 @@ import {
type SelectHaexWorkspaces,
} from '~/database/schemas'
import type { Swiper } from 'swiper/types'
+import { convertFileSrc } from '@tauri-apps/api/core'
export type IWorkspace = SelectHaexWorkspaces
@@ -203,12 +204,86 @@ export const useWorkspaceStore = defineStore('workspaceStore', () => {
isOverviewMode.value = false
}
+ const updateWorkspaceBackgroundAsync = async (
+ workspaceId: string,
+ base64Image: string | null,
+ ) => {
+ if (!currentVault.value?.drizzle) {
+ throw new Error('Kein Vault geöffnet')
+ }
+
+ try {
+ const result = await currentVault.value.drizzle
+ .update(haexWorkspaces)
+ .set({ background: base64Image })
+ .where(eq(haexWorkspaces.id, workspaceId))
+ .returning()
+
+ if (result.length > 0 && result[0]) {
+ const index = workspaces.value.findIndex((ws) => ws.id === workspaceId)
+ if (index !== -1) {
+ workspaces.value[index] = result[0]
+ }
+ }
+ } catch (error) {
+ console.error('Fehler beim Aktualisieren des Workspace-Hintergrunds:', error)
+ throw error
+ }
+ }
+
+ const getWorkspaceBackgroundStyle = (workspace: IWorkspace) => {
+ if (!workspace.background) return {}
+
+ // The background field contains the absolute file path
+ // Convert it to an asset URL
+ const assetUrl = convertFileSrc(workspace.background)
+
+ return {
+ backgroundImage: `url(${assetUrl})`,
+ backgroundSize: 'cover',
+ backgroundPosition: 'center',
+ backgroundRepeat: 'no-repeat',
+ }
+ }
+
+ const getWorkspaceContextMenuItems = (workspaceId: string) => {
+ const windowManager = useWindowManagerStore()
+
+ return [[
+ {
+ label: 'Hintergrund ändern',
+ icon: 'i-mdi-image',
+ onSelect: async () => {
+ // Store the workspace ID for settings to use
+ currentWorkspaceIndex.value = workspaces.value.findIndex(
+ (ws) => ws.id === workspaceId,
+ )
+ // Get settings window info
+ const settingsWindow = windowManager.getAllSystemWindows()
+ .find((win) => win.id === 'settings')
+
+ if (settingsWindow) {
+ await windowManager.openWindowAsync({
+ type: 'system',
+ sourceId: settingsWindow.id,
+ title: settingsWindow.name,
+ icon: settingsWindow.icon || undefined,
+ workspaceId,
+ })
+ }
+ },
+ },
+ ]]
+ }
+
return {
addWorkspaceAsync,
allowSwipe,
closeWorkspaceAsync,
currentWorkspace,
currentWorkspaceIndex,
+ getWorkspaceBackgroundStyle,
+ getWorkspaceContextMenuItems,
isOverviewMode,
slideToWorkspace,
loadWorkspacesAsync,
@@ -218,6 +293,7 @@ export const useWorkspaceStore = defineStore('workspaceStore', () => {
switchToNext,
switchToPrevious,
switchToWorkspace,
+ updateWorkspaceBackgroundAsync,
workspaces,
}
})