mirror of
https://github.com/haexhub/haex-hub.git
synced 2025-12-16 14:10:52 +01:00
add notifications
This commit is contained in:
@ -1,10 +1,10 @@
|
||||
import { defineConfig } from 'drizzle-kit';
|
||||
import { defineConfig } from 'drizzle-kit'
|
||||
|
||||
export default defineConfig({
|
||||
schema: './src/database/schemas/**.ts',
|
||||
out: './src/database/migrations',
|
||||
schema: './src-tauri/database/schemas/**.ts',
|
||||
out: './src-tauri/database/migrations',
|
||||
dialect: 'sqlite',
|
||||
dbCredentials: {
|
||||
url: './src/database/default.db',
|
||||
url: './src-tauri/database/vault.db',
|
||||
},
|
||||
});
|
||||
})
|
||||
|
||||
@ -2,10 +2,6 @@ import tailwindcss from '@tailwindcss/vite'
|
||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
|
||||
export default defineNuxtConfig({
|
||||
app: {
|
||||
baseURL: './',
|
||||
},
|
||||
|
||||
modules: [
|
||||
'nuxt-zod-i18n',
|
||||
'@nuxtjs/i18n',
|
||||
|
||||
21
package.json
21
package.json
@ -16,35 +16,36 @@
|
||||
"eslint:fix": "eslint --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@libsql/client": "^0.15.7",
|
||||
"@libsql/client": "^0.15.8",
|
||||
"@nuxt/eslint": "1.4.1",
|
||||
"@nuxt/icon": "^1.13.0",
|
||||
"@nuxtjs/i18n": "^9.5.4",
|
||||
"@nuxtjs/i18n": "^9.5.5",
|
||||
"@pinia/nuxt": "^0.11.0",
|
||||
"@tailwindcss/vite": "^4.1.7",
|
||||
"@tailwindcss/vite": "^4.1.8",
|
||||
"@tauri-apps/api": "^2.5.0",
|
||||
"@tauri-apps/plugin-dialog": "^2.2.2",
|
||||
"@tauri-apps/plugin-fs": "^2.3.0",
|
||||
"@tauri-apps/plugin-http": "~2.4.4",
|
||||
"@tauri-apps/plugin-notification": "~2.2.2",
|
||||
"@tauri-apps/plugin-opener": "^2.2.7",
|
||||
"@tauri-apps/plugin-os": "^2.2.1",
|
||||
"@tauri-apps/plugin-sql": "~2.2.0",
|
||||
"@tauri-apps/plugin-store": "^2.2.0",
|
||||
"@vueuse/core": "^13.2.0",
|
||||
"@vueuse/nuxt": "^13.2.0",
|
||||
"@vueuse/core": "^13.3.0",
|
||||
"@vueuse/nuxt": "^13.3.0",
|
||||
"drizzle-orm": "^0.43.1",
|
||||
"eslint": "^9.27.0",
|
||||
"eslint": "^9.28.0",
|
||||
"flyonui": "^2.2.0",
|
||||
"nuxt": "^3.17.4",
|
||||
"nuxt-snackbar": "1.3.0",
|
||||
"nuxt-zod-i18n": "^1.11.5",
|
||||
"tailwindcss": "^4.1.7",
|
||||
"vue": "^3.5.14",
|
||||
"tailwindcss": "^4.1.8",
|
||||
"vue": "^3.5.16",
|
||||
"vue-router": "^4.5.1",
|
||||
"zod": "^3.25.21"
|
||||
"zod": "^3.25.42"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify/json": "^2.2.340",
|
||||
"@iconify/json": "^2.2.343",
|
||||
"@iconify/tailwind4": "^1.0.6",
|
||||
"@tauri-apps/cli": "^2.5.0",
|
||||
"drizzle-kit": "^0.31.1",
|
||||
|
||||
3242
pnpm-lock.yaml
generated
3242
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
69
src-tauri/Cargo.lock
generated
69
src-tauri/Cargo.lock
generated
@ -1548,6 +1548,7 @@ dependencies = [
|
||||
"tauri-plugin-dialog",
|
||||
"tauri-plugin-fs",
|
||||
"tauri-plugin-http",
|
||||
"tauri-plugin-notification",
|
||||
"tauri-plugin-opener",
|
||||
"tauri-plugin-os",
|
||||
"tauri-plugin-store",
|
||||
@ -2180,6 +2181,18 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
|
||||
|
||||
[[package]]
|
||||
name = "mac-notification-sys"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b95dfb34071d1592b45622bf93e315e3a72d414b6782aca9a015c12bec367ef"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"objc2 0.6.0",
|
||||
"objc2-foundation 0.3.0",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "markup5ever"
|
||||
version = "0.11.0"
|
||||
@ -2328,6 +2341,20 @@ version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
||||
|
||||
[[package]]
|
||||
name = "notify-rust"
|
||||
version = "4.11.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6442248665a5aa2514e794af3b39661a8e73033b1cc5e59899e1276117ee4400"
|
||||
dependencies = [
|
||||
"futures-lite",
|
||||
"log",
|
||||
"mac-notification-sys",
|
||||
"serde",
|
||||
"tauri-winrt-notification",
|
||||
"zbus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
@ -2889,7 +2916,7 @@ checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"indexmap 2.8.0",
|
||||
"quick-xml",
|
||||
"quick-xml 0.32.0",
|
||||
"serde",
|
||||
"time",
|
||||
]
|
||||
@ -3044,6 +3071,15 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.37.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn"
|
||||
version = "0.11.7"
|
||||
@ -4259,6 +4295,25 @@ dependencies = [
|
||||
"urlpattern",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-notification"
|
||||
version = "2.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c474c7cc524385e682ccc1e149e13913a66fd8586ac4c2319cf01b78f070d309"
|
||||
dependencies = [
|
||||
"log",
|
||||
"notify-rust",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"thiserror 2.0.12",
|
||||
"time",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-opener"
|
||||
version = "2.2.6"
|
||||
@ -4412,6 +4467,18 @@ dependencies = [
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-winrt-notification"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b1e66e07de489fe43a46678dd0b8df65e0c973909df1b60ba33874e297ba9b9"
|
||||
dependencies = [
|
||||
"quick-xml 0.37.5",
|
||||
"thiserror 2.0.12",
|
||||
"windows 0.61.1",
|
||||
"windows-version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.19.1"
|
||||
|
||||
@ -40,4 +40,5 @@ tauri-plugin-opener = "2.2"
|
||||
tauri-plugin-os = "2"
|
||||
tauri-plugin-store = "2"
|
||||
tauri-plugin-http = "2.4"
|
||||
tauri-plugin-notification = "2"
|
||||
#tauri-plugin-sql = { version = "2", features = ["sqlite"] }
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
"dialog:default",
|
||||
"fs:allow-appdata-read-recursive",
|
||||
"fs:allow-appdata-write-recursive",
|
||||
"fs:allow-appconfig-read-recursive",
|
||||
"fs:allow-appconfig-write-recursive",
|
||||
"fs:allow-read-file",
|
||||
"fs:allow-resource-read-recursive",
|
||||
"fs:default",
|
||||
@ -26,6 +28,10 @@
|
||||
"opener:default",
|
||||
"os:default",
|
||||
"os:allow-hostname",
|
||||
"store:default"
|
||||
"store:default",
|
||||
"notification:default",
|
||||
"notification:allow-notify",
|
||||
"notification:allow-create-channel",
|
||||
"notification:allow-list-channels"
|
||||
]
|
||||
}
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
CREATE TABLE `haex_notofications` (
|
||||
`id` text PRIMARY KEY NOT NULL,
|
||||
`title` text,
|
||||
`text` text,
|
||||
`type` text NOT NULL,
|
||||
`read` integer,
|
||||
`date` text,
|
||||
`image` text,
|
||||
`alt` text,
|
||||
`icon` text
|
||||
);
|
||||
251
src-tauri/database/migrations/meta/0003_snapshot.json
Normal file
251
src-tauri/database/migrations/meta/0003_snapshot.json
Normal file
@ -0,0 +1,251 @@
|
||||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"id": "5f413421-18a5-4c1b-9c5b-99f574b10126",
|
||||
"prevId": "ea3507ca-77bc-4f3c-a605-8426614f5803",
|
||||
"tables": {
|
||||
"haex_extensions": {
|
||||
"name": "haex_extensions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"author": {
|
||||
"name": "author",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"enabled": {
|
||||
"name": "enabled",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"url": {
|
||||
"name": "url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"version": {
|
||||
"name": "version",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"haex_extensions_permissions": {
|
||||
"name": "haex_extensions_permissions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"extension_id": {
|
||||
"name": "extension_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"resource": {
|
||||
"name": "resource",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"operation": {
|
||||
"name": "operation",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"path": {
|
||||
"name": "path",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"haex_extensions_permissions_extension_id_resource_operation_path_unique": {
|
||||
"name": "haex_extensions_permissions_extension_id_resource_operation_path_unique",
|
||||
"columns": [
|
||||
"extension_id",
|
||||
"resource",
|
||||
"operation",
|
||||
"path"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"haex_extensions_permissions_extension_id_haex_extensions_id_fk": {
|
||||
"name": "haex_extensions_permissions_extension_id_haex_extensions_id_fk",
|
||||
"tableFrom": "haex_extensions_permissions",
|
||||
"tableTo": "haex_extensions",
|
||||
"columnsFrom": [
|
||||
"extension_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"haex_notofications": {
|
||||
"name": "haex_notofications",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"text": {
|
||||
"name": "text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"read": {
|
||||
"name": "read",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"date": {
|
||||
"name": "date",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"image": {
|
||||
"name": "image",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"alt": {
|
||||
"name": "alt",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"haex_settings": {
|
||||
"name": "haex_settings",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"key": {
|
||||
"name": "key",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"value": {
|
||||
"name": "value",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"enums": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@ -22,6 +22,13 @@
|
||||
"when": 1747583956679,
|
||||
"tag": "0002_married_bushwacker",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "6",
|
||||
"when": 1748873820060,
|
||||
"tag": "0003_familiar_doctor_faustus",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -11,6 +11,8 @@ export const haexSettings = sqliteTable('haex_settings', {
|
||||
key: text(),
|
||||
value: text(),
|
||||
})
|
||||
export type InsertHaexSettings = typeof haexSettings.$inferInsert
|
||||
export type SelectHaexSettings = typeof haexSettings.$inferSelect
|
||||
|
||||
export const haexExtensions = sqliteTable('haex_extensions', {
|
||||
id: text().primaryKey(),
|
||||
@ -21,6 +23,8 @@ export const haexExtensions = sqliteTable('haex_extensions', {
|
||||
url: text(),
|
||||
version: text(),
|
||||
})
|
||||
export type InsertHaexExtensions = typeof haexExtensions.$inferInsert
|
||||
export type SelectHaexExtensions = typeof haexExtensions.$inferSelect
|
||||
|
||||
export const haexExtensionsPermissions = sqliteTable(
|
||||
'haex_extensions_permissions',
|
||||
@ -37,14 +41,21 @@ export const haexExtensionsPermissions = sqliteTable(
|
||||
unique().on(table.extensionId, table.resource, table.operation, table.path),
|
||||
],
|
||||
)
|
||||
|
||||
export type InsertHaexSettings = typeof haexSettings.$inferInsert
|
||||
export type SelectHaexSettings = typeof haexSettings.$inferSelect
|
||||
|
||||
export type InsertHaexExtensions = typeof haexExtensions.$inferInsert
|
||||
export type SelectHaexExtensions = typeof haexExtensions.$inferSelect
|
||||
|
||||
export type InsertHaexExtensionsPermissions =
|
||||
typeof haexExtensionsPermissions.$inferInsert
|
||||
export type SelectHaexExtensionsPermissions =
|
||||
typeof haexExtensionsPermissions.$inferSelect
|
||||
|
||||
export const haexNotifications = sqliteTable('haex_notofications', {
|
||||
id: text().primaryKey(),
|
||||
title: text(),
|
||||
text: text(),
|
||||
type: text({ enum: ['error', 'success', 'warning', 'info'] }).notNull(),
|
||||
read: integer({ mode: 'boolean' }),
|
||||
date: text(),
|
||||
image: text(),
|
||||
alt: text(),
|
||||
icon: text(),
|
||||
})
|
||||
export type InsertHaexNotifications = typeof haexNotifications.$inferInsert
|
||||
export type SelectHaexNotifications = typeof haexNotifications.$inferSelect
|
||||
|
||||
Binary file not shown.
@ -4,11 +4,12 @@ pub mod core;
|
||||
use rusqlite::{Connection, OpenFlags, Result as RusqliteResult};
|
||||
use serde_json::Value as JsonValue;
|
||||
use std::fs;
|
||||
use std::io::Read;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Mutex;
|
||||
use tauri::utils::resources::Resource;
|
||||
use tauri::{path::BaseDirectory, AppHandle, Manager, State, Wry};
|
||||
use tokio::io::join;
|
||||
use tauri_plugin_fs::FsExt;
|
||||
|
||||
pub struct DbConnection(pub Mutex<Option<Connection>>);
|
||||
|
||||
@ -31,6 +32,18 @@ pub async fn sql_execute(
|
||||
core::execute(sql, params, &state).await
|
||||
}
|
||||
|
||||
// remember to call `.manage(MyState::default())`
|
||||
#[tauri::command]
|
||||
pub fn test(app_handle: AppHandle) -> Result<String, String> {
|
||||
let resource_path = app_handle
|
||||
.path()
|
||||
.resolve("database/vault.db", BaseDirectory::Resource)
|
||||
.map_err(|e| format!("Fehler {}", e));
|
||||
//let file = app_handle.fs().open(resource_path, {}).unwrap().read();
|
||||
Ok(String::from(resource_path.unwrap().to_string_lossy()))
|
||||
/* std::fs::exists(String::from(resource_path.unwrap().to_string_lossy()))
|
||||
.map_err(|e| format!("Fehler: {}", e)) */
|
||||
}
|
||||
/// Erstellt eine verschlüsselte Datenbank
|
||||
#[tauri::command]
|
||||
pub fn create_encrypted_database(
|
||||
|
||||
@ -199,7 +199,11 @@ pub fn extension_protocol_handler<R: Runtime>(
|
||||
let segments_iter = path_str.split('/').filter(|s| !s.is_empty());
|
||||
let resource_segments: Vec<&str> = segments_iter.collect();
|
||||
let raw_asset_path = resource_segments.join("/");
|
||||
let asset_to_load = if raw_asset_path.is_empty() { "index.html"} else {&raw_asset_path};
|
||||
let asset_to_load = if raw_asset_path.is_empty() {
|
||||
"index.html"
|
||||
} else {
|
||||
&raw_asset_path
|
||||
};
|
||||
|
||||
match process_hex_encoded_json(&host) {
|
||||
Ok(info) => {
|
||||
|
||||
@ -12,6 +12,7 @@ pub fn run() {
|
||||
let protocol_name = "haex-extension";
|
||||
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_notification::init())
|
||||
.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
|
||||
@ -58,7 +59,8 @@ pub fn run() {
|
||||
database::sql_select,
|
||||
extension::database::extension_sql_execute,
|
||||
extension::database::extension_sql_select,
|
||||
extension::copy_directory //browser::create_tab
|
||||
extension::copy_directory,
|
||||
database::test
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
||||
@ -29,7 +29,8 @@
|
||||
"connect-src": [
|
||||
"'self'",
|
||||
"http://tauri.localhost",
|
||||
"ipc:http://ipc.localhost"
|
||||
"ipc:",
|
||||
"http://ipc.localhost"
|
||||
],
|
||||
"img-src": ["'self'", "http://tauri.localhost", "data:", "blob:"],
|
||||
"font-src": ["'self'", "http://tauri.localhost"],
|
||||
|
||||
@ -1,36 +1,42 @@
|
||||
<template>
|
||||
<UiDropdown activator-class="btn btn-text btn-circle " dropdown-class="[--offset:20]">
|
||||
<UiDropdown offset="[--offset:20]">
|
||||
<template #activator>
|
||||
<div class="size-9.5 rounded-full items-center justify-center text-base-content text-base">
|
||||
<Icon name="mdi:format-list-bulleted" class="size-full p-2" />
|
||||
<div
|
||||
class="size-9.5 rounded-full items-center justify-center text-base-content text-base"
|
||||
>
|
||||
<Icon
|
||||
name="mdi:format-list-bulleted"
|
||||
class="size-full p-2"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<!-- <ul class="dropdown-menu dropdown-open:opacity-100 hidden min-w-60" role="menu" aria-orientation="vertical"
|
||||
aria-labelledby="dropdown-avatar"> -->
|
||||
|
||||
<template #items>
|
||||
|
||||
<li>
|
||||
<NuxtLinkLocale class="dropdown-item" :to="{ name: 'haexSettings' }">
|
||||
<span class="icon-[tabler--settings]"/>
|
||||
<NuxtLinkLocale
|
||||
class="dropdown-item"
|
||||
:to="{ name: 'haexSettings' }"
|
||||
>
|
||||
<span class="icon-[tabler--settings]" />
|
||||
{{ t('settings') }}
|
||||
</NuxtLinkLocale>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
<li class="dropdown-footer gap-2">
|
||||
<button class="btn btn-error btn-soft btn-block" @click="onVaultCloseAsync">
|
||||
<span class="icon-[tabler--logout]"/>
|
||||
<button
|
||||
class="btn btn-error btn-soft btn-block"
|
||||
@click="onVaultCloseAsync"
|
||||
>
|
||||
<span class="icon-[tabler--logout]" />
|
||||
{{ t('vault.close') }}
|
||||
</button>
|
||||
</li>
|
||||
</template>
|
||||
<!--
|
||||
</ul> -->
|
||||
|
||||
</UiDropdown>
|
||||
</template>
|
||||
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div class="dropdown relative inline-flex">
|
||||
<div
|
||||
class="dropdown relative inline-flex"
|
||||
:class="offset"
|
||||
>
|
||||
<button
|
||||
:id
|
||||
class="dropdown-toggle"
|
||||
@ -42,13 +45,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" generic="T">
|
||||
import type { HSDropdown } from 'flyonui/flyonui'
|
||||
|
||||
const { itemIs = 'li' } = defineProps<{
|
||||
const { itemIs = 'li', offset = '[--offset:0]' } = defineProps<{
|
||||
label?: string
|
||||
items?: T[]
|
||||
itemIs?: string
|
||||
activatorClass?: string
|
||||
offset?: string
|
||||
}>()
|
||||
|
||||
defineOptions({
|
||||
@ -58,4 +60,6 @@ defineOptions({
|
||||
defineEmits<{ select: [T] }>()
|
||||
|
||||
const id = useId()
|
||||
|
||||
//const offset = '[--offset:30]'
|
||||
</script>
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
<UiTextGradient>HaexVault</UiTextGradient>
|
||||
</template>
|
||||
</i18n-t>
|
||||
<p class="text-sm">{{ path }}</p>
|
||||
<p class="text-sm">{{ database.path }}</p>
|
||||
</template>
|
||||
|
||||
<template #trigger>
|
||||
@ -63,6 +63,11 @@ const database = reactive<{
|
||||
type: 'password',
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.path,
|
||||
() => (database.path = props.path),
|
||||
)
|
||||
|
||||
const initDatabase = () => {
|
||||
database.name = ''
|
||||
database.password = ''
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
|
||||
<div class="navbar-end flex items-center gap-4 me-4">
|
||||
<div
|
||||
class="dropdown relative inline-flex [--auto-close:inside] [--offset:8] [--placement:bottom-end]"
|
||||
class="dropdown relative inline-flex [--auto-close:inside] [--offset:20] [--placement:bottom-end]"
|
||||
>
|
||||
<button
|
||||
id="dropdown-scrollable"
|
||||
@ -73,7 +73,7 @@
|
||||
>
|
||||
<div
|
||||
v-for="notification in notifications"
|
||||
:key="notification.date.toDateString()"
|
||||
:key="notification.id"
|
||||
class="dropdown-item"
|
||||
>
|
||||
<div class="avatar">
|
||||
@ -94,7 +94,7 @@
|
||||
{{ notification.title }}
|
||||
</h6>
|
||||
<small class="text-base-content/50 truncate">
|
||||
{{ notification.description }}
|
||||
{{ notification.text }}
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -4,11 +4,6 @@
|
||||
<UiDropdownLocale @select="setLocale" />
|
||||
</div>
|
||||
<div class="flex flex-col justify-center items-center gap-5 max-w-3xl">
|
||||
<!-- <img
|
||||
:src="convertFileSrc('/logo.svg', 'http')"
|
||||
class="bg-primary p-3 size-16 rounded-full"
|
||||
alt="HaexVault Logo"
|
||||
/> -->
|
||||
<UiLogoHaexhub class="bg-primary p-3 size-16 rounded-full" />
|
||||
<span
|
||||
class="flex flex-wrap font-bold text-pretty text-xl gap-2 justify-center"
|
||||
@ -26,8 +21,6 @@
|
||||
v-model:open="passwordPromptOpen"
|
||||
:path="vaultPath"
|
||||
/>
|
||||
|
||||
<UiButton @click="refresh">Refresh</UiButton>
|
||||
</div>
|
||||
|
||||
<div
|
||||
@ -83,7 +76,6 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { UiLogoHaexhub } from '#components'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
|
||||
const refresh = () => location.reload()
|
||||
|
||||
@ -14,8 +14,10 @@ definePageMeta({
|
||||
})
|
||||
|
||||
const extensionStore = useExtensionsStore()
|
||||
const { readNotificationsAsync } = useNotificationStore()
|
||||
|
||||
onMounted(async () => {
|
||||
await extensionStore.loadExtensionsAsync()
|
||||
await readNotificationsAsync()
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -26,6 +26,20 @@
|
||||
</template>
|
||||
</UiInput>
|
||||
</div>
|
||||
|
||||
<div class="p-2">{{ t('notifications.label') }}</div>
|
||||
<div class="flex items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="switch switch-primary"
|
||||
:checked="isNotificationAllowed"
|
||||
readonly
|
||||
/>
|
||||
{{ isNotificationAllowed }}
|
||||
<UiButton @click="requestNotificationPermissionAsync">
|
||||
{{ t('notifications.requestPermission') }}
|
||||
</UiButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -71,6 +85,10 @@ const onSetVaultNameAsync = async () => {
|
||||
add({ text: t('vaultName.update.error'), type: 'error' })
|
||||
}
|
||||
}
|
||||
|
||||
const { isNotificationAllowed } = storeToRefs(useNotificationStore())
|
||||
const { requestNotificationPermissionAsync } = useNotificationStore()
|
||||
//const { test } = useLastVaultStore()
|
||||
</script>
|
||||
|
||||
<i18n lang="yaml">
|
||||
@ -78,6 +96,9 @@ de:
|
||||
language: Sprache
|
||||
design: Design
|
||||
save: Änderung speichern
|
||||
notifications:
|
||||
label: Benachrichtigungen
|
||||
requestPermission: Benachrichtigung erlauben
|
||||
vaultName:
|
||||
label: Vaultname
|
||||
update:
|
||||
@ -87,6 +108,9 @@ en:
|
||||
language: Language
|
||||
design: Design
|
||||
save: save changes
|
||||
notifications:
|
||||
label: Notifications
|
||||
requestPermission: Grant Permission
|
||||
vaultName:
|
||||
label: Vault Name
|
||||
update:
|
||||
|
||||
@ -14,6 +14,7 @@ const logoFileName = 'icon.svg'
|
||||
|
||||
export const useExtensionsStore = defineStore('extensionsStore', () => {
|
||||
const availableExtensions = ref<IHaexHubExtensionLink[]>([])
|
||||
const { addNotificationAsync } = useNotificationStore()
|
||||
|
||||
const extensionLinks = computed<ISidebarItem[]>(() =>
|
||||
availableExtensions.value
|
||||
@ -78,6 +79,7 @@ export const useExtensionsStore = defineStore('extensionsStore', () => {
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
addNotificationAsync({ type: 'error', text: JSON.stringify(error) })
|
||||
//throw error //new Error(`Keine Leseberechtigung für Ordner ${extensionDirectory}`);
|
||||
}
|
||||
}
|
||||
@ -176,6 +178,7 @@ export const useExtensionsStore = defineStore('extensionsStore', () => {
|
||||
*/
|
||||
return manifest
|
||||
} catch (error) {
|
||||
addNotificationAsync({ type: 'error', text: JSON.stringify(error) })
|
||||
console.error('ERROR readManifestFileAsync', error)
|
||||
}
|
||||
}
|
||||
@ -218,7 +221,12 @@ export const useExtensionsStore = defineStore('extensionsStore', () => {
|
||||
})
|
||||
|
||||
console.log('insert extensions', res)
|
||||
addNotificationAsync({
|
||||
type: 'success',
|
||||
text: `${manifest.name} wurde installiert`,
|
||||
})
|
||||
} catch (error) {
|
||||
addNotificationAsync({ type: 'error', text: JSON.stringify(error) })
|
||||
throw error
|
||||
/*
|
||||
const resourcePath = await resourceDir();
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
export interface IHaexNotication {
|
||||
title: string
|
||||
description?: string
|
||||
icon?: string
|
||||
image?: string
|
||||
alt?: string
|
||||
date: Date
|
||||
}
|
||||
|
||||
export const useNotificationStore = defineStore('notificationStore', () => {
|
||||
const notifications = ref<IHaexNotication[]>([
|
||||
{
|
||||
title: 'huhu',
|
||||
alt: 'test',
|
||||
description: 'Ganz was tolles',
|
||||
image: 'https://cdn.flyonui.com/fy-assets/avatar/avatar-1.png',
|
||||
date: new Date(),
|
||||
},
|
||||
])
|
||||
|
||||
return {
|
||||
notifications,
|
||||
}
|
||||
})
|
||||
@ -59,7 +59,9 @@ export const useLastVaultStore = defineStore('lastVaultStore', () => {
|
||||
await syncLastVaultsAsync()
|
||||
}
|
||||
|
||||
const test = async () => console.log('test')
|
||||
return {
|
||||
test,
|
||||
addVaultAsync,
|
||||
syncLastVaultsAsync,
|
||||
lastVaults,
|
||||
|
||||
@ -1 +1,103 @@
|
||||
export const useNotificationStore = defineStore('notificationStore', () => {})
|
||||
import { eq } from 'drizzle-orm'
|
||||
import {
|
||||
haexNotifications,
|
||||
type InsertHaexNotifications,
|
||||
} from '~~/src-tauri/database/schemas/vault'
|
||||
import {
|
||||
channels,
|
||||
isPermissionGranted,
|
||||
requestPermission,
|
||||
sendNotification,
|
||||
} from '@tauri-apps/plugin-notification'
|
||||
|
||||
export interface IHaexNotification {
|
||||
id: string
|
||||
title: string | null
|
||||
text?: string | null
|
||||
icon?: string | null
|
||||
image?: string | null
|
||||
alt?: string | null
|
||||
date: string | null
|
||||
type?: 'error' | 'success' | 'warning' | 'info' | null
|
||||
}
|
||||
|
||||
export const useNotificationStore = defineStore('notificationStore', () => {
|
||||
const isNotificationAllowed = ref<boolean>(false)
|
||||
|
||||
const requestNotificationPermissionAsync = async () => {
|
||||
console.log('requestNotificationPermissionAsync')
|
||||
const permission = await requestPermission()
|
||||
console.log('got permission', permission)
|
||||
isNotificationAllowed.value = permission === 'granted'
|
||||
sendNotification({
|
||||
title: 'Tauri',
|
||||
body: 'Tauri is awesome!',
|
||||
icon: 'dialog-information',
|
||||
})
|
||||
/* const existingChannels = await channels()
|
||||
console.log('existingChannels', existingChannels) */
|
||||
}
|
||||
const test = async () => console.log('test')
|
||||
const checkNotificationAsync = async () => {
|
||||
isNotificationAllowed.value = await isPermissionGranted()
|
||||
return isNotificationAllowed.value
|
||||
}
|
||||
|
||||
const notifications = ref<IHaexNotification[]>([])
|
||||
|
||||
const readNotificationsAsync = async (read: boolean = false) => {
|
||||
const { currentVault } = storeToRefs(useVaultStore())
|
||||
notifications.value = await currentVault.value.drizzle
|
||||
.select()
|
||||
.from(haexNotifications)
|
||||
.where(eq(haexNotifications.read, read))
|
||||
console.log('readNotificationsAsync', notifications.value)
|
||||
}
|
||||
|
||||
const addNotificationAsync = async (
|
||||
notification: Partial<InsertHaexNotifications>,
|
||||
) => {
|
||||
const { currentVault } = storeToRefs(useVaultStore())
|
||||
try {
|
||||
const _notification: InsertHaexNotifications = {
|
||||
id: crypto.randomUUID(),
|
||||
type: notification.type || 'info',
|
||||
alt: notification.alt,
|
||||
date: new Date().toUTCString(),
|
||||
icon: notification.icon,
|
||||
image: notification.image,
|
||||
read: notification.read || false,
|
||||
text: notification.text ?? '',
|
||||
title: notification.title ?? '',
|
||||
}
|
||||
|
||||
await currentVault.value.drizzle
|
||||
.insert(haexNotifications)
|
||||
.values(_notification)
|
||||
|
||||
await readNotificationsAsync()
|
||||
|
||||
if (!isNotificationAllowed.value) {
|
||||
const permission = await requestPermission()
|
||||
isNotificationAllowed.value = permission === 'granted'
|
||||
}
|
||||
|
||||
if (isNotificationAllowed.value) {
|
||||
sendNotification({
|
||||
title: _notification.title!,
|
||||
body: _notification.text!,
|
||||
})
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
return {
|
||||
notifications,
|
||||
isNotificationAllowed,
|
||||
checkNotificationAsync,
|
||||
addNotificationAsync,
|
||||
readNotificationsAsync,
|
||||
requestNotificationPermissionAsync,
|
||||
test,
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user