added token storage in a store, and improved layout on mobile

This commit is contained in:
2025-12-15 16:24:30 +01:00
parent d6a26c0d09
commit 0714088d4b
17 changed files with 170 additions and 154 deletions

View File

@@ -12,7 +12,7 @@
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2", "@tauri-apps/api": "^2",
"@tauri-apps/plugin-opener": "^2", "@tauri-apps/plugin-opener": "^2",
"pinia": "^3.0.4", "@tauri-apps/plugin-store": "~2",
"vue": "^3.5.13", "vue": "^3.5.13",
"vue-router": "^4.6.4" "vue-router": "^4.6.4"
}, },

29
src-tauri/Cargo.lock generated
View File

@@ -444,6 +444,7 @@ dependencies = [
"tauri", "tauri",
"tauri-build", "tauri-build",
"tauri-plugin-opener", "tauri-plugin-opener",
"tauri-plugin-store",
] ]
[[package]] [[package]]
@@ -3642,6 +3643,22 @@ dependencies = [
"zbus", "zbus",
] ]
[[package]]
name = "tauri-plugin-store"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59a77036340a97eb5bbe1b3209c31e5f27f75e6f92a52fd9dd4b211ef08bf310"
dependencies = [
"dunce",
"serde",
"serde_json",
"tauri",
"tauri-plugin",
"thiserror 2.0.17",
"tokio",
"tracing",
]
[[package]] [[package]]
name = "tauri-runtime" name = "tauri-runtime"
version = "2.9.2" version = "2.9.2"
@@ -3859,9 +3876,21 @@ dependencies = [
"mio", "mio",
"pin-project-lite", "pin-project-lite",
"socket2", "socket2",
"tokio-macros",
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
[[package]]
name = "tokio-macros"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]] [[package]]
name = "tokio-util" name = "tokio-util"
version = "0.7.17" version = "0.7.17"

View File

@@ -22,4 +22,5 @@ tauri = { version = "2", features = [] }
tauri-plugin-opener = "2" tauri-plugin-opener = "2"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
tauri-plugin-store = "2"

View File

@@ -7,6 +7,7 @@
], ],
"permissions": [ "permissions": [
"core:default", "core:default",
"opener:default" "opener:default",
"store:default"
] ]
} }

View File

@@ -2,10 +2,33 @@ package com.strawberries.chatapp
import android.os.Bundle import android.os.Bundle
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsControllerCompat
class MainActivity : TauriActivity() { class MainActivity : TauriActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge() enableEdgeToEdge()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
// Allow content to extend under the system bars
WindowCompat.setDecorFitsSystemWindows(window, false)
// Make status and navigation bars transparent
window.statusBarColor = android.graphics.Color.TRANSPARENT
window.navigationBarColor = android.graphics.Color.TRANSPARENT
// Get the insets controller
val insetsController = WindowInsetsControllerCompat(window, window.decorView)
// Set system bar icons to light (white)
// false = dark background → light icons
insetsController.isAppearanceLightStatusBars = false
insetsController.isAppearanceLightNavigationBars = false
// Optional: handle display cutout (notch)
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
window.attributes.layoutInDisplayCutoutMode =
android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
}
} }
} }

View File

@@ -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_store::Builder::new().build())
.plugin(tauri_plugin_opener::init()) .plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![greet]) .invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!()) .run(tauri::generate_context!())

View File

@@ -1,10 +1,25 @@
<script setup lang="ts">
import { useAuthStore } from "./stores/auth";
const auth = useAuthStore();
</script>
<template> <template>
<!-- You can later replace this with a real layout --> <div id="page">
<router-view /> <router-view />
</div>
</template> </template>
<style scoped>
#page {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
padding: 2rem;
box-sizing: border-box;
background: var(--background);
}
@media screen and (max-width: 720px) {
#page {
padding: 0;
padding-top: 20px;
padding-bottom: 40px;
}
}
</style>

View File

@@ -1,12 +1,12 @@
import { useAuthStore } from '../stores/auth' import { initAuth } from '../stores/auth.ts'
const BASE_URL = 'http://localhost:8080' const BASE_URL = 'http://192.168.1.183:8081'
export async function apiFetch<T>( export async function apiFetch<T>(
path: string, path: string,
options: RequestInit = {} options: RequestInit = {}
): Promise<T> { ): Promise<T> {
const auth = useAuthStore() const auth = await initAuth()
const res = await fetch(`${BASE_URL}${path}`, { const res = await fetch(`${BASE_URL}${path}`, {
...options, ...options,

View File

@@ -1,4 +1,3 @@
/* ---- CSS reset (minimal, modern) ---- */
*, *,
*::before, *::before,
*::after { *::after {
@@ -16,19 +15,17 @@ body,
height: 100%; height: 100%;
} }
/* ---- Theme variables ---- */
:root { :root {
--bg: #0f1115; --bg: #0f1116;
--panel: #171923; --panel: #171922;
--text: #e6e6eb; --text: #e6e6eb;
--muted: #9aa0a6; --muted: #9aa0aa;
--accent: #f27aa2; --accent: #f27aa3;
--accent-hover: #ff91b4; --accent-hover: #ff91b3;
--border: #2a2f3a; --border: #2a2f3b;
--radius: 8px; --radius: 8px;
} }
/* ---- Base ---- */
body { body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, font-family: system-ui, -apple-system, BlinkMacSystemFont,
"Segoe UI", sans-serif; "Segoe UI", sans-serif;
@@ -37,7 +34,6 @@ body {
line-height: 1.5; line-height: 1.5;
} }
/* ---- Inputs & buttons ---- */
input, textarea { input, textarea {
background: var(--panel); background: var(--panel);
border: 1px solid var(--border); border: 1px solid var(--border);

View File

@@ -5,8 +5,9 @@ defineProps<{ messages: Message[] }>()
<template> <template>
<ul> <ul>
<li v-for="(m, i) in messages" :key="i"> <li v-for="(m, i) in messages" :key="i" class="message">
<strong>{{ m.sender }}:</strong> {{ m.content }} <div class="sender">{{ m.sender }}</div>
<div class="message-content">{{ m.content }}</div>
</li> </li>
</ul> </ul>
</template> </template>
@@ -16,16 +17,22 @@ ul {
padding: 0; padding: 0;
margin: 0; margin: 0;
list-style: none; list-style: none;
word-wrap: break-word;
} }
li { .message {
white-space: pre-wrap; margin-bottom: 1rem;
}
.sender {
font-weight: bold;
margin-bottom: 0.25rem;
} }
.message-content { .message-content {
display: inline-block; padding-left: 1rem;
white-space: pre-wrap;
word-wrap: break-word;
max-width: 100%; max-width: 100%;
word-break: break-word; display: block;
} }
</style> </style>

View File

@@ -1,11 +1,9 @@
import { createApp } from 'vue' import { createApp } from 'vue'
import { createPinia } from 'pinia'
import router from './router' import router from './router'
import App from './App.vue' import App from './App.vue'
import './base.css' import './base.css'
createApp(App) createApp(App)
.use(createPinia())
.use(router) .use(router)
.mount('#app') .mount('#app')

View File

@@ -50,9 +50,8 @@ function scrollToBottom() {
.chat-page { .chat-page {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 95%;
max-width: 720px; width: 90%;
margin: 0 auto;
padding: 15px; padding: 15px;
border: 1px solid var(--border); border: 1px solid var(--border);
border-radius: var(--radius); border-radius: var(--radius);

View File

@@ -1,18 +1,22 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue"; import { ref } from "vue";
import { useAuthStore } from "../stores/auth"; import { login } from '../stores/auth.ts'
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
const email = ref(""); const email = ref("");
const username = ref("");
const password = ref(""); const password = ref("");
const errorMessage = ref("");
const auth = useAuthStore();
const router = useRouter(); const router = useRouter();
async function submit() { async function submit() {
await auth.login(email.value, username.value, password.value); errorMessage.value = "";
router.push("/"); try {
await login(email.value, "", password.value);
router.push("/");
} catch (err: any) {
errorMessage.value = err?.message || "An unknown error occurred";
}
} }
</script> </script>
@@ -25,6 +29,8 @@ async function submit() {
<input v-model="password" type="password" placeholder="password" /> <input v-model="password" type="password" placeholder="password" />
<button type="submit">Login</button> <button type="submit">Login</button>
<p v-if="errorMessage" class="error-message">{{ errorMessage }}</p>
</form> </form>
</div> </div>
</template> </template>
@@ -55,4 +61,11 @@ async function submit() {
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
text-align: center; text-align: center;
} }
.error-message {
color: red;
font-size: 0.9rem;
text-align: center;
margin-top: 0.5rem;
}
</style> </style>

View File

@@ -17,14 +17,14 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref } from 'vue' import { onMounted, ref } from 'vue'
import { useAuthStore } from '../stores/auth' import { initAuth } from '../stores/auth.ts'
import { fetchRooms } from '../api/rooms' import { fetchRooms } from '../api/rooms'
import type { Room } from '../types/api' import type { Room } from '../types/api'
const auth = useAuthStore()
const rooms = ref<Room[]>([]) const rooms = ref<Room[]>([])
onMounted(async () => { onMounted(async () => {
const auth = await initAuth()
rooms.value = await fetchRooms(auth.uuid!) rooms.value = await fetchRooms(auth.uuid!)
}) })
</script> </script>

View File

@@ -1,5 +1,5 @@
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
import { useAuthStore } from '../stores/auth' import { initAuth } from '../stores/auth.ts'
import LoginPage from '../pages/LoginPage.vue' import LoginPage from '../pages/LoginPage.vue'
import RoomsPage from '../pages/RoomsPage.vue' import RoomsPage from '../pages/RoomsPage.vue'
@@ -14,8 +14,8 @@ const router = createRouter({
], ],
}) })
router.beforeEach((to) => { router.beforeEach(async (to) => {
const auth = useAuthStore() const auth = await initAuth()
if (!auth.isAuthenticated && to.path !== '/login') { if (!auth.isAuthenticated && to.path !== '/login') {
return '/login' return '/login'
} }

View File

@@ -1,32 +1,41 @@
import { defineStore } from 'pinia' import { load, Store } from '@tauri-apps/plugin-store'
import type { LoginResponse } from '../types/api' import type { LoginResponse } from '../types/api'
import { apiFetch } from '../api/client' import { apiFetch } from '../api/client'
export const useAuthStore = defineStore('auth', { let store: Store | null = null
state: () => ({
token: null as string | null,
uuid: null as string | null,
}),
getters: { async function getStore() {
isAuthenticated: (s) => !!s.token, if (!store) {
}, store = await load('store.json', { autoSave: false })
}
return store
}
actions: { export async function initAuth() {
async login(email: string, username: string, password: string) { const s = await getStore()
const res = await apiFetch<LoginResponse>('/login', { const token = await s.get<string>('token')
method: 'POST', const uuid = await s.get<string>('uuid')
body: JSON.stringify({ email, username, password }), return { token: token || null, uuid: uuid || null, isAuthenticated: !!token }
}) }
this.token = res.token export async function login(email: string, username: string, password: string) {
this.uuid = res.uuid const res: LoginResponse = await apiFetch('/login', {
}, method: 'POST',
body: JSON.stringify({ email, username, password }),
})
logout() { const s = await getStore()
this.token = null await s.set('token', res.token)
this.uuid = null await s.set('uuid', res.uuid)
}, await s.save()
},
})
return { token: res.token, uuid: res.uuid, isAuthenticated: true }
}
export async function logout() {
const s = await getStore()
await s.delete('token')
await s.delete('uuid')
await s.save()
return { token: null, uuid: null, isAuthenticated: false }
}

View File

@@ -356,6 +356,13 @@
dependencies: dependencies:
"@tauri-apps/api" "^2.8.0" "@tauri-apps/api" "^2.8.0"
"@tauri-apps/plugin-store@~2":
version "2.4.1"
resolved "https://registry.yarnpkg.com/@tauri-apps/plugin-store/-/plugin-store-2.4.1.tgz#5e2d3362e41861d2fa79a3f1a78c091e12963236"
integrity sha512-ckGSEzZ5Ii4Hf2D5x25Oqnm2Zf9MfDWAzR+volY0z/OOBz6aucPKEY0F649JvQ0Vupku6UJo7ugpGRDOFOunkA==
dependencies:
"@tauri-apps/api" "^2.8.0"
"@types/estree@1.0.8": "@types/estree@1.0.8":
version "1.0.8" version "1.0.8"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e"
@@ -442,33 +449,6 @@
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz#cbe97fe0162b365edc1dba80e173f90492535343" resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz#cbe97fe0162b365edc1dba80e173f90492535343"
integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g== integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==
"@vue/devtools-api@^7.7.7":
version "7.7.9"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-7.7.9.tgz#999dbea50da6b00cf59a1336f11fdc2b43d9e063"
integrity sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==
dependencies:
"@vue/devtools-kit" "^7.7.9"
"@vue/devtools-kit@^7.7.9":
version "7.7.9"
resolved "https://registry.yarnpkg.com/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz#bc218a815616e8987df7ab3e10fc1fb3b8706c58"
integrity sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==
dependencies:
"@vue/devtools-shared" "^7.7.9"
birpc "^2.3.0"
hookable "^5.5.3"
mitt "^3.0.1"
perfect-debounce "^1.0.0"
speakingurl "^14.0.1"
superjson "^2.2.2"
"@vue/devtools-shared@^7.7.9":
version "7.7.9"
resolved "https://registry.yarnpkg.com/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz#fa4c096b744927081a7dda5fcf05f34b1ae6ca14"
integrity sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==
dependencies:
rfdc "^1.4.1"
"@vue/language-core@2.2.12": "@vue/language-core@2.2.12":
version "2.2.12" version "2.2.12"
resolved "https://registry.yarnpkg.com/@vue/language-core/-/language-core-2.2.12.tgz#d01f7e865f593f968cb65c12a13d8337e65641f0" resolved "https://registry.yarnpkg.com/@vue/language-core/-/language-core-2.2.12.tgz#d01f7e865f593f968cb65c12a13d8337e65641f0"
@@ -531,11 +511,6 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
birpc@^2.3.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/birpc/-/birpc-2.9.0.tgz#b59550897e4cd96a223e2a6c1475b572236ed145"
integrity sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==
brace-expansion@^2.0.1: brace-expansion@^2.0.1:
version "2.0.2" version "2.0.2"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7"
@@ -543,13 +518,6 @@ brace-expansion@^2.0.1:
dependencies: dependencies:
balanced-match "^1.0.0" balanced-match "^1.0.0"
copy-anything@^4:
version "4.0.5"
resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-4.0.5.tgz#16cabafd1ea4bb327a540b750f2b4df522825aea"
integrity sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==
dependencies:
is-what "^5.2.0"
csstype@^3.1.3: csstype@^3.1.3:
version "3.2.3" version "3.2.3"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a"
@@ -617,16 +585,6 @@ he@^1.2.0:
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
hookable@^5.5.3:
version "5.5.3"
resolved "https://registry.yarnpkg.com/hookable/-/hookable-5.5.3.tgz#6cfc358984a1ef991e2518cb9ed4a778bbd3215d"
integrity sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==
is-what@^5.2.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/is-what/-/is-what-5.5.0.tgz#a3031815757cfe1f03fed990bf6355a2d3f628c4"
integrity sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==
magic-string@^0.30.21: magic-string@^0.30.21:
version "0.30.21" version "0.30.21"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.21.tgz#56763ec09a0fa8091df27879fd94d19078c00d91" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.21.tgz#56763ec09a0fa8091df27879fd94d19078c00d91"
@@ -641,11 +599,6 @@ minimatch@^9.0.3:
dependencies: dependencies:
brace-expansion "^2.0.1" brace-expansion "^2.0.1"
mitt@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1"
integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==
muggle-string@^0.4.1: muggle-string@^0.4.1:
version "0.4.1" version "0.4.1"
resolved "https://registry.yarnpkg.com/muggle-string/-/muggle-string-0.4.1.tgz#3b366bd43b32f809dc20659534dd30e7c8a0d328" resolved "https://registry.yarnpkg.com/muggle-string/-/muggle-string-0.4.1.tgz#3b366bd43b32f809dc20659534dd30e7c8a0d328"
@@ -661,11 +614,6 @@ path-browserify@^1.0.1:
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==
perfect-debounce@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz#9c2e8bc30b169cc984a58b7d5b28049839591d2a"
integrity sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==
picocolors@^1.1.1: picocolors@^1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
@@ -676,13 +624,6 @@ picomatch@^4.0.2, picomatch@^4.0.3:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042"
integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==
pinia@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/pinia/-/pinia-3.0.4.tgz#75dde12784a61e34c1fa6abcd13c1a1061c360c0"
integrity sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==
dependencies:
"@vue/devtools-api" "^7.7.7"
postcss@^8.5.3, postcss@^8.5.6: postcss@^8.5.3, postcss@^8.5.6:
version "8.5.6" version "8.5.6"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c"
@@ -692,11 +633,6 @@ postcss@^8.5.3, postcss@^8.5.6:
picocolors "^1.1.1" picocolors "^1.1.1"
source-map-js "^1.2.1" source-map-js "^1.2.1"
rfdc@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca"
integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==
rollup@^4.34.9: rollup@^4.34.9:
version "4.53.4" version "4.53.4"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.53.4.tgz#5517de2593624928ac18f041b269f3b79cb64e09" resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.53.4.tgz#5517de2593624928ac18f041b269f3b79cb64e09"
@@ -733,18 +669,6 @@ source-map-js@^1.2.1:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
speakingurl@^14.0.1:
version "14.0.1"
resolved "https://registry.yarnpkg.com/speakingurl/-/speakingurl-14.0.1.tgz#f37ec8ddc4ab98e9600c1c9ec324a8c48d772a53"
integrity sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==
superjson@^2.2.2:
version "2.2.6"
resolved "https://registry.yarnpkg.com/superjson/-/superjson-2.2.6.tgz#a223a3a988172a5f9656e2063fe5f733af40d099"
integrity sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==
dependencies:
copy-anything "^4"
tinyglobby@^0.2.13: tinyglobby@^0.2.13:
version "0.2.15" version "0.2.15"
resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2" resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2"