fix launcher

This commit is contained in:
2025-10-20 22:44:35 +02:00
parent 57fb496fca
commit df97a3cb8b
5 changed files with 132 additions and 152 deletions

View File

@ -123,7 +123,7 @@
const props = defineProps<{ const props = defineProps<{
id: string id: string
title: string title: string
icon?: string icon?: string | null
initialX?: number initialX?: number
initialY?: number initialY?: number
initialWidth?: number initialWidth?: number

View File

@ -51,13 +51,9 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import type { SystemWindowDefinition } from '@/stores/desktop/windowManager'
const extensionStore = useExtensionsStore() const extensionStore = useExtensionsStore()
const windowManagerStore = useWindowManagerStore() const windowManagerStore = useWindowManagerStore()
const router = useRouter()
const route = useRoute()
const localePath = useLocalePath()
const { t } = useI18n() const { t } = useI18n()
const open = ref(false) const open = ref(false)
@ -107,35 +103,21 @@ const disabledExtensions = computed(() => {
return extensionStore.availableExtensions.filter((ext) => !ext.enabled) return extensionStore.availableExtensions.filter((ext) => !ext.enabled)
}) })
const { currentWorkspace } = storeToRefs(useWorkspaceStore())
// Open launcher item (system window or extension) // Open launcher item (system window or extension)
const openItem = async (item: LauncherItem) => { const openItem = async (item: LauncherItem) => {
// Check if we're on the desktop page try {
const isOnDesktop = route.name === 'desktop' // Open the window with correct type and sourceId
await windowManagerStore.openWindowAsync({
sourceId: item.id,
type: item.type,
icon: item.icon,
title: item.name,
})
console.log('currentWorkspace', currentWorkspace.value, route.name) open.value = false
/* if (!isOnDesktop) { } catch (error) {
// Navigate to desktop first console.log(error)
await router.push( }
localePath({
name: 'desktop',
}),
)
// Wait for navigation and DOM update
await nextTick()
} */
// Open the window with correct type and sourceId
windowManagerStore.openWindow({
sourceId: item.id,
type: item.type, // 'system' or 'extension'
icon: item.icon, // systemWindowId or extensionId
title: item.name,
workspaceId: currentWorkspace.value?.id,
})
open.value = false
} }
</script> </script>

View File

@ -1,10 +1,10 @@
<template> <template>
<div class="w-full h-full flex flex-col bg-white dark:bg-gray-900"> <div class="w-full h-full flex flex-col bg-white dark:bg-gray-900">
<!-- Settings Header --> <!-- Settings Header -->
<div class="flex-shrink-0 border-b border-gray-200 dark:border-gray-700 p-6"> <div
<h1 class="text-2xl font-bold text-gray-900 dark:text-white"> class="flex-shrink-0 border-b border-gray-200 dark:border-gray-700 p-6"
Settings >
</h1> <h1 class="text-2xl font-bold text-gray-900 dark:text-white">Settings</h1>
<p class="text-sm text-gray-600 dark:text-gray-400 mt-1"> <p class="text-sm text-gray-600 dark:text-gray-400 mt-1">
Manage your HaexHub preferences and configuration Manage your HaexHub preferences and configuration
</p> </p>
@ -21,9 +21,7 @@
<div class="space-y-4 bg-gray-50 dark:bg-gray-800 rounded-lg p-4"> <div class="space-y-4 bg-gray-50 dark:bg-gray-800 rounded-lg p-4">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<p class="font-medium text-gray-900 dark:text-white"> <p class="font-medium text-gray-900 dark:text-white">Theme</p>
Theme
</p>
<p class="text-sm text-gray-600 dark:text-gray-400"> <p class="text-sm text-gray-600 dark:text-gray-400">
Choose your preferred theme Choose your preferred theme
</p> </p>
@ -65,7 +63,6 @@
Lock vault after inactivity Lock vault after inactivity
</p> </p>
</div> </div>
<UToggle />
</div> </div>
</div> </div>
</section> </section>
@ -77,12 +74,20 @@
</h2> </h2>
<div class="space-y-2 bg-gray-50 dark:bg-gray-800 rounded-lg p-4"> <div class="space-y-2 bg-gray-50 dark:bg-gray-800 rounded-lg p-4">
<div class="flex justify-between"> <div class="flex justify-between">
<span class="text-sm text-gray-600 dark:text-gray-400">Version</span> <span class="text-sm text-gray-600 dark:text-gray-400"
<span class="text-sm font-medium text-gray-900 dark:text-white">0.1.0</span> >Version</span
>
<span class="text-sm font-medium text-gray-900 dark:text-white"
>0.1.0</span
>
</div> </div>
<div class="flex justify-between"> <div class="flex justify-between">
<span class="text-sm text-gray-600 dark:text-gray-400">Platform</span> <span class="text-sm text-gray-600 dark:text-gray-400"
<span class="text-sm font-medium text-gray-900 dark:text-white">Tauri + Vue</span> >Platform</span
>
<span class="text-sm font-medium text-gray-900 dark:text-white"
>Tauri + Vue</span
>
</div> </div>
</div> </div>
</section> </section>

View File

@ -163,15 +163,13 @@ export const useDesktopStore = defineStore('desktopStore', () => {
) )
if (extension) { if (extension) {
windowManager.openWindow( windowManager.openWindowAsync({
'extension', sourceId: extension.id,
extension.id, type: 'extension',
extension.name, icon: extension.icon,
extension.icon || undefined, title: extension.name,
undefined, // Use default viewport-aware width
undefined, // Use default viewport-aware height
sourcePosition, sourcePosition,
) })
} }
} }
// Für später: file und folder handling // Für später: file und folder handling

View File

@ -6,7 +6,7 @@ export interface IWindow {
type: 'system' | 'extension' type: 'system' | 'extension'
sourceId: string // extensionId or systemWindowId (depends on type) sourceId: string // extensionId or systemWindowId (depends on type)
title: string title: string
icon?: string icon?: string | null
x: number x: number
y: number y: number
width: number width: number
@ -35,9 +35,6 @@ export interface SystemWindowDefinition {
} }
export const useWindowManagerStore = defineStore('windowManager', () => { export const useWindowManagerStore = defineStore('windowManager', () => {
const workspaceStore = useWorkspaceStore()
const { currentWorkspace, workspaces } = storeToRefs(workspaceStore)
const windows = ref<IWindow[]>([]) const windows = ref<IWindow[]>([])
const activeWindowId = ref<string | null>(null) const activeWindowId = ref<string | null>(null)
const nextZIndex = ref(100) const nextZIndex = ref(100)
@ -83,9 +80,9 @@ export const useWindowManagerStore = defineStore('windowManager', () => {
// Get windows for current workspace only // Get windows for current workspace only
const currentWorkspaceWindows = computed(() => { const currentWorkspaceWindows = computed(() => {
if (!currentWorkspace.value) return [] if (!useWorkspaceStore().currentWorkspace) return []
return windows.value.filter( return windows.value.filter(
(w) => w.workspaceId === currentWorkspace.value?.id, (w) => w.workspaceId === useWorkspaceStore().currentWorkspace?.id,
) )
}) })
@ -102,18 +99,18 @@ export const useWindowManagerStore = defineStore('windowManager', () => {
windowsFrom.value.forEach((window) => (window.workspaceId = toWorkspaceId)) windowsFrom.value.forEach((window) => (window.workspaceId = toWorkspaceId))
} }
const openWindow = ({ const openWindowAsync = async ({
height, height = 800,
icon, icon = '',
sourceId, sourceId,
sourcePosition, sourcePosition,
title, title,
type, type,
width, width = 600,
workspaceId, workspaceId,
}: { }: {
height?: number height?: number
icon?: string icon?: string | null
sourceId: string sourceId: string
sourcePosition?: { x: number; y: number; width: number; height: number } sourcePosition?: { x: number; y: number; width: number; height: number }
title?: string title?: string
@ -121,107 +118,105 @@ export const useWindowManagerStore = defineStore('windowManager', () => {
width?: number width?: number
workspaceId?: string workspaceId?: string
}) => { }) => {
// Wenn kein workspaceId angegeben ist, nutze die current workspace try {
const targetWorkspaceId = workspaceId || currentWorkspace.value?.id // Wenn kein workspaceId angegeben ist, nutze die current workspace
const targetWorkspaceId =
workspaceId || useWorkspaceStore().currentWorkspace?.id
if (!targetWorkspaceId) { if (!targetWorkspaceId) {
console.error('Cannot open window: No active workspace') console.error('Cannot open window: No active workspace')
return
}
// Sicherheitscheck
if (!targetWorkspaceId) {
console.error('Cannot open window: No workspace available')
return
}
const workspace = workspaces.value?.find((w) => w.id === targetWorkspaceId)
if (!workspace) {
console.error('Cannot open window: Invalid workspace')
return
}
// System Window specific handling
if (type === 'system') {
const systemWindowDef = getSystemWindow(sourceId)
if (!systemWindowDef) {
console.error(`System window '${sourceId}' not found in registry`)
return return
} }
// Singleton check: If already open, activate existing window const workspace = useWorkspaceStore().workspaces?.find(
if (systemWindowDef.singleton) { (w) => w.id === targetWorkspaceId,
const existingWindow = windows.value.find( )
(w) => w.type === 'system' && w.sourceId === sourceId, if (!workspace) {
) console.error('Cannot open window: Invalid workspace')
if (existingWindow) { return
activateWindow(existingWindow.id) }
return existingWindow.id
// System Window specific handling
if (type === 'system') {
const systemWindowDef = getSystemWindow(sourceId)
if (!systemWindowDef) {
console.error(`System window '${sourceId}' not found in registry`)
return
} }
// Singleton check: If already open, activate existing window
if (systemWindowDef.singleton) {
const existingWindow = windows.value.find(
(w) => w.type === 'system' && w.sourceId === sourceId,
)
if (existingWindow) {
activateWindow(existingWindow.id)
return existingWindow.id
}
}
// Use system window defaults
title = title ?? systemWindowDef.name
icon = icon ?? systemWindowDef.icon
width = width ?? systemWindowDef.defaultWidth
height = height ?? systemWindowDef.defaultHeight
} }
// Use system window defaults // Create new window
title = title ?? systemWindowDef.name const windowId = crypto.randomUUID()
icon = icon ?? systemWindowDef.icon
width = width ?? systemWindowDef.defaultWidth
height = height ?? systemWindowDef.defaultHeight
}
// Create new window // Calculate viewport-aware size
const windowId = crypto.randomUUID() const viewportWidth = window.innerWidth
const viewportHeight = window.innerHeight
// Calculate viewport-aware size const windowWidth = width > viewportWidth ? viewportWidth : width
const viewportWidth = window.innerWidth const windowHeight = height > viewportHeight ? viewportHeight : height
const viewportHeight = window.innerHeight
const isMobile = viewportWidth < 768 // Tailwind md breakpoint
// Default size based on viewport // Calculate centered position with cascading offset (only count windows in current workspace)
const defaultWidth = isMobile ? Math.floor(viewportWidth * 0.95) : 800 const offset = currentWorkspaceWindows.value.length * 30
const defaultHeight = isMobile ? Math.floor(viewportHeight * 0.85) : 600 const centerX = Math.max(0, (viewportWidth - windowWidth) / 1 / 3)
const centerY = Math.max(0, (viewportHeight - windowHeight) / 1 / 3)
const x = Math.min(centerX + offset, viewportWidth - windowWidth)
const y = Math.min(centerY + offset, viewportHeight - windowHeight)
const windowWidth = width ?? defaultWidth const newWindow: IWindow = {
const windowHeight = height ?? defaultHeight id: windowId,
workspaceId: workspace.id,
// Calculate centered position with cascading offset (only count windows in current workspace) type,
const offset = currentWorkspaceWindows.value.length * 30 sourceId,
const centerX = Math.max(0, (viewportWidth - windowWidth) / 2) title: title!,
const centerY = Math.max(0, (viewportHeight - windowHeight) / 2) icon,
const x = Math.min(centerX + offset, viewportWidth - windowWidth) x,
const y = Math.min(centerY + offset, viewportHeight - windowHeight) y,
width: windowWidth,
const newWindow: IWindow = { height: windowHeight,
id: windowId, isMinimized: false,
workspaceId: workspace.id, zIndex: nextZIndex.value++,
type, sourceX: sourcePosition?.x,
sourceId, sourceY: sourcePosition?.y,
title: title!, sourceWidth: sourcePosition?.width,
icon, sourceHeight: sourcePosition?.height,
x, isOpening: true,
y, isClosing: false,
width: windowWidth,
height: windowHeight,
isMinimized: false,
zIndex: nextZIndex.value++,
sourceX: sourcePosition?.x,
sourceY: sourcePosition?.y,
sourceWidth: sourcePosition?.width,
sourceHeight: sourcePosition?.height,
isOpening: true,
isClosing: false,
}
windows.value.push(newWindow)
activeWindowId.value = windowId
// Remove opening flag after animation
setTimeout(() => {
const window = windows.value.find((w) => w.id === windowId)
if (window) {
window.isOpening = false
} }
}, windowAnimationDuration.value)
return windowId windows.value.push(newWindow)
activeWindowId.value = windowId
// Remove opening flag after animation
setTimeout(() => {
const window = windows.value.find((w) => w.id === windowId)
if (window) {
window.isOpening = false
}
}, windowAnimationDuration.value)
return windowId
} catch (error) {
console.error('Error opening window:', error)
// Optional: Fehler weiterwerfen wenn nötig
throw error
}
} }
/***************************************************************************************************** /*****************************************************************************************************
@ -324,7 +319,7 @@ export const useWindowManagerStore = defineStore('windowManager', () => {
isWindowActive, isWindowActive,
minimizeWindow, minimizeWindow,
moveWindowsToWorkspace, moveWindowsToWorkspace,
openWindow, openWindowAsync,
restoreWindow, restoreWindow,
updateWindowPosition, updateWindowPosition,
updateWindowSize, updateWindowSize,