migrate to nuxt and groundwork

This commit is contained in:
DecDuck
2024-10-08 00:39:42 +11:00
parent c46c54b2a5
commit c9577444cd
83 changed files with 5566 additions and 388 deletions

0
.bashrc Normal file
View File

2
.gitignore vendored
View File

@ -22,3 +22,5 @@ dist-ssr
*.njsproj
*.sln
*.sw?
.nuxt
.output

View File

@ -1,16 +1 @@
# Tauri + Vue + TypeScript
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
## Recommended IDE Setup
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)
## Type Support For `.vue` Imports in TS
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's Take Over mode by following these steps:
1. Run `Extensions: Show Built-in Extensions` from VS Code's command palette, look for `TypeScript and JavaScript Language Features`, then right click and select `Disable (Workspace)`. By default, Take Over mode will enable itself if the default TypeScript extension is disabled.
2. Reload the VS Code window by running `Developer: Reload Window` from the command palette.
You can learn more about Take Over mode [here](https://github.com/johnsoncodehk/volar/discussions/471).
# Drop App

14
app.vue Normal file
View File

@ -0,0 +1,14 @@
<template>
<div class="flex flex-col bg-zinc-900 h-screen w-screen overflow-hidden">
<Header class="select-none" />
<div class="grow overflow-y-scroll">
<div class="h-[200vh]" />
</div>
</div>
</template>
<script setup lang="ts">
import { invoke } from "@tauri-apps/api/core";
const state = await invoke("fetch_state");
</script>

3
assets/main.scss Normal file
View File

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

107
components/Header.vue Normal file
View File

@ -0,0 +1,107 @@
<template>
<div
@mousedown="() => window.startDragging()"
class="cursor-pointer bg-gray-950 flex flex-row pl-4 pr-2 py-2"
>
<div class="grow inline-flex items-center gap-x-10">
<Wordmark class="h-8 mb-1" />
<nav class="inline-flex items-center">
<ol class="inline-flex items-center gap-x-6">
<li
class="transition text-gray-300 hover:text-gray-100 uppercase font-display font-semibold text-md"
v-for="(nav, navIdx) in navigation"
>
{{ nav.label }}
</li>
</ol>
</nav>
</div>
<div class="inline-flex items-center">
<ol class="inline-flex gap-3">
<li v-for="(item, itemIdx) in quickActions">
<HeaderWidget
@click="item.action"
:notifications="item.notifications"
>
<component class="h-5" :is="item.icon" />
</HeaderWidget>
</li>
<HeaderUserWidget />
</ol>
<div class="ml-3 inline-flex h-6 gap-x-2">
<HeaderButton @click="() => window.minimize()">
<MinusIcon />
</HeaderButton>
<HeaderButton @click="() => window.maximize()">
<svg
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
x="6"
y="6"
width="12"
height="12"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</HeaderButton>
<HeaderButton @click="() => window.close()">
<XMarkIcon />
</HeaderButton>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {
BellIcon,
MinusIcon,
UserGroupIcon,
XMarkIcon,
} from "@heroicons/vue/16/solid";
import type { NavigationItem, QuickActionNav } from "./types";
import HeaderWidget from "./HeaderWidget.vue";
import { getCurrentWindow } from "@tauri-apps/api/window";
const window = getCurrentWindow();
const navigation: Array<NavigationItem> = [
{
prefix: "/store",
route: "/store",
label: "Store",
},
{
prefix: "/library",
route: "/library",
label: "Library",
},
{
prefix: "/community",
route: "/community",
label: "Community",
},
{
prefix: "/news",
route: "/news",
label: "News",
},
];
const quickActions: Array<QuickActionNav> = [
{
icon: UserGroupIcon,
action: async () => {},
},
{
icon: BellIcon,
action: async () => {},
},
];
</script>

View File

@ -0,0 +1,5 @@
<template>
<button class="transition h-full aspect-square text-zinc-300 hover:bg-zinc-800 hover:text-zinc-100">
<slot />
</button>
</template>

View File

@ -0,0 +1,82 @@
<template>
<Menu as="div" class="relative inline-block">
<MenuButton>
<HeaderWidget>
<div class="inline-flex items-center text-zinc-300 hover:text-white">
<img :src="userData.image" class="w-5 h-5 rounded-sm" />
<span class="ml-2 text-sm font-bold">{{ userData.name }}</span>
<ChevronDownIcon class="ml-3 h-4" />
</div>
</HeaderWidget>
</MenuButton>
<transition
enter-active-class="transition ease-out duration-100"
enter-from-class="transform opacity-0 scale-95"
enter-to-class="transform opacity-100 scale-100"
leave-active-class="transition ease-in duration-75"
leave-from-class="transform opacity-100 scale-100"
leave-to-class="transform opacity-0 scale-95"
>
<MenuItems
class="absolute bg-zinc-900 right-0 top-10 z-10 w-56 origin-top-right focus:outline-none shadow-md"
>
<PanelWidget class="flex-col gap-y-2">
<NuxtLink
to="/id/me"
class="transition inline-flex items-center w-full py-3 px-4 hover:bg-zinc-800"
>
<div class="inline-flex items-center text-zinc-300">
<img :src="userData.image" class="w-5 h-5 rounded-sm" />
<span class="ml-2 text-sm font-bold">{{ userData.name }}</span>
</div>
</NuxtLink>
<div class="h-0.5 rounded-full w-full bg-zinc-800" />
<div class="flex flex-col mb-1">
<MenuItem v-for="(nav, navIdx) in navigation" v-slot="{ active }">
<NuxtLink
:href="nav.route"
:class="[
active ? 'bg-zinc-800 text-zinc-100' : 'text-zinc-400',
'transition block px-4 py-2 text-sm',
]"
>
{{ nav.label }}</NuxtLink
>
</MenuItem>
</div>
</PanelWidget>
</MenuItems>
</transition>
</Menu>
</template>
<script setup lang="ts">
import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/vue";
import { ChevronDownIcon } from "@heroicons/vue/16/solid";
import type { NavigationItem } from "./types";
import HeaderWidget from "./HeaderWidget.vue";
const userData = {
image: "https://avatars.githubusercontent.com/u/64579723?v=4",
name: "DecDuck",
};
const navigation: NavigationItem[] = [
{
label: "Admin Dashboard",
route: "/admin",
prefix: "",
},
{
label: "Account settings",
route: "/account",
prefix: "",
},
{
label: "Sign out",
route: "/signout",
prefix: "",
},
];
</script>

View File

@ -0,0 +1,17 @@
<template>
<div class="transition inline-flex items-center cursor-pointer rounded-sm px-4 py-2 bg-zinc-900 text-zinc-600 hover:bg-zinc-800 hover:text-zinc-300 relative">
<slot />
<div v-if="props.notifications !== undefined"
class="text-zinc-900 absolute top-0 right-0 translate-x-[30%] translate-y-[-30%] text-xs bg-blue-300 rounded-full w-3.5 h-3.5 text-center">
{{ props.notifications }}
</div>
</div>
</template>
<script setup lang="ts">
const props = defineProps<{
notifications?: number
}>();
</script>

7
components/Logo.vue Normal file
View File

@ -0,0 +1,7 @@
<template>
<svg class="text-blue-400" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M4 13.5C4 11.0008 5.38798 8.76189 7.00766 7C8.43926 5.44272 10.0519 4.25811 11.0471 3.5959C11.6287 3.20893 12.3713 3.20893 12.9529 3.5959C13.9481 4.25811 15.5607 5.44272 16.9923 7C18.612 8.76189 20 11.0008 20 13.5C20 17.9183 16.4183 21.5 12 21.5C7.58172 21.5 4 17.9183 4 13.5Z"
stroke="currentColor" stroke-width="2" />
</svg>
</template>

11
components/Wordmark.vue Normal file
View File

@ -0,0 +1,11 @@
<template>
<div class="inline-flex justify-center items-center gap-x-1 -mb-1 relative">
<svg aria-hidden="true" viewBox="0 0 418 42" class="absolute inset-0 h-full w-full fill-blue-300/30 scale-75"
preserveAspectRatio="none">
<path
d="M203.371.916c-26.013-2.078-76.686 1.963-124.73 9.946L67.3 12.749C35.421 18.062 18.2 21.766 6.004 25.934 1.244 27.561.828 27.778.874 28.61c.07 1.214.828 1.121 9.595-1.176 9.072-2.377 17.15-3.92 39.246-7.496C123.565 7.986 157.869 4.492 195.942 5.046c7.461.108 19.25 1.696 19.17 2.582-.107 1.183-7.874 4.31-25.75 10.366-21.992 7.45-35.43 12.534-36.701 13.884-2.173 2.308-.202 4.407 4.442 4.734 2.654.187 3.263.157 15.593-.78 35.401-2.686 57.944-3.488 88.365-3.143 46.327.526 75.721 2.23 130.788 7.584 19.787 1.924 20.814 1.98 24.557 1.332l.066-.011c1.201-.203 1.53-1.825.399-2.335-2.911-1.31-4.893-1.604-22.048-3.261-57.509-5.556-87.871-7.36-132.059-7.842-23.239-.254-33.617-.116-50.627.674-11.629.54-42.371 2.494-46.696 2.967-2.359.259 8.133-3.625 26.504-9.81 23.239-7.825 27.934-10.149 28.304-14.005.417-4.348-3.529-6-16.878-7.066Z" />
</svg>
<Logo class="h-6" />
<span class="text-blue-400 font-display font-bold text-xl uppercase">Drop</span>
</div>
</template>

13
components/types.d.ts vendored Normal file
View File

@ -0,0 +1,13 @@
import type { Component } from "vue"
export type NavigationItem = {
prefix: string,
route: string,
label: string,
}
export type QuickActionNav = {
icon: Component,
notifications?: number,
action: () => Promise<void>,
}

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

View File

@ -1,14 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tauri + Vue + Typescript App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

16
nuxt.config.ts Normal file
View File

@ -0,0 +1,16 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
compatibilityDate: "2024-04-03",
devtools: { enabled: true },
postcss: {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
},
css: ['~/assets/main.scss'],
ssr: false,
});

View File

@ -4,22 +4,29 @@
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview",
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare",
"tauri": "tauri"
},
"dependencies": {
"vue": "^3.3.4",
"@tauri-apps/api": ">=2.0.0",
"@tauri-apps/plugin-shell": ">=2.0.0"
"@tauri-apps/plugin-shell": ">=2.0.0",
"@headlessui/vue": "^1.7.23",
"@heroicons/vue": "^2.1.5",
"nuxt": "^3.13.0",
"scss": "^0.2.4",
"vue": "latest",
"vue-router": "latest"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.5",
"typescript": "^5.2.2",
"vite": "^5.3.1",
"vue-tsc": "^2.0.22",
"@tauri-apps/cli": ">=2.0.0"
"@tauri-apps/cli": ">=2.0.0",
"autoprefixer": "^10.4.20",
"postcss": "^8.4.47",
"sass-embedded": "^1.79.4",
"tailwindcss": "^3.4.13"
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}

View File

@ -1,6 +0,0 @@
<svg width="206" height="231" viewBox="0 0 206 231" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M143.143 84C143.143 96.1503 133.293 106 121.143 106C108.992 106 99.1426 96.1503 99.1426 84C99.1426 71.8497 108.992 62 121.143 62C133.293 62 143.143 71.8497 143.143 84Z" fill="#FFC131"/>
<ellipse cx="84.1426" cy="147" rx="22" ry="22" transform="rotate(180 84.1426 147)" fill="#24C8DB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M166.738 154.548C157.86 160.286 148.023 164.269 137.757 166.341C139.858 160.282 141 153.774 141 147C141 144.543 140.85 142.121 140.558 139.743C144.975 138.204 149.215 136.139 153.183 133.575C162.73 127.404 170.292 118.608 174.961 108.244C179.63 97.8797 181.207 86.3876 179.502 75.1487C177.798 63.9098 172.884 53.4021 165.352 44.8883C157.82 36.3744 147.99 30.2165 137.042 27.1546C126.095 24.0926 114.496 24.2568 103.64 27.6274C92.7839 30.998 83.1319 37.4317 75.8437 46.1553C74.9102 47.2727 74.0206 48.4216 73.176 49.5993C61.9292 50.8488 51.0363 54.0318 40.9629 58.9556C44.2417 48.4586 49.5653 38.6591 56.679 30.1442C67.0505 17.7298 80.7861 8.57426 96.2354 3.77762C111.685 -1.01901 128.19 -1.25267 143.769 3.10474C159.348 7.46215 173.337 16.2252 184.056 28.3411C194.775 40.457 201.767 55.4101 204.193 71.404C206.619 87.3978 204.374 103.752 197.73 118.501C191.086 133.25 180.324 145.767 166.738 154.548ZM41.9631 74.275L62.5557 76.8042C63.0459 72.813 63.9401 68.9018 65.2138 65.1274C57.0465 67.0016 49.2088 70.087 41.9631 74.275Z" fill="#FFC131"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M38.4045 76.4519C47.3493 70.6709 57.2677 66.6712 67.6171 64.6132C65.2774 70.9669 64 77.8343 64 85.0001C64 87.1434 64.1143 89.26 64.3371 91.3442C60.0093 92.8732 55.8533 94.9092 51.9599 97.4256C42.4128 103.596 34.8505 112.392 30.1816 122.756C25.5126 133.12 23.9357 144.612 25.6403 155.851C27.3449 167.09 32.2584 177.598 39.7906 186.112C47.3227 194.626 57.153 200.784 68.1003 203.846C79.0476 206.907 90.6462 206.743 101.502 203.373C112.359 200.002 122.011 193.568 129.299 184.845C130.237 183.722 131.131 182.567 131.979 181.383C143.235 180.114 154.132 176.91 164.205 171.962C160.929 182.49 155.596 192.319 148.464 200.856C138.092 213.27 124.357 222.426 108.907 227.222C93.458 232.019 76.9524 232.253 61.3736 227.895C45.7948 223.538 31.8055 214.775 21.0867 202.659C10.3679 190.543 3.37557 175.59 0.949823 159.596C-1.47592 143.602 0.768139 127.248 7.41237 112.499C14.0566 97.7497 24.8183 85.2327 38.4045 76.4519ZM163.062 156.711L163.062 156.711C162.954 156.773 162.846 156.835 162.738 156.897C162.846 156.835 162.954 156.773 163.062 156.711Z" fill="#24C8DB"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

87
src-tauri/Cargo.lock generated
View File

@ -106,6 +106,12 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "base64"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
[[package]]
name = "base64"
version = "0.21.7"
@ -118,6 +124,15 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]]
name = "bitflags"
version = "1.3.2"
@ -621,6 +636,15 @@ dependencies = [
"crypto-common",
]
[[package]]
name = "directories"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs"
version = "5.0.1"
@ -685,7 +709,9 @@ name = "drop-app"
version = "0.1.0"
dependencies = [
"ciborium",
"directories",
"rayon",
"rustbreak",
"serde",
"serde_json",
"tauri",
@ -772,6 +798,22 @@ dependencies = [
"typeid",
]
[[package]]
name = "errno"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "fastrand"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
[[package]]
name = "fdeflate"
version = "0.3.5"
@ -1658,6 +1700,12 @@ dependencies = [
"libc",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
name = "lock_api"
version = "0.4.12"
@ -2557,6 +2605,19 @@ dependencies = [
"windows-registry",
]
[[package]]
name = "rustbreak"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460d97902465327d69ecfe8cefdb5972c6f94d6127ac9e992acdb51458bebc27"
dependencies = [
"base64 0.12.3",
"bincode",
"serde",
"tempfile",
"thiserror",
]
[[package]]
name = "rustc-demangle"
version = "0.1.24"
@ -2572,6 +2633,19 @@ dependencies = [
"semver",
]
[[package]]
name = "rustix"
version = "0.38.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
dependencies = [
"bitflags 2.6.0",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
]
[[package]]
name = "ryu"
version = "1.0.18"
@ -3300,6 +3374,19 @@ dependencies = [
"toml 0.7.8",
]
[[package]]
name = "tempfile"
version = "3.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
dependencies = [
"cfg-if",
"fastrand",
"once_cell",
"rustix",
"windows-sys 0.59.0",
]
[[package]]
name = "tendril"
version = "0.4.3"

View File

@ -25,3 +25,9 @@ serde_json = "1"
ciborium = "0.2.2"
zstd = "0.13.2"
rayon = "1.10.0"
directories = "5.0.1"
[dependencies.rustbreak]
version = "2"
features = ["bin_enc"] # You can also use "yaml_enc" or "ron_enc"
# Check the documentation to add your own!

View File

@ -5,6 +5,10 @@
"windows": ["main"],
"permissions": [
"core:default",
"shell:allow-open"
"shell:allow-open",
"core:window:allow-start-dragging",
"core:window:allow-minimize",
"core:window:allow-maximize",
"core:window:allow-close"
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 974 B

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 903 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

14
src-tauri/src/auth.rs Normal file
View File

@ -0,0 +1,14 @@
use tauri::Error;
use crate::{data::DatabaseInterface, AppAuthenticationStatus, User};
pub fn setup(db: DatabaseInterface) -> Result<(AppAuthenticationStatus, Option<User>), Error> {
let data = db.get_data(true).unwrap();
// If we have certs, exit for now
if data.certs.is_some() {
// TODO: check if it's still valid, and fetch user information
return Ok((AppAuthenticationStatus::SignedInNeedsReauth, None));
}
return Ok((AppAuthenticationStatus::SignedOut, None));
}

32
src-tauri/src/data.rs Normal file
View File

@ -0,0 +1,32 @@
use std::fs::create_dir_all;
use directories::BaseDirs;
use rustbreak::{deser::Bincode, FileDatabase, PathDatabase};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone)]
pub struct DatabaseCerts {
pub private: String,
pub public: String,
pub cert: String,
}
#[derive(Serialize, Clone, Deserialize)]
pub struct Database {
pub certs: Option<DatabaseCerts>,
}
pub type DatabaseInterface =
rustbreak::Database<Database, rustbreak::backend::PathBackend, Bincode>;
pub fn setup() -> DatabaseInterface {
let db_path = BaseDirs::new().unwrap().data_dir().join("drop");
let default = Database {
certs: None
};
let db = PathDatabase::<Database, Bincode>::create_at_path(db_path, default).unwrap();
db.save().unwrap();
return db;
}

View File

@ -1,24 +1,45 @@
mod auth;
mod data;
mod unpacker;
use data::DatabaseInterface;
use serde::Serialize;
use tauri::Runtime;
use unpacker::unpack;
#[derive(Clone, Copy, Serialize)]
pub enum AppAuthenticationStatus {
SignedOut,
SignedIn,
SignedInNeedsReauth,
}
#[derive(Clone, Copy, Serialize)]
pub struct User {}
#[derive(Clone, Copy, Serialize)]
pub struct AppState {
auth: AppAuthenticationStatus,
user: Option<User>,
}
#[tauri::command]
async fn unpack_debug<R: Runtime>(
app: tauri::AppHandle<R>,
window: tauri::Window<R>,
) -> Result<String, String> {
unpack().unwrap();
return Ok("Successful".to_string());
fn fetch_state(state: tauri::State<AppState>) -> Result<AppState, String> {
Ok(*state.inner())
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
let db: DatabaseInterface = data::setup();
let auth_result = auth::setup(db).unwrap();
let state = AppState {
auth: auth_result.0,
user: auth_result.1,
};
tauri::Builder::default()
.manage(state)
.invoke_handler(tauri::generate_handler![fetch_state])
.plugin(tauri_plugin_shell::init())
.invoke_handler(tauri::generate_handler![unpack_debug])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

View File

@ -27,7 +27,7 @@ struct Manifest {
record: HashMap<String, ManifestRecord>,
}
pub fn unpack() -> Result<(), Error> {
pub async fn unpack() -> Result<(), Error> {
let chunk_size: u64 = 1024 * 1024 * 16;
let input = Path::new("/home/decduck/Dev/droplet-output");
@ -53,13 +53,12 @@ pub fn unpack() -> Result<(), Error> {
let chunk_path = input.join(chunk.uuid + ".bin");
let chunk_handle = File::open(chunk_path).unwrap();
let chunk_reader = BufReader::new(chunk_handle);
let mut decompressor = zstd::Decoder::new(chunk_reader).unwrap();
let mut chunk_reader = BufReader::new(chunk_handle);
let offset = u64::try_from(chunk.index).unwrap() * chunk_size;
file_handle.seek(io::SeekFrom::Start(offset)).unwrap();
io::copy(&mut decompressor, &mut file_handle).unwrap();
io::copy(&mut chunk_reader, &mut file_handle).unwrap();
file_handle.flush().unwrap();
}
});

View File

@ -1,21 +1,23 @@
{
"$schema": "https://schema.tauri.app/config/2.0.0",
"productName": "drop-app",
"productName": "drop",
"version": "0.1.0",
"identifier": "dev.drop.drop",
"build": {
"beforeDevCommand": "yarn dev",
"devUrl": "http://localhost:1420",
"beforeBuildCommand": "yarn build",
"frontendDist": "../dist"
"devUrl": "http://localhost:3000",
"beforeBuildCommand": "yarn generate",
"frontendDist": "../.output/public"
},
"app": {
"windows": [
{
"title": "drop-app",
"width": 800,
"height": 600
"width": 1536,
"height": 864,
"minWidth": 820,
"minHeight": 600,
"decorations": false
}
],
"security": {
@ -24,7 +26,7 @@
},
"bundle": {
"active": true,
"targets": "all",
"targets": ["msi", "deb"],
"icon": [
"icons/32x32.png",
"icons/128x128.png",

View File

@ -1,148 +1,19 @@
<script setup lang="ts">
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
import Greet from "./components/Greet.vue";
import { invoke } from '@tauri-apps/api/core';
import { ref } from 'vue';
const state = ref({});
invoke("fetch_state").then((value) => {
state.value = value as any;
})
</script>
<template>
<div class="container">
<h1>Welcome to Tauri!</h1>
<div class="row">
<a href="https://vitejs.dev" target="_blank">
<img src="/vite.svg" class="logo vite" alt="Vite logo" />
</a>
<a href="https://tauri.app" target="_blank">
<img src="/tauri.svg" class="logo tauri" alt="Tauri logo" />
</a>
<a href="https://vuejs.org/" target="_blank">
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
</a>
</div>
<p>Click on the Tauri, Vite, and Vue logos to learn more.</p>
<Greet />
</div>
hello world
<Suspense>
{{ state }}
</Suspense>
</template>
<style scoped>
.logo.vite:hover {
filter: drop-shadow(0 0 2em #747bff);
}
.logo.vue:hover {
filter: drop-shadow(0 0 2em #249b73);
}
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color: #0f0f0f;
background-color: #f6f6f6;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
.container {
margin: 0;
padding-top: 10vh;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: 0.75s;
}
.logo.tauri:hover {
filter: drop-shadow(0 0 2em #24c8db);
}
.row {
display: flex;
justify-content: center;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
h1 {
text-align: center;
}
input,
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
color: #0f0f0f;
background-color: #ffffff;
transition: border-color 0.25s;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
}
button {
cursor: pointer;
}
button:hover {
border-color: #396cd8;
}
button:active {
border-color: #396cd8;
background-color: #e8e8e8;
}
input,
button {
outline: none;
}
#greet-input {
margin-right: 5px;
}
@media (prefers-color-scheme: dark) {
:root {
color: #f6f6f6;
background-color: #2f2f2f;
}
a:hover {
color: #24c8db;
}
input,
button {
color: #ffffff;
background-color: #0f0f0f98;
}
button:active {
background-color: #0f0f0f69;
}
}
</style>
<style scoped></style>

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

Before

Width:  |  Height:  |  Size: 496 B

View File

@ -1,24 +0,0 @@
<script setup lang="ts">
import { ref } from "vue";
import { invoke } from "@tauri-apps/api/core";
const greetMsg = ref("");
const name = ref("");
async function greet() {
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
const start = Date.now();
await invoke("unpack_debug");
const ms = Date.now() - start;
greetMsg.value = `Took ${ms}ms`;
}
</script>
<template>
<form class="row" @submit.prevent="greet">
<input id="greet-input" v-model="name" placeholder="Enter a name..." />
<button type="submit">Unpack</button>
</form>
<p>{{ greetMsg }}</p>
</template>

16
tailwind.config.js Normal file
View File

@ -0,0 +1,16 @@
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./components/**/*.{js,vue,ts}",
"./layouts/**/*.vue",
"./pages/**/*.vue",
"./plugins/**/*.{js,ts}",
"./app.vue",
"./error.vue",
],
theme: {
extend: {
},
},
plugins: [],
};

View File

@ -1,25 +1,4 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json"
}

View File

@ -1,10 +0,0 @@
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}

View File

@ -1,32 +0,0 @@
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// @ts-expect-error process is a nodejs global
const host = process.env.TAURI_DEV_HOST;
// https://vitejs.dev/config/
export default defineConfig(async () => ({
plugins: [vue()],
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
//
// 1. prevent vite from obscuring rust errors
clearScreen: false,
// 2. tauri expects a fixed port, fail if that port is not available
server: {
port: 1420,
strictPort: true,
host: host || false,
hmr: host
? {
protocol: "ws",
host,
port: 1421,
}
: undefined,
watch: {
// 3. tell vite to ignore watching `src-tauri`
ignored: ["**/src-tauri/**"],
},
},
}));

5138
yarn.lock

File diff suppressed because it is too large Load Diff