Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Varun Patil | 71a10b7971 |
|
@ -13,6 +13,7 @@
|
||||||
"@nextcloud/paths": "^2.1.0",
|
"@nextcloud/paths": "^2.1.0",
|
||||||
"@nextcloud/vue": "^7.0.0",
|
"@nextcloud/vue": "^7.0.0",
|
||||||
"justified-layout": "^4.1.0",
|
"justified-layout": "^4.1.0",
|
||||||
|
"localforage": "^1.10.0",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"path-posix": "^1.0.0",
|
"path-posix": "^1.0.0",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
|
@ -6780,6 +6781,11 @@
|
||||||
"node": ">= 4"
|
"node": ">= 4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/immediate": {
|
||||||
|
"version": "3.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||||
|
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
|
||||||
|
},
|
||||||
"node_modules/immutable": {
|
"node_modules/immutable": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
|
||||||
|
@ -7482,6 +7488,14 @@
|
||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lie": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==",
|
||||||
|
"dependencies": {
|
||||||
|
"immediate": "~3.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lines-and-columns": {
|
"node_modules/lines-and-columns": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||||
|
@ -7528,6 +7542,14 @@
|
||||||
"node": ">=8.9.0"
|
"node": ">=8.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/localforage": {
|
||||||
|
"version": "1.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
|
||||||
|
"integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
|
||||||
|
"dependencies": {
|
||||||
|
"lie": "3.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/locate-path": {
|
"node_modules/locate-path": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||||
|
@ -17243,6 +17265,11 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"immediate": {
|
||||||
|
"version": "3.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||||
|
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
|
||||||
|
},
|
||||||
"immutable": {
|
"immutable": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
|
||||||
|
@ -17749,6 +17776,14 @@
|
||||||
"type-check": "~0.4.0"
|
"type-check": "~0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"lie": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==",
|
||||||
|
"requires": {
|
||||||
|
"immediate": "~3.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"lines-and-columns": {
|
"lines-and-columns": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||||
|
@ -17787,6 +17822,14 @@
|
||||||
"json5": "^2.1.2"
|
"json5": "^2.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"localforage": {
|
||||||
|
"version": "1.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
|
||||||
|
"integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
|
||||||
|
"requires": {
|
||||||
|
"lie": "3.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"locate-path": {
|
"locate-path": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
"@nextcloud/paths": "^2.1.0",
|
"@nextcloud/paths": "^2.1.0",
|
||||||
"@nextcloud/vue": "^7.0.0",
|
"@nextcloud/vue": "^7.0.0",
|
||||||
"justified-layout": "^4.1.0",
|
"justified-layout": "^4.1.0",
|
||||||
|
"localforage": "^1.10.0",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"path-posix": "^1.0.0",
|
"path-posix": "^1.0.0",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
|
|
|
@ -102,6 +102,7 @@ import moment from 'moment';
|
||||||
|
|
||||||
import * as dav from "../services/DavRequests";
|
import * as dav from "../services/DavRequests";
|
||||||
import * as utils from "../services/Utils";
|
import * as utils from "../services/Utils";
|
||||||
|
import localforage from "localforage";
|
||||||
import justifiedLayout from "justified-layout";
|
import justifiedLayout from "justified-layout";
|
||||||
import axios from '@nextcloud/axios'
|
import axios from '@nextcloud/axios'
|
||||||
import Folder from "./frame/Folder.vue";
|
import Folder from "./frame/Folder.vue";
|
||||||
|
@ -150,8 +151,6 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
private squareMode = false;
|
private squareMode = false;
|
||||||
/** Header rows for dayId key */
|
/** Header rows for dayId key */
|
||||||
private heads: { [dayid: number]: IHeadRow } = {};
|
private heads: { [dayid: number]: IHeadRow } = {};
|
||||||
/** Original days response */
|
|
||||||
private days: IDay[] = [];
|
|
||||||
|
|
||||||
/** Computed row height */
|
/** Computed row height */
|
||||||
private rowHeight = 100;
|
private rowHeight = 100;
|
||||||
|
@ -215,12 +214,11 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
// Fit to window
|
// Fit to window
|
||||||
this.handleResize();
|
this.handleResize();
|
||||||
|
|
||||||
|
// Add scroll listener
|
||||||
|
(this.$refs.recycler as any).$el.addEventListener('scroll', this.scrollPositionChange, false);
|
||||||
|
|
||||||
// Get data
|
// Get data
|
||||||
await this.fetchDays();
|
await this.fetchDays();
|
||||||
|
|
||||||
// Timeline recycler init
|
|
||||||
(this.$refs.recycler as any).$el.addEventListener('scroll', this.scrollPositionChange, false);
|
|
||||||
this.scrollPositionChange();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reset all state */
|
/** Reset all state */
|
||||||
|
@ -230,7 +228,6 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
this.list = [];
|
this.list = [];
|
||||||
this.numRows = 0;
|
this.numRows = 0;
|
||||||
this.heads = {};
|
this.heads = {};
|
||||||
this.days = [];
|
|
||||||
this.currentStart = 0;
|
this.currentStart = 0;
|
||||||
this.currentEnd = 0;
|
this.currentEnd = 0;
|
||||||
this.scrollerManager.reset();
|
this.scrollerManager.reset();
|
||||||
|
@ -488,9 +485,11 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
let params: any = {};
|
let params: any = {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.loading++;
|
// this.loading++;
|
||||||
const startState = this.state;
|
const startState = this.state;
|
||||||
|
|
||||||
|
const furl = generateUrl(this.appendQuery(url), params);
|
||||||
|
|
||||||
let data: IDay[] = [];
|
let data: IDay[] = [];
|
||||||
if (this.$route.name === 'thisday') {
|
if (this.$route.name === 'thisday') {
|
||||||
data = await dav.getOnThisDayData();
|
data = await dav.getOnThisDayData();
|
||||||
|
@ -499,7 +498,12 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
} else if (this.$route.name === 'people' && !this.$route.params.name) {
|
} else if (this.$route.name === 'people' && !this.$route.params.name) {
|
||||||
data = await dav.getPeopleData();
|
data = await dav.getPeopleData();
|
||||||
} else {
|
} else {
|
||||||
data = (await axios.get<IDay[]>(generateUrl(this.appendQuery(url), params))).data;
|
const foraged = await localforage.getItem<IDay[]>(furl);
|
||||||
|
if (foraged) {
|
||||||
|
await this.processDays(foraged);
|
||||||
|
}
|
||||||
|
data = (await axios.get<IDay[]>(furl)).data;
|
||||||
|
await localforage.setItem(furl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.state !== startState) return;
|
if (this.state !== startState) return;
|
||||||
|
@ -508,7 +512,7 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
showError(err?.response?.data?.message || err.message);
|
showError(err?.response?.data?.message || err.message);
|
||||||
} finally {
|
} finally {
|
||||||
this.loading--;
|
// this.loading--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,9 +594,12 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store globally
|
// Store globally
|
||||||
this.days = data;
|
if (this.list.length) {
|
||||||
this.list = list;
|
this.replaceRows(list);
|
||||||
this.heads = heads;
|
} else {
|
||||||
|
this.list = list;
|
||||||
|
this.heads = heads;
|
||||||
|
}
|
||||||
|
|
||||||
// Iterate the preload map
|
// Iterate the preload map
|
||||||
// Now the inner detail objects are reactive
|
// Now the inner detail objects are reactive
|
||||||
|
@ -604,6 +611,57 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
|
|
||||||
// Fix view height variable
|
// Fix view height variable
|
||||||
await this.scrollerManager.reflow();
|
await this.scrollerManager.reflow();
|
||||||
|
this.scrollPositionChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Replace current rows with this one gracefully */
|
||||||
|
private replaceRows(rows: IRow[]) {
|
||||||
|
// Two pointers: match heads
|
||||||
|
let pOld = 0;
|
||||||
|
let pNew = 0;
|
||||||
|
let insert = false;
|
||||||
|
let remove = false
|
||||||
|
while (pOld < this.list.length && pNew < rows.length) {
|
||||||
|
const oldRow = this.list[pOld];
|
||||||
|
const newRow = rows[pNew];
|
||||||
|
|
||||||
|
// Insert new rows
|
||||||
|
if (insert) {
|
||||||
|
this.list.splice(pOld, 0, newRow);
|
||||||
|
pOld++;
|
||||||
|
pNew++;
|
||||||
|
if (rows[pNew].type === IRowType.HEAD) {
|
||||||
|
insert = false;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove old rows
|
||||||
|
if (remove) {
|
||||||
|
this.list.splice(pOld, 1);
|
||||||
|
if (this.list[pOld].type === IRowType.HEAD) {
|
||||||
|
remove = false;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the next heads
|
||||||
|
if (newRow.type !== IRowType.HEAD) { pNew++; continue; }
|
||||||
|
if (oldRow.type !== IRowType.HEAD) { pOld++; continue; }
|
||||||
|
|
||||||
|
if (oldRow.dayId < newRow.dayId) {
|
||||||
|
// newRow is a new head, start insertion
|
||||||
|
insert = true;
|
||||||
|
this.heads[newRow.dayId] = newRow as IHeadRow;
|
||||||
|
} else if (oldRow.dayId > newRow.dayId) {
|
||||||
|
// Different head, remove old
|
||||||
|
remove = true;
|
||||||
|
} else {
|
||||||
|
// Same head, continue
|
||||||
|
pOld++;
|
||||||
|
pNew++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Fetch image data for one dayId */
|
/** Fetch image data for one dayId */
|
||||||
|
@ -620,7 +678,7 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
const data = res.data;
|
const data = res.data;
|
||||||
if (this.state !== startState) return;
|
if (this.state !== startState) return;
|
||||||
|
|
||||||
const day = this.days.find(d => d.dayid === dayId);
|
const day = this.heads[dayId].day;
|
||||||
day.detail = data;
|
day.detail = data;
|
||||||
day.count = data.length;
|
day.count = data.length;
|
||||||
this.processDay(day);
|
this.processDay(day);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="p-outer fill-block"
|
<div class="p-outer fill-block"
|
||||||
:class="{
|
:class="{
|
||||||
'selected': (data.flag & c.FLAG_SELECTED),
|
'selected': (data.flag & c.FLAG_SELECTED),
|
||||||
'p-loading': !(data.flag & c.FLAG_LOADED),
|
'placeholder': (data.flag & c.FLAG_PLACEHOLDER),
|
||||||
'leaving': (data.flag & c.FLAG_LEAVING),
|
'leaving': (data.flag & c.FLAG_LEAVING),
|
||||||
'exit-left': (data.flag & c.FLAG_EXIT_LEFT),
|
'exit-left': (data.flag & c.FLAG_EXIT_LEFT),
|
||||||
'enter-right': (data.flag & c.FLAG_ENTER_RIGHT),
|
'enter-right': (data.flag & c.FLAG_ENTER_RIGHT),
|
||||||
|
@ -28,8 +28,7 @@
|
||||||
:src="src()"
|
:src="src()"
|
||||||
:key="data.fileid"
|
:key="data.fileid"
|
||||||
|
|
||||||
@error="error"
|
@error="error" />
|
||||||
@load="load" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -89,14 +88,9 @@ export default class Photo extends Mixins(GlobalMixin) {
|
||||||
return getPreviewUrl(this.data.fileid, this.data.etag, false, size)
|
return getPreviewUrl(this.data.fileid, this.data.etag, false, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Image loaded successfully */
|
|
||||||
load() {
|
|
||||||
this.data.flag |= this.c.FLAG_LOADED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Error in loading image */
|
/** Error in loading image */
|
||||||
error(e: any) {
|
error(e: any) {
|
||||||
this.data.flag |= (this.c.FLAG_LOADED | this.c.FLAG_LOAD_FAIL);
|
this.data.flag |= this.c.FLAG_LOAD_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Clear timers */
|
/** Clear timers */
|
||||||
|
@ -284,7 +278,7 @@ div.img-outer {
|
||||||
transition: box-shadow 0.1s ease;
|
transition: box-shadow 0.1s ease;
|
||||||
|
|
||||||
.selected > & { box-shadow: 0 0 4px 2px var(--color-primary); }
|
.selected > & { box-shadow: 0 0 4px 2px var(--color-primary); }
|
||||||
.p-outer.p-loading > & { display: none; }
|
.p-outer.placeholder > & { display: none; }
|
||||||
.p-outer.error & { object-fit: contain; }
|
.p-outer.error & { object-fit: contain; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue