parent
c3a27eeb7d
commit
a49d5dfad3
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace OCA\Memories\Db;
|
||||
|
||||
use OCA\Memories\ClustersBackend;
|
||||
use OCA\Memories\Util;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IDBConnection;
|
||||
|
||||
|
@ -222,8 +223,12 @@ trait TimelineQueryDays
|
|||
// All cluster transformations
|
||||
ClustersBackend\Manager::applyDayPostTransforms($this->request, $row);
|
||||
|
||||
// We don't need these fields
|
||||
unset($row['datetaken']);
|
||||
// Remove datetaken unless native (for sorting)
|
||||
if (Util::callerIsNative()) {
|
||||
$row['datetaken'] = Util::sqlUtcToTimestamp($row['datetaken']);
|
||||
} else {
|
||||
unset($row['datetaken']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -56,17 +56,9 @@ trait TimelineQuerySingleItem
|
|||
'dayid' => (int) $row['dayid'],
|
||||
'w' => (int) $row['w'],
|
||||
'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
|
||||
if ($basic) {
|
||||
return $info;
|
||||
|
|
14
lib/Util.php
14
lib/Util.php
|
@ -304,6 +304,20 @@ class Util
|
|||
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.
|
||||
*
|
||||
|
|
|
@ -173,11 +173,11 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
origDateNewest() {
|
||||
return new Date(this.sortedPhotos[0].datetaken!);
|
||||
return new Date(this.sortedPhotos[0].datetaken! * 1000);
|
||||
},
|
||||
|
||||
origDateOldest() {
|
||||
return new Date(this.sortedPhotos[this.sortedPhotos.length - 1].datetaken!);
|
||||
return new Date(this.sortedPhotos[this.sortedPhotos.length - 1].datetaken! * 1000);
|
||||
},
|
||||
|
||||
origDateDiff() {
|
||||
|
@ -206,7 +206,7 @@ export default defineComponent({
|
|||
photos.sort((a, b) => b.datetaken! - a.datetaken!);
|
||||
|
||||
// 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.month = (date.getUTCMonth() + 1).toString();
|
||||
this.day = date.getUTCDate().toString();
|
||||
|
@ -216,7 +216,7 @@ export default defineComponent({
|
|||
|
||||
// Get date of oldest photo
|
||||
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.monthLast = (date.getUTCMonth() + 1).toString();
|
||||
this.dayLast = date.getUTCDate().toString();
|
||||
|
@ -259,7 +259,7 @@ export default defineComponent({
|
|||
// Interpolate date
|
||||
const dT = this.date.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));
|
||||
},
|
||||
|
||||
|
|
|
@ -112,14 +112,7 @@ export default defineComponent({
|
|||
try {
|
||||
const url = API.Q(API.IMAGE_INFO(p.fileid), { tags: 1 });
|
||||
const res = await axios.get<any>(url);
|
||||
|
||||
// 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.datetaken = res.data.datetaken;
|
||||
p.imageInfo = res.data;
|
||||
} catch (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));
|
||||
localOnly.forEach((p) => (p.islocal = true));
|
||||
photos.push(...localOnly);
|
||||
|
||||
// Sort by datetaken
|
||||
photos.sort((a, b) => (b.datetaken ?? 0) - (a.datetaken ?? 0));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue