Add on this day tab (#41)
parent
efd9232c94
commit
5a250818a5
|
@ -14,6 +14,7 @@ return [
|
|||
['name' => 'page#favorites', 'url' => '/favorites', 'verb' => 'GET'],
|
||||
['name' => 'page#videos', 'url' => '/videos', 'verb' => 'GET'],
|
||||
['name' => 'page#archive', 'url' => '/archive', 'verb' => 'GET'],
|
||||
['name' => 'page#thisday', 'url' => '/thisday', 'verb' => 'GET'],
|
||||
|
||||
// API
|
||||
['name' => 'api#days', 'url' => '/api/days', 'verb' => 'GET'],
|
||||
|
|
|
@ -96,4 +96,12 @@ class PageController extends Controller {
|
|||
public function archive() {
|
||||
return $this->main();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function thisday() {
|
||||
return $this->main();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
:title="t('memories', 'Archive')">
|
||||
<ArchiveIcon slot="icon" :size="20" />
|
||||
</NcAppNavigationItem>
|
||||
<NcAppNavigationItem :to="{name: 'thisday'}"
|
||||
:title="t('memories', 'On this day')">
|
||||
<CalendarIcon slot="icon" :size="20" />
|
||||
</NcAppNavigationItem>
|
||||
</template>
|
||||
<template #footer>
|
||||
<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 Video from 'vue-material-design-icons/Video.vue'
|
||||
import ArchiveIcon from 'vue-material-design-icons/PackageDown.vue';
|
||||
import CalendarIcon from 'vue-material-design-icons/Calendar.vue';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
|
@ -86,6 +91,7 @@ import ArchiveIcon from 'vue-material-design-icons/PackageDown.vue';
|
|||
Star,
|
||||
Video,
|
||||
ArchiveIcon,
|
||||
CalendarIcon,
|
||||
},
|
||||
})
|
||||
export default class App extends Mixins(GlobalMixin) {
|
||||
|
|
|
@ -519,6 +519,7 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
|||
return this.$route.name === 'timeline' ||
|
||||
this.$route.name === 'favorites' ||
|
||||
this.$route.name === 'videos' ||
|
||||
this.$route.name === 'thisday' ||
|
||||
this.$route.name === 'archive';
|
||||
}
|
||||
|
||||
|
@ -559,8 +560,14 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
|||
try {
|
||||
this.loading++;
|
||||
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;
|
||||
await this.processDays(data);
|
||||
} catch (err) {
|
||||
|
|
|
@ -90,5 +90,14 @@
|
|||
rootTitle: t('memories', 'Archive'),
|
||||
}),
|
||||
},
|
||||
|
||||
{
|
||||
path: '/thisday',
|
||||
component: Timeline,
|
||||
name: 'thisday',
|
||||
props: route => ({
|
||||
rootTitle: t('memories', 'On this day'),
|
||||
}),
|
||||
},
|
||||
],
|
||||
})
|
|
@ -4,7 +4,7 @@ import { encodePath } from '@nextcloud/paths'
|
|||
import { showError } from '@nextcloud/dialogs'
|
||||
import { translate as t, translatePlural as n } from '@nextcloud/l10n'
|
||||
import { genFileInfo } from './FileUtils'
|
||||
import { IFileInfo } from '../types';
|
||||
import { IDay, IFileInfo, IPhoto } from '../types';
|
||||
import axios from '@nextcloud/axios'
|
||||
import client from './DavClient';
|
||||
|
||||
|
@ -369,3 +369,59 @@ export async function downloadFilesByIds(fileIds: number[]) {
|
|||
|
||||
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;
|
||||
}
|
Loading…
Reference in New Issue