Add on this day tab (#41)

cache
Varun Patil 2022-10-06 13:20:29 -07:00
parent efd9232c94
commit 5a250818a5
6 changed files with 90 additions and 3 deletions

View File

@ -14,6 +14,7 @@ return [
['name' => 'page#favorites', 'url' => '/favorites', 'verb' => 'GET'], ['name' => 'page#favorites', 'url' => '/favorites', 'verb' => 'GET'],
['name' => 'page#videos', 'url' => '/videos', 'verb' => 'GET'], ['name' => 'page#videos', 'url' => '/videos', 'verb' => 'GET'],
['name' => 'page#archive', 'url' => '/archive', 'verb' => 'GET'], ['name' => 'page#archive', 'url' => '/archive', 'verb' => 'GET'],
['name' => 'page#thisday', 'url' => '/thisday', 'verb' => 'GET'],
// API // API
['name' => 'api#days', 'url' => '/api/days', 'verb' => 'GET'], ['name' => 'api#days', 'url' => '/api/days', 'verb' => 'GET'],

View File

@ -96,4 +96,12 @@ class PageController extends Controller {
public function archive() { public function archive() {
return $this->main(); return $this->main();
} }
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function thisday() {
return $this->main();
}
} }

View File

@ -23,6 +23,10 @@
:title="t('memories', 'Archive')"> :title="t('memories', 'Archive')">
<ArchiveIcon slot="icon" :size="20" /> <ArchiveIcon slot="icon" :size="20" />
</NcAppNavigationItem> </NcAppNavigationItem>
<NcAppNavigationItem :to="{name: 'thisday'}"
:title="t('memories', 'On this day')">
<CalendarIcon slot="icon" :size="20" />
</NcAppNavigationItem>
</template> </template>
<template #footer> <template #footer>
<NcAppNavigationSettings :title="t('memories', 'Settings')"> <NcAppNavigationSettings :title="t('memories', 'Settings')">
@ -69,6 +73,7 @@ import FolderIcon from 'vue-material-design-icons/Folder.vue'
import Star from 'vue-material-design-icons/Star.vue' import Star from 'vue-material-design-icons/Star.vue'
import Video from 'vue-material-design-icons/Video.vue' import Video from 'vue-material-design-icons/Video.vue'
import ArchiveIcon from 'vue-material-design-icons/PackageDown.vue'; import ArchiveIcon from 'vue-material-design-icons/PackageDown.vue';
import CalendarIcon from 'vue-material-design-icons/Calendar.vue';
@Component({ @Component({
components: { components: {
@ -86,6 +91,7 @@ import ArchiveIcon from 'vue-material-design-icons/PackageDown.vue';
Star, Star,
Video, Video,
ArchiveIcon, ArchiveIcon,
CalendarIcon,
}, },
}) })
export default class App extends Mixins(GlobalMixin) { export default class App extends Mixins(GlobalMixin) {

View File

@ -519,6 +519,7 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
return this.$route.name === 'timeline' || return this.$route.name === 'timeline' ||
this.$route.name === 'favorites' || this.$route.name === 'favorites' ||
this.$route.name === 'videos' || this.$route.name === 'videos' ||
this.$route.name === 'thisday' ||
this.$route.name === 'archive'; this.$route.name === 'archive';
} }
@ -559,8 +560,14 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
try { try {
this.loading++; this.loading++;
const startState = this.state; const startState = this.state;
const res = await axios.get<IDay[]>(generateUrl(this.appendQuery(url), params));
const data = res.data; let data: IDay[] = [];
if (this.$route.name === 'thisday') {
data = await dav.getOnThisDayData();
} else {
data = (await axios.get<IDay[]>(generateUrl(this.appendQuery(url), params))).data;
}
if (this.state !== startState) return; if (this.state !== startState) return;
await this.processDays(data); await this.processDays(data);
} catch (err) { } catch (err) {

View File

@ -90,5 +90,14 @@
rootTitle: t('memories', 'Archive'), rootTitle: t('memories', 'Archive'),
}), }),
}, },
{
path: '/thisday',
component: Timeline,
name: 'thisday',
props: route => ({
rootTitle: t('memories', 'On this day'),
}),
},
], ],
}) })

View File

@ -4,7 +4,7 @@ import { encodePath } from '@nextcloud/paths'
import { showError } from '@nextcloud/dialogs' import { showError } from '@nextcloud/dialogs'
import { translate as t, translatePlural as n } from '@nextcloud/l10n' import { translate as t, translatePlural as n } from '@nextcloud/l10n'
import { genFileInfo } from './FileUtils' import { genFileInfo } from './FileUtils'
import { IFileInfo } from '../types'; import { IDay, IFileInfo, IPhoto } from '../types';
import axios from '@nextcloud/axios' import axios from '@nextcloud/axios'
import client from './DavClient'; import client from './DavClient';
@ -368,4 +368,60 @@ export async function downloadFilesByIds(fileIds: number[]) {
}); });
yield* runInParallel(calls, 10); yield* runInParallel(calls, 10);
}
/**
* Get the onThisDay data
* Query for last 120 years; should be enough
*/
export async function getOnThisDayData() {
const diffs: { [dayId: number]: number } = {};
const now = new Date();
const nowUTC = new Date(now.getTime() - now.getTimezoneOffset() * 60000);
// Populate dayIds
for (let i = 1; i <= 120; i++) {
// +- 3 days from this day
for (let j = -3; j <= 3; j++) {
const d = new Date(nowUTC);
d.setFullYear(d.getFullYear() - i);
d.setDate(d.getDate() + j);
const dayId = Math.floor(d.getTime() / 1000 / 86400)
diffs[dayId] = i;
}
}
// Query for photos
let data: IPhoto[] = [];
try {
const res = await axios.post<IPhoto[]>(generateUrl('/apps/memories/api/days/BODY'), {
body_ids: Object.keys(diffs).join(','),
});
data = res.data;
} catch (e) {
throw e;
}
// Group photos by day
const ans: IDay[] = [];
const prevDayId = Number.MIN_SAFE_INTEGER;
for (const photo of data) {
if (!photo.dayid) continue;
// This works because the response is sorted by date taken
if (photo.dayid !== prevDayId) {
ans.push({
dayid: photo.dayid,
count: 0,
detail: [],
});
}
// Add to last day
const day = ans[ans.length - 1];
day.detail.push(photo);
day.count++;
}
return ans;
} }