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 */ /** 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>

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

View File

@ -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;
}[];
}