mirror of
https://github.com/haexhub/haex-hub.git
synced 2025-12-16 22:20:51 +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({
|
export default defineConfig({
|
||||||
schema: './src/database/schemas/**.ts',
|
schema: './src-tauri/database/schemas/**.ts',
|
||||||
out: './src/database/migrations',
|
out: './src-tauri/database/migrations',
|
||||||
dialect: 'sqlite',
|
dialect: 'sqlite',
|
||||||
dbCredentials: {
|
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
|
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||||
|
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
app: {
|
|
||||||
baseURL: './',
|
|
||||||
},
|
|
||||||
|
|
||||||
modules: [
|
modules: [
|
||||||
'nuxt-zod-i18n',
|
'nuxt-zod-i18n',
|
||||||
'@nuxtjs/i18n',
|
'@nuxtjs/i18n',
|
||||||
|
|||||||
21
package.json
21
package.json
@ -16,35 +16,36 @@
|
|||||||
"eslint:fix": "eslint --fix"
|
"eslint:fix": "eslint --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@libsql/client": "^0.15.7",
|
"@libsql/client": "^0.15.8",
|
||||||
"@nuxt/eslint": "1.4.1",
|
"@nuxt/eslint": "1.4.1",
|
||||||
"@nuxt/icon": "^1.13.0",
|
"@nuxt/icon": "^1.13.0",
|
||||||
"@nuxtjs/i18n": "^9.5.4",
|
"@nuxtjs/i18n": "^9.5.5",
|
||||||
"@pinia/nuxt": "^0.11.0",
|
"@pinia/nuxt": "^0.11.0",
|
||||||
"@tailwindcss/vite": "^4.1.7",
|
"@tailwindcss/vite": "^4.1.8",
|
||||||
"@tauri-apps/api": "^2.5.0",
|
"@tauri-apps/api": "^2.5.0",
|
||||||
"@tauri-apps/plugin-dialog": "^2.2.2",
|
"@tauri-apps/plugin-dialog": "^2.2.2",
|
||||||
"@tauri-apps/plugin-fs": "^2.3.0",
|
"@tauri-apps/plugin-fs": "^2.3.0",
|
||||||
"@tauri-apps/plugin-http": "~2.4.4",
|
"@tauri-apps/plugin-http": "~2.4.4",
|
||||||
|
"@tauri-apps/plugin-notification": "~2.2.2",
|
||||||
"@tauri-apps/plugin-opener": "^2.2.7",
|
"@tauri-apps/plugin-opener": "^2.2.7",
|
||||||
"@tauri-apps/plugin-os": "^2.2.1",
|
"@tauri-apps/plugin-os": "^2.2.1",
|
||||||
"@tauri-apps/plugin-sql": "~2.2.0",
|
"@tauri-apps/plugin-sql": "~2.2.0",
|
||||||
"@tauri-apps/plugin-store": "^2.2.0",
|
"@tauri-apps/plugin-store": "^2.2.0",
|
||||||
"@vueuse/core": "^13.2.0",
|
"@vueuse/core": "^13.3.0",
|
||||||
"@vueuse/nuxt": "^13.2.0",
|
"@vueuse/nuxt": "^13.3.0",
|
||||||
"drizzle-orm": "^0.43.1",
|
"drizzle-orm": "^0.43.1",
|
||||||
"eslint": "^9.27.0",
|
"eslint": "^9.28.0",
|
||||||
"flyonui": "^2.2.0",
|
"flyonui": "^2.2.0",
|
||||||
"nuxt": "^3.17.4",
|
"nuxt": "^3.17.4",
|
||||||
"nuxt-snackbar": "1.3.0",
|
"nuxt-snackbar": "1.3.0",
|
||||||
"nuxt-zod-i18n": "^1.11.5",
|
"nuxt-zod-i18n": "^1.11.5",
|
||||||
"tailwindcss": "^4.1.7",
|
"tailwindcss": "^4.1.8",
|
||||||
"vue": "^3.5.14",
|
"vue": "^3.5.16",
|
||||||
"vue-router": "^4.5.1",
|
"vue-router": "^4.5.1",
|
||||||
"zod": "^3.25.21"
|
"zod": "^3.25.42"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@iconify/json": "^2.2.340",
|
"@iconify/json": "^2.2.343",
|
||||||
"@iconify/tailwind4": "^1.0.6",
|
"@iconify/tailwind4": "^1.0.6",
|
||||||
"@tauri-apps/cli": "^2.5.0",
|
"@tauri-apps/cli": "^2.5.0",
|
||||||
"drizzle-kit": "^0.31.1",
|
"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-dialog",
|
||||||
"tauri-plugin-fs",
|
"tauri-plugin-fs",
|
||||||
"tauri-plugin-http",
|
"tauri-plugin-http",
|
||||||
|
"tauri-plugin-notification",
|
||||||
"tauri-plugin-opener",
|
"tauri-plugin-opener",
|
||||||
"tauri-plugin-os",
|
"tauri-plugin-os",
|
||||||
"tauri-plugin-store",
|
"tauri-plugin-store",
|
||||||
@ -2180,6 +2181,18 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
|
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]]
|
[[package]]
|
||||||
name = "markup5ever"
|
name = "markup5ever"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
@ -2328,6 +2341,20 @@ version = "0.1.14"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
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]]
|
[[package]]
|
||||||
name = "num-conv"
|
name = "num-conv"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -2889,7 +2916,7 @@ checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"indexmap 2.8.0",
|
"indexmap 2.8.0",
|
||||||
"quick-xml",
|
"quick-xml 0.32.0",
|
||||||
"serde",
|
"serde",
|
||||||
"time",
|
"time",
|
||||||
]
|
]
|
||||||
@ -3044,6 +3071,15 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-xml"
|
||||||
|
version = "0.37.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quinn"
|
name = "quinn"
|
||||||
version = "0.11.7"
|
version = "0.11.7"
|
||||||
@ -4259,6 +4295,25 @@ dependencies = [
|
|||||||
"urlpattern",
|
"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]]
|
[[package]]
|
||||||
name = "tauri-plugin-opener"
|
name = "tauri-plugin-opener"
|
||||||
version = "2.2.6"
|
version = "2.2.6"
|
||||||
@ -4412,6 +4467,18 @@ dependencies = [
|
|||||||
"toml",
|
"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]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.19.1"
|
version = "3.19.1"
|
||||||
|
|||||||
@ -40,4 +40,5 @@ tauri-plugin-opener = "2.2"
|
|||||||
tauri-plugin-os = "2"
|
tauri-plugin-os = "2"
|
||||||
tauri-plugin-store = "2"
|
tauri-plugin-store = "2"
|
||||||
tauri-plugin-http = "2.4"
|
tauri-plugin-http = "2.4"
|
||||||
|
tauri-plugin-notification = "2"
|
||||||
#tauri-plugin-sql = { version = "2", features = ["sqlite"] }
|
#tauri-plugin-sql = { version = "2", features = ["sqlite"] }
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
"dialog:default",
|
"dialog:default",
|
||||||
"fs:allow-appdata-read-recursive",
|
"fs:allow-appdata-read-recursive",
|
||||||
"fs:allow-appdata-write-recursive",
|
"fs:allow-appdata-write-recursive",
|
||||||
|
"fs:allow-appconfig-read-recursive",
|
||||||
|
"fs:allow-appconfig-write-recursive",
|
||||||
"fs:allow-read-file",
|
"fs:allow-read-file",
|
||||||
"fs:allow-resource-read-recursive",
|
"fs:allow-resource-read-recursive",
|
||||||
"fs:default",
|
"fs:default",
|
||||||
@ -26,6 +28,10 @@
|
|||||||
"opener:default",
|
"opener:default",
|
||||||
"os:default",
|
"os:default",
|
||||||
"os:allow-hostname",
|
"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,
|
"when": 1747583956679,
|
||||||
"tag": "0002_married_bushwacker",
|
"tag": "0002_married_bushwacker",
|
||||||
"breakpoints": true
|
"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(),
|
key: text(),
|
||||||
value: text(),
|
value: text(),
|
||||||
})
|
})
|
||||||
|
export type InsertHaexSettings = typeof haexSettings.$inferInsert
|
||||||
|
export type SelectHaexSettings = typeof haexSettings.$inferSelect
|
||||||
|
|
||||||
export const haexExtensions = sqliteTable('haex_extensions', {
|
export const haexExtensions = sqliteTable('haex_extensions', {
|
||||||
id: text().primaryKey(),
|
id: text().primaryKey(),
|
||||||
@ -21,6 +23,8 @@ export const haexExtensions = sqliteTable('haex_extensions', {
|
|||||||
url: text(),
|
url: text(),
|
||||||
version: text(),
|
version: text(),
|
||||||
})
|
})
|
||||||
|
export type InsertHaexExtensions = typeof haexExtensions.$inferInsert
|
||||||
|
export type SelectHaexExtensions = typeof haexExtensions.$inferSelect
|
||||||
|
|
||||||
export const haexExtensionsPermissions = sqliteTable(
|
export const haexExtensionsPermissions = sqliteTable(
|
||||||
'haex_extensions_permissions',
|
'haex_extensions_permissions',
|
||||||
@ -37,14 +41,21 @@ export const haexExtensionsPermissions = sqliteTable(
|
|||||||
unique().on(table.extensionId, table.resource, table.operation, table.path),
|
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 =
|
export type InsertHaexExtensionsPermissions =
|
||||||
typeof haexExtensionsPermissions.$inferInsert
|
typeof haexExtensionsPermissions.$inferInsert
|
||||||
export type SelectHaexExtensionsPermissions =
|
export type SelectHaexExtensionsPermissions =
|
||||||
typeof haexExtensionsPermissions.$inferSelect
|
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 rusqlite::{Connection, OpenFlags, Result as RusqliteResult};
|
||||||
use serde_json::Value as JsonValue;
|
use serde_json::Value as JsonValue;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::io::Read;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use tauri::utils::resources::Resource;
|
use tauri::utils::resources::Resource;
|
||||||
use tauri::{path::BaseDirectory, AppHandle, Manager, State, Wry};
|
use tauri::{path::BaseDirectory, AppHandle, Manager, State, Wry};
|
||||||
use tokio::io::join;
|
use tauri_plugin_fs::FsExt;
|
||||||
|
|
||||||
pub struct DbConnection(pub Mutex<Option<Connection>>);
|
pub struct DbConnection(pub Mutex<Option<Connection>>);
|
||||||
|
|
||||||
@ -31,6 +32,18 @@ pub async fn sql_execute(
|
|||||||
core::execute(sql, params, &state).await
|
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
|
/// Erstellt eine verschlüsselte Datenbank
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn create_encrypted_database(
|
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 segments_iter = path_str.split('/').filter(|s| !s.is_empty());
|
||||||
let resource_segments: Vec<&str> = segments_iter.collect();
|
let resource_segments: Vec<&str> = segments_iter.collect();
|
||||||
let raw_asset_path = resource_segments.join("/");
|
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) {
|
match process_hex_encoded_json(&host) {
|
||||||
Ok(info) => {
|
Ok(info) => {
|
||||||
|
|||||||
@ -12,6 +12,7 @@ pub fn run() {
|
|||||||
let protocol_name = "haex-extension";
|
let protocol_name = "haex-extension";
|
||||||
|
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
|
.plugin(tauri_plugin_notification::init())
|
||||||
.register_uri_scheme_protocol(protocol_name, move |context, request| {
|
.register_uri_scheme_protocol(protocol_name, move |context, request| {
|
||||||
match extension::core::extension_protocol_handler(&context, &request) {
|
match extension::core::extension_protocol_handler(&context, &request) {
|
||||||
Ok(response) => response, // Wenn der Handler Ok ist, gib die Response direkt zurück
|
Ok(response) => response, // Wenn der Handler Ok ist, gib die Response direkt zurück
|
||||||
@ -58,7 +59,8 @@ pub fn run() {
|
|||||||
database::sql_select,
|
database::sql_select,
|
||||||
extension::database::extension_sql_execute,
|
extension::database::extension_sql_execute,
|
||||||
extension::database::extension_sql_select,
|
extension::database::extension_sql_select,
|
||||||
extension::copy_directory //browser::create_tab
|
extension::copy_directory,
|
||||||
|
database::test
|
||||||
])
|
])
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application");
|
||||||
|
|||||||
@ -29,7 +29,8 @@
|
|||||||
"connect-src": [
|
"connect-src": [
|
||||||
"'self'",
|
"'self'",
|
||||||
"http://tauri.localhost",
|
"http://tauri.localhost",
|
||||||
"ipc:http://ipc.localhost"
|
"ipc:",
|
||||||
|
"http://ipc.localhost"
|
||||||
],
|
],
|
||||||
"img-src": ["'self'", "http://tauri.localhost", "data:", "blob:"],
|
"img-src": ["'self'", "http://tauri.localhost", "data:", "blob:"],
|
||||||
"font-src": ["'self'", "http://tauri.localhost"],
|
"font-src": ["'self'", "http://tauri.localhost"],
|
||||||
|
|||||||
@ -1,36 +1,42 @@
|
|||||||
<template>
|
<template>
|
||||||
<UiDropdown activator-class="btn btn-text btn-circle " dropdown-class="[--offset:20]">
|
<UiDropdown offset="[--offset:20]">
|
||||||
<template #activator>
|
<template #activator>
|
||||||
<div class="size-9.5 rounded-full items-center justify-center text-base-content text-base">
|
<div
|
||||||
<Icon name="mdi:format-list-bulleted" class="size-full p-2" />
|
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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<!-- <ul class="dropdown-menu dropdown-open:opacity-100 hidden min-w-60" role="menu" aria-orientation="vertical"
|
<!-- <ul class="dropdown-menu dropdown-open:opacity-100 hidden min-w-60" role="menu" aria-orientation="vertical"
|
||||||
aria-labelledby="dropdown-avatar"> -->
|
aria-labelledby="dropdown-avatar"> -->
|
||||||
|
|
||||||
<template #items>
|
<template #items>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<NuxtLinkLocale class="dropdown-item" :to="{ name: 'haexSettings' }">
|
<NuxtLinkLocale
|
||||||
<span class="icon-[tabler--settings]"/>
|
class="dropdown-item"
|
||||||
|
:to="{ name: 'haexSettings' }"
|
||||||
|
>
|
||||||
|
<span class="icon-[tabler--settings]" />
|
||||||
{{ t('settings') }}
|
{{ t('settings') }}
|
||||||
</NuxtLinkLocale>
|
</NuxtLinkLocale>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<li class="dropdown-footer gap-2">
|
<li class="dropdown-footer gap-2">
|
||||||
<button class="btn btn-error btn-soft btn-block" @click="onVaultCloseAsync">
|
<button
|
||||||
<span class="icon-[tabler--logout]"/>
|
class="btn btn-error btn-soft btn-block"
|
||||||
|
@click="onVaultCloseAsync"
|
||||||
|
>
|
||||||
|
<span class="icon-[tabler--logout]" />
|
||||||
{{ t('vault.close') }}
|
{{ t('vault.close') }}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
<!--
|
<!--
|
||||||
</ul> -->
|
</ul> -->
|
||||||
|
|
||||||
</UiDropdown>
|
</UiDropdown>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="dropdown relative inline-flex">
|
<div
|
||||||
|
class="dropdown relative inline-flex"
|
||||||
|
:class="offset"
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
:id
|
:id
|
||||||
class="dropdown-toggle"
|
class="dropdown-toggle"
|
||||||
@ -42,13 +45,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" generic="T">
|
<script setup lang="ts" generic="T">
|
||||||
import type { HSDropdown } from 'flyonui/flyonui'
|
const { itemIs = 'li', offset = '[--offset:0]' } = defineProps<{
|
||||||
|
|
||||||
const { itemIs = 'li' } = defineProps<{
|
|
||||||
label?: string
|
label?: string
|
||||||
items?: T[]
|
items?: T[]
|
||||||
itemIs?: string
|
itemIs?: string
|
||||||
activatorClass?: string
|
activatorClass?: string
|
||||||
|
offset?: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -58,4 +60,6 @@ defineOptions({
|
|||||||
defineEmits<{ select: [T] }>()
|
defineEmits<{ select: [T] }>()
|
||||||
|
|
||||||
const id = useId()
|
const id = useId()
|
||||||
|
|
||||||
|
//const offset = '[--offset:30]'
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
<UiTextGradient>HaexVault</UiTextGradient>
|
<UiTextGradient>HaexVault</UiTextGradient>
|
||||||
</template>
|
</template>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
<p class="text-sm">{{ path }}</p>
|
<p class="text-sm">{{ database.path }}</p>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
@ -63,6 +63,11 @@ const database = reactive<{
|
|||||||
type: 'password',
|
type: 'password',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.path,
|
||||||
|
() => (database.path = props.path),
|
||||||
|
)
|
||||||
|
|
||||||
const initDatabase = () => {
|
const initDatabase = () => {
|
||||||
database.name = ''
|
database.name = ''
|
||||||
database.password = ''
|
database.password = ''
|
||||||
|
|||||||
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
<div class="navbar-end flex items-center gap-4 me-4">
|
<div class="navbar-end flex items-center gap-4 me-4">
|
||||||
<div
|
<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
|
<button
|
||||||
id="dropdown-scrollable"
|
id="dropdown-scrollable"
|
||||||
@ -73,7 +73,7 @@
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="notification in notifications"
|
v-for="notification in notifications"
|
||||||
:key="notification.date.toDateString()"
|
:key="notification.id"
|
||||||
class="dropdown-item"
|
class="dropdown-item"
|
||||||
>
|
>
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
@ -94,7 +94,7 @@
|
|||||||
{{ notification.title }}
|
{{ notification.title }}
|
||||||
</h6>
|
</h6>
|
||||||
<small class="text-base-content/50 truncate">
|
<small class="text-base-content/50 truncate">
|
||||||
{{ notification.description }}
|
{{ notification.text }}
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -4,11 +4,6 @@
|
|||||||
<UiDropdownLocale @select="setLocale" />
|
<UiDropdownLocale @select="setLocale" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col justify-center items-center gap-5 max-w-3xl">
|
<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" />
|
<UiLogoHaexhub class="bg-primary p-3 size-16 rounded-full" />
|
||||||
<span
|
<span
|
||||||
class="flex flex-wrap font-bold text-pretty text-xl gap-2 justify-center"
|
class="flex flex-wrap font-bold text-pretty text-xl gap-2 justify-center"
|
||||||
@ -26,8 +21,6 @@
|
|||||||
v-model:open="passwordPromptOpen"
|
v-model:open="passwordPromptOpen"
|
||||||
:path="vaultPath"
|
:path="vaultPath"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<UiButton @click="refresh">Refresh</UiButton>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@ -83,7 +76,6 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { UiLogoHaexhub } from '#components'
|
import { UiLogoHaexhub } from '#components'
|
||||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
|
||||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||||
|
|
||||||
const refresh = () => location.reload()
|
const refresh = () => location.reload()
|
||||||
|
|||||||
@ -14,8 +14,10 @@ definePageMeta({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const extensionStore = useExtensionsStore()
|
const extensionStore = useExtensionsStore()
|
||||||
|
const { readNotificationsAsync } = useNotificationStore()
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await extensionStore.loadExtensionsAsync()
|
await extensionStore.loadExtensionsAsync()
|
||||||
|
await readNotificationsAsync()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -26,6 +26,20 @@
|
|||||||
</template>
|
</template>
|
||||||
</UiInput>
|
</UiInput>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -71,6 +85,10 @@ const onSetVaultNameAsync = async () => {
|
|||||||
add({ text: t('vaultName.update.error'), type: 'error' })
|
add({ text: t('vaultName.update.error'), type: 'error' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { isNotificationAllowed } = storeToRefs(useNotificationStore())
|
||||||
|
const { requestNotificationPermissionAsync } = useNotificationStore()
|
||||||
|
//const { test } = useLastVaultStore()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<i18n lang="yaml">
|
<i18n lang="yaml">
|
||||||
@ -78,6 +96,9 @@ de:
|
|||||||
language: Sprache
|
language: Sprache
|
||||||
design: Design
|
design: Design
|
||||||
save: Änderung speichern
|
save: Änderung speichern
|
||||||
|
notifications:
|
||||||
|
label: Benachrichtigungen
|
||||||
|
requestPermission: Benachrichtigung erlauben
|
||||||
vaultName:
|
vaultName:
|
||||||
label: Vaultname
|
label: Vaultname
|
||||||
update:
|
update:
|
||||||
@ -87,6 +108,9 @@ en:
|
|||||||
language: Language
|
language: Language
|
||||||
design: Design
|
design: Design
|
||||||
save: save changes
|
save: save changes
|
||||||
|
notifications:
|
||||||
|
label: Notifications
|
||||||
|
requestPermission: Grant Permission
|
||||||
vaultName:
|
vaultName:
|
||||||
label: Vault Name
|
label: Vault Name
|
||||||
update:
|
update:
|
||||||
|
|||||||
@ -14,6 +14,7 @@ const logoFileName = 'icon.svg'
|
|||||||
|
|
||||||
export const useExtensionsStore = defineStore('extensionsStore', () => {
|
export const useExtensionsStore = defineStore('extensionsStore', () => {
|
||||||
const availableExtensions = ref<IHaexHubExtensionLink[]>([])
|
const availableExtensions = ref<IHaexHubExtensionLink[]>([])
|
||||||
|
const { addNotificationAsync } = useNotificationStore()
|
||||||
|
|
||||||
const extensionLinks = computed<ISidebarItem[]>(() =>
|
const extensionLinks = computed<ISidebarItem[]>(() =>
|
||||||
availableExtensions.value
|
availableExtensions.value
|
||||||
@ -78,6 +79,7 @@ export const useExtensionsStore = defineStore('extensionsStore', () => {
|
|||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
addNotificationAsync({ type: 'error', text: JSON.stringify(error) })
|
||||||
//throw error //new Error(`Keine Leseberechtigung für Ordner ${extensionDirectory}`);
|
//throw error //new Error(`Keine Leseberechtigung für Ordner ${extensionDirectory}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,6 +178,7 @@ export const useExtensionsStore = defineStore('extensionsStore', () => {
|
|||||||
*/
|
*/
|
||||||
return manifest
|
return manifest
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
addNotificationAsync({ type: 'error', text: JSON.stringify(error) })
|
||||||
console.error('ERROR readManifestFileAsync', error)
|
console.error('ERROR readManifestFileAsync', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -218,7 +221,12 @@ export const useExtensionsStore = defineStore('extensionsStore', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
console.log('insert extensions', res)
|
console.log('insert extensions', res)
|
||||||
|
addNotificationAsync({
|
||||||
|
type: 'success',
|
||||||
|
text: `${manifest.name} wurde installiert`,
|
||||||
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
addNotificationAsync({ type: 'error', text: JSON.stringify(error) })
|
||||||
throw error
|
throw error
|
||||||
/*
|
/*
|
||||||
const resourcePath = await resourceDir();
|
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()
|
await syncLastVaultsAsync()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const test = async () => console.log('test')
|
||||||
return {
|
return {
|
||||||
|
test,
|
||||||
addVaultAsync,
|
addVaultAsync,
|
||||||
syncLastVaultsAsync,
|
syncLastVaultsAsync,
|
||||||
lastVaults,
|
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