folders: add breadcrumb top matter (fix #51)
parent
9360e1475f
commit
345b394229
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -89,9 +89,8 @@ export default class Folder extends Mixins(GlobalMixin) {
|
||||||
|
|
||||||
/** Open folder */
|
/** Open folder */
|
||||||
openFolder(folder: IFolder) {
|
openFolder(folder: IFolder) {
|
||||||
this.$router.push({ name: 'folders', params: {
|
const path = folder.path.split('/').filter(x => x).slice(2).join('/');
|
||||||
path: folder.path.split('/').slice(3).join('/'),
|
this.$router.push({ name: 'folders', params: { path }});
|
||||||
}});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
<template>
|
||||||
|
<NcBreadcrumbs v-if="topMatter">
|
||||||
|
<NcBreadcrumb title="Home" :to="{ name: 'folders' }">
|
||||||
|
<template #icon>
|
||||||
|
<HomeIcon :size="20" />
|
||||||
|
</template>
|
||||||
|
</NcBreadcrumb>
|
||||||
|
<NcBreadcrumb v-for="folder in topMatter.list" :key="folder.path" :title="folder.text"
|
||||||
|
:to="{ name: 'folders', params: { path: folder.path }}" />
|
||||||
|
</NcBreadcrumbs>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Component, Mixins, Watch } from 'vue-property-decorator';
|
||||||
|
import { TopMatterFolder, TopMatterType } from "../types";
|
||||||
|
import { NcBreadcrumbs, NcBreadcrumb } from '@nextcloud/vue';
|
||||||
|
import GlobalMixin from '../mixins/GlobalMixin';
|
||||||
|
import HomeIcon from 'vue-material-design-icons/Home.vue';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
components: {
|
||||||
|
NcBreadcrumbs,
|
||||||
|
NcBreadcrumb,
|
||||||
|
HomeIcon,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
export default class FolderTopMatter extends Mixins(GlobalMixin) {
|
||||||
|
private topMatter?: TopMatterFolder = null;
|
||||||
|
|
||||||
|
@Watch('$route')
|
||||||
|
async routeChange(from: any, to: any) {
|
||||||
|
this.createMatter();
|
||||||
|
}
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.createMatter();
|
||||||
|
}
|
||||||
|
|
||||||
|
createMatter() {
|
||||||
|
if (this.$route.name === 'folders') {
|
||||||
|
this.topMatter = {
|
||||||
|
type: TopMatterType.FOLDER,
|
||||||
|
list: (this.$route.params.path || '').split('/').filter(x => x).map((x, idx, arr) => {
|
||||||
|
return {
|
||||||
|
text: x,
|
||||||
|
path: arr.slice(0, idx + 1).join('/'),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this.topMatter = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,5 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="container" ref="container" :class="{ 'icon-loading': loading > 0 }">
|
<div class="container" ref="container" :class="{ 'icon-loading': loading > 0 }">
|
||||||
|
<div ref="topmatter" class="top-matter" v-if="topMatterType">
|
||||||
|
<FolderTopMatter v-if="topMatterType === 1" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Main recycler view for rows -->
|
<!-- Main recycler view for rows -->
|
||||||
<RecycleScroller
|
<RecycleScroller
|
||||||
ref="recycler"
|
ref="recycler"
|
||||||
|
@ -16,7 +20,7 @@
|
||||||
>
|
>
|
||||||
<div v-if="item.type === 0" class="head-row"
|
<div v-if="item.type === 0" class="head-row"
|
||||||
:class="{
|
:class="{
|
||||||
'first': item.id === 1,
|
'first': item.id === 1 && !topMatterType,
|
||||||
'selected': item.selected,
|
'selected': item.selected,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
|
@ -114,7 +118,7 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Watch, Mixins } from 'vue-property-decorator';
|
import { Component, Watch, Mixins } from 'vue-property-decorator';
|
||||||
import { IDay, IFolder, IHeadRow, IPhoto, IRow, IRowType, ITick } from "../types";
|
import { IDay, IFolder, IHeadRow, IPhoto, IRow, IRowType, ITick, TopMatterType } from "../types";
|
||||||
import { generateUrl } from '@nextcloud/router'
|
import { generateUrl } from '@nextcloud/router'
|
||||||
import { showError } from '@nextcloud/dialogs'
|
import { showError } from '@nextcloud/dialogs'
|
||||||
import GlobalMixin from '../mixins/GlobalMixin';
|
import GlobalMixin from '../mixins/GlobalMixin';
|
||||||
|
@ -125,6 +129,7 @@ import * as utils from "../services/Utils";
|
||||||
import axios from '@nextcloud/axios'
|
import axios from '@nextcloud/axios'
|
||||||
import Folder from "./Folder.vue";
|
import Folder from "./Folder.vue";
|
||||||
import Photo from "./Photo.vue";
|
import Photo from "./Photo.vue";
|
||||||
|
import FolderTopMatter from "./FolderTopMatter.vue";
|
||||||
import UserConfig from "../mixins/UserConfig";
|
import UserConfig from "../mixins/UserConfig";
|
||||||
|
|
||||||
import Star from 'vue-material-design-icons/Star.vue';
|
import Star from 'vue-material-design-icons/Star.vue';
|
||||||
|
@ -150,6 +155,7 @@ for (const [key, value] of Object.entries(API_ROUTES)) {
|
||||||
components: {
|
components: {
|
||||||
Folder,
|
Folder,
|
||||||
Photo,
|
Photo,
|
||||||
|
FolderTopMatter,
|
||||||
NcActions,
|
NcActions,
|
||||||
NcActionButton,
|
NcActionButton,
|
||||||
NcButton,
|
NcButton,
|
||||||
|
@ -210,6 +216,9 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
/** Set of selected file ids */
|
/** Set of selected file ids */
|
||||||
private selection = new Map<number, IPhoto>();
|
private selection = new Map<number, IPhoto>();
|
||||||
|
|
||||||
|
/** Static top matter type for current page */
|
||||||
|
private topMatterType: TopMatterType = TopMatterType.NONE;
|
||||||
|
|
||||||
/** State for request cancellations */
|
/** State for request cancellations */
|
||||||
private state = Math.random();
|
private state = Math.random();
|
||||||
|
|
||||||
|
@ -237,6 +246,9 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
|
|
||||||
/** Create new state */
|
/** Create new state */
|
||||||
async createState() {
|
async createState() {
|
||||||
|
// Initializations in this tick cycle
|
||||||
|
this.setTopMatter();
|
||||||
|
|
||||||
// Wait for one tick before doing anything
|
// Wait for one tick before doing anything
|
||||||
await this.$nextTick();
|
await this.$nextTick();
|
||||||
|
|
||||||
|
@ -266,6 +278,18 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
this.loadedDays.clear();
|
this.loadedDays.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Create top matter */
|
||||||
|
setTopMatter() {
|
||||||
|
switch (this.$route.name) {
|
||||||
|
case 'folders':
|
||||||
|
this.topMatterType = TopMatterType.FOLDER;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.topMatterType = TopMatterType.NONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Do resize after some time */
|
/** Do resize after some time */
|
||||||
handleResizeWithDelay() {
|
handleResizeWithDelay() {
|
||||||
if (this.resizeTimer) {
|
if (this.resizeTimer) {
|
||||||
|
@ -280,9 +304,10 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
/** Handle window resize and initialization */
|
/** Handle window resize and initialization */
|
||||||
handleResize() {
|
handleResize() {
|
||||||
const e = this.$refs.container as Element;
|
const e = this.$refs.container as Element;
|
||||||
let height = e.clientHeight;
|
const tm = this.$refs.topmatter as Element;
|
||||||
|
let height = e.clientHeight - (tm?.clientHeight || 0);
|
||||||
let width = e.clientWidth;
|
let width = e.clientWidth;
|
||||||
this.timelineHeight = e.clientHeight;
|
this.timelineHeight = height;
|
||||||
|
|
||||||
const recycler = this.$refs.recycler as any;
|
const recycler = this.$refs.recycler as any;
|
||||||
recycler.$el.style.height = (height - 4) + 'px';
|
recycler.$el.style.height = (height - 4) + 'px';
|
||||||
|
@ -1255,7 +1280,7 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Top bar */
|
/** Top bar for selected items */
|
||||||
.top-bar {
|
.top-bar {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px; right: 60px;
|
top: 10px; right: 60px;
|
||||||
|
@ -1279,4 +1304,12 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
top: 35px; right: 15px;
|
top: 35px; right: 15px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Static top matter */
|
||||||
|
.top-matter {
|
||||||
|
padding-top: 4px;
|
||||||
|
@include phone {
|
||||||
|
padding-left: 38px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
15
src/types.ts
15
src/types.ts
|
@ -91,3 +91,18 @@ export type ITick = {
|
||||||
/** Whether this tick should be shown */
|
/** Whether this tick should be shown */
|
||||||
s?: boolean;
|
s?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type TopMatter = {
|
||||||
|
type: TopMatterType;
|
||||||
|
}
|
||||||
|
export enum TopMatterType {
|
||||||
|
NONE = 0,
|
||||||
|
FOLDER = 1,
|
||||||
|
}
|
||||||
|
export type TopMatterFolder = TopMatter & {
|
||||||
|
type: TopMatterType.FOLDER;
|
||||||
|
list: {
|
||||||
|
text: string;
|
||||||
|
path: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue