[web] Add breadcrumb to navigate through the folders
This commit is contained in:
parent
263a197da4
commit
25e005ff32
|
@ -1,14 +1,18 @@
|
|||
<template>
|
||||
<div
|
||||
v-if="$route.query.directory"
|
||||
class="media is-align-items-center"
|
||||
@click="open_parent()"
|
||||
>
|
||||
<figure class="media-left is-clickable">
|
||||
<mdicon class="icon" name="subdirectory-arrow-left" size="16" />
|
||||
<div v-if="$route.query.directory" class="media is-align-items-center">
|
||||
<figure class="media-left is-clickable" @click="open_parent">
|
||||
<mdicon class="icon" name="chevron-left" size="16" />
|
||||
</figure>
|
||||
<div class="media-content is-clickable is-clipped">
|
||||
<h1 class="title is-6">..</h1>
|
||||
<div class="media-content is-clipped">
|
||||
<nav class="breadcrumb">
|
||||
<ul>
|
||||
<li v-for="directory in directories" :key="directory.index">
|
||||
<a @click="open(directory)">
|
||||
<span v-text="directory.name" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="media-right">
|
||||
<slot name="actions" />
|
||||
|
@ -20,11 +24,7 @@
|
|||
<mdicon class="icon" name="folder" size="16" />
|
||||
</figure>
|
||||
<div class="media-content is-clickable is-clipped">
|
||||
<h1
|
||||
class="title is-6"
|
||||
v-text="item.path.substring(item.path.lastIndexOf('/') + 1)"
|
||||
/>
|
||||
<h2 class="subtitle is-7 has-text-grey" v-text="item.path" />
|
||||
<h1 class="title is-6" v-text="item.name" />
|
||||
</div>
|
||||
<div class="media-right">
|
||||
<a @click.prevent.stop="open_dialog(item)">
|
||||
|
@ -58,37 +58,34 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
current() {
|
||||
return this.$route.query?.directory || '/'
|
||||
directories() {
|
||||
const directories = []
|
||||
let path = ''
|
||||
this.$route.query?.directory
|
||||
.split('/')
|
||||
.slice(1, -1)
|
||||
.forEach((name, index) => {
|
||||
path = `${path}/${name}`
|
||||
directories.push({ index, name, path })
|
||||
})
|
||||
return directories
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
open(item) {
|
||||
this.$router.push({
|
||||
name: 'files',
|
||||
query: { directory: item.path }
|
||||
})
|
||||
const route = { name: 'files' }
|
||||
if (item.index !== 0) {
|
||||
route.query = { directory: item.path }
|
||||
}
|
||||
this.$router.push(route)
|
||||
},
|
||||
open_dialog(item) {
|
||||
this.selected_item = item.path
|
||||
this.show_details_modal = true
|
||||
},
|
||||
open_parent() {
|
||||
const parent = this.current.slice(0, this.current.lastIndexOf('/'))
|
||||
if (
|
||||
parent === '' ||
|
||||
this.$store.state.config.directories.includes(this.current)
|
||||
) {
|
||||
this.$router.push({ name: 'files' })
|
||||
} else {
|
||||
this.$router.push({
|
||||
name: 'files',
|
||||
query: {
|
||||
directory: this.current.slice(0, this.current.lastIndexOf('/'))
|
||||
}
|
||||
})
|
||||
}
|
||||
this.open(this.directories.slice(-1).pop())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
mdiCellphone,
|
||||
mdiCheck,
|
||||
mdiChevronDown,
|
||||
mdiChevronLeft,
|
||||
mdiChevronUp,
|
||||
mdiContentSave,
|
||||
mdiDelete,
|
||||
|
@ -57,7 +58,6 @@ import {
|
|||
mdiSpeaker,
|
||||
mdiSpotify,
|
||||
mdiStop,
|
||||
mdiSubdirectoryArrowLeft,
|
||||
mdiVolumeHigh,
|
||||
mdiVolumeOff,
|
||||
mdiWeb
|
||||
|
@ -77,6 +77,7 @@ export const icons = {
|
|||
mdiCellphone,
|
||||
mdiCheck,
|
||||
mdiChevronDown,
|
||||
mdiChevronLeft,
|
||||
mdiChevronUp,
|
||||
mdiContentSave,
|
||||
mdiDelete,
|
||||
|
@ -122,7 +123,6 @@ export const icons = {
|
|||
mdiSpeaker,
|
||||
mdiSpotify,
|
||||
mdiStop,
|
||||
mdiSubdirectoryArrowLeft,
|
||||
mdiVolumeHigh,
|
||||
mdiVolumeOff,
|
||||
mdiWeb
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
.tabs a {
|
||||
border-bottom-color: $grey-dark;
|
||||
}
|
||||
.breadcrumb a:hover,
|
||||
.tabs a,
|
||||
.hero.is-light .title,
|
||||
.title,
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
<div>
|
||||
<content-with-heading>
|
||||
<template #heading-left>
|
||||
<p class="title is-4" v-text="$t('page.files.title')" />
|
||||
<p class="title is-7 has-text-grey" v-text="current_directory" />
|
||||
<p class="title is-4" v-text="name" />
|
||||
</template>
|
||||
<template #heading-right>
|
||||
<div class="buttons is-centered">
|
||||
|
@ -20,7 +19,7 @@
|
|||
</div>
|
||||
</template>
|
||||
<template #content>
|
||||
<list-directories :items="dirs" />
|
||||
<list-directories :items="directories" />
|
||||
<list-playlists :items="playlists" />
|
||||
<list-tracks
|
||||
:expression="play_expression"
|
||||
|
@ -28,7 +27,7 @@
|
|||
:show_icon="true"
|
||||
/>
|
||||
<modal-dialog-directory
|
||||
:item="current_directory"
|
||||
:item="current"
|
||||
:show="show_details_modal"
|
||||
@close="show_details_modal = false"
|
||||
/>
|
||||
|
@ -53,25 +52,24 @@ const dataObject = {
|
|||
}
|
||||
return Promise.resolve()
|
||||
},
|
||||
|
||||
set(vm, response) {
|
||||
if (response) {
|
||||
vm.dirs = response.data.directories
|
||||
vm.playlists = new GroupedList(response.data.playlists)
|
||||
vm.tracks = new GroupedList(response.data.tracks)
|
||||
} else {
|
||||
if (vm.$store.state.config.directories) {
|
||||
vm.dirs = vm.$store.state.config.directories.map((dir) => ({
|
||||
path: dir
|
||||
}))
|
||||
vm.directories = response.data.directories.map((directory) =>
|
||||
vm.transform(directory.path)
|
||||
)
|
||||
} else if (vm.$store.state.config.directories) {
|
||||
vm.directories = vm.$store.state.config.directories.map((path) =>
|
||||
vm.transform(path)
|
||||
)
|
||||
} else {
|
||||
webapi.config().then((config) => {
|
||||
vm.dirs = config.data.directories.map((dir) => ({ path: dir }))
|
||||
vm.directories = config.data.directories.map((path) =>
|
||||
vm.transform(path)
|
||||
)
|
||||
})
|
||||
}
|
||||
vm.playlists = new GroupedList()
|
||||
vm.tracks = new GroupedList()
|
||||
}
|
||||
vm.playlists = new GroupedList(response?.data.playlists)
|
||||
vm.tracks = new GroupedList(response?.data.tracks)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,7 +98,7 @@ export default {
|
|||
|
||||
data() {
|
||||
return {
|
||||
dirs: [],
|
||||
directories: [],
|
||||
playlists: new GroupedList(),
|
||||
show_details_modal: false,
|
||||
tracks: new GroupedList()
|
||||
|
@ -108,20 +106,26 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
current_directory() {
|
||||
if (this.$route.query && this.$route.query.directory) {
|
||||
return this.$route.query.directory
|
||||
current() {
|
||||
return this.$route.query?.directory || '/'
|
||||
},
|
||||
name() {
|
||||
if (this.current !== '/') {
|
||||
return this.current?.slice(this.current.lastIndexOf('/') + 1)
|
||||
}
|
||||
return '/'
|
||||
return this.$t('page.files.title')
|
||||
},
|
||||
play_expression() {
|
||||
return `path starts with "${this.current_directory}" order by path asc`
|
||||
return `path starts with "${this.current}" order by path asc`
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
play() {
|
||||
webapi.player_play_expression(this.play_expression, false)
|
||||
},
|
||||
transform(path) {
|
||||
return { path, name: path.slice(path.lastIndexOf('/') + 1) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue