refined colors, added multiple color themes, and added window control titlebar
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
"@tauri-apps/plugin-fs": "~2",
|
"@tauri-apps/plugin-fs": "~2",
|
||||||
"@tauri-apps/plugin-http": "~2",
|
"@tauri-apps/plugin-http": "~2",
|
||||||
"@tauri-apps/plugin-opener": "^2",
|
"@tauri-apps/plugin-opener": "^2",
|
||||||
|
"@tauri-apps/plugin-os": "~2",
|
||||||
"@tauri-apps/plugin-store": "~2",
|
"@tauri-apps/plugin-store": "~2",
|
||||||
"@tauri-apps/plugin-upload": "~2",
|
"@tauri-apps/plugin-upload": "~2",
|
||||||
"@tauri-apps/plugin-websocket": "~2",
|
"@tauri-apps/plugin-websocket": "~2",
|
||||||
|
|||||||
83
src-tauri/Cargo.lock
generated
83
src-tauri/Cargo.lock
generated
@@ -1028,6 +1028,7 @@ dependencies = [
|
|||||||
"tauri-plugin-fs",
|
"tauri-plugin-fs",
|
||||||
"tauri-plugin-http",
|
"tauri-plugin-http",
|
||||||
"tauri-plugin-opener",
|
"tauri-plugin-opener",
|
||||||
|
"tauri-plugin-os",
|
||||||
"tauri-plugin-store",
|
"tauri-plugin-store",
|
||||||
"tauri-plugin-upload",
|
"tauri-plugin-upload",
|
||||||
"tauri-plugin-websocket",
|
"tauri-plugin-websocket",
|
||||||
@@ -1263,6 +1264,16 @@ dependencies = [
|
|||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gethostname"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8"
|
||||||
|
dependencies = [
|
||||||
|
"rustix",
|
||||||
|
"windows-link 0.2.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.1.16"
|
version = "0.1.16"
|
||||||
@@ -2315,6 +2326,16 @@ dependencies = [
|
|||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2-core-location"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009"
|
||||||
|
dependencies = [
|
||||||
|
"objc2",
|
||||||
|
"objc2-foundation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2-core-text"
|
name = "objc2-core-text"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
@@ -2419,8 +2440,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22"
|
checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.10.0",
|
"bitflags 2.10.0",
|
||||||
|
"block2",
|
||||||
"objc2",
|
"objc2",
|
||||||
|
"objc2-cloud-kit",
|
||||||
|
"objc2-core-data",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
|
"objc2-core-graphics",
|
||||||
|
"objc2-core-image",
|
||||||
|
"objc2-core-location",
|
||||||
|
"objc2-core-text",
|
||||||
|
"objc2-foundation",
|
||||||
|
"objc2-quartz-core",
|
||||||
|
"objc2-user-notifications",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2-user-notifications"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e"
|
||||||
|
dependencies = [
|
||||||
|
"objc2",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2474,6 +2514,22 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "os_info"
|
||||||
|
version = "3.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e4022a17595a00d6a369236fdae483f0de7f0a339960a53118b818238e132224"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"log",
|
||||||
|
"nix",
|
||||||
|
"objc2",
|
||||||
|
"objc2-foundation",
|
||||||
|
"objc2-ui-kit",
|
||||||
|
"serde",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pango"
|
name = "pango"
|
||||||
version = "0.18.3"
|
version = "0.18.3"
|
||||||
@@ -3782,6 +3838,15 @@ dependencies = [
|
|||||||
"syn 2.0.111",
|
"syn 2.0.111",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sys-locale"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "system-configuration"
|
name = "system-configuration"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
@@ -4091,6 +4156,24 @@ dependencies = [
|
|||||||
"zbus",
|
"zbus",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-plugin-os"
|
||||||
|
version = "2.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d8f08346c8deb39e96f86973da0e2d76cbb933d7ac9b750f6dc4daf955a6f997"
|
||||||
|
dependencies = [
|
||||||
|
"gethostname",
|
||||||
|
"log",
|
||||||
|
"os_info",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serialize-to-javascript",
|
||||||
|
"sys-locale",
|
||||||
|
"tauri",
|
||||||
|
"tauri-plugin",
|
||||||
|
"thiserror 2.0.17",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-plugin-store"
|
name = "tauri-plugin-store"
|
||||||
version = "2.4.1"
|
version = "2.4.1"
|
||||||
|
|||||||
@@ -28,4 +28,5 @@ tauri-plugin-websocket = "2"
|
|||||||
tauri-plugin-upload = "2"
|
tauri-plugin-upload = "2"
|
||||||
tauri-plugin-dialog = "2"
|
tauri-plugin-dialog = "2"
|
||||||
tauri-plugin-fs = "2"
|
tauri-plugin-fs = "2"
|
||||||
|
tauri-plugin-os = "2"
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,12 @@
|
|||||||
],
|
],
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"core:default",
|
"core:default",
|
||||||
|
"core:window:allow-maximize",
|
||||||
|
"core:window:allow-minimize",
|
||||||
|
"core:window:allow-close",
|
||||||
|
"core:window:allow-toggle-maximize",
|
||||||
|
"core:window:allow-start-dragging",
|
||||||
|
"core:window:allow-set-fullscreen",
|
||||||
"opener:default",
|
"opener:default",
|
||||||
"store:default",
|
"store:default",
|
||||||
{
|
{
|
||||||
@@ -47,7 +53,7 @@
|
|||||||
"allow": [
|
"allow": [
|
||||||
"*"
|
"*"
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"os:default"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ fn greet(name: &str) -> String {
|
|||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
|
.plugin(tauri_plugin_os::init())
|
||||||
.plugin(tauri_plugin_fs::init())
|
.plugin(tauri_plugin_fs::init())
|
||||||
.plugin(tauri_plugin_dialog::init())
|
.plugin(tauri_plugin_dialog::init())
|
||||||
.plugin(tauri_plugin_upload::init())
|
.plugin(tauri_plugin_upload::init())
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
"title": "frangipane",
|
"title": "frangipane",
|
||||||
"width": 800,
|
"width": 800,
|
||||||
"height": 600,
|
"height": 600,
|
||||||
"decorations": true,
|
"decorations": false,
|
||||||
"resizable": true,
|
"resizable": true,
|
||||||
"fullscreen": false,
|
"fullscreen": false,
|
||||||
"center": true,
|
"center": true,
|
||||||
|
|||||||
146
src/App.vue
146
src/App.vue
@@ -1,16 +1,35 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="page">
|
<div id="page">
|
||||||
<main id="content">
|
<div v-if="currentPlatform != 'android' && currentPlatform != 'ios'" data-tauri-drag-region class="titlebar">
|
||||||
<router-view />
|
<div class="titlebar-button" @click="minimize">
|
||||||
</main>
|
<svg width="12" height="12" viewBox="0 0 12 12">
|
||||||
|
<rect fill="currentColor" width="10" height="1" x="1" y="6" />
|
||||||
<VersionWarningModal v-if="showVersionWarningModal" :appVersion="appVersion" :backendVersion="backendVersion"
|
</svg>
|
||||||
:expectedBackendVersion="expectedBackendVersion" @close="showVersionWarningModal = false" />
|
</div>
|
||||||
|
<div class="titlebar-button" @click="toggleMaximize">
|
||||||
<footer v-if="!$route.meta.hideNavbar">
|
<svg width="12" height="12" viewBox="0 0 12 12">
|
||||||
<Navbar />
|
<rect fill="none" stroke="currentColor" stroke-width="1" width="9" height="9" x="1.5" y="1.5" />
|
||||||
</footer>
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="titlebar-button" id="close-btn" @click="close">
|
||||||
|
<svg width="12" height="12" viewBox="0 0 12 12">
|
||||||
|
<path fill="currentColor"
|
||||||
|
d="M11 1.57L10.43 1 6 5.43 1.57 1 1 1.57 5.43 6 1 10.43 1.57 11 6 6.57 10.43 11 11 10.43 6.57 6z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<main id="content">
|
||||||
|
<router-view />
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<VersionWarningModal v-if="showVersionWarningModal" :appVersion="appVersion" :backendVersion="backendVersion"
|
||||||
|
:expectedBackendVersion="expectedBackendVersion" @close="showVersionWarningModal = false" />
|
||||||
|
|
||||||
|
<footer v-if="!$route.meta.hideNavbar">
|
||||||
|
<Navbar />
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -19,6 +38,12 @@ import Navbar from './components/Navbar.vue'
|
|||||||
import VersionWarningModal from './components/VersionWarningModal.vue'
|
import VersionWarningModal from './components/VersionWarningModal.vue'
|
||||||
import { apiFetch } from './api/client'
|
import { apiFetch } from './api/client'
|
||||||
import { VersionResponse } from './types'
|
import { VersionResponse } from './types'
|
||||||
|
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||||
|
import { platform } from '@tauri-apps/plugin-os';
|
||||||
|
|
||||||
|
const currentPlatform = ref('')
|
||||||
|
|
||||||
|
const appWindow = getCurrentWindow()
|
||||||
|
|
||||||
const showVersionWarningModal = ref(false)
|
const showVersionWarningModal = ref(false)
|
||||||
const backendVersion = ref('')
|
const backendVersion = ref('')
|
||||||
@@ -26,52 +51,97 @@ const backendVersion = ref('')
|
|||||||
const appVersion = __APP_VERSION__
|
const appVersion = __APP_VERSION__
|
||||||
const expectedBackendVersion = __BACKEND_VERSION__
|
const expectedBackendVersion = __BACKEND_VERSION__
|
||||||
|
|
||||||
|
const isFullScreen = ref(false)
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
backendVersion.value = (await getBackendVersion()).version
|
backendVersion.value = (await getBackendVersion()).version
|
||||||
if (backendVersion.value !== expectedBackendVersion) {
|
if (backendVersion.value !== expectedBackendVersion) {
|
||||||
showVersionWarningModal.value = true
|
showVersionWarningModal.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentPlatform.value = platform()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const minimize = () => appWindow.minimize()
|
||||||
|
const toggleMaximize = () => {
|
||||||
|
appWindow.setFullscreen(!isFullScreen.value)
|
||||||
|
isFullScreen.value = !isFullScreen.value
|
||||||
|
}
|
||||||
|
const close = () => appWindow.close()
|
||||||
|
|
||||||
async function getBackendVersion() {
|
async function getBackendVersion() {
|
||||||
return await apiFetch<VersionResponse>('/version')
|
return await apiFetch<VersionResponse>('/version')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
#page {
|
#page {
|
||||||
background: var(--bg);
|
background: var(--bg);
|
||||||
height: 100dvh;
|
height: 100dvh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#content {
|
#content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 1100px;
|
max-width: 1100px;
|
||||||
padding: 2rem;
|
/* padding: 2rem; */
|
||||||
|
padding: calc(20px + 2rem) 2rem 2rem 2rem;
|
||||||
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.titlebar {
|
||||||
|
height: 30px;
|
||||||
|
background: var(--panel);
|
||||||
|
user-select: none;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.titlebar-button {
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 45px;
|
||||||
|
height: 30px;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
color: var(--text-color);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.titlebar-button:hover {
|
||||||
|
background: var(--panel-accent)
|
||||||
|
}
|
||||||
|
|
||||||
|
#close-btn:hover {
|
||||||
|
background: #e81123;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding-bottom: 24px;
|
padding-bottom: 24px;
|
||||||
background: var(--bg);
|
background: var(--bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 720px) {
|
@media (max-width: 720px) {
|
||||||
#content {
|
#content {
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
padding-top: 30px;
|
padding-top: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
padding-bottom: 56px;
|
padding-bottom: 56px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
22
src/base.css
22
src/base.css
@@ -16,6 +16,7 @@ body,
|
|||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is overwritten by the theme configuration */
|
||||||
:root {
|
:root {
|
||||||
--bg: #0f1116;
|
--bg: #0f1116;
|
||||||
--panel: #171922;
|
--panel: #171922;
|
||||||
@@ -23,6 +24,7 @@ body,
|
|||||||
--text: #e6e6eb;
|
--text: #e6e6eb;
|
||||||
--muted: #9aa0aa;
|
--muted: #9aa0aa;
|
||||||
--accent: #f27aa3;
|
--accent: #f27aa3;
|
||||||
|
--accent-rgb: 242, 122, 163;
|
||||||
--accent-hover: #ff91b3;
|
--accent-hover: #ff91b3;
|
||||||
--accent-second: #96CDFB;
|
--accent-second: #96CDFB;
|
||||||
--border: #2a2f3b;
|
--border: #2a2f3b;
|
||||||
@@ -30,6 +32,10 @@ body,
|
|||||||
--radius: 8px;
|
--radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
transition: background-color 0.2s ease, border-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: system-ui, -apple-system, BlinkMacSystemFont,
|
font-family: system-ui, -apple-system, BlinkMacSystemFont,
|
||||||
"Segoe UI", sans-serif;
|
"Segoe UI", sans-serif;
|
||||||
@@ -59,7 +65,8 @@ input:focus, textarea:focus {
|
|||||||
button, .button {
|
button, .button {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
background: var(--accent);
|
background: var(--accent);
|
||||||
color: #0b0d12;
|
color: var(--bg);
|
||||||
|
/* color: var(--btn-text); */
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: var(--radius);
|
border-radius: var(--radius);
|
||||||
padding: 0.6rem 1rem;
|
padding: 0.6rem 1rem;
|
||||||
@@ -74,6 +81,19 @@ button:hover, .button:hover {
|
|||||||
background: var(--accent-hover);
|
background: var(--accent-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.secondary {
|
||||||
|
background: transparent;
|
||||||
|
color: var(--text);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: var(--radius);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.secondary:hover {
|
||||||
|
background: var(--panel-hover);
|
||||||
|
}
|
||||||
|
|
||||||
input[type="checkbox"] {
|
input[type="checkbox"] {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ async function onSend(content: string) {
|
|||||||
border-radius: var(--radius);
|
border-radius: var(--radius);
|
||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: white;
|
color: var(--text);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
font-size: 1.6rem;
|
font-size: 1.6rem;
|
||||||
@@ -386,7 +386,7 @@ async function onSend(content: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.retry-btn:hover {
|
.retry-btn:hover {
|
||||||
background: rgba(255, 255, 255, 0.05);
|
background: var(--panel-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
.no-room {
|
.no-room {
|
||||||
|
|||||||
@@ -76,15 +76,6 @@ const emit = defineEmits(['yes', 'no']);
|
|||||||
color: var(--text);
|
color: var(--text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.secondary {
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 8px 16px;
|
|
||||||
border-radius: var(--radius);
|
|
||||||
background: transparent;
|
|
||||||
color: var(--text);
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-danger {
|
.btn-danger {
|
||||||
border-color: var(--error);
|
border-color: var(--error);
|
||||||
color: var(--error);
|
color: var(--error);
|
||||||
|
|||||||
@@ -92,14 +92,4 @@ async function submit() {
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.secondary {
|
|
||||||
background: transparent;
|
|
||||||
color: var(--text);
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.secondary:hover {
|
|
||||||
background: rgba(255, 255, 255, 0.05);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -120,14 +120,4 @@ async function submit() {
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.secondary {
|
|
||||||
background: transparent;
|
|
||||||
color: var(--text);
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.secondary:hover {
|
|
||||||
background: rgba(255, 255, 255, 0.05);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ onMounted(() => {
|
|||||||
top: 4px;
|
top: 4px;
|
||||||
right: 4px;
|
right: 4px;
|
||||||
background-color: var(--accent);
|
background-color: var(--accent);
|
||||||
color: black;
|
color: var(--bg);
|
||||||
font-size: 0.65rem;
|
font-size: 0.65rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
min-width: 18px;
|
min-width: 18px;
|
||||||
@@ -92,7 +92,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
.nav-item:hover {
|
.nav-item:hover {
|
||||||
background: rgba(255, 255, 255, 0.04);
|
background: var(--panel-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item:not(.router-link-active):hover i {
|
.nav-item:not(.router-link-active):hover i {
|
||||||
|
|||||||
@@ -205,15 +205,6 @@ const handleAvatarError = (event: Event) => {
|
|||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.secondary {
|
|
||||||
background: transparent;
|
|
||||||
color: var(--text);
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
padding: 8px 16px;
|
|
||||||
border-radius: var(--radius);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.member-list {
|
.member-list {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.retry-btn:hover {
|
.retry-btn:hover {
|
||||||
background: rgba(255, 255, 255, 0.05);
|
background: var(--panel-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
.room-content-wrapper {
|
.room-content-wrapper {
|
||||||
@@ -150,7 +150,7 @@ onMounted(async () => {
|
|||||||
|
|
||||||
.unread-badge {
|
.unread-badge {
|
||||||
background-color: var(--accent);
|
background-color: var(--accent);
|
||||||
color: black;
|
color: var(--bg);
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
min-width: 20px;
|
min-width: 20px;
|
||||||
@@ -193,7 +193,7 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.room-item:hover {
|
.room-item:hover {
|
||||||
background: rgba(255, 255, 255, 0.05);
|
background: var(--panel-hover);
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,6 +236,6 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.create-btn:hover {
|
.create-btn:hover {
|
||||||
background: rgba(255, 255, 255, 0.05);
|
background: var(--panel-hover);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -112,7 +112,6 @@ async function submit() {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1.2rem;
|
gap: 1.2rem;
|
||||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.subtitle {
|
.subtitle {
|
||||||
@@ -154,10 +153,4 @@ button:disabled {
|
|||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.secondary {
|
|
||||||
background: transparent;
|
|
||||||
color: var(--text);
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ async function handleUpload() {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
background: rgba(255, 255, 255, 0.02);
|
background: var(--panel-accent);
|
||||||
min-height: 180px;
|
min-height: 180px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -221,7 +221,7 @@ async function handleUpload() {
|
|||||||
|
|
||||||
.drop-zone:hover {
|
.drop-zone:hover {
|
||||||
border-color: var(--accent);
|
border-color: var(--accent);
|
||||||
background: rgba(255, 255, 255, 0.05);
|
background: var(--panel-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
.drop-content i {
|
.drop-content i {
|
||||||
@@ -299,10 +299,4 @@ async function handleUpload() {
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.secondary {
|
|
||||||
background: transparent;
|
|
||||||
color: var(--text);
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -49,10 +49,4 @@ const emit = defineEmits(['close']);
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.secondary {
|
|
||||||
background: transparent;
|
|
||||||
color: var(--text);
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ settings-loading = Loading settings...
|
|||||||
settings-title = Settings
|
settings-title = Settings
|
||||||
settings-account = Account
|
settings-account = Account
|
||||||
settings-language = Language
|
settings-language = Language
|
||||||
|
settings-appearance = Appearance
|
||||||
settings-label-username = Username:
|
settings-label-username = Username:
|
||||||
settings-label-email = Email:
|
settings-label-email = Email:
|
||||||
settings-update-btn = Update
|
settings-update-btn = Update
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ settings-loading = Chargement des paramètres...
|
|||||||
settings-title = Paramètres
|
settings-title = Paramètres
|
||||||
settings-account = Compte
|
settings-account = Compte
|
||||||
settings-language = Langue
|
settings-language = Langue
|
||||||
|
settings-appearance = Apparence
|
||||||
settings-label-username = Nom d'utilisateur :
|
settings-label-username = Nom d'utilisateur :
|
||||||
settings-label-email = Email :
|
settings-label-email = Email :
|
||||||
settings-update-btn = Modifier
|
settings-update-btn = Modifier
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import router from './router.ts'
|
import router from './router.ts'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import { validateToken } from './store.ts'
|
import { validateToken, initTheme } from './store.ts'
|
||||||
import { fluent, setLanguage } from './i18n'
|
import { fluent, setLanguage } from './i18n'
|
||||||
|
|
||||||
import './base.css'
|
import './base.css'
|
||||||
@@ -17,6 +17,8 @@ async function init() {
|
|||||||
const savedLocale = await getLocalePreference();
|
const savedLocale = await getLocalePreference();
|
||||||
const osLocale = navigator.language;
|
const osLocale = navigator.language;
|
||||||
|
|
||||||
|
await initTheme();
|
||||||
|
|
||||||
if (savedLocale) {
|
if (savedLocale) {
|
||||||
setLanguage(savedLocale);
|
setLanguage(savedLocale);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ const handleNotification = (roomUuid: string) => {
|
|||||||
.sidebar-overlay {
|
.sidebar-overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
background: rgba(0, 0, 0, 0.3);
|
/* background: rgba(0, 0, 0, 0.3); */
|
||||||
z-index: 15;
|
z-index: 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ async function declineRoom(senderUuid: string, roomUuid: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.decline-btn:hover {
|
.decline-btn:hover {
|
||||||
background-color: rgba(255, 255, 255, 0.05);
|
background-color: var(--panel-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 720px) {
|
@media (max-width: 720px) {
|
||||||
|
|||||||
@@ -38,6 +38,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h2>{{ $t('settings-appearance') || 'Appearance' }}</h2>
|
||||||
|
<div class="theme-grid">
|
||||||
|
<button v-for="theme in availableThemes" :key="theme.id" class="theme-btn"
|
||||||
|
:class="{ active: currentTheme === theme.id }" @click="changeTheme(theme.id)">
|
||||||
|
{{ theme.name }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button class="logout-btn" @click="logout">
|
<button class="logout-btn" @click="logout">
|
||||||
<i class="fa-solid fa-right-from-bracket"></i>
|
<i class="fa-solid fa-right-from-bracket"></i>
|
||||||
<span>{{ $t('settings-logout-btn') }}</span>
|
<span>{{ $t('settings-logout-btn') }}</span>
|
||||||
@@ -49,6 +57,7 @@
|
|||||||
import { ref, onMounted, computed } from 'vue'
|
import { ref, onMounted, computed } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { logout as authLogout } from '../store.ts'
|
import { logout as authLogout } from '../store.ts'
|
||||||
|
import { saveThemePreference, getThemePreference } from "../store.ts"
|
||||||
import { getAuthData } from "../store.ts"
|
import { getAuthData } from "../store.ts"
|
||||||
import type { User } from "../types"
|
import type { User } from "../types"
|
||||||
import UpdateAccountModal from '../components/UpdateAccountModal.vue'
|
import UpdateAccountModal from '../components/UpdateAccountModal.vue'
|
||||||
@@ -58,6 +67,7 @@ import { getSupportedLanguagesMetadata, setLanguage } from '../i18n'
|
|||||||
import UploadAvatarModal from '../components/UploadAvatarModal.vue'
|
import UploadAvatarModal from '../components/UploadAvatarModal.vue'
|
||||||
import defaultAvatar from '../assets/default-avatar.png'
|
import defaultAvatar from '../assets/default-avatar.png'
|
||||||
import { getAvatarUrl } from '../store.ts'
|
import { getAvatarUrl } from '../store.ts'
|
||||||
|
import { getAvailableThemes } from '../themeLoader';
|
||||||
|
|
||||||
const handleAvatarError = (event: Event) => {
|
const handleAvatarError = (event: Event) => {
|
||||||
const img = event.target as HTMLImageElement;
|
const img = event.target as HTMLImageElement;
|
||||||
@@ -73,6 +83,8 @@ const { $t } = useFluent()
|
|||||||
const currentLang = ref('')
|
const currentLang = ref('')
|
||||||
|
|
||||||
const languages = computed(() => getSupportedLanguagesMetadata())
|
const languages = computed(() => getSupportedLanguagesMetadata())
|
||||||
|
const currentTheme = ref('default');
|
||||||
|
const availableThemes = getAvailableThemes();
|
||||||
|
|
||||||
async function fetchUserData() {
|
async function fetchUserData() {
|
||||||
try {
|
try {
|
||||||
@@ -85,8 +97,8 @@ async function fetchUserData() {
|
|||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const pref = await getLocalePreference()
|
const pref = await getLocalePreference()
|
||||||
// Synchronize the UI state with the actual active language
|
|
||||||
currentLang.value = pref || (navigator.language.split('-')[0])
|
currentLang.value = pref || (navigator.language.split('-')[0])
|
||||||
|
currentTheme.value = await getThemePreference()
|
||||||
|
|
||||||
fetchUserData()
|
fetchUserData()
|
||||||
})
|
})
|
||||||
@@ -97,6 +109,11 @@ async function changeLanguage(code: string) {
|
|||||||
await saveLocalePreference(actual)
|
await saveLocalePreference(actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function changeTheme(theme: string) {
|
||||||
|
currentTheme.value = theme
|
||||||
|
await saveThemePreference(theme)
|
||||||
|
}
|
||||||
|
|
||||||
function logout() {
|
function logout() {
|
||||||
authLogout()
|
authLogout()
|
||||||
router.push('/login')
|
router.push('/login')
|
||||||
@@ -171,12 +188,44 @@ h2 {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lang-btn:hover:not(.active) {
|
||||||
|
background: rgba(var(--accent-rgb), 0.1);
|
||||||
|
border-color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
.lang-btn.active {
|
.lang-btn.active {
|
||||||
background: var(--accent);
|
background: var(--accent);
|
||||||
color: #000;
|
color: #000;
|
||||||
border-color: var(--accent);
|
border-color: var(--accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theme-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
|
||||||
|
gap: 0.5rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-btn {
|
||||||
|
background: var(--panel);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
color: var(--text);
|
||||||
|
margin: 0;
|
||||||
|
padding: 12px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-btn.active {
|
||||||
|
background: var(--accent);
|
||||||
|
color: var(--bg);
|
||||||
|
border-color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-btn:hover:not(.active) {
|
||||||
|
background: rgba(var(--accent-rgb), 0.1);
|
||||||
|
border-color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
.logout-btn {
|
.logout-btn {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -193,11 +242,11 @@ h2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.logout-btn:hover {
|
.logout-btn:hover {
|
||||||
color: rgba(255, 80, 80, 0.8);
|
color: var(--error);
|
||||||
}
|
}
|
||||||
|
|
||||||
.logout-btn:hover i {
|
.logout-btn:hover i {
|
||||||
color: rgba(255, 80, 80, 0.8);
|
color: var(--error);
|
||||||
}
|
}
|
||||||
|
|
||||||
.logout-btn i {
|
.logout-btn i {
|
||||||
|
|||||||
26
src/store.ts
26
src/store.ts
@@ -8,6 +8,7 @@ import { load, Store } from '@tauri-apps/plugin-store'
|
|||||||
import { UpdateUserResponse } from './types'
|
import { UpdateUserResponse } from './types'
|
||||||
import { reactive } from 'vue'
|
import { reactive } from 'vue'
|
||||||
import { API } from './main'
|
import { API } from './main'
|
||||||
|
import { applyTheme } from './themeLoader.ts';
|
||||||
|
|
||||||
let store: Store | null = null
|
let store: Store | null = null
|
||||||
export const initAuth = getAuthData
|
export const initAuth = getAuthData
|
||||||
@@ -184,3 +185,28 @@ export function getAvatarUrl(uuid: string | undefined | null) {
|
|||||||
export function refreshAvatar(uuid: string) {
|
export function refreshAvatar(uuid: string) {
|
||||||
avatarTimestamps[uuid] = Date.now()
|
avatarTimestamps[uuid] = Date.now()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==== Color themes ====
|
||||||
|
|
||||||
|
export async function saveThemePreference(themeId: string) {
|
||||||
|
const s = await getStore();
|
||||||
|
await s.set('theme', themeId);
|
||||||
|
await s.save();
|
||||||
|
applyTheme(themeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function initTheme() {
|
||||||
|
const s = await getStore();
|
||||||
|
const themeId = (await s.get<string>('theme')) || 'default';
|
||||||
|
applyTheme(themeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getThemePreference(): Promise<string> {
|
||||||
|
const s = await getStore()
|
||||||
|
return (await s.get<string>('theme')) ?? 'default'
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function applyStoredTheme() {
|
||||||
|
const theme = await getThemePreference();
|
||||||
|
document.documentElement.setAttribute('data-theme', theme);
|
||||||
|
}
|
||||||
|
|||||||
26
src/themeLoader.ts
Normal file
26
src/themeLoader.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import themes from './themes.json';
|
||||||
|
|
||||||
|
export type ThemeKey = keyof typeof themes;
|
||||||
|
|
||||||
|
export function applyTheme(themeKey: string) {
|
||||||
|
const theme = (themes as any)[themeKey] || themes.default;
|
||||||
|
const root = document.documentElement;
|
||||||
|
|
||||||
|
// Convert json keys to css Variables
|
||||||
|
Object.entries(theme.colors).forEach(([key, value]) => {
|
||||||
|
root.style.setProperty(`--${key}`, value as string);
|
||||||
|
});
|
||||||
|
|
||||||
|
// if (themeKey.includes('light')) {
|
||||||
|
// root.style.setProperty('--btn-text', theme.colors.bg);
|
||||||
|
// } else {
|
||||||
|
// root.style.setProperty('--btn-text', '#0b0d12');
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAvailableThemes() {
|
||||||
|
return Object.entries(themes).map(([id, data]) => ({
|
||||||
|
id,
|
||||||
|
name: data.name
|
||||||
|
}));
|
||||||
|
}
|
||||||
172
src/themes.json
Normal file
172
src/themes.json
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
{
|
||||||
|
"frangipane-dark": {
|
||||||
|
"name": "Frangipane Dark",
|
||||||
|
"colors": {
|
||||||
|
"bg": "#0f1116",
|
||||||
|
"panel": "#171922",
|
||||||
|
"panel-accent": "#12141B",
|
||||||
|
"panel-hover": "#22242D",
|
||||||
|
"text": "#e6e6eb",
|
||||||
|
"muted": "#9aa0aa",
|
||||||
|
"accent": "#f27aa3",
|
||||||
|
"accent-rgb": "242, 122, 163",
|
||||||
|
"accent-hover": "#ff91b3",
|
||||||
|
"accent-second": "#96CDFB",
|
||||||
|
"border": "#2a2f3b",
|
||||||
|
"error": "#ff5050"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"catppuccin-latte": {
|
||||||
|
"name": "Catppuccin Latte",
|
||||||
|
"colors": {
|
||||||
|
"bg": "#eff1f5",
|
||||||
|
"panel": "#e6e9ef",
|
||||||
|
"panel-hover": "#bcc0cc",
|
||||||
|
"panel-accent": "#ccd0da",
|
||||||
|
"text": "#4c4f69",
|
||||||
|
"muted": "#7c7f93",
|
||||||
|
"accent": "#ea76cb",
|
||||||
|
"accent-rgb": "234, 118, 203",
|
||||||
|
"accent-hover": "#d20f39",
|
||||||
|
"accent-second": "#1e66f5",
|
||||||
|
"border": "#dce0e8",
|
||||||
|
"error": "#d20f39"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"catppuccin-frappe": {
|
||||||
|
"name": "Catppuccin Frappé",
|
||||||
|
"colors": {
|
||||||
|
"bg": "#303446",
|
||||||
|
"panel": "#292c3c",
|
||||||
|
"panel-accent": "#232634",
|
||||||
|
"panel-hover": "#414559",
|
||||||
|
"text": "#c6d0f5",
|
||||||
|
"muted": "#838ba7",
|
||||||
|
"accent": "#a6d189",
|
||||||
|
"accent-rgb": "166, 209, 137",
|
||||||
|
"accent-hover": "#81c8be",
|
||||||
|
"accent-second": "#f2d5cf",
|
||||||
|
"border": "#414559",
|
||||||
|
"error": "#e78284"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"catppuccin-macchiato": {
|
||||||
|
"name": "Catppuccin Macchiato",
|
||||||
|
"colors": {
|
||||||
|
"bg": "#24273a",
|
||||||
|
"panel": "#1e2030",
|
||||||
|
"panel-accent": "#181926",
|
||||||
|
"panel-hover": "#363a4f",
|
||||||
|
"text": "#cad3f5",
|
||||||
|
"muted": "#8087a2",
|
||||||
|
"accent": "#c6a0f6",
|
||||||
|
"accent-rgb": "198, 160, 246",
|
||||||
|
"accent-hover": "#f5bde6",
|
||||||
|
"accent-second": "#8aadf4",
|
||||||
|
"border": "#494d64",
|
||||||
|
"error": "#ed8796"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"catppuccin-mocha": {
|
||||||
|
"name": "Catppuccin Mocha",
|
||||||
|
"colors": {
|
||||||
|
"bg": "#1e1e2e",
|
||||||
|
"panel": "#181825",
|
||||||
|
"panel-accent": "#11111b",
|
||||||
|
"panel-hover": "#313244",
|
||||||
|
"text": "#cdd6f4",
|
||||||
|
"muted": "#7f849c",
|
||||||
|
"accent": "#89b4fa",
|
||||||
|
"accent-rgb": "137, 180, 250",
|
||||||
|
"accent-hover": "#89dceb",
|
||||||
|
"accent-second": "#f5c2e7",
|
||||||
|
"border": "#313244",
|
||||||
|
"error": "#f38ba8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nord": {
|
||||||
|
"name": "Nordic",
|
||||||
|
"colors": {
|
||||||
|
"bg": "#2e3440",
|
||||||
|
"panel": "#3b4252",
|
||||||
|
"panel-accent": "#242933",
|
||||||
|
"panel-hover": "#434c5e",
|
||||||
|
"text": "#eceff4",
|
||||||
|
"muted": "#d8dee9",
|
||||||
|
"accent": "#88c0d0",
|
||||||
|
"accent-rgb": "136, 192, 208",
|
||||||
|
"accent-hover": "#8fbcbb",
|
||||||
|
"accent-second": "#81a1c1",
|
||||||
|
"border": "#4c566a",
|
||||||
|
"error": "#bf616a"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tokyo-night": {
|
||||||
|
"name": "Tokyo Night",
|
||||||
|
"colors": {
|
||||||
|
"bg": "#1a1b26",
|
||||||
|
"panel": "#16161e",
|
||||||
|
"panel-accent": "#1f2335",
|
||||||
|
"panel-hover": "#292e42",
|
||||||
|
"text": "#a9b1d6",
|
||||||
|
"muted": "#565f89",
|
||||||
|
"accent": "#7aa2f7",
|
||||||
|
"accent-rgb": "122, 162, 247",
|
||||||
|
"accent-hover": "#7dcfff",
|
||||||
|
"accent-second": "#bb9af7",
|
||||||
|
"border": "#24283b",
|
||||||
|
"error": "#f7768e"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gruvbox-dark": {
|
||||||
|
"name": "Gruvbox Dark",
|
||||||
|
"colors": {
|
||||||
|
"bg": "#282828",
|
||||||
|
"panel": "#3c3836",
|
||||||
|
"panel-accent": "#282828",
|
||||||
|
"panel-hover": "#504945",
|
||||||
|
"text": "#ebdbb2",
|
||||||
|
"muted": "#a89984",
|
||||||
|
"accent": "#fabd2f",
|
||||||
|
"accent-rgb": "250, 189, 47",
|
||||||
|
"accent-hover": "#fe8019",
|
||||||
|
"accent-second": "#b8bb26",
|
||||||
|
"border": "#504945",
|
||||||
|
"error": "#fb4934"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gruvbox-light": {
|
||||||
|
"name": "Gruvbox Light",
|
||||||
|
"colors": {
|
||||||
|
"bg": "#fbf1c7",
|
||||||
|
"panel": "#f2e5bc",
|
||||||
|
"panel-accent": "#d5c4a1",
|
||||||
|
"panel-hover": "#ebdbb2",
|
||||||
|
"text": "#3c3836",
|
||||||
|
"muted": "#7c6f64",
|
||||||
|
"accent": "#d65d0e",
|
||||||
|
"accent-rgb": "214, 93, 14",
|
||||||
|
"accent-hover": "#9d0006",
|
||||||
|
"accent-second": "#458588",
|
||||||
|
"border": "#bdae93",
|
||||||
|
"error": "#cc241d"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"solarized-dark": {
|
||||||
|
"name": "Solarized Dark",
|
||||||
|
"colors": {
|
||||||
|
"bg": "#002b36",
|
||||||
|
"panel": "#073642",
|
||||||
|
"panel-accent": "#00212b",
|
||||||
|
"panel-hover": "#586e75",
|
||||||
|
"text": "#839496",
|
||||||
|
"muted": "#657b83",
|
||||||
|
"accent": "#268bd2",
|
||||||
|
"accent-rgb": "38, 139, 210",
|
||||||
|
"accent-hover": "#2aa198",
|
||||||
|
"accent-second": "#859900",
|
||||||
|
"border": "#073642",
|
||||||
|
"error": "#dc322f"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -430,6 +430,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@tauri-apps/api" "^2.8.0"
|
"@tauri-apps/api" "^2.8.0"
|
||||||
|
|
||||||
|
"@tauri-apps/plugin-os@~2":
|
||||||
|
version "2.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tauri-apps/plugin-os/-/plugin-os-2.3.2.tgz#de916a82d8d955bba59a2ffdba7f7aaa29397246"
|
||||||
|
integrity sha512-n+nXWeuSeF9wcEsSPmRnBEGrRgOy6jjkSU+UVCOV8YUGKb2erhDOxis7IqRXiRVHhY8XMKks00BJ0OAdkpf6+A==
|
||||||
|
dependencies:
|
||||||
|
"@tauri-apps/api" "^2.8.0"
|
||||||
|
|
||||||
"@tauri-apps/plugin-store@~2":
|
"@tauri-apps/plugin-store@~2":
|
||||||
version "2.4.1"
|
version "2.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/@tauri-apps/plugin-store/-/plugin-store-2.4.1.tgz#5e2d3362e41861d2fa79a3f1a78c091e12963236"
|
resolved "https://registry.yarnpkg.com/@tauri-apps/plugin-store/-/plugin-store-2.4.1.tgz#5e2d3362e41861d2fa79a3f1a78c091e12963236"
|
||||||
|
|||||||
Reference in New Issue
Block a user