folders: add breadcrumb top matter (fix #51)

pull/62/head
Varun Patil 2022-09-25 01:31:52 -07:00
parent 9360e1475f
commit 345b394229
6 changed files with 114 additions and 12 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -89,9 +89,8 @@ export default class Folder extends Mixins(GlobalMixin) {
/** Open folder */
openFolder(folder: IFolder) {
this.$router.push({ name: 'folders', params: {
path: folder.path.split('/').slice(3).join('/'),
}});
const path = folder.path.split('/').filter(x => x).slice(2).join('/');
this.$router.push({ name: 'folders', params: { path }});
}
}
</script>

View File

@ -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>

View File

@ -1,5 +1,9 @@
<template>
<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 -->
<RecycleScroller
ref="recycler"
@ -16,7 +20,7 @@
>
<div v-if="item.type === 0" class="head-row"
:class="{
'first': item.id === 1,
'first': item.id === 1 && !topMatterType,
'selected': item.selected,
}"
>
@ -114,7 +118,7 @@
<script lang="ts">
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 { showError } from '@nextcloud/dialogs'
import GlobalMixin from '../mixins/GlobalMixin';
@ -125,6 +129,7 @@ import * as utils from "../services/Utils";
import axios from '@nextcloud/axios'
import Folder from "./Folder.vue";
import Photo from "./Photo.vue";
import FolderTopMatter from "./FolderTopMatter.vue";
import UserConfig from "../mixins/UserConfig";
import Star from 'vue-material-design-icons/Star.vue';
@ -150,6 +155,7 @@ for (const [key, value] of Object.entries(API_ROUTES)) {
components: {
Folder,
Photo,
FolderTopMatter,
NcActions,
NcActionButton,
NcButton,
@ -210,6 +216,9 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
/** Set of selected file ids */
private selection = new Map<number, IPhoto>();
/** Static top matter type for current page */
private topMatterType: TopMatterType = TopMatterType.NONE;
/** State for request cancellations */
private state = Math.random();
@ -237,6 +246,9 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
/** Create new state */
async createState() {
// Initializations in this tick cycle
this.setTopMatter();
// Wait for one tick before doing anything
await this.$nextTick();
@ -266,6 +278,18 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
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 */
handleResizeWithDelay() {
if (this.resizeTimer) {
@ -280,9 +304,10 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
/** Handle window resize and initialization */
handleResize() {
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;
this.timelineHeight = e.clientHeight;
this.timelineHeight = height;
const recycler = this.$refs.recycler as any;
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 {
position: absolute;
top: 10px; right: 60px;
@ -1279,4 +1304,12 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
top: 35px; right: 15px;
}
}
/** Static top matter */
.top-matter {
padding-top: 4px;
@include phone {
padding-left: 38px;
}
}
</style>

View File

@ -90,4 +90,19 @@ export type ITick = {
text?: string | number;
/** Whether this tick should be shown */
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;
}[];
}