better dev runner, bug fixes, design changes, and more

This commit is contained in:
Zoe
2024-09-11 00:57:33 -05:00
parent 70a9bcd904
commit 1fb4c71b2b
14 changed files with 377 additions and 81 deletions

View File

@@ -13,9 +13,12 @@
--highlight-low: 11 18 22;
--highlight-med: 32 37 38;
--highlight-high: 49 55 58;
--color-foam: 86 148 159;
--color-foam: 32 159 181;
--color-love: 220 100 130;
--color-pine: 40 105 131;
--color-accent: 136 57 239;
--color-accent-20: #dac9f1;
--nav-height: 48px;
}
@@ -31,9 +34,11 @@
--highlight-low: 244 237 232;
--highlight-med: 223 218 217;
--highlight-high: 206 202 205;
--color-foam: 156 207 216;
--color-foam: 145 215 227;
--color-love: 235 111 146;
--color-pine: 49 116 143;
--color-accent: 154 87 237;
--color-accent-20: #342c3f;
color-scheme: dark;
}

Binary file not shown.

View File

@@ -25,7 +25,7 @@ const crumbs = computed(() => {
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m9 6l6 6l-6 6" />
</svg>
<NuxtLink class="hover:text-text" :class="index === crumbs.length - 1 ? 'text-foam' : 'text-subtle'"
<NuxtLink :class="index === crumbs.length - 1 ? 'text-foam' : 'text-subtle hover:text-text'"
:to="crumb.link">{{
crumb.name }}</NuxtLink>
</span>

View File

@@ -1,6 +1,6 @@
<template>
<div v-on:click="toggle()" class="w-5 h-5 border rounded cursor-pointer flex items-center justify-center"
:class="state === 'unchecked' ? 'hover:bg-muted/5 active:bg-muted/15' : 'bg-foam/10 hover:bg-foam/15 active:bg-foam/25 text-foam'">
:class="state === 'unchecked' ? 'hover:bg-muted/5 active:bg-muted/15' : 'bg-accent/10 hover:bg-accent/15 active:bg-accent/25 text-accent'">
<div v-if="state === 'some'" class="w-8/12 h-0.5 bg-current rounded-full"></div>
<span v-else-if="state === 'checked'">
<svg class="w-full h-full" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">

View File

@@ -45,63 +45,54 @@ const isInFolder = computed(() => route.path.startsWith('/home/') && route.path
<NuxtLink to="/home"
class="flex py-1.5 px-4 rounded-lg transition-bg duration-300 hover:bg-muted/10"
:class="{ 'bg-muted/10': isAllFilesActive }">
<svg class="m-0.5 mr-2" xmlns="http://www.w3.org/2000/svg" width="20" height="20"
viewBox="0 0 256 256">
<g fill="currentColor">
<path d="M208 72v112a8 8 0 0 1-8 8h-24v-88l-40-40H80V40a8 8 0 0 1 8-8h80Z"
opacity=".2" />
<path
d="m213.66 66.34l-40-40A8 8 0 0 0 168 24H88a16 16 0 0 0-16 16v16H56a16 16 0 0 0-16 16v144a16 16 0 0 0 16 16h112a16 16 0 0 0 16-16v-16h16a16 16 0 0 0 16-16V72a8 8 0 0 0-2.34-5.66ZM168 216H56V72h76.69L168 107.31V216Zm32-32h-16v-80a8 8 0 0 0-2.34-5.66l-40-40A8 8 0 0 0 136 56H88V40h76.69L200 75.31Zm-56-32a8 8 0 0 1-8 8H88a8 8 0 0 1 0-16h48a8 8 0 0 1 8 8Zm0 32a8 8 0 0 1-8 8H88a8 8 0 0 1 0-16h48a8 8 0 0 1 8 8Z" />
</g>
</svg>
All files
<div class="flex relative">
<svg class="m-0.5 mr-2" xmlns="http://www.w3.org/2000/svg" width="20" height="20"
viewBox="0 0 256 256">
<g fill="currentColor">
<path d="M208 72v112a8 8 0 0 1-8 8h-24v-88l-40-40H80V40a8 8 0 0 1 8-8h80Z"
opacity=".2" />
<path
d="m213.66 66.34l-40-40A8 8 0 0 0 168 24H88a16 16 0 0 0-16 16v16H56a16 16 0 0 0-16 16v144a16 16 0 0 0 16 16h112a16 16 0 0 0 16-16v-16h16a16 16 0 0 0 16-16V72a8 8 0 0 0-2.34-5.66ZM168 216H56V72h76.69L168 107.31V216Zm32-32h-16v-80a8 8 0 0 0-2.34-5.66l-40-40A8 8 0 0 0 136 56H88V40h76.69L200 75.31Zm-56-32a8 8 0 0 1-8 8H88a8 8 0 0 1 0-16h48a8 8 0 0 1 8 8Zm0 32a8 8 0 0 1-8 8H88a8 8 0 0 1 0-16h48a8 8 0 0 1 8 8Z" />
</g>
</svg>
All files
<div class="absolute -left-1.5 top-px bottom-px bg-accent w-[2px]"
:class="{ 'hidden': !isAllFilesActive }"></div>
</div>
</NuxtLink>
</li>
<li class="flex flex-col">
<!-- <li class="flex flex-col">
<NuxtLink to="/home/name"
class="flex py-1.5 px-4 rounded-lg transition-bg duration-300 hover:bg-muted/10"
:class="{ 'bg-muted/10': isInFolder }">
<svg v-if="isInFolder" class="m-0.5 mr-2" xmlns="http://www.w3.org/2000/svg" width="20"
height="20" viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2"
d="m5 19l2.757-7.351A1 1 0 0 1 8.693 11H21a1 1 0 0 1 .986 1.164l-.996 5.211A2 2 0 0 1 19.026 19za2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h4l3 3h7a2 2 0 0 1 2 2v2" />
</svg>
<svg v-else class="m-0.5 mr-2" xmlns="http://www.w3.org/2000/svg" width="20" height="20"
viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2"
d="M5 4h4l3 3h7a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2" />
</svg>
Folders
<div class="flex relative">
<svg v-if="isInFolder" class="m-0.5 mr-2" xmlns="http://www.w3.org/2000/svg" width="20"
height="20" viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2"
d="m5 19l2.757-7.351A1 1 0 0 1 8.693 11H21a1 1 0 0 1 .986 1.164l-.996 5.211A2 2 0 0 1 19.026 19za2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h4l3 3h7a2 2 0 0 1 2 2v2" />
</svg>
<svg v-else class="m-0.5 mr-2" xmlns="http://www.w3.org/2000/svg" width="20" height="20"
viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2"
d="M5 4h4l3 3h7a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2" />
</svg>
Folders
<div class="absolute -left-1.5 top-px bottom-px bg-accent w-[2px]"
:class="{ 'hidden': !isInFolder }"></div>
</div>
</NuxtLink>
<!-- <ul class="flex flex-col gap-y-2 w-4/5 mt-2 ml-auto">
<li>
<a href="/folder/thing" class="flex py-1.5 px-4 rounded-lg transition-bg duration-300"
:class="isActive('/folder/thing') ? 'bg-muted/10' : 'hover:bg-muted/10'">
<svg class="m-0.5 mr-2" xmlns="http://www.w3.org/2000/svg" width="20" height="20"
viewBox="0 0 256 256">
<g fill="currentColor">
<path d="M208 72v112a8 8 0 0 1-8 8h-24v-88l-40-40H80V40a8 8 0 0 1 8-8h80Z"
opacity=".2" />
<path
d="m213.66 66.34l-40-40A8 8 0 0 0 168 24H88a16 16 0 0 0-16 16v16H56a16 16 0 0 0-16 16v144a16 16 0 0 0 16 16h112a16 16 0 0 0 16-16v-16h16a16 16 0 0 0 16-16V72a8 8 0 0 0-2.34-5.66ZM168 216H56V72h76.69L168 107.31V216Zm32-32h-16v-80a8 8 0 0 0-2.34-5.66l-40-40A8 8 0 0 0 136 56H88V40h76.69L200 75.31Zm-56-32a8 8 0 0 1-8 8H88a8 8 0 0 1 0-16h48a8 8 0 0 1 8 8Zm0 32a8 8 0 0 1-8 8H88a8 8 0 0 1 0-16h48a8 8 0 0 1 8 8Z" />
</g>
</svg>
All files
</a>
</li>
</ul> -->
</li>
</li> -->
</ul>
</div>
<div class="m-2 w-[calc(100%-16px)]">
<div class="p-3 bg-overlay border rounded-lg flex items-end">
<svg width="32" height="32" class="-rotate-90 mr-2" xmlns="http://www.w3.org/2000/svg">
<!-- Background Track -->
<circle class="stroke-foam/20" cx="16" cy="16" :r="radius" fill="none" stroke-width="3" />
<circle class="stroke-accent/20" cx="16" cy="16" :r="radius" fill="none" stroke-width="3" />
<!-- Progress Track -->
<circle class="stroke-foam" cx="16" cy="16" :r="radius" fill="none" stroke-width="3"
<circle class="stroke-accent" cx="16" cy="16" :r="radius" fill="none" stroke-width="3"
:stroke-dasharray="circumference" :stroke-dashoffset="offset" stroke-linecap="round" />
</svg>
<p class="text-sm h-min"> {{ usage }} of {{ capacity }}</p>

View File

@@ -1,6 +1,6 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
ssr: true,
ssr: process.env.NODE_ENV === 'production' ? true : false,
compatibilityDate: '2024-04-03',
css: ['~/assets/css/main.css'],
@@ -11,10 +11,6 @@ export default defineNuxtConfig({
devtools: { enabled: true },
experimental: {
buildCache: true,
},
modules: [
'@nuxtjs/color-mode',
],

View File

@@ -208,9 +208,14 @@ const openFilePicker = () => {
}
const createFolder = async () => {
let { data, error } = await useFetch('/api/files/upload/' + route.path.replace(/^\/home/, '') + '/' + folderName.value, {
method: "POST"
})
const { data, error } = await useAsyncData(
() => $fetch('/api/files/upload' + route.path.replace(/^\/home/, '') + '/' + folderName.value, {
method: "POST",
body: {
files: selectedFiles.value?.map(file => ({ name: file.name }))
}
})
)
if (error.value != null) {
folderError.value = error.value.data.message;
@@ -224,7 +229,7 @@ const createFolder = async () => {
}
const deleteFiles = async () => {
await useFetch('/api/files/delete' + route.path.replace(/^\/home/, ''), {
await $fetch('/api/files/delete' + route.path.replace(/^\/home/, ''), {
method: "POST",
body: {
files: selectedFiles.value?.map(file => ({ name: file.name }))
@@ -233,6 +238,47 @@ const deleteFiles = async () => {
files.value = files.value?.filter(file => !selectedFiles.value?.includes(file))
}
const downloadFile = (file) => {
const anchor = document.createElement('a');
anchor.href = '/api/files/download/' + file.name;
anchor.download = file.name;
document.body.appendChild(anchor);
anchor.click();
document.body.removeChild(anchor);
}
const downloadFiles = async () => {
let filenames = ""
selectedFiles.value?.forEach((file, i) => {
filenames += encodeURIComponent(file.name)
if (i != selectedFiles.value?.length - 1) {
filenames += ",";
}
})
let { data, error } = await useAsyncData(
() => $fetch('/api/files/download', {
params: {
"filenames": filenames
}
})
)
console.log("DATA", data.value)
if (error.value == null) {
const anchor = document.createElement('a');
anchor.href = window.URL.createObjectURL(data.value)
anchor.download = "filething.zip";
document.body.appendChild(anchor);
anchor.click();
document.body.removeChild(anchor);
}
}
</script>
<template>
@@ -251,10 +297,10 @@ const deleteFiles = async () => {
</div>
<div class="ml-auto flex gap-x-1.5">
<button v-on:click="popupVisable = !popupVisable"
class=" px-2 py-1 rounded-md text-sm border bg-muted/10 hover:bg-muted/15 active:bg-muted/25">Close</button>
class=" px-2 py-1 rounded-md text-sm border bg-muted/10 hover:bg-muted/15 active:bg-muted/25 transition-bg">Close</button>
<button v-on:click="createFolder" :disabled="folderName === ''"
class=" px-2 py-1 rounded-md text-sm
disabled:bg-highlight-med/50 bg-highlight-med hover:brightness-105 active:brightness-110 transition-[background-color,filter] text-surface disabled:cursor-not-allowed">Confirm</button>
disabled:bg-highlight-med/50 bg-highlight-med not:hover:brightness-105 not:active:brightness-110 transition-[background-color,filter] text-surface disabled:cursor-not-allowed">Confirm</button>
</div>
</div>
</Popup>
@@ -271,7 +317,7 @@ const deleteFiles = async () => {
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<path d="M7 18a4.6 4.4 0 0 1 0-9a5 4.5 0 0 1 11 2h1a3.5 3.5 0 0 1 0 7h-1" />
<path d="m9 15l3-3l3 3m-3-3v9" />
<path stroke="rgb(var(--color-accent))" d="m9 15l3-3l3 3m-3-3v9" />
</g>
</svg>
Upload
@@ -279,9 +325,11 @@ const deleteFiles = async () => {
<button v-on:click="popupVisable = !popupVisable"
class="rounded-xl border-2 border-surface flex flex-col gap-y-2 px-2 py-3 w-40 justify-center items-center hover:bg-muted/10 active:bg-muted/20 transition-bg">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2"
d="M12 19H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h4l3 3h7a2 2 0 0 1 2 2v3.5M16 19h6m-3-3v6" />
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<path d="M12 19H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h4l3 3h7a2 2 0 0 1 2 2v3.5M16" />
<path stroke="rgb(var(--color-accent))" d="M16 19h6m-3-3v6" />
</g>
</svg>
New folder
</button>
@@ -294,7 +342,16 @@ const deleteFiles = async () => {
<Breadcrumbs :path="route.path" />
</h3>
<div class="mt-2">
<div v-if="selectedFiles?.length > 0">
<div class="flex flex-row gap-x-2" v-if="selectedFiles?.length > 0">
<button v-on:click="downloadFiles"
class="flex flex-row px-2 py-1 rounded-md transition-bg text-xs border hover:bg-muted/10 active:bg-muted/20 items-center">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2"
d="M4 20h16m-8-6V4m0 10l4-4m-4 4l-4-4" />
</svg>
Download
</button>
<button v-on:click="deleteFiles"
class="flex flex-row px-2 py-1 rounded-md transition-bg text-xs border hover:bg-love/10 active:bg-love/20 hover:text-love active:text-love items-center">
<svg class="mr-1" xmlns="http://www.w3.org/2000/svg" width="16" height="16"
@@ -329,8 +386,9 @@ const deleteFiles = async () => {
</tr>
</thead>
<tbody class="block">
<tr class="flex flex-row h-10 group items-center border-b hover:bg-muted/10 transition-bg"
v-for="file in sortedFiles">
<tr class="flex border-l-2 flex-row h-10 group items-center border-b active:bg-surface/45 transition-bg relative"
v-for="file in sortedFiles"
:class="file.toggled === 'checked' ? 'bg-accent/20 border-l-accent' : 'border-l-transparent hover:bg-surface'">
<td class="-ml-7 pr-4 flex-shrink-0">
<div class="w-5 h-5">
<Checkbox class="group-hover:flex"
@@ -371,6 +429,18 @@ const deleteFiles = async () => {
<td class="min-w-28 text-start sm:block hidden">
{{ file.last_modified }}
</td>
<td :class="file.toggled === 'checked' ? 'context-active' : 'context'"
class="absolute pl-6 top-0 bottom-0 right-0 hidden group-hover:flex items-center pr-8">
<button v-on:click="downloadFile(file)"
class="p-2 rounded hover:bg-muted/10 active:bg-muted/20">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20"
viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2"
d="M4 20h16m-8-6V4m0 10l4-4m-4 4l-4-4" />
</svg>
</button>
</td>
</tr>
</tbody>
</table>
@@ -388,4 +458,12 @@ th {
text-overflow: ellipsis;
white-space: nowrap;
}
.context-active {
background: linear-gradient(to right, transparent, var(--color-accent-20) 16px, var(--color-accent-20) 100%);
}
.context {
background: linear-gradient(to right, transparent, rgb(var(--color-surface)) 16px, rgb(var(--color-surface)) 100%);
}
</style>

View File

@@ -21,6 +21,7 @@ module.exports = {
foam: "rgb(var(--color-foam))",
love: "rgb(var(--color-love))",
pine: "rgb(var(--color-pine))",
accent: "rgb(var(--color-accent))",
"highlight-low": "rgb(var(--highlight-low))",
"highlight-med": "rgb(var(--highlight-med))",
"highlight-high": "rgb(var(--highlight-high))",
@@ -30,5 +31,8 @@ module.exports = {
},
},
},
future: {
hoverOnlyWhenSupported: true,
},
plugins: [],
};