feat: add bookmark
This commit is contained in:
parent
2bf0926824
commit
a548aa7e75
5
frontend/src/api/context.js
Normal file
5
frontend/src/api/context.js
Normal file
@ -0,0 +1,5 @@
|
||||
import { fetchJSON } from './utils'
|
||||
|
||||
export async function get () {
|
||||
return await fetchJSON(`/api/context`, {})
|
||||
}
|
||||
@ -112,10 +112,22 @@ export async function post (url, content = '', overwrite = false, onupload) {
|
||||
}
|
||||
|
||||
request.send(content)
|
||||
// Upload is done no more message before closing the tab
|
||||
// Upload is done no more message before closing the tab
|
||||
}).finally(() => { window.onbeforeunload = null })
|
||||
}
|
||||
|
||||
export function bookmark (items) {
|
||||
let promises = []
|
||||
|
||||
for (let item of items) {
|
||||
const path = removePrefix(item.path)
|
||||
const url = `${path}?action=${item.bookmarked ? 'bookmark' : 'remove-bookmark'}`
|
||||
promises.push(resourceAction(url, 'PATCH'))
|
||||
}
|
||||
|
||||
return Promise.all(promises)
|
||||
}
|
||||
|
||||
function moveCopy (items, copy = false) {
|
||||
let promises = []
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ import * as files from './files'
|
||||
import * as share from './share'
|
||||
import * as users from './users'
|
||||
import * as settings from './settings'
|
||||
import * as context from './context'
|
||||
import search from './search'
|
||||
import commands from './commands'
|
||||
|
||||
@ -11,5 +12,6 @@ export {
|
||||
users,
|
||||
settings,
|
||||
commands,
|
||||
search
|
||||
search,
|
||||
context
|
||||
}
|
||||
|
||||
@ -45,6 +45,7 @@
|
||||
<switch-button v-show="isListing"></switch-button>
|
||||
<download-button v-show="showDownloadButton"></download-button>
|
||||
<upload-button v-show="showUpload"></upload-button>
|
||||
<bookmark-button v-show="showBookmarkButton"></bookmark-button>
|
||||
<info-button v-show="isFiles"></info-button>
|
||||
|
||||
<button v-show="isListing" @click="openSelect" :aria-label="$t('buttons.selectMultiple')" :title="$t('buttons.selectMultiple')" class="action">
|
||||
@ -71,6 +72,7 @@ import MoveButton from './buttons/Move'
|
||||
import CopyButton from './buttons/Copy'
|
||||
import ShareButton from './buttons/Share'
|
||||
import ShellButton from './buttons/Shell'
|
||||
import BookmarkButton from './buttons/Bookmark'
|
||||
import {mapGetters, mapState} from 'vuex'
|
||||
import { logoURL } from '@/utils/constants'
|
||||
import * as api from '@/api'
|
||||
@ -89,7 +91,8 @@ export default {
|
||||
UploadButton,
|
||||
SwitchButton,
|
||||
MoveButton,
|
||||
ShellButton
|
||||
ShellButton,
|
||||
BookmarkButton
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
@ -145,6 +148,9 @@ export default {
|
||||
? (this.selectedCount === 1 && this.user.perm.rename)
|
||||
: this.user.perm.rename)
|
||||
},
|
||||
showBookmarkButton () {
|
||||
return this.isFiles && this.isListing
|
||||
},
|
||||
showShareButton () {
|
||||
return this.isFiles && (this.isListing
|
||||
? (this.selectedCount === 1 && this.user.perm.share)
|
||||
|
||||
@ -6,7 +6,14 @@
|
||||
<span>{{ $t('sidebar.myFiles') }}</span>
|
||||
</router-link>
|
||||
|
||||
<div v-if="user.perm.create">
|
||||
<div>
|
||||
<router-link v-for="(bookmark) in bookmarks" :to="'/files'+bookmark.path" class="action" :aria-label="bookmark.name" :title="bookmark.name">
|
||||
<i class="material-icons">folder</i>
|
||||
<span>{{ bookmark.name }}</span>
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div v-if="user.perm.create" v-show="showNew">
|
||||
<button @click="$store.commit('showHover', 'newDir')" class="action" :aria-label="$t('sidebar.newFolder')" :title="$t('sidebar.newFolder')">
|
||||
<i class="material-icons">create_new_folder</i>
|
||||
<span>{{ $t('sidebar.newFolder') }}</span>
|
||||
@ -46,7 +53,7 @@
|
||||
<span>
|
||||
<span v-if="disableExternal">File Browser</span>
|
||||
<a v-else rel="noopener noreferrer" target="_blank" href="https://github.com/filebrowser/filebrowser">File Browser</a>
|
||||
<span> {{ version }}</span>
|
||||
<span> v{{ version }}</span>
|
||||
</span>
|
||||
<span><a @click="help">{{ $t('sidebar.help') }}</a></span>
|
||||
</p>
|
||||
@ -62,10 +69,18 @@ export default {
|
||||
name: 'sidebar',
|
||||
computed: {
|
||||
...mapState([ 'user' ]),
|
||||
...mapGetters([ 'isLogged' ]),
|
||||
...mapGetters([
|
||||
'isLogged',
|
||||
'bookmarks',
|
||||
'isFiles',
|
||||
'isListing'
|
||||
]),
|
||||
active () {
|
||||
return this.$store.state.show === 'sidebar'
|
||||
},
|
||||
showNew() {
|
||||
return this.isFiles && this.isListing
|
||||
},
|
||||
signup: () => signup,
|
||||
version: () => version,
|
||||
disableExternal: () => disableExternal,
|
||||
@ -78,4 +93,4 @@ export default {
|
||||
logout: auth.logout
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
43
frontend/src/components/buttons/Bookmark.vue
Normal file
43
frontend/src/components/buttons/Bookmark.vue
Normal file
@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<button @click="toggle" :aria-label="$t('buttons.bookmark')" :title="$t('buttons.bookmark')" class="action" id="bookmark-button">
|
||||
<i class="material-icons">{{ icon }}</i>
|
||||
<span>{{ $t('buttons.bookmark') }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapMutations } from 'vuex'
|
||||
import { files as filesApi, context as contextApi } from '@/api'
|
||||
|
||||
export default {
|
||||
name: 'bookmark-button',
|
||||
computed: {
|
||||
...mapState(['req']),
|
||||
icon: function () {
|
||||
if (this.req.bookmarked) return 'bookmark'
|
||||
return 'bookmark_border'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations([ 'updateBookmark', 'closeHovers' ]),
|
||||
toggle: async function () {
|
||||
this.closeHovers()
|
||||
|
||||
const data = {
|
||||
path: this.req.path,
|
||||
bookmarked: (this.icon === 'bookmark_border')
|
||||
}
|
||||
|
||||
try {
|
||||
await filesApi.bookmark([data])
|
||||
this.updateBookmark(data)
|
||||
|
||||
const ctx = await contextApi.get()
|
||||
this.$store.commit('updateContext', ctx)
|
||||
} catch (e) {
|
||||
this.$showError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -32,7 +32,8 @@
|
||||
"toggleSidebar": "Toggle sidebar",
|
||||
"update": "Update",
|
||||
"upload": "Upload",
|
||||
"permalink": "Get Permanent Link"
|
||||
"permalink": "Get Permanent Link",
|
||||
"bookmark": "Bookmark"
|
||||
},
|
||||
"success": {
|
||||
"linkCopied": "Link copied!"
|
||||
|
||||
@ -3,7 +3,8 @@ const getters = {
|
||||
isFiles: state => !state.loading && state.route.name === 'Files',
|
||||
isListing: (state, getters) => getters.isFiles && state.req.isDir,
|
||||
isEditor: (state, getters) => getters.isFiles && (state.req.type === 'text' || state.req.type === 'textImmutable'),
|
||||
selectedCount: state => state.selected.length
|
||||
selectedCount: state => state.selected.length,
|
||||
bookmarks: state => state.context.bookmarks
|
||||
}
|
||||
|
||||
export default getters
|
||||
|
||||
@ -8,6 +8,7 @@ Vue.use(Vuex)
|
||||
const state = {
|
||||
user: null,
|
||||
req: {},
|
||||
context: {},
|
||||
oldReq: {},
|
||||
clipboard: {
|
||||
key: '',
|
||||
|
||||
@ -71,10 +71,18 @@ const mutations = {
|
||||
state.user[field] = value[field]
|
||||
}
|
||||
},
|
||||
updateBookmark: (state, value) => {
|
||||
if (value.path === state.req.path) {
|
||||
state.req.bookmarked = value.bookmarked
|
||||
}
|
||||
},
|
||||
updateRequest: (state, value) => {
|
||||
state.oldReq = state.req
|
||||
state.req = value
|
||||
},
|
||||
updateContext: (state, value) => {
|
||||
state.context = value
|
||||
},
|
||||
updateClipboard: (state, value) => {
|
||||
state.clipboard.key = value.key
|
||||
state.clipboard.items = value.items
|
||||
|
||||
@ -19,6 +19,7 @@ import Sidebar from '@/components/Sidebar'
|
||||
import Prompts from '@/components/prompts/Prompts'
|
||||
import SiteHeader from '@/components/Header'
|
||||
import Shell from '@/components/Shell'
|
||||
import { context as api } from '@/api'
|
||||
|
||||
export default {
|
||||
name: 'layout',
|
||||
@ -38,6 +39,14 @@ export default {
|
||||
this.$store.commit('multiple', false)
|
||||
if (this.$store.state.show !== 'success') this.$store.commit('closeHovers')
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
try {
|
||||
const res = await api.get()
|
||||
this.$store.commit('updateContext', res)
|
||||
} catch (e) {
|
||||
this.$showError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user