mirror of
https://github.com/haexhub/haex-hub.git
synced 2025-12-16 14:10:52 +01:00
fixed build
This commit is contained in:
@ -1,10 +0,0 @@
|
||||
import { defineConfig } from 'drizzle-kit';
|
||||
|
||||
export default defineConfig({
|
||||
schema: './src-tauri/database/schemas/**.ts',
|
||||
out: './src-tauri/database/migrations',
|
||||
dialect: 'sqlite',
|
||||
dbCredentials: {
|
||||
url: './src-tauri/database/vault.db',
|
||||
},
|
||||
});
|
||||
@ -1,6 +1,11 @@
|
||||
import tailwindcss from '@tailwindcss/vite'
|
||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
|
||||
export default defineNuxtConfig({
|
||||
app: {
|
||||
baseURL: './',
|
||||
},
|
||||
|
||||
modules: [
|
||||
'nuxt-zod-i18n',
|
||||
'@nuxtjs/i18n',
|
||||
@ -89,12 +94,10 @@ export default defineNuxtConfig({
|
||||
ssr: false,
|
||||
// Enables the development server to be discoverable by other devices when running on iOS physical devices
|
||||
devServer: {
|
||||
host: process.env.TAURI_DEV_HOST || '0.0.0.0',
|
||||
host: process.env.TAURI_DEV_HOST || 'localhost',
|
||||
},
|
||||
|
||||
vite: {
|
||||
base: './',
|
||||
|
||||
plugins: [tailwindcss()],
|
||||
// Better support for Tauri CLI output
|
||||
clearScreen: false,
|
||||
|
||||
9
src-tauri/.cargo/config.toml
Normal file
9
src-tauri/.cargo/config.toml
Normal file
@ -0,0 +1,9 @@
|
||||
# Nur dieser Inhalt in src-tauri/.cargo/config.toml
|
||||
|
||||
[target.aarch64-linux-android]
|
||||
# Ersetze die Pfade durch deine tatsächlichen NDK-Pfade
|
||||
# Dein NDK-Basispfad: /home/haex/Android/Sdk/ndk/29.0.13113456
|
||||
# Stelle sicher, dass der clang-Name (mit API-Level, z.B. ...24-clang) korrekt ist.
|
||||
linker = "/home/haex/Android/Sdk/ndk/29.0.13113456/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android33-clang"
|
||||
#ar = "/home/haex/Android/Sdk/ndk/29.0.13113456/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar"
|
||||
#ranlib = "/home/haex/Android/Sdk/ndk/29.0.13113456/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib"
|
||||
@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<!-- AndroidTV support -->
|
||||
<uses-feature android:name="android.software.leanback" android:required="false" />
|
||||
|
||||
|
||||
BIN
src-tauri/gen/android/app/src/main/assets/database/vault.db
Normal file
BIN
src-tauri/gen/android/app/src/main/assets/database/vault.db
Normal file
Binary file not shown.
@ -1,11 +1,15 @@
|
||||
// database/mod.rs
|
||||
pub mod core;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use rusqlite::{Connection, OpenFlags, Result as RusqliteResult};
|
||||
use serde_json::Value as JsonValue;
|
||||
use std::path::Path;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Mutex;
|
||||
use tauri::{path::BaseDirectory, AppHandle, Manager, State};
|
||||
use tauri::utils::resources::Resource;
|
||||
use tauri::{path::BaseDirectory, AppHandle, Manager, State, Wry};
|
||||
use tokio::io::join;
|
||||
|
||||
pub struct DbConnection(pub Mutex<Option<Connection>>);
|
||||
|
||||
// Öffentliche Funktionen für direkten Datenbankzugriff
|
||||
@ -29,7 +33,7 @@ pub async fn sql_execute(
|
||||
|
||||
/// Erstellt eine verschlüsselte Datenbank
|
||||
#[tauri::command]
|
||||
pub fn create_encrypted_database(
|
||||
pub fn create_encrypted_database_old(
|
||||
app_handle: AppHandle,
|
||||
path: String,
|
||||
key: String,
|
||||
@ -39,7 +43,7 @@ pub fn create_encrypted_database(
|
||||
|
||||
let resource_path = app_handle
|
||||
.path()
|
||||
.resolve("resources/vault.db", BaseDirectory::Resource)
|
||||
.resolve("vault.db", BaseDirectory::Resource)
|
||||
.map_err(|e| format!("Fehler beim Auflösen des Ressourcenpfads: {}", e))?;
|
||||
|
||||
// Prüfen, ob die Ressourcendatei existiert
|
||||
@ -229,3 +233,325 @@ pub fn open_encrypted_database(
|
||||
|
||||
Ok(format!("success"))
|
||||
}
|
||||
|
||||
// Notwendige Imports an den Anfang des Moduls stellen
|
||||
//use tauri::{AppHandle, Manager, State, path::BaseDirectory, Wry};
|
||||
//use rusqlite::{Connection, OpenFlags, Result as RusqliteResult};
|
||||
//use std::fs;
|
||||
//use std::path::{Path, PathBuf};
|
||||
//use std::sync::Mutex; // Für den State
|
||||
|
||||
// Stelle sicher, dass dein DbConnection-Typ hier bekannt ist.
|
||||
// z.B. durch pub struct DbConnection(pub Mutex<Option<Connection>>);
|
||||
// oder wenn es in einem anderen Modul ist: use crate::path_to::DbConnection;
|
||||
// Für dieses Beispiel gehe ich davon aus, dass es in crate::DbConnection liegt.
|
||||
// Ersetze `crate::DbConnection` mit dem korrekten Pfad zu deiner Definition.
|
||||
//type SharedDbConnectionState = State<'_, crate::DbConnection>;
|
||||
|
||||
/// Hilfsfunktion: Lädt ein Asset und kopiert es in eine temporäre Datei.
|
||||
/// Gibt den Pfad zur temporären Datei zurück.
|
||||
fn prepare_temporary_asset_db(
|
||||
app_handle: &AppHandle<Wry>,
|
||||
asset_name: &str,
|
||||
temp_base_dir: BaseDirectory,
|
||||
) -> Result<PathBuf, String> {
|
||||
println!("Lade Asset '{}' aus dem App-Bundle...", asset_name);
|
||||
|
||||
//.resolve("vault.db", BaseDirectory::Resource)
|
||||
let asset_bytes = app_handle
|
||||
.asset_resolver()
|
||||
.get(asset_name.to_string())
|
||||
.ok_or_else(|| format!("Asset '{}' wurde nicht im Bundle gefunden.", asset_name))?
|
||||
.bytes()
|
||||
.to_vec();
|
||||
|
||||
println!(
|
||||
"Asset '{}' erfolgreich geladen ({} bytes).",
|
||||
asset_name,
|
||||
asset_bytes.len()
|
||||
);
|
||||
|
||||
let temp_db_filename = format!("temp_unencrypted_{}", asset_name);
|
||||
let temp_db_path = app_handle
|
||||
.path()
|
||||
.resolve(&temp_db_filename, temp_base_dir)
|
||||
.map_err(|e| {
|
||||
format!(
|
||||
"Fehler beim Auflösen des Pfads für die temporäre DB '{}': {}",
|
||||
temp_db_filename, e
|
||||
)
|
||||
})?;
|
||||
|
||||
println!(
|
||||
"Temporärer Pfad für unverschlüsselte DB: {}",
|
||||
temp_db_path.display()
|
||||
);
|
||||
|
||||
if let Some(parent) = temp_db_path.parent() {
|
||||
if !parent.exists() {
|
||||
fs::create_dir_all(parent).map_err(|e| {
|
||||
format!(
|
||||
"Fehler beim Erstellen des temporären Verzeichnisses '{}': {}",
|
||||
parent.display(),
|
||||
e
|
||||
)
|
||||
})?;
|
||||
println!("Temporäres Verzeichnis '{}' erstellt.", parent.display());
|
||||
}
|
||||
}
|
||||
|
||||
if temp_db_path.exists() {
|
||||
fs::remove_file(&temp_db_path).map_err(|e| {
|
||||
format!(
|
||||
"Fehler beim Löschen der alten temporären DB '{}': {}",
|
||||
temp_db_path.display(),
|
||||
e
|
||||
)
|
||||
})?;
|
||||
println!("Alte temporäre DB '{}' gelöscht.", temp_db_path.display());
|
||||
}
|
||||
|
||||
fs::write(&temp_db_path, &asset_bytes).map_err(|e| {
|
||||
format!(
|
||||
"Fehler beim Schreiben der Asset-DB nach '{}': {}",
|
||||
temp_db_path.display(),
|
||||
e
|
||||
)
|
||||
})?;
|
||||
println!(
|
||||
"Asset-DB erfolgreich nach '{}' geschrieben.",
|
||||
temp_db_path.display()
|
||||
);
|
||||
|
||||
Ok(temp_db_path)
|
||||
}
|
||||
|
||||
/// Hilfsfunktion: Verschlüsselt eine Quelldatenbank in eine Zieldatenbank.
|
||||
fn encrypt_database_from_source(
|
||||
unencrypted_source_path: &Path,
|
||||
target_encrypted_path_str: &str,
|
||||
key: &str,
|
||||
) -> Result<(), String> {
|
||||
println!(
|
||||
"Öffne temporäre Quelldatenbank '{}'...",
|
||||
unencrypted_source_path.display()
|
||||
);
|
||||
let source_conn = Connection::open(unencrypted_source_path).map_err(|e| {
|
||||
format!(
|
||||
"Fehler beim Öffnen der Quelldatenbank '{}': {}",
|
||||
unencrypted_source_path.display(),
|
||||
e
|
||||
)
|
||||
})?;
|
||||
println!(
|
||||
"Verbindung zur Quelldatenbank '{}' geöffnet.",
|
||||
unencrypted_source_path.display()
|
||||
);
|
||||
|
||||
let final_encrypted_db_path = PathBuf::from(target_encrypted_path_str);
|
||||
println!(
|
||||
"Zielpfad für verschlüsselte DB: {}",
|
||||
final_encrypted_db_path.display()
|
||||
);
|
||||
|
||||
if let Some(parent) = final_encrypted_db_path.parent() {
|
||||
if !parent.exists() {
|
||||
fs::create_dir_all(parent).map_err(|e| {
|
||||
format!(
|
||||
"Fehler beim Erstellen des Zielverzeichnisses '{}': {}",
|
||||
parent.display(),
|
||||
e
|
||||
)
|
||||
})?;
|
||||
println!("Zielverzeichnis '{}' erstellt.", parent.display());
|
||||
}
|
||||
}
|
||||
if final_encrypted_db_path.exists() {
|
||||
fs::remove_file(&final_encrypted_db_path).map_err(|e| {
|
||||
format!(
|
||||
"Fehler beim Löschen der alten verschlüsselten DB '{}': {}",
|
||||
final_encrypted_db_path.display(),
|
||||
e
|
||||
)
|
||||
})?;
|
||||
println!(
|
||||
"Alte verschlüsselte DB '{}' gelöscht.",
|
||||
final_encrypted_db_path.display()
|
||||
);
|
||||
}
|
||||
|
||||
let attach_path_str = final_encrypted_db_path.to_str().ok_or_else(|| {
|
||||
format!(
|
||||
"Ungültiger UTF-8 Pfad für ATTACH: {}",
|
||||
final_encrypted_db_path.display()
|
||||
)
|
||||
})?;
|
||||
|
||||
println!(
|
||||
"Hänge neue verschlüsselte DB an: '{}' mit KEY '{}'",
|
||||
attach_path_str, key
|
||||
);
|
||||
source_conn
|
||||
.execute(
|
||||
"ATTACH DATABASE ?1 AS encrypted_vault KEY ?2;",
|
||||
&[attach_path_str, key],
|
||||
)
|
||||
.map_err(|e| format!("Fehler bei ATTACH DATABASE an '{}': {}", attach_path_str, e))?;
|
||||
println!("Verschlüsselte DB 'encrypted_vault' erfolgreich angehängt.");
|
||||
|
||||
println!("Exportiere Daten von 'main' (Quelle) nach 'encrypted_vault'...");
|
||||
if let Err(e) = source_conn.execute("SELECT sqlcipher_export('encrypted_vault');", []) {
|
||||
eprintln!("!!! FEHLER während sqlcipher_export: {}", e);
|
||||
source_conn
|
||||
.execute("DETACH DATABASE encrypted_vault;", [])
|
||||
.ok(); // Best-effort cleanup
|
||||
return Err(format!("Fehler bei sqlcipher_export: {}", e));
|
||||
}
|
||||
println!("SQLCipher Export nach 'encrypted_vault' erfolgreich.");
|
||||
|
||||
println!("Löse 'encrypted_vault'...");
|
||||
source_conn
|
||||
.execute("DETACH DATABASE encrypted_vault;", [])
|
||||
.map_err(|e| format!("Fehler bei DETACH DATABASE 'encrypted_vault': {}", e))?;
|
||||
println!("'encrypted_vault' erfolgreich gelöst.");
|
||||
|
||||
// Verbindung zur Quelldatenbank wird hier durch drop(source_conn) geschlossen.
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Hilfsfunktion: Öffnet eine verschlüsselte Datenbank und verifiziert sie.
|
||||
/// Gibt die geöffnete und verifizierte Verbindung zurück.
|
||||
fn open_and_verify_encrypted_db(db_path: &Path, key: &str) -> Result<Connection, String> {
|
||||
println!(
|
||||
"Öffne verschlüsselte DB '{}' zur Überprüfung...",
|
||||
db_path.display()
|
||||
);
|
||||
let conn = Connection::open(db_path).map_err(|e| {
|
||||
format!(
|
||||
"Fehler beim Öffnen der verschlüsselten DB '{}' für Check: {}",
|
||||
db_path.display(),
|
||||
e
|
||||
)
|
||||
})?;
|
||||
|
||||
conn.pragma_update(None, "key", key).map_err(|e| {
|
||||
format!(
|
||||
"Fehler beim Setzen des PRAGMA key für DB '{}': {}",
|
||||
db_path.display(),
|
||||
e
|
||||
)
|
||||
})?;
|
||||
println!("PRAGMA key für DB '{}' gesetzt.", db_path.display());
|
||||
|
||||
println!("Prüfe SQLCipher-Version auf DB '{}'...", db_path.display());
|
||||
match conn.query_row("PRAGMA cipher_version;", [], |row| row.get::<_, String>(0)) {
|
||||
Ok(version) => {
|
||||
println!(
|
||||
"SQLCipher ist aktiv auf DB '{}'! Version: {}",
|
||||
db_path.display(),
|
||||
version
|
||||
);
|
||||
match conn.query_row(
|
||||
"SELECT count(*) FROM sqlite_master WHERE type='table';",
|
||||
[],
|
||||
|row| row.get::<_, i32>(0),
|
||||
) {
|
||||
Ok(count) => println!(
|
||||
"Testabfrage erfolgreich: {} Tabelle(n) in DB '{}' gefunden.",
|
||||
count,
|
||||
db_path.display()
|
||||
),
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"Fehler bei Testabfrage auf verschlüsselter DB '{}': {}",
|
||||
db_path.display(),
|
||||
e
|
||||
);
|
||||
return Err(format!(
|
||||
"Testabfrage auf verschlüsselter DB '{}' fehlgeschlagen: {}",
|
||||
db_path.display(),
|
||||
e
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"FEHLER: SQLCipher scheint NICHT aktiv zu sein auf DB '{}'!",
|
||||
db_path.display()
|
||||
);
|
||||
eprintln!("'PRAGMA cipher_version;' schlug fehl: {}", e);
|
||||
return Err(format!(
|
||||
"SQLCipher Aktivitätscheck für DB '{}' fehlgeschlagen: {}",
|
||||
db_path.display(),
|
||||
e
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(conn)
|
||||
}
|
||||
|
||||
/// Hauptfunktion: Erstellt eine verschlüsselte Datenbank aus einem gebündelten Asset.
|
||||
#[tauri::command]
|
||||
pub fn create_encrypted_database(
|
||||
app_handle: AppHandle<Wry>,
|
||||
path: String,
|
||||
key: String,
|
||||
state: State<'_, DbConnection>,
|
||||
) -> Result<String, String> {
|
||||
let asset_name = "database/vault.db";
|
||||
let temp_db_path: PathBuf; // Muss deklariert werden, um im Fehlerfall aufgeräumt werden zu können
|
||||
|
||||
// Schritt 1: Asset vorbereiten
|
||||
match prepare_temporary_asset_db(&app_handle, &asset_name, BaseDirectory::AppData) {
|
||||
Ok(path) => temp_db_path = path,
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
|
||||
// Schritt 2: Datenbank verschlüsseln
|
||||
// Wir geben einen String-Slice für path, da die Funktion das erwartet.
|
||||
if let Err(e) = encrypt_database_from_source(&temp_db_path, &path, &key) {
|
||||
// Versuche, die temporäre Datei auch im Fehlerfall zu löschen
|
||||
let _ = fs::remove_file(&temp_db_path); // Fehler beim Löschen hier ignorieren
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
// Schritt 3: Temporäre Datei aufräumen
|
||||
if let Err(e) = fs::remove_file(&temp_db_path) {
|
||||
// Logge den Fehler, aber fahre fort, da die verschlüsselte DB erstellt wurde
|
||||
eprintln!("Warnung: Fehler beim Löschen der temporären DB '{}': {}. Die verschlüsselte DB wurde jedoch erstellt.", temp_db_path.display(), e);
|
||||
} else {
|
||||
println!(
|
||||
"Temporäre DB '{}' erfolgreich gelöscht.",
|
||||
temp_db_path.display()
|
||||
);
|
||||
}
|
||||
println!("Datenbank erfolgreich nach '{}' verschlüsselt.", path);
|
||||
|
||||
// Schritt 4: Neu erstellte verschlüsselte Datenbank öffnen und verifizieren
|
||||
let final_encrypted_db_path = PathBuf::from(path.clone()); // Klonen, da String für Pfad benötigt wird
|
||||
let final_conn = match open_and_verify_encrypted_db(&final_encrypted_db_path, &key) {
|
||||
Ok(conn) => conn,
|
||||
Err(e) => {
|
||||
// Wenn das Öffnen/Verifizieren fehlschlägt, existiert die Datei vielleicht, ist aber unbrauchbar.
|
||||
// Je nach Strategie könnte man hier die `final_encrypted_db_path` löschen.
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
|
||||
// Schritt 5: Datenbankverbindung im State aktualisieren
|
||||
println!(
|
||||
"Aktualisiere DB-Verbindung im State mit '{}'",
|
||||
final_encrypted_db_path.display()
|
||||
);
|
||||
let mut db_state_lock = state
|
||||
.0
|
||||
.lock()
|
||||
.map_err(|e| format!("Mutex-Fehler beim Sperren des DB-Status: {}", e.to_string()))?;
|
||||
*db_state_lock = Some(final_conn);
|
||||
|
||||
Ok(format!(
|
||||
"Verschlüsselte Datenbank erfolgreich erstellt, geprüft und im State gespeichert unter: {}",
|
||||
final_encrypted_db_path.display()
|
||||
))
|
||||
}
|
||||
|
||||
@ -12,6 +12,73 @@ pub fn run() {
|
||||
let protocol_name = "haex-extension";
|
||||
|
||||
tauri::Builder::default()
|
||||
.setup(|app| {
|
||||
// --- START DER ASSET-INVENTUR (Korrigierte Version) ---
|
||||
println!("\n[INVENTUR] App-Setup wird ausgeführt. Liste alle Assets im Bundle auf...");
|
||||
|
||||
let mut found_assets_count = 0;
|
||||
|
||||
// KORREKTE METHODE: Direkt über eine Referenz auf den AssetResolver iterieren
|
||||
for asset_name in app.asset_resolver().iter() {
|
||||
found_assets_count += 1;
|
||||
// Wir geben jeden gefundenen Asset-Namen aus
|
||||
println!("[INVENTUR] Gefundenes Asset: '{}'", asset_name.0);
|
||||
}
|
||||
|
||||
if found_assets_count == 0 {
|
||||
println!("[INVENTUR] Es wurden KEINE Assets im Bundle gefunden!");
|
||||
} else {
|
||||
println!(
|
||||
"[INVENTUR] Inventur abgeschlossen. {} Assets gefunden.",
|
||||
found_assets_count
|
||||
);
|
||||
}
|
||||
|
||||
println!("[INVENTUR] --- ENDE DER INVENTUR ---\n");
|
||||
// --- ENDE DER ASSET-INVENTUR ---
|
||||
// --- START DES DEFINITIVEN ASSET-TESTS ---
|
||||
println!("\n[DEBUG] App-Setup wird ausgeführt. Versuche, die Datenbank zu laden...");
|
||||
|
||||
// BITTE SICHERSTELLEN: Dieser String muss EXAKT dem SCHLÜSSEL (KEY)
|
||||
// in deiner tauri.conf.json entsprechen!
|
||||
let asset_to_find = "database/vault.db";
|
||||
|
||||
println!(
|
||||
"[DEBUG] Suche nach Asset mit dem Alias: '{}'",
|
||||
asset_to_find
|
||||
);
|
||||
|
||||
match app.asset_resolver().get(asset_to_find.to_string()) {
|
||||
Some(asset) => {
|
||||
// ERFOLG! Das Asset wurde gefunden.
|
||||
println!("\n✅ ✅ ✅ ERFOLG! ✅ ✅ ✅");
|
||||
println!(
|
||||
"[DEBUG] Asset '{}' wurde im Bundle gefunden.",
|
||||
asset_to_find
|
||||
);
|
||||
println!("[DEBUG] Größe der Datenbank: {} Bytes.", asset.bytes.len());
|
||||
}
|
||||
None => {
|
||||
// FEHLER! Das Asset wurde nicht gefunden.
|
||||
println!("\n❌ ❌ ❌ FEHLER! ❌ ❌ ❌");
|
||||
println!(
|
||||
"[DEBUG] Asset '{}' wurde NICHT im Bundle gefunden.",
|
||||
asset_to_find
|
||||
);
|
||||
println!("[DEBUG] Mögliche Ursachen:");
|
||||
println!("[DEBUG] 1. Der Alias-String im Code ist falsch (Tippfehler?).");
|
||||
println!("[DEBUG] 2. Der Schlüssel in 'tauri.conf.json' ist anders.");
|
||||
println!(
|
||||
"[DEBUG] 3. Der Build-Cache ist veraltet (lösche 'src-tauri/target')."
|
||||
);
|
||||
}
|
||||
}
|
||||
println!("[DEBUG] --- ENDE DES ASSET-TESTS ---\n");
|
||||
// --- ENDE DES DEFINITIVEN ASSET-TESTS ---
|
||||
|
||||
// Hier kann dein restlicher Setup-Code stehen bleiben
|
||||
Ok(())
|
||||
})
|
||||
.register_uri_scheme_protocol(protocol_name, move |context, request| {
|
||||
match extension::core::extension_protocol_handler(&context, &request) {
|
||||
Ok(response) => response, // Wenn der Handler Ok ist, gib die Response direkt zurück
|
||||
@ -42,11 +109,11 @@ pub fn run() {
|
||||
}
|
||||
}
|
||||
})
|
||||
.plugin(tauri_plugin_http::init())
|
||||
.manage(DbConnection(Mutex::new(None)))
|
||||
.manage(ExtensionState::default())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_fs::init())
|
||||
.plugin(tauri_plugin_http::init())
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.plugin(tauri_plugin_os::init())
|
||||
.plugin(tauri_plugin_store::Builder::new().build())
|
||||
|
||||
@ -5,9 +5,9 @@
|
||||
"identifier": "space.haex.hub",
|
||||
"build": {
|
||||
"beforeDevCommand": "pnpm dev",
|
||||
"devUrl": "http://0.0.0.0:3001",
|
||||
"devUrl": "http://localhost:3000",
|
||||
"beforeBuildCommand": "pnpm generate",
|
||||
"frontendDist": "../.output/public"
|
||||
"frontendDist": "../dist"
|
||||
},
|
||||
"app": {
|
||||
"windows": [
|
||||
@ -40,7 +40,7 @@
|
||||
},
|
||||
"assetProtocol": {
|
||||
"enable": true,
|
||||
"scope": ["*"]
|
||||
"scope": ["$APPDATA", "$RESOURCE"]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -54,22 +54,6 @@
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
],
|
||||
"resources": {
|
||||
"database/vault.db": "resources/vault.db"
|
||||
},
|
||||
"linux": {
|
||||
"appimage": {
|
||||
"bundleMediaFramework": false,
|
||||
"files": {}
|
||||
},
|
||||
"deb": {
|
||||
"files": {}
|
||||
},
|
||||
"rpm": {
|
||||
"epoch": 0,
|
||||
"files": {},
|
||||
"release": "1"
|
||||
}
|
||||
}
|
||||
"resources": ["test.txt"]
|
||||
}
|
||||
}
|
||||
|
||||
0
src-tauri/test.txt
Normal file
0
src-tauri/test.txt
Normal file
@ -8,7 +8,6 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
const { currentTheme } = storeToRefs(useUiStore())
|
||||
</script>
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
v-model:open="open"
|
||||
:title="t('title')"
|
||||
class="btn btn-primary btn-outline shadow-md md:btn-lg shrink-0 flex-1 whitespace-nowrap flex-nowrap"
|
||||
@click="open = true"
|
||||
>
|
||||
<template #trigger>
|
||||
<Icon name="mdi:plus" />
|
||||
|
||||
@ -4,11 +4,11 @@
|
||||
<UiDropdownLocale @select="setLocale" />
|
||||
</div>
|
||||
<div class="flex flex-col justify-center items-center gap-5 max-w-3xl">
|
||||
<img
|
||||
<!-- <img
|
||||
src="/logo.svg"
|
||||
class="bg-primary p-3 size-16 rounded-full"
|
||||
alt="HaexVault Logo"
|
||||
>
|
||||
/> -->
|
||||
|
||||
<span
|
||||
class="flex flex-wrap font-bold text-pretty text-xl gap-2 justify-center"
|
||||
|
||||
@ -19,11 +19,11 @@ export default defineNuxtPlugin(() => {
|
||||
}, 50)
|
||||
})
|
||||
|
||||
if (import.meta.client) {
|
||||
/* if (import.meta.client) {
|
||||
setTimeout(() => {
|
||||
if (window.HSStaticMethods) {
|
||||
window.HSStaticMethods.autoInit()
|
||||
}
|
||||
}, 50)
|
||||
}
|
||||
} */
|
||||
})
|
||||
|
||||
121
utils/helper.ts
121
utils/helper.ts
@ -1,121 +0,0 @@
|
||||
import type { LocationQueryValue, RouteLocationRawI18n } from 'vue-router'
|
||||
|
||||
export const bytesToBase64DataUrlAsync = async (
|
||||
bytes: Uint8Array,
|
||||
type = 'application/octet-stream',
|
||||
) => {
|
||||
return await new Promise((resolve, reject) => {
|
||||
const reader = Object.assign(new FileReader(), {
|
||||
onload: () => resolve(reader.result),
|
||||
onerror: () => reject(reader.error),
|
||||
})
|
||||
reader.readAsDataURL(new File([new Blob([bytes])], '', { type }))
|
||||
})
|
||||
}
|
||||
|
||||
export const blobToImageAsync = (blob: Blob): Promise<HTMLImageElement> => {
|
||||
return new Promise((resolve) => {
|
||||
console.log('transform blob', blob)
|
||||
const url = URL.createObjectURL(blob)
|
||||
const img = new Image()
|
||||
img.onload = () => {
|
||||
URL.revokeObjectURL(url)
|
||||
resolve(img)
|
||||
}
|
||||
img.src = url
|
||||
})
|
||||
}
|
||||
|
||||
/* export const deepToRaw = <T extends Record<string, any>>(sourceObj: T): T => {
|
||||
const objectIterator = (input: any): any => {
|
||||
if (Array.isArray(input)) {
|
||||
return input.map((item) => objectIterator(item));
|
||||
}
|
||||
if (isRef(input) || isReactive(input) || isProxy(input)) {
|
||||
return objectIterator(toRaw(input));
|
||||
}
|
||||
if (input && typeof input === "object") {
|
||||
return Object.keys(input).reduce((acc, key) => {
|
||||
acc[key as keyof typeof acc] = objectIterator(input[key]);
|
||||
return acc;
|
||||
}, {} as T);
|
||||
}
|
||||
return input;
|
||||
};
|
||||
|
||||
return objectIterator(sourceObj);
|
||||
}; */
|
||||
|
||||
export const readableFileSize = (sizeInByte: number | string = 0) => {
|
||||
if (!sizeInByte) {
|
||||
return '0 KB'
|
||||
}
|
||||
const size =
|
||||
typeof sizeInByte === 'string' ? parseInt(sizeInByte) : sizeInByte
|
||||
const sizeInKb = size / 1024
|
||||
const sizeInMb = sizeInKb / 1024
|
||||
const sizeInGb = sizeInMb / 1024
|
||||
const sizeInTb = sizeInGb / 1024
|
||||
|
||||
if (sizeInTb > 1) return `${sizeInTb.toFixed(2)} TB`
|
||||
if (sizeInGb > 1) return `${sizeInGb.toFixed(2)} GB`
|
||||
if (sizeInMb > 1) return `${sizeInMb.toFixed(2)} MB`
|
||||
|
||||
return `${sizeInKb.toFixed(2)} KB`
|
||||
}
|
||||
|
||||
export const getSingleRouteParam = (
|
||||
param: string | string[] | LocationQueryValue | LocationQueryValue[],
|
||||
): string => {
|
||||
const _param = Array.isArray(param) ? param.at(0) ?? '' : param ?? ''
|
||||
//console.log('found param', _param, param);
|
||||
return decodeURIComponent(_param)
|
||||
}
|
||||
|
||||
export const isRouteActive = (
|
||||
to: RouteLocationRawI18n,
|
||||
exact: boolean = false,
|
||||
) =>
|
||||
computed(() => {
|
||||
const found = useRouter()
|
||||
.getRoutes()
|
||||
.find((route) => route.name === useLocaleRoute()(to)?.name)
|
||||
//console.log('found route', found, useRouter().currentRoute.value, to);
|
||||
return exact
|
||||
? found?.name === useRouter().currentRoute.value.name
|
||||
: found?.name === useRouter().currentRoute.value.name ||
|
||||
found?.children.some(
|
||||
(child) => child.name === useRouter().currentRoute.value.name,
|
||||
)
|
||||
})
|
||||
|
||||
export const isKey = <T extends object>(x: T, k: PropertyKey): k is keyof T => {
|
||||
return k in x
|
||||
}
|
||||
|
||||
export const filterAsync = async <T>(
|
||||
arr: T[],
|
||||
predicate: (value: T, index: number, array: T[]) => Promise<boolean>,
|
||||
) => {
|
||||
// 1. Mappe jedes Element auf ein Promise, das zu true/false auflöst
|
||||
const results = await Promise.all(arr.map(predicate))
|
||||
|
||||
// 2. Filtere das ursprüngliche Array basierend auf den Ergebnissen
|
||||
return arr.filter((_value, index) => results[index])
|
||||
}
|
||||
|
||||
export const stringToHex = (str: string) =>
|
||||
str
|
||||
.split('')
|
||||
.map((char) => char.charCodeAt(0).toString(16).padStart(2, '0'))
|
||||
.join('') // Join array into a single string
|
||||
|
||||
export const hexToString = (hex: string) => {
|
||||
if (!hex) return ''
|
||||
const parsedValue = hex
|
||||
.match(/.{1,2}/g) // Split hex into pairs
|
||||
?.map((byte) => String.fromCharCode(parseInt(byte, 16))) // Convert hex to char
|
||||
.join('') // Join array into a single string
|
||||
|
||||
return parsedValue ? parsedValue : ''
|
||||
}
|
||||
Reference in New Issue
Block a user