zwischenstand

This commit is contained in:
2025-05-28 11:35:02 +02:00
parent 07ff15aba0
commit 4774d3fdc1
105 changed files with 4129 additions and 1438 deletions

View File

@ -1,127 +0,0 @@
<template>
<div class="bg-red-400 h-full">
browser {{ useRouter().currentRoute.value.meta.name }}
<HaexBrowser
:tabs="tabs"
:activeTabId="activeTabId"
@createTab="createNewTab"
@closeTab="closeTab"
@navigate="navigateToUrl"
@goBack="goBack"
@goForward="goForward"
/>
</div>
</template>
<script setup lang="ts">
import { invoke } from "@tauri-apps/api/core";
import { listen, type UnlistenFn } from "@tauri-apps/api/event";
import { Window, getCurrentWindow } from "@tauri-apps/api/window";
import { Webview } from "@tauri-apps/api/webview";
definePageMeta({
name: "haexBrowser",
});
interface Tab {
id: string;
title: string;
url: string;
isLoading: boolean;
isActive: boolean;
window_label: string;
}
const tabs = ref<Tab[]>([]);
const activeTabId = ref<string | null>(null);
let unlistenTabCreated: UnlistenFn | null = null;
let unlistenTabClosed: UnlistenFn | null = null;
onMounted(async () => {
// Erstelle einen ersten Tab beim Start
//createNewTab("https://www.google.com");
// Höre auf Tab-Events
unlistenTabCreated = await listen("tab-created", (event) => {
const newTab = event.payload as Tab;
tabs.value = tabs.value.map((tab) => ({
...tab,
isActive: tab.id === newTab.id,
}));
if (!tabs.value.some((tab) => tab.id === newTab.id)) {
tabs.value.push(newTab);
}
activeTabId.value = newTab.id;
});
unlistenTabClosed = await listen("tab-closed", (event) => {
const closedTabId = event.payload as string;
tabs.value = tabs.value.filter((tab) => tab.id !== closedTabId);
});
});
onUnmounted(() => {
if (unlistenTabCreated) unlistenTabCreated();
if (unlistenTabClosed) unlistenTabClosed();
});
const createNewTab = async (url: string = "about:blank") => {
try {
/* const appWindow = new Window('uniqueLabel111', {
fullscreen: true,
});
*/
/* const appWindow = getCurrentWindow();
const webview = new Webview(appWindow, 'theUniqueLabel', {
url: 'https://github.com/tauri-apps/tauri',
height: 1000,
width: 1000,
x: 110,
y: 0,
});
await webview.show(); */
//console.log('create webview', webview);
const tab_id = "foo";
await invoke("create_tab", { url, tabId: "foo" });
} catch (error) {
console.error("Fehler beim Erstellen des Tabs:", error);
}
};
const closeTab = async (tabId: string) => {
try {
//await invoke('close_tab', { tabId });
} catch (error) {
console.error("Fehler beim Schließen des Tabs:", error);
}
};
const navigateToUrl = async (tabId: string, url: string) => {
try {
//await invoke('navigate_to_url', { tabId, url });
} catch (error) {
console.error("Fehler bei der Navigation:", error);
}
};
const goBack = async (tabId: string | null) => {
try {
//await invoke('go_back', { tabId });
} catch (error) {
console.error("Fehler beim Zurückgehen:", error);
}
};
const goForward = async (tabId: string | null) => {
try {
//await invoke('go_forward', { tabId });
} catch (error) {
console.error("Fehler beim Vorwärtsgehen:", error);
}
};
</script>

View File

@ -1,73 +1,28 @@
<template>
<div class="w-full h-full overflow-scroll">
<!-- <div>
{{ iframeSrc }}
</div> -->
<div>
{{ iframeIndex }}
</div>
<iframe
v-if="iframeIndex"
class="w-full h-full"
@load=""
ref="iFrameRef"
class="w-full h-full"
:src="iframeIndex"
sandbox="allow-scripts allow-same-origin"
allow="autoplay; speaker-selection; encrypted-media;"
>
</iframe>
<UiButton @click="go = true">Go</UiButton>
<!-- <p v-else>{{ t("loading") }}</p> -->
{{ audioTest }}
<audio v-if="go" controls :src="audioTest">
Dein Browser unterstützt das Audio-Element nicht.
</audio>
<video v-if="go" controls width="600" :src="demoVideo"></video>
<div v-if="audioError">
Fehler beim Laden der Audio-Datei: {{ audioError }}
</div>
/>
</div>
</template>
<script setup lang="ts">
import { convertFileSrc } from '@tauri-apps/api/core'
import { appDataDir, join, resourceDir } from '@tauri-apps/api/path'
definePageMeta({
name: 'haexExtension',
})
const { t } = useI18n()
const iframeRef = useTemplateRef('iFrameRef')
const { extensionEntry: iframeSrc, currentExtension } = storeToRefs(
useExtensionsStore()
)
const audioAssetUrl = ref('')
const audioError = ref('')
const audioTest = convertFileSrc(
await join(await appDataDir(), 'resources/demo.mp3')
)
const { extensionEntry: iframeSrc } = storeToRefs(useExtensionsStore())
//computed(() => `${iframeSrc.value}/sounds/music/demo.mp3`)
const go = ref(false)
const iframeIndex = computed(() => `${iframeSrc.value}/index.html`)
const demoVideo = computed(() => `${iframeSrc.value}/sounds/music/demo.mp3`)
const extensionStore = useExtensionsStore()
watch(
demoVideo,
async () => {
const res = await fetch(
'/home/haex/.local/share/space.haex.hub/extensions/pokedemo/1.0/sounds/music/demo.mp3'
)
console.log('respo', res)
console.log('iframeSrc', iframeSrc.value)
},
{
immediate: true,
}
const iframeIndex = computed(() =>
iframeSrc.value ? `${iframeSrc.value}/index.html` : '',
)
</script>

View File

@ -1,24 +1,31 @@
<template>
<div class="flex flex-col p-1 relative h-full">
<div class="flex" v-if="extensionStore.availableExtensions.length">
<div class="flex flex-col p-4 relative h-full">
<div
v-if="extensionStore.availableExtensions.length"
class="flex"
>
<UiButton
class="fixed top-20 right-4 btn-square btn-primary"
@click="loadExtensionManifestAsync"
@click="prepareInstallExtensionAsyn"
>
<Icon name="mdi:plus" size="1.5em" />
<Icon
name="mdi:plus"
size="1.5em"
/>
</UiButton>
<HaexExtensionCard
v-for="extension in extensionStore.availableExtensions"
v-bind="extension"
@remove="onShowRemoveDialog(extension)"
>
</HaexExtensionCard>
v-for="_extension in extensionStore.availableExtensions"
v-bind="_extension"
:key="_extension.id"
@remove="onShowRemoveDialog(_extension)"
/>
</div>
<!-- <SvgoExtensionsOverview class="h-screen w-screen" /> -->
<!-- <nuxt-icon name="extensions-overview" class="size-full" /> -->
<div v-else class="h-full w-full">
<div
v-else
class="h-full w-full"
>
<Icon
name="my-icon:extensions-overview"
class="size-full md:size-2/3 md:translate-x-1/5 md:translate-y-1/3"
@ -27,17 +34,27 @@
<UiTooltip :tooltip="t('extension.add')">
<UiButton
class="btn-square btn-primary btn-xl btn-gradient rotate-45"
@click="loadExtensionManifestAsync"
@click="prepareInstallExtensionAsyn"
>
<Icon name="mdi:plus" size="1.5em" class="rotate-45" />
<Icon
name="mdi:plus"
size="1.5em"
class="rotate-45"
/>
</UiButton>
</UiTooltip>
</div>
</div>
<HaexExtensionManifestConfirm
<HaexExtensionDialogReinstall
v-model:open="openOverwriteDialog"
:manifest="extension.manifest"
@confirm="addExtensionAsync"
/>
<HaexExtensionDialogInstall
v-model:open="showConfirmation"
:manifest="extension.manifest"
@confirm="addExtensionAsync"
/>
@ -45,8 +62,7 @@
v-model:open="showRemoveDialog"
:extension="extensionToBeRemoved"
@confirm="removeExtensionAsync"
>
</HaexExtensionDialogRemove>
/>
</div>
</template>
@ -67,6 +83,7 @@ const { t } = useI18n()
const extensionStore = useExtensionsStore()
const showConfirmation = ref(false)
const openOverwriteDialog = ref(false)
const extension = reactive<{
manifest: IHaexHubExtensionManifest | null | undefined
@ -82,14 +99,13 @@ const loadExtensionManifestAsync = async () => {
if (!extension.path) return
const manifestFile = JSON.parse(
await readTextFile(await join(extension.path, 'manifest.json'))
await readTextFile(await join(extension.path, 'manifest.json')),
)
if (!extensionStore.checkManifest(manifestFile))
throw new Error(`Manifest fehlerhaft ${JSON.stringify(manifestFile)}`)
extension.manifest = manifestFile
showConfirmation.value = true
return manifestFile
} catch (error) {
console.error('Fehler loadExtensionManifestAsync:', error)
add({ type: 'error', text: JSON.stringify(error) })
@ -98,6 +114,27 @@ const loadExtensionManifestAsync = async () => {
const { add } = useSnackbar()
const prepareInstallExtensionAsyn = async () => {
try {
const manifest = await loadExtensionManifestAsync()
if (!manifest) throw new Error('No valid Manifest found')
extension.manifest = manifest
const isAlreadyInstalled = await extensionStore.isExtensionInstalledAsync({
id: manifest.id,
version: manifest.version,
})
if (isAlreadyInstalled) {
openOverwriteDialog.value = true
} else {
await addExtensionAsync()
}
} catch (error) {
add({ type: 'error', text: JSON.stringify(error) })
}
}
const addExtensionAsync = async () => {
try {
await extensionStore.installAsync(extension.path)
@ -133,7 +170,7 @@ const removeExtensionAsync = async () => {
try {
await extensionStore.removeExtensionAsync(
extensionToBeRemoved.value.id,
extensionToBeRemoved.value.version
extensionToBeRemoved.value.version,
)
await extensionStore.loadExtensionsAsync()
add({
@ -173,4 +210,17 @@ de:
text: 'Die Erweiterung wurde erfolgreich hinzugefügt'
en:
title: 'Install extension'
extension:
remove:
success:
text: 'Extension {extensionName} was removed'
title: '{extensionName} removed'
error:
text: "Extension {extensionName} couldn't be removed. \n {error}"
title: 'Exception during uninstall {extensionName}'
add: 'Add Extension'
success:
title: '{extension} added'
text: 'Extensions was added successfully'
</i18n>

View File

@ -0,0 +1,8 @@
<template>
<div class="flex">
<HaexPassSidebar />
<div>
<NuxtPage />
</div>
</div>
</template>

View File

@ -0,0 +1,9 @@
<template>
<div>passwords</div>
</template>
<script setup lang="ts">
definePageMeta({
name: "haexpassOverview"
})
</script>

View File

@ -1,5 +1,11 @@
<template>
<div class="h-full text-base-content"></div>
<div class="h-full text-base-content flex bg-base-200 p-4">
<HaexExtensionCard
v-for="extension in extensionStore.availableExtensions"
v-bind="extension"
:key="extension.id"
/>
</div>
</template>
<script setup lang="ts">

View File

@ -10,10 +10,16 @@
<div class="p-2">{{ t('vaultName.label') }}</div>
<div>
<UiInput v-model="currentVaultName" :placeholder="t('vaultName.label')">
<UiInput
v-model="currentVaultName"
:placeholder="t('vaultName.label')"
>
<template #append>
<UiTooltip :tooltip="t('save')">
<UiButton class="btn-primary" @click="onSetVaultNameAsync">
<UiButton
class="btn-primary"
@click="onSetVaultNameAsync"
>
<Icon name="mdi:content-save-outline" />
</UiButton>
</UiTooltip>
@ -25,7 +31,7 @@
<script setup lang="ts">
import { eq } from 'drizzle-orm'
import { type Locale } from 'vue-i18n'
import type { Locale } from 'vue-i18n'
import { haexSettings } from '~~/src-tauri/database/schemas/vault'
definePageMeta({
@ -61,6 +67,7 @@ const onSetVaultNameAsync = async () => {
await updateVaultNameAsync(currentVaultName.value)
add({ text: t('vaultName.update.success'), type: 'success' })
} catch (error) {
console.error(error)
add({ text: t('vaultName.update.error'), type: 'error' })
}
}