Recreated page navigation buttons.

This commit is contained in:
Leo Vasanko
2023-11-04 00:21:35 +00:00
parent 589b21f944
commit 12eabd29c3
73 changed files with 209 additions and 205 deletions

View File

@@ -51,23 +51,16 @@ export type { Path }
</script>
<template>
<header class="wrapper">
<HeaderMain WS="WS"></HeaderMain>
<AppNavigation :path="path.pathList"></AppNavigation>
<LoginModal />
<header>
<HeaderMain />
<BreadCrumb :path="path.pathList" />
</header>
<RouterView class="page-container" />
</template>
<style scoped>
.wrapper {
background-color: var(--header-background);
display: flex;
flex-direction: column;
gap: 10px;
}
.page-container {
flex-grow: 2;
padding: 0;
header {
background: #000;
}
</style>

View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="-12 -12 512 512"><path d="M480 416L355.44 291.44C373.22 262.4 384 228.58 384 192 384 85.98 298 0 192 0 85.98 0 0 85.98 0 192c0 106 85.98 192 192 192 36.58 0 70.4-10.78 99.44-28.5L416 480c8.75 8.75 23.25 8.7 32 0l32-32a22.8 22.8 0 0 0 0-32zm-288-96c-70.7 0-128-57.3-128-128S121.3 64 192 64s128 57.3 128 128-57.3 128-128 128z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-12 -12 512 512"><path d="M480 416L355.44 291.44C373.22 262.4 384 228.58 384 192 384 85.98 298 0 192 0 85.98 0 0 85.98 0 192c0 106 85.98 192 192 192 36.58 0 70.4-10.78 99.44-28.5L416 480c8.75 8.75 23.25 8.7 32 0l32-32a22.8 22.8 0 0 0 0-32zm-288-96c-70.7 0-128-57.3-128-128S121.3 64 192 64s128 57.3 128 128-57.3 128-128 128z"/></svg>

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 405 B

View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="352" height="448" viewBox="10 10 372 468"><path d="M128 344V168c0-4.5-3.5-8-8-8h-16c-4.5 0-8 3.5-8 8v176c0 4.5 3.5 8 8 8h16c4.5 0 8-3.5 8-8zm64 0V168c0-4.5-3.5-8-8-8h-16c-4.5 0-8 3.5-8 8v176c0 4.5 3.5 8 8 8h16c4.5 0 8-3.5 8-8zm64 0V168c0-4.5-3.5-8-8-8h-16c-4.5 0-8 3.5-8 8v176c0 4.5 3.5 8 8 8h16c4.5 0 8-3.5 8-8zM120 96h112l-12-29.25c-.75-1-3-2.5-4.25-2.75H136.5c-1.5.25-3.5 1.75-4.25 2.75zm232 8v16c0 4.5-3.5 8-8 8h-24v237c0 27.5-18 51-40 51H72c-22 0-40-22.5-40-50V128H8c-4.5 0-8-3.5-8-8v-16c0-4.5 3.5-8 8-8h77.25l17.5-41.75C107.75 42 122.75 32 136 32h80c13.25 0 28.25 10 33.25 22.25L266.75 96H344c4.5 0 8 3.5 8 8z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="40" viewBox="10 10 372 468"><path d="M128 344V168c0-4.5-3.5-8-8-8h-16c-4.5 0-8 3.5-8 8v176c0 4.5 3.5 8 8 8h16c4.5 0 8-3.5 8-8zm64 0V168c0-4.5-3.5-8-8-8h-16c-4.5 0-8 3.5-8 8v176c0 4.5 3.5 8 8 8h16c4.5 0 8-3.5 8-8zm64 0V168c0-4.5-3.5-8-8-8h-16c-4.5 0-8 3.5-8 8v176c0 4.5 3.5 8 8 8h16c4.5 0 8-3.5 8-8zM120 96h112l-12-29.25c-.75-1-3-2.5-4.25-2.75H136.5c-1.5.25-3.5 1.75-4.25 2.75zm232 8v16c0 4.5-3.5 8-8 8h-24v237c0 27.5-18 51-40 51H72c-22 0-40-22.5-40-50V128H8c-4.5 0-8-3.5-8-8v-16c0-4.5 3.5-8 8-8h77.25l17.5-41.75C107.75 42 122.75 32 136 32h80c13.25 0 28.25 10 33.25 22.25L266.75 96H344c4.5 0 8 3.5 8 8z"/></svg>

Before

Width:  |  Height:  |  Size: 671 B

After

Width:  |  Height:  |  Size: 670 B

View File

@@ -1,72 +0,0 @@
<script setup lang="ts">
const props = withDefaults(
defineProps<{
path: Array<string>
}>(),
{}
)
</script>
<template>
<nav>
<!--
<div class="view-nav">
<div class="view-nav-left">
<button class="af button tip tip-se" aria-label="Upload files from disk">{{{svg "add-file"}}}</button>
<button class="ad button tip tip-s" aria-label="Upload folder from disk">{{{svg "add-folder"}}}</button>
<button class="cd button tip tip-s" aria-label="Create folder">{{{svg "create-folder"}}}</button>
</div>
<div class="view-nav-right">
<div class="search toggled-off tip tip-s" aria-label="Search">
{{{svg "find"}}}
<input class="search-input" type="search" placeholder="Term" />
</div>
<button class="reload button tip tip-s" aria-label="Reload View">{{{svg "reload"}}}</button>
<button class="newview button tip tip-s" aria-label="Create new View">{{{svg "window"}}}</button>
<button class="prefs button tip tip-s" aria-label="Preferences">{{{svg "cog"}}}</button>
<button class="about button tip tip-s" aria-label="About">{{{svg "info"}}}</button>
<button class="logout button tip tip-sw" aria-label="Sign out">{{{svg "signout"}}}</button>
</div>
</div>
<ul class="path"></ul>
<div class="content-container">
<div class="content"></div>
</div>
<div class="dropzone">
<svg></svg>
</div>
<div class="info-box">
<div class="icon">{{{svg "link"}}}</div>
<span></span>
<div class="link-out mousetrap"></div>
<div class="link-options">
<div class="copy-link tip tip-nw" aria-label="Copy to clipboard">
{{{svg "copy"}}}<div>Copy</div>
</div>
<div class="dl-link checked tip tip-sw" aria-label="Trigger a download when opened">
{{{svg "check"}}}<div>Is DL</div>
</div>
</div>
</div>
<div class="paste-button">
{{{svg "paste"}}}
<span>Paste here</span>
{{{svg "triangle"}}}
</div>
-->
<BreadCrumb :path="props.path" />
</nav>
</template>
<style scoped>
nav,
span {
color: var(--primary-color);
}
span:hover,
.last {
color: var(--blue-color);
}
</style>

View File

@@ -10,8 +10,10 @@
</template>
<script setup lang="ts">
import home from '@/assets/svg/home.svg'
import { withDefaults, defineProps } from 'vue'
//import home from '@/assets/svg/home.svg'
import { withDefaults, defineProps, defineAsyncComponent } from 'vue'
const home = defineAsyncComponent(() => import(`@/assets/svg/home.svg`))
const props = withDefaults(
defineProps<{

View File

@@ -38,10 +38,18 @@
<tr v-if="editing?.key === 'new'" class="folder">
<td class="selection"></td>
<td class="name">
<FileRenameInput :doc="editing" :rename="mkdir" :exit="() => { editing = null }"/>
<FileRenameInput
:doc="editing"
:rename="mkdir"
:exit="
() => {
editing = null
}
"
/>
</td>
<td class="right">{{editing.modified}}</td>
<td class="right">{{editing.sizedisp}}</td>
<td class="right">{{ editing.modified }}</td>
<td class="right">{{ editing.sizedisp }}</td>
</tr>
<tr
v-for="doc of sorted(props.documents as FolderDocument[])"
@@ -158,7 +166,7 @@ const mkdir = (doc: FolderDocument, name: string) => {
control.send(
JSON.stringify({
op: 'mkdir',
path: `${decodeURIComponent(linkBasePath.value)}/${name}`,
path: `${decodeURIComponent(linkBasePath.value)}/${name}`
})
)
}

View File

@@ -1,16 +1,21 @@
<script setup lang="ts">
import { useDocumentStore } from '@/stores/documents'
import { ref } from 'vue'
import { ref, nextTick } from 'vue'
const documentStore = useDocumentStore()
const searchQuery = ref<string>('')
const showSearchInput = ref<boolean>(false)
const search = ref<HTMLInputElement | null>()
const toggleSearchInput = () => {
showSearchInput.value = !showSearchInput.value
if (!showSearchInput.value) {
searchQuery.value = ''
}
nextTick(() => {
const input = search.value
if (input) input.focus()
})
}
const executeSearch = (ev: InputEvent) => {
@@ -23,104 +28,56 @@ const executeSearch = (ev: InputEvent) => {
</script>
<template>
<div class="actions-container">
<div class="actions-list">
<nav>
<div class="buttons">
<UploadButton />
<!--
<a-tooltip title="Upload folder from disk">
<a-button @click="uploadFolderHandler" type="text" class="action-button" :icon="h(FolderAddFilled)" />
</a-tooltip>
<a-tooltip title="Create file">
<a-button @click="createFileHandler" type="text" class="action-button" :icon="h(FileFilled)" />
</a-tooltip>
<a-tooltip title="Create folder">
<a-button @click="createFolderHandler" type="text" class="action-button" :icon="h(FolderFilled)" />
</a-tooltip>
<template v-if="documentStore.selected.size > 0">
<a-tooltip title="Share">
<a-button type="text" @click="share" class="action-button" :icon="h(LinkOutlined)" />
</a-tooltip>
<a-tooltip title="Download Zip">
<a-button type="text" @click="download" class="action-button" :icon="h(DownloadOutlined)" />
</a-tooltip>
<a-tooltip title="Delete">
<a-button type="text" @click="deleteHandler" class="action-button" :icon="h(DeleteOutlined)" />
</a-tooltip>
<SvgButton name="create-folder" />
<template v-if="true">
<div class="smallgap"></div>
<p>N selected files:</p>
<!-- Needs better icons for copy/move/remove -->
<SvgButton name="copy" />
<SvgButton name="paste" />
<SvgButton name="trash" />
</template>
-->
</div>
<div class="actions-list">
<LoginModal></LoginModal>
<div class="spacer"></div>
<SvgButton name="find" @click="toggleSearchInput" />
<template v-if="showSearchInput">
<input type="search" v-model="searchQuery" class="margin-input" />
<input
ref="search"
type="search"
v-model="searchQuery"
class="margin-input"
@keyup.esc="toggleSearchInput"
/>
</template>
<!--
<a-tooltip title="Search">
<a-button @click="toggleSearchInput" type="text" class="action-button" :icon="h(SearchOutlined)" />
</a-tooltip>
<a-tooltip title="Create new view">
<a-button @click="newViewHandler" type="text" class="action-button" :icon="h(PlusSquareOutlined)" />
</a-tooltip>
<a-tooltip title="Preferences">
<a-button @click="preferencesHandler" type="text" class="action-button" :icon="h(SettingOutlined)" />
</a-tooltip>
<a-tooltip title="About">
<a-button @click="about" type="text" class="action-button" :icon="h(InfoCircleOutlined)" />
</a-tooltip>
-->
</div>
</div>
</nav>
</template>
<style>
.actions-container,
.actions-list {
<style scoped>
.buttons {
padding: 0 0.5em;
display: flex;
flex-wrap: nowrap;
gap: 15px;
align-items: center;
}
.actions-container {
justify-content: space-between;
.spacer {
flex-grow: 1;
}
.action-button {
padding: 0;
font-size: 1.5em;
color: var(--secondary-color);
&:hover {
color: var(--blue-color) !important;
}
.smallgap {
margin-left: 2em;
}
@media only screen and (max-width: 600px) {
.actions-container,
.actions-list {
gap: 6px;
}
.search-widget {
display: flex;
align-items: center;
}
.margin-input {
margin-top: 5px;
}
.path {
box-shadow: 0 0 0.5em rgba(0, 0, 0, 0.15);
overflow: hidden;
white-space: nowrap;
width: 100%;
z-index: 1;
flex: 0 0 1.5rem;
order: 1;
font-size: 0.9rem;
position: relative;
input[type='search'] {
background: var(--primary-background);
color: var(--text-color);
border: 0;
border-radius: 0.1rem;
padding: 0.5rem;
outline: none;
font-size: 1.2rem;
}
</style>

View File

@@ -0,0 +1,37 @@
<template>
<button class="action-button">
<component :is="icon" />
<slot></slot>
</button>
</template>
<script setup lang="ts">
import { defineAsyncComponent, defineProps } from 'vue'
const props = defineProps<{
name: string
}>()
const icon = defineAsyncComponent(() => import(`@/assets/svg/${props.name}.svg`))
</script>
<style scoped>
button {
background: none;
border: none;
color: #ccc;
cursor: pointer;
transition: all 0.2s ease;
padding: 0.5rem;
}
button:hover {
color: #fff;
}
svg {
fill: #ccc;
transform: fill 0.2s ease;
}
button:hover svg {
fill: #fff;
}
</style>

View File

@@ -3,6 +3,7 @@ import { useDocumentStore } from '@/stores/documents'
import { h, ref } from 'vue'
const fileUploadButton = ref()
const folderUploadButton = ref()
const documentStore = useDocumentStore()
const open = (placement: any) => openNotification(placement)
@@ -74,19 +75,22 @@ async function uploadFileChangeHandler(event: Event) {
}
</script>
<template>
(buttons here)
<!--
<a-tooltip title="Upload files from disk">
<a-button @click="uploadFileHandler" type="text" class="action-button" :icon="h(FileAddFilled)" />
<input ref="fileUploadButton" @change="uploadFileChangeHandler" class="upload-input" type="file" onclick="this.value=null;" />
</a-tooltip>
<contextHolder />
-->
<template>
<input
ref="fileUploadButton"
@change="uploadFileChangeHandler"
class="upload-input"
type="file"
multiple
/>
<input
ref="folderUploadButton"
@change="uploadFileChangeHandler"
class="upload-input"
type="file"
webkitdirectory
/>
</template>
<SvgButton name="add-file" @click="fileUploadButton.click()" />
<SvgButton name="add-folder" @click="folderUploadButton.click()" />
</template>
<style scoped>
/* Extends styles from HeaderMain.vue too */
.upload-input {
display: none;
}
</style>

View File

@@ -64,7 +64,7 @@ export class DocumentHandler {
handleWebSocketMessage(event: MessageEvent) {
const msg = JSON.parse(event.data)
if ("error" in msg) {
if ('error' in msg) {
if (msg.error.code === 401) {
this.store.user.isLoggedIn = false
this.store.user.isOpenLoginModal = true
@@ -72,10 +72,12 @@ export class DocumentHandler {
this.store.error = msg.error.message
}
// The server closes the websocket after errors, so we need to reopen it
setTimeout(
() => { this.store.wsWatch = createWebSocket(url_document_watch_ws, this.handleWebSocketMessage)},
1000
)
setTimeout(() => {
this.store.wsWatch = createWebSocket(
url_document_watch_ws,
this.handleWebSocketMessage
)
}, 1000)
}
switch (true) {
case !!msg.root:

View File

@@ -44,7 +44,12 @@ export const useDocumentStore = defineStore({
wsWatch: undefined,
wsUpload: undefined,
error: '' as string,
user: { username: "", privileged: false, isLoggedIn: false, isOpenLoginModal: false } as User
user: {
username: '',
privileged: false,
isLoggedIn: false,
isOpenLoginModal: false
} as User
}),
actions: {