Initial commit of version 0.2.0

This commit is contained in:
Elijah 2026-07-19 18:37:14 -07:00
parent 86fc06b877
commit dfb04462f3
108 changed files with 16167 additions and 80 deletions

5348
app/src-tauri/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

22
app/src-tauri/Cargo.toml Normal file
View file

@ -0,0 +1,22 @@
[package]
name = "decky"
version = "0.2.0"
description = "A focused cross-platform client for Nextcloud Deck"
authors = ["Elijah Kuntz"]
edition = "2021"
[lib]
name = "decky_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "2", features = [] }
[dependencies]
keyring = { version = "3.6.3", features = ["apple-native", "windows-native", "sync-secret-service"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tauri = { version = "2", features = [] }
tauri-plugin-http = "2"
tauri-plugin-process = "2"
tauri-plugin-updater = "2"

3
app/src-tauri/build.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
tauri_build::build()
}

View file

@ -0,0 +1,23 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Permissions required by the Decky main window",
"windows": ["main"],
"permissions": [
"core:default",
"core:window:allow-close",
"core:window:allow-minimize",
"core:window:allow-toggle-maximize",
"core:window:allow-start-dragging",
"process:allow-restart",
"updater:default",
{
"identifier": "http:default",
"allow": [
{ "url": "https://**" },
{ "url": "http://localhost:**" },
{ "url": "http://127.0.0.1:**" }
]
}
]
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"default":{"identifier":"default","description":"Permissions required by the Decky main window","local":true,"windows":["main"],"permissions":["core:default","core:window:allow-close","core:window:allow-minimize","core:window:allow-toggle-maximize","core:window:allow-start-dragging","process:allow-restart","updater:default",{"identifier":"http:default","allow":[{"url":"https://**"},{"url":"http://localhost:**"},{"url":"http://127.0.0.1:**"}]}]}}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
<background android:drawable="@color/ic_launcher_background"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#fff</color>
</resources>

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">
<defs>
<linearGradient id="bg" x1="80" y1="48" x2="432" y2="464" gradientUnits="userSpaceOnUse">
<stop stop-color="#A497FF"/>
<stop offset="1" stop-color="#6757D9"/>
</linearGradient>
</defs>
<rect width="512" height="512" rx="116" fill="#11151D"/>
<rect x="70" y="70" width="372" height="372" rx="88" fill="url(#bg)"/>
<rect x="132" y="145" width="104" height="222" rx="27" fill="white" fill-opacity=".96"/>
<rect x="276" y="145" width="104" height="138" rx="27" fill="white" fill-opacity=".96"/>
<path d="m298 332 24 24 50-57" fill="none" stroke="white" stroke-width="25" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 752 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 740 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

45
app/src-tauri/src/lib.rs Normal file
View file

@ -0,0 +1,45 @@
const CREDENTIAL_SERVICE: &str = "com.elijahkuntz.decky.nextcloud";
fn credential_entry(server: &str, username: &str) -> Result<keyring::Entry, String> {
let account = format!("{}|{}", server.trim().to_lowercase(), username.trim());
keyring::Entry::new(CREDENTIAL_SERVICE, &account).map_err(|error| error.to_string())
}
#[tauri::command]
fn get_credential(server: String, username: String) -> Result<Option<String>, String> {
match credential_entry(&server, &username)?.get_password() {
Ok(password) => Ok(Some(password)),
Err(keyring::Error::NoEntry) => Ok(None),
Err(error) => Err(error.to_string()),
}
}
#[tauri::command]
fn set_credential(server: String, username: String, password: String) -> Result<(), String> {
credential_entry(&server, &username)?
.set_password(&password)
.map_err(|error| error.to_string())
}
#[tauri::command]
fn delete_credential(server: String, username: String) -> Result<(), String> {
match credential_entry(&server, &username)?.delete_credential() {
Ok(()) | Err(keyring::Error::NoEntry) => Ok(()),
Err(error) => Err(error.to_string()),
}
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_http::init())
.plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_updater::Builder::new().build())
.invoke_handler(tauri::generate_handler![
get_credential,
set_credential,
delete_credential
])
.run(tauri::generate_context!())
.expect("error while running Decky");
}

View file

@ -0,0 +1,5 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
decky_lib::run();
}

View file

@ -0,0 +1,59 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "Decky",
"version": "0.2.0",
"identifier": "com.elijahkuntz.decky",
"build": {
"beforeDevCommand": "npm run dev",
"devUrl": "http://127.0.0.1:1420",
"beforeBuildCommand": "npm run build",
"frontendDist": "../dist"
},
"app": {
"windows": [
{
"label": "main",
"title": "Decky",
"width": 1320,
"height": 820,
"minWidth": 820,
"minHeight": 560,
"center": true,
"decorations": false,
"dragDropEnabled": false
}
],
"security": {
"csp": "default-src 'self'; connect-src ipc: http://ipc.localhost; img-src 'self' asset: http://asset.localhost data:; style-src 'self' 'unsafe-inline'"
}
},
"bundle": {
"active": true,
"targets": ["nsis"],
"createUpdaterArtifacts": true,
"category": "Productivity",
"shortDescription": "Nextcloud Deck on your desktop",
"longDescription": "A focused cross-platform desktop client for viewing and editing Nextcloud Deck boards.",
"copyright": "Copyright © 2026 Elijah Kuntz",
"windows": {
"webviewInstallMode": {
"type": "downloadBootstrapper"
},
"nsis": {
"installMode": "currentUser",
"installerIcon": "icons/icon.ico"
}
}
},
"plugins": {
"updater": {
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEMyN0NBMzgwMjA3QkM4NwpSV1NIdkFjQ09Nb25ERWJQYStYMDRjSTNORERDcG5nQSthYzdVWnZpdnh2YmlOY1ZlekJVc1luUQo=",
"endpoints": [
"https://git.elijahkuntz.com/Elijah/Decky/raw/branch/main/releases/latest.json"
],
"windows": {
"installMode": "passive"
}
}
}
}