try to make audio play

This commit is contained in:
Martin Drechsel
2025-05-16 08:52:04 +02:00
parent ad3aa4293a
commit 6a1351752b
9 changed files with 250 additions and 1218 deletions

View File

@ -18,6 +18,18 @@ export default defineNuxtConfig({
dirs: ["composables/**", "stores/**", "components/**", "pages/**", "types/**"], dirs: ["composables/**", "stores/**", "components/**", "pages/**", "types/**"],
}, },
icon: {
provider: 'server',
mode: "svg",
clientBundle: {
icons: ["solar:global-outline", "gg:extension"],
scan: true,
includeCustomCollections: true,
},
serverBundle: { collections: ["mdi", "line-md", "solar", "gg"] }
//collections: ["mdi", "line-md"]
},
i18n: { i18n: {
strategy: "prefix_and_default", strategy: "prefix_and_default",
defaultLocale: "de", defaultLocale: "de",

View File

@ -10,6 +10,7 @@
"preview": "nuxt preview", "preview": "nuxt preview",
"postinstall": "nuxt prepare", "postinstall": "nuxt prepare",
"tauri": "tauri", "tauri": "tauri",
"tauri:build:debug": "tauri build --debug",
"drizzle:generate": "drizzle-kit generate", "drizzle:generate": "drizzle-kit generate",
"drizzle:migrate": "drizzle-kit migrate" "drizzle:migrate": "drizzle-kit migrate"
}, },
@ -18,7 +19,7 @@
"@nuxt/icon": "1.11.0", "@nuxt/icon": "1.11.0",
"@nuxt/image": "1.10.0", "@nuxt/image": "1.10.0",
"@nuxtjs/i18n": "^9.5.3", "@nuxtjs/i18n": "^9.5.3",
"@pinia/nuxt": "^0.10.1", "@pinia/nuxt": "^0.11.0",
"@tailwindcss/vite": "^4.1.5", "@tailwindcss/vite": "^4.1.5",
"@tauri-apps/api": "^2.5.0", "@tauri-apps/api": "^2.5.0",
"@tauri-apps/plugin-dialog": "^2.2.1", "@tauri-apps/plugin-dialog": "^2.2.1",
@ -30,7 +31,7 @@
"@tauri-apps/plugin-store": "^2.2.0", "@tauri-apps/plugin-store": "^2.2.0",
"@vueuse/core": "^13.1.0", "@vueuse/core": "^13.1.0",
"@vueuse/nuxt": "^13.1.0", "@vueuse/nuxt": "^13.1.0",
"drizzle-orm": "^0.41.0", "drizzle-orm": "^0.43.0",
"flyonui": "^2.1.0", "flyonui": "^2.1.0",
"nuxt": "^3.17.0", "nuxt": "^3.17.0",
"nuxt-snackbar": "1.3.0", "nuxt-snackbar": "1.3.0",
@ -42,13 +43,12 @@
}, },
"devDependencies": { "devDependencies": {
"@egoist/tailwindcss-icons": "^1.9.0", "@egoist/tailwindcss-icons": "^1.9.0",
"@iconify/json": "^2.2.332", "@iconify/json": "^2.2.338",
"@iconify/tailwind4": "^1.0.6", "@iconify/tailwind4": "^1.0.6",
"@nuxtjs/tailwindcss": "^6.14.0",
"@tauri-apps/cli": "^2.5.0", "@tauri-apps/cli": "^2.5.0",
"@vitejs/plugin-vue": "^5.2.3", "@vitejs/plugin-vue": "^5.2.3",
"drizzle-kit": "^0.30.6", "drizzle-kit": "^0.31.1",
"typescript": "~5.6.3", "typescript": "~5.8.3",
"vite": "^6.3.3", "vite": "^6.3.3",
"vue-tsc": "^2.2.10" "vue-tsc": "^2.2.10"
}, },

1345
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,7 @@ mime_guess = "2.0"
mime = "0.3" mime = "0.3"
fs_extra = "1.3.0" fs_extra = "1.3.0"
sqlparser = { version = "0.56.0", features = [] } sqlparser = { version = "0.56.0", features = [] }
tauri = { version = "2.5", features = ["protocol-asset"] } tauri = { version = "2.5", features = ["protocol-asset", "devtools"] }
tauri-plugin-dialog = "2.2" tauri-plugin-dialog = "2.2"
tauri-plugin-fs = "2.2.0" tauri-plugin-fs = "2.2.0"
tauri-plugin-opener = "2.2" tauri-plugin-opener = "2.2"

View File

@ -5,25 +5,26 @@
"windows": ["main"], "windows": ["main"],
"permissions": [ "permissions": [
"core:default", "core:default",
"core:webview:allow-create-webview-window",
"core:webview:allow-create-webview",
"core:webview:allow-webview-show",
"core:webview:default",
"core:window:allow-create",
"core:window:allow-get-all-windows",
"core:window:allow-show",
"core:window:default",
"dialog:default", "dialog:default",
"fs:allow-appdata-read-recursive",
"fs:allow-appdata-write-recursive",
"fs:allow-read-file", "fs:allow-read-file",
"fs:allow-resource-read-recursive", "fs:allow-resource-read-recursive",
"fs:default", "fs:default",
"fs:allow-resource-write-recursive",
"http:allow-fetch-send", "http:allow-fetch-send",
"http:allow-fetch", "http:allow-fetch",
"http:default", "http:default",
"opener:allow-open-url", "opener:allow-open-url",
"opener:default", "opener:default",
"os:default", "os:default",
"store:default", "store:default"
"core:window:allow-create",
"core:window:default",
"core:window:allow-get-all-windows",
"core:window:allow-show",
"core:webview:allow-create-webview",
"core:webview:allow-create-webview-window",
"core:webview:default",
"core:webview:allow-webview-show"
] ]
} }

View File

@ -130,7 +130,7 @@ pub fn resolve_secure_extension_asset_path<R: Runtime>(
// 2. Bestimme das Basisverzeichnis für alle Erweiterungen (Resource Directory) // 2. Bestimme das Basisverzeichnis für alle Erweiterungen (Resource Directory)
let base_extensions_dir = app_handle let base_extensions_dir = app_handle
.path() .path()
.resource_dir() // Korrekt für Ressourcen .app_data_dir() // Korrekt für Ressourcen
// Wenn du stattdessen App Local Data willst: .app_local_data_dir() // Wenn du stattdessen App Local Data willst: .app_local_data_dir()
.map_err(|e: TauriError| format!("Basis-Verzeichnis nicht gefunden: {}", e))? .map_err(|e: TauriError| format!("Basis-Verzeichnis nicht gefunden: {}", e))?
.join("extensions"); .join("extensions");
@ -220,6 +220,7 @@ pub fn extension_protocol_handler<R: Runtime>(
let mime_type = mime_guess::from_path(&absolute_secure_path) let mime_type = mime_guess::from_path(&absolute_secure_path)
.first_or(mime::APPLICATION_OCTET_STREAM) .first_or(mime::APPLICATION_OCTET_STREAM)
.to_string(); .to_string();
let content_length = content.len();
println!( println!(
"Liefere {} ({}) ", "Liefere {} ({}) ",
absolute_secure_path.display(), absolute_secure_path.display(),
@ -228,6 +229,9 @@ pub fn extension_protocol_handler<R: Runtime>(
Response::builder() Response::builder()
.status(200) .status(200)
.header("Content-Type", mime_type) .header("Content-Type", mime_type)
.header("Content-Length", content_length.to_string()) // <-- HIER HINZUGEFÜGT
// Optional, aber gut für Streaming-Fähigkeit:
.header("Accept-Ranges", "bytes")
.body(content) .body(content)
.map_err(|e| e.into()) .map_err(|e| e.into())
} }

View File

@ -19,12 +19,13 @@
], ],
"security": { "security": {
"csp": { "csp": {
"default-src": ["'self'", "haex-extensions"], "default-src": ["'self'", "haex-extension: data: blob: asset:"],
"script-src": ["'self'", "haex-extensions"], "script-src": ["'self'", "haex-extension:"],
"style-src": ["'self'", "haex-extensions"], "style-src": ["'self'", "haex-extension:"],
"connect-src": ["'self'", "haex-extensions"], "connect-src": ["'self'", "haex-extension:"],
"img-src": ["'self'", "haex-extensions", "data:"], "img-src": ["'self'", "haex-extension:", "data:"],
"font-src": ["'self'", "haex-extensions", "data:"] "font-src": ["'self'", "haex-extension:", "data:"],
"media-src": "'self' haex-extension: data: blob: asset:"
}, },
"assetProtocol": { "assetProtocol": {
"enable": true, "enable": true,
@ -44,6 +45,20 @@
], ],
"resources": { "resources": {
"database/vault.db": "resources/vault.db" "database/vault.db": "resources/vault.db"
},
"linux": {
"appimage": {
"bundleMediaFramework": false,
"files": {}
},
"deb": {
"files": {}
},
"rpm": {
"epoch": 0,
"files": {},
"release": "1"
}
} }
} }
} }

View File

@ -1,33 +1,46 @@
<template> <template>
<div class="w-full h-full overflow-scroll bg-red-300"> <div class="w-full h-full overflow-scroll">
<div> <!-- <div>
{{ iframeSrc }} {{ iframeSrc }}
</div> </div> -->
<iframe <iframe
v-if="iframeSrc" v-if="iframeSrc"
class="w-full h-full" class="w-full h-full"
@load="" @load=""
ref="iFrameRef" ref="iFrameRef"
:src="iframeSrc" :src="iframeIndex"
sandbox="allow-scripts allow-same-origin" sandbox="allow-scripts allow-same-origin"
allow="autoplay; speaker-selection; encrypted-media;"
> >
</iframe> </iframe>
<!-- <p v-else>{{ t("loading") }}</p> --> <!-- <p v-else>{{ t("loading") }}</p> -->
<audio controls :src="audioTest">
Dein Browser unterstützt das Audio-Element nicht.
</audio>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
definePageMeta({ definePageMeta({
name: "haexExtension", name: 'haexExtension',
}); })
const { t } = useI18n(); const { t } = useI18n()
const iframeRef = useTemplateRef("iFrameRef"); const iframeRef = useTemplateRef('iFrameRef')
const { extensionEntry: iframeSrc, currentExtension } = storeToRefs(
useExtensionsStore()
)
const audioTest = computed(() => `${iframeSrc.value}/sounds/music/demo.mp3`)
watch(audioTest, () => console.log('audioTest', audioTest.value), {
immediate: true,
})
const { extensionEntry: iframeSrc, currentExtension } = storeToRefs(useExtensionsStore()); const iframeIndex = computed(() => `${iframeSrc.value}/index.html`)
const extensionStore = useExtensionsStore(); const extensionStore = useExtensionsStore()
watch(iframeSrc, () => console.log("iframeSrc", iframeSrc.value), { immediate: true }); watch(iframeSrc, () => console.log('iframeSrc', iframeSrc.value), {
immediate: true,
})
onMounted(async () => { onMounted(async () => {
/* const minfest = await extensionStore.readManifestFileAsync( /* const minfest = await extensionStore.readManifestFileAsync(
@ -35,7 +48,7 @@ onMounted(async () => {
currentExtension.value!.version currentExtension.value!.version
); );
console.log("manifest", minfest, extensionStore.extensionEntry); */ console.log("manifest", minfest, extensionStore.extensionEntry); */
}); })
</script> </script>
<i18n lang="yaml"> <i18n lang="yaml">

View File

@ -1,5 +1,5 @@
import { convertFileSrc, invoke } from "@tauri-apps/api/core"; import { convertFileSrc, invoke } from "@tauri-apps/api/core";
import { join, resourceDir } from "@tauri-apps/api/path"; import { appDataDir, join } from "@tauri-apps/api/path";
import { exists, readDir, readTextFile, remove } from "@tauri-apps/plugin-fs"; import { exists, readDir, readTextFile, remove } from "@tauri-apps/plugin-fs";
import { and, eq } from "drizzle-orm"; import { and, eq } from "drizzle-orm";
import type { import type {
@ -49,7 +49,7 @@ export const useExtensionsStore = defineStore("extensionsStore", () => {
const getExtensionPathAsync = async (extensionId?: string, version?: string) => { const getExtensionPathAsync = async (extensionId?: string, version?: string) => {
if (!extensionId || !version) return ""; if (!extensionId || !version) return "";
return await join(await resourceDir(), "extensions", extensionId, version); return await join(await appDataDir(), "extensions", extensionId, version);
}; };
const checkSourceExtensionDirectoryAsync = async (extensionDirectory: string) => { const checkSourceExtensionDirectoryAsync = async (extensionDirectory: string) => {
@ -315,7 +315,7 @@ export const useExtensionsStore = defineStore("extensionsStore", () => {
}) })
); );
return `haex-extension://${hexName}/index.html`; return `haex-extension://${hexName}`;
return convertFileSrc(entryPath); //`asset://localhost/${entryPath}`; return convertFileSrc(entryPath); //`asset://localhost/${entryPath}`;
let entryHtml = await readTextFile(entryPath); let entryHtml = await readTextFile(entryPath);