parent
c3a27eeb7d
commit
a49d5dfad3
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||||
namespace OCA\Memories\Db;
|
namespace OCA\Memories\Db;
|
||||||
|
|
||||||
use OCA\Memories\ClustersBackend;
|
use OCA\Memories\ClustersBackend;
|
||||||
|
use OCA\Memories\Util;
|
||||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||||
use OCP\IDBConnection;
|
use OCP\IDBConnection;
|
||||||
|
|
||||||
|
@ -222,8 +223,12 @@ trait TimelineQueryDays
|
||||||
// All cluster transformations
|
// All cluster transformations
|
||||||
ClustersBackend\Manager::applyDayPostTransforms($this->request, $row);
|
ClustersBackend\Manager::applyDayPostTransforms($this->request, $row);
|
||||||
|
|
||||||
// We don't need these fields
|
// Remove datetaken unless native (for sorting)
|
||||||
unset($row['datetaken']);
|
if (Util::callerIsNative()) {
|
||||||
|
$row['datetaken'] = Util::sqlUtcToTimestamp($row['datetaken']);
|
||||||
|
} else {
|
||||||
|
unset($row['datetaken']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -56,17 +56,9 @@ trait TimelineQuerySingleItem
|
||||||
'dayid' => (int) $row['dayid'],
|
'dayid' => (int) $row['dayid'],
|
||||||
'w' => (int) $row['w'],
|
'w' => (int) $row['w'],
|
||||||
'h' => (int) $row['h'],
|
'h' => (int) $row['h'],
|
||||||
'datetaken' => (int) $row['datetaken'],
|
'datetaken' => Util::sqlUtcToTimestamp($row['datetaken']),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Attempt to get the date in the correct timezone
|
|
||||||
try {
|
|
||||||
$utcDate = new \DateTime($row['datetaken'], new \DateTimeZone('UTC'));
|
|
||||||
$info['datetaken'] = $utcDate->getTimestamp();
|
|
||||||
} catch (\Throwable $e) {
|
|
||||||
// Ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return if only basic info is needed
|
// Return if only basic info is needed
|
||||||
if ($basic) {
|
if ($basic) {
|
||||||
return $info;
|
return $info;
|
||||||
|
|
14
lib/Util.php
14
lib/Util.php
|
@ -304,6 +304,20 @@ class Util
|
||||||
return mb_ereg_replace('\/\/+', '/', $path); // remove extra slashes
|
return mb_ereg_replace('\/\/+', '/', $path); // remove extra slashes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert SQL UTC date to timestamp.
|
||||||
|
*
|
||||||
|
* @param mixed $sqlDate
|
||||||
|
*/
|
||||||
|
public static function sqlUtcToTimestamp($sqlDate): int
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return (new \DateTime($sqlDate, new \DateTimeZone('UTC')))->getTimestamp();
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Explode a string into fixed number of components.
|
* Explode a string into fixed number of components.
|
||||||
*
|
*
|
||||||
|
|
|
@ -173,11 +173,11 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
origDateNewest() {
|
origDateNewest() {
|
||||||
return new Date(this.sortedPhotos[0].datetaken!);
|
return new Date(this.sortedPhotos[0].datetaken! * 1000);
|
||||||
},
|
},
|
||||||
|
|
||||||
origDateOldest() {
|
origDateOldest() {
|
||||||
return new Date(this.sortedPhotos[this.sortedPhotos.length - 1].datetaken!);
|
return new Date(this.sortedPhotos[this.sortedPhotos.length - 1].datetaken! * 1000);
|
||||||
},
|
},
|
||||||
|
|
||||||
origDateDiff() {
|
origDateDiff() {
|
||||||
|
@ -206,7 +206,7 @@ export default defineComponent({
|
||||||
photos.sort((a, b) => b.datetaken! - a.datetaken!);
|
photos.sort((a, b) => b.datetaken! - a.datetaken!);
|
||||||
|
|
||||||
// Get date of newest photo
|
// Get date of newest photo
|
||||||
let date = new Date(photos[0].datetaken!);
|
let date = new Date(photos[0].datetaken! * 1000);
|
||||||
this.year = date.getUTCFullYear().toString();
|
this.year = date.getUTCFullYear().toString();
|
||||||
this.month = (date.getUTCMonth() + 1).toString();
|
this.month = (date.getUTCMonth() + 1).toString();
|
||||||
this.day = date.getUTCDate().toString();
|
this.day = date.getUTCDate().toString();
|
||||||
|
@ -216,7 +216,7 @@ export default defineComponent({
|
||||||
|
|
||||||
// Get date of oldest photo
|
// Get date of oldest photo
|
||||||
if (photos.length > 1) {
|
if (photos.length > 1) {
|
||||||
date = new Date(photos[photos.length - 1].datetaken!);
|
date = new Date(photos[photos.length - 1].datetaken! * 1000);
|
||||||
this.yearLast = date.getUTCFullYear().toString();
|
this.yearLast = date.getUTCFullYear().toString();
|
||||||
this.monthLast = (date.getUTCMonth() + 1).toString();
|
this.monthLast = (date.getUTCMonth() + 1).toString();
|
||||||
this.dayLast = date.getUTCDate().toString();
|
this.dayLast = date.getUTCDate().toString();
|
||||||
|
@ -259,7 +259,7 @@ export default defineComponent({
|
||||||
// Interpolate date
|
// Interpolate date
|
||||||
const dT = this.date.getTime();
|
const dT = this.date.getTime();
|
||||||
const doT = this.origDateNewest.getTime();
|
const doT = this.origDateNewest.getTime();
|
||||||
const offset = (photo.datetaken || doT) - doT;
|
const offset = ((photo.datetaken ?? 0) * 1000 || doT) - doT;
|
||||||
return this.getExifFormat(new Date(dT + offset * this.scaleFactor));
|
return this.getExifFormat(new Date(dT + offset * this.scaleFactor));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -112,14 +112,7 @@ export default defineComponent({
|
||||||
try {
|
try {
|
||||||
const url = API.Q(API.IMAGE_INFO(p.fileid), { tags: 1 });
|
const url = API.Q(API.IMAGE_INFO(p.fileid), { tags: 1 });
|
||||||
const res = await axios.get<any>(url);
|
const res = await axios.get<any>(url);
|
||||||
|
p.datetaken = res.data.datetaken;
|
||||||
// Validate response
|
|
||||||
p.imageInfo = null;
|
|
||||||
if (typeof res.data.datetaken !== 'number') {
|
|
||||||
console.error('Invalid date for', p.fileid);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p.datetaken = res.data.datetaken * 1000;
|
|
||||||
p.imageInfo = res.data;
|
p.imageInfo = res.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to get date info for', p.fileid, error);
|
console.error('Failed to get date info for', p.fileid, error);
|
||||||
|
|
|
@ -108,4 +108,7 @@ export async function extendDayWithLocal(dayId: number, photos: IPhoto[]) {
|
||||||
const localOnly = localPhotos.filter((p) => !photosSet.has(p.basename));
|
const localOnly = localPhotos.filter((p) => !photosSet.has(p.basename));
|
||||||
localOnly.forEach((p) => (p.islocal = true));
|
localOnly.forEach((p) => (p.islocal = true));
|
||||||
photos.push(...localOnly);
|
photos.push(...localOnly);
|
||||||
|
|
||||||
|
// Sort by datetaken
|
||||||
|
photos.sort((a, b) => (b.datetaken ?? 0) - (a.datetaken ?? 0));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue