Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/components/MobileHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
</div>

<div class="actions">
<GoToDateMenuItem />
<UploadMenuItem />
<SearchbarMenuItem />
</div>
Expand All @@ -21,6 +22,7 @@
import { defineComponent } from 'vue';
import { generateUrl } from '@nextcloud/router';

import GoToDateMenuItem from '@components/header/GoToDateMenuItem.vue';
import UploadMenuItem from '@components/header/UploadMenuItem.vue';
import SearchbarMenuItem from '@components/header/SearchbarMenuItem.vue';

Expand All @@ -31,6 +33,7 @@ import banner from '@assets/banner.svg';
export default defineComponent({
name: 'MobileHeader',
components: {
GoToDateMenuItem,
UploadMenuItem,
SearchbarMenuItem,
},
Expand Down
47 changes: 47 additions & 0 deletions src/components/Timeline.vue
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ export default defineComponent({
utils.bus.on('memories:timeline:deleted', this.deleteFromViewWithAnimation);
utils.bus.on('memories:timeline:soft-refresh', this.softRefresh);
utils.bus.on('memories:timeline:hard-refresh', this.refresh);
utils.bus.on('memories:timeline:scrollToDate', this.scrollToDate);
utils.bus.on('memories:timeline:getDateRange', this.getDateRange);
},

beforeDestroy() {
Expand All @@ -246,6 +248,8 @@ export default defineComponent({
utils.bus.off('memories:timeline:deleted', this.deleteFromViewWithAnimation);
utils.bus.off('memories:timeline:soft-refresh', this.softRefresh);
utils.bus.off('memories:timeline:hard-refresh', this.refresh);
utils.bus.off('memories:timeline:scrollToDate', this.scrollToDate);
utils.bus.off('memories:timeline:getDateRange', this.getDateRange);
this.resetState();
this.state = 0;
},
Expand Down Expand Up @@ -347,6 +351,49 @@ export default defineComponent({
return this.containerSize[0] <= 768;
},

/** Scroll to the nearest day matching the given date */
scrollToDate(date: Date) {
const targetDayId = utils.dateToDayId(date);

// Find the nearest dayId <= target (closest earlier or exact date)
let bestDayId: number | null = null;
for (const dayId of this.heads.keys()) {
if (dayId <= targetDayId) {
if (bestDayId === null || dayId > bestDayId) {
bestDayId = dayId;
}
}
}

// If no earlier date found, use the closest one overall
if (bestDayId === null) {
for (const dayId of this.heads.keys()) {
if (bestDayId === null || Math.abs(dayId - targetDayId) < Math.abs(bestDayId - targetDayId)) {
bestDayId = dayId;
}
}
}

if (bestDayId === null) return;

const index = this.list.findIndex((r) => r.type === 0 && r.dayId === bestDayId);
if (index !== -1) {
this.refs.recycler?.scrollToItem(index);
}
},

/** Provide the date range of the current view */
getDateRange(event: { result: { min: Date; max: Date } | null }) {
const dayIds = Array.from(this.heads.keys());
if (dayIds.length === 0) return;
const min = Math.min(...dayIds);
const max = Math.max(...dayIds);
event.result = {
min: utils.dayIdToDate(min),
max: utils.dayIdToDate(max),
};
},

isMobileLayout() {
return this.containerSize[0] <= 600;
},
Expand Down
31 changes: 31 additions & 0 deletions src/components/header/GoToDateMenuItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<template>
<NcDateTimePicker
:value="new Date()"
type="date"
:clearable="false"
:placeholder="t('memories', 'Go to date')"
@update:value="onDateSelected"
/>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

import NcDateTimePicker from '@nextcloud/vue/dist/Components/NcDateTimePicker.js';

import * as utils from '@services/utils';

export default defineComponent({
name: 'GoToDateMenuItem',
components: {
NcDateTimePicker,
},

methods: {
onDateSelected(date: Date) {
if (!date) return;
utils.bus.emit('memories:timeline:scrollToDate', date);
},
},
});
</script>
15 changes: 15 additions & 0 deletions src/components/top-matter/FolderTopMatter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@
</template>
</NcActionButton>
</NcActions>

<NcDateTimePicker
:value="new Date()"
type="date"
:clearable="false"
:placeholder="t('memories', 'Go to date')"
@update:value="onDateSelected"
/>
</div>
</div>
</template>
Expand All @@ -67,6 +75,7 @@ const NcBreadcrumbs = () => import('@nextcloud/vue/dist/Components/NcBreadcrumbs
const NcBreadcrumb = () => import('@nextcloud/vue/dist/Components/NcBreadcrumb.js');
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js';
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js';
import NcDateTimePicker from '@nextcloud/vue/dist/Components/NcDateTimePicker.js';
import PublicUploadHandler from '@components/upload/PublicUploadHandler.vue';

import * as utils from '@services/utils';
Expand All @@ -86,6 +95,7 @@ export default defineComponent({
NcBreadcrumb,
NcActions,
NcActionButton,
NcDateTimePicker,
PublicUploadHandler,
HomeIcon,
ShareIcon,
Expand Down Expand Up @@ -161,6 +171,11 @@ export default defineComponent({
uploadHandler(): InstanceType<typeof PublicUploadHandler> | null {
return (this.$refs.uploadHandler as InstanceType<typeof PublicUploadHandler>) || null;
},

onDateSelected(date: Date) {
if (!date) return;
utils.bus.emit('memories:timeline:scrollToDate', date);
},
},
});
</script>
Expand Down
16 changes: 14 additions & 2 deletions src/components/top-matter/TopMatter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
:class="{
'dynamic-visible': dynamicVisible,
}"
v-if="currentmatter"
>
<component :is="currentmatter" />
<component v-if="currentmatter" :is="currentmatter" />

<div v-if="!currentmatter" class="top-matter-date-only">
<div class="right-actions">
<GoToDateMenuItem />
</div>
</div>
</div>
</template>

Expand All @@ -19,6 +24,8 @@ import FaceTopMatter from './FaceTopMatter.vue';
import AlbumTopMatter from './AlbumTopMatter.vue';
import PlacesTopMatter from './PlacesTopMatter.vue';

import GoToDateMenuItem from '@components/header/GoToDateMenuItem.vue';

import * as utils from '@services/utils';

export default defineComponent({
Expand All @@ -28,6 +35,7 @@ export default defineComponent({
ClusterTopMatter,
FaceTopMatter,
AlbumTopMatter,
GoToDateMenuItem,
},

data: () => ({
Expand Down Expand Up @@ -134,6 +142,10 @@ export default defineComponent({
}
}

.top-matter-date-only {
justify-content: flex-end;
}

:deep button {
display: inline-block;
}
Expand Down
4 changes: 4 additions & 0 deletions src/services/utils/event-bus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ export type BusEvent = {
previous: number;
dynTopMatterVisible: boolean;
};
/** Scroll timeline to a specific date */
'memories:timeline:scrollToDate': Date;
/** Request the date range of the current view (handler fills in result) */
'memories:timeline:getDateRange': { result: { min: Date; max: Date } | null };

/** Albums were updated for these photos */
'memories:albums:update': IPhoto[];
Expand Down