mirror of
https://github.com/KevinMidboe/immich.git
synced 2025-12-08 04:09:07 +00:00
fix: use local time for time buckets and improve memories (#4072)
* fix: timezone bucket timezones * chore: open api * fix: interpret local time in utc * fix: tests * fix: refactor memory lane * fix(web): use local date in memory viewer * chore: set localDateTime non-null * fix: filter out memories from the current year * wip: move localDateTime to asset * fix: correct sorting from db * fix: migration * fix: web typo * fix: formatting * fix: e2e * chore: localDateTime is non-null * chore: more non-nulliness * fix: asset stub * fix: tests * fix: use extract and index for day of year * fix: don't show memories before today * fix: cleanup * fix: tests * fix: only use localtime for tz * fix: display memories in client timezone * fix: tests * fix: svelte tests * fix: bugs * chore: open api --------- Co-authored-by: Jonathan Jogenfors <jonathan@jogenfors.se>
This commit is contained in:
51
web/src/api/open-api/api.ts
generated
51
web/src/api/open-api/api.ts
generated
@@ -669,6 +669,12 @@ export interface AssetResponseDto {
|
||||
* @memberof AssetResponseDto
|
||||
*/
|
||||
'livePhotoVideoId'?: string | null;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AssetResponseDto
|
||||
*/
|
||||
'localDateTime': string;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
@@ -6340,13 +6346,16 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {string} timestamp Get pictures for +24 hours from this time going back x years
|
||||
* @param {number} day
|
||||
* @param {number} month
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getMemoryLane: async (timestamp: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'timestamp' is not null or undefined
|
||||
assertParamExists('getMemoryLane', 'timestamp', timestamp)
|
||||
getMemoryLane: async (day: number, month: number, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'day' is not null or undefined
|
||||
assertParamExists('getMemoryLane', 'day', day)
|
||||
// verify required parameter 'month' is not null or undefined
|
||||
assertParamExists('getMemoryLane', 'month', month)
|
||||
const localVarPath = `/asset/memory-lane`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
@@ -6368,10 +6377,12 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
if (timestamp !== undefined) {
|
||||
localVarQueryParameter['timestamp'] = (timestamp as any instanceof Date) ?
|
||||
(timestamp as any).toISOString() :
|
||||
timestamp;
|
||||
if (day !== undefined) {
|
||||
localVarQueryParameter['day'] = day;
|
||||
}
|
||||
|
||||
if (month !== undefined) {
|
||||
localVarQueryParameter['month'] = month;
|
||||
}
|
||||
|
||||
|
||||
@@ -7152,12 +7163,13 @@ export const AssetApiFp = function(configuration?: Configuration) {
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {string} timestamp Get pictures for +24 hours from this time going back x years
|
||||
* @param {number} day
|
||||
* @param {number} month
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async getMemoryLane(timestamp: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<MemoryLaneResponseDto>>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getMemoryLane(timestamp, options);
|
||||
async getMemoryLane(day: number, month: number, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<MemoryLaneResponseDto>>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getMemoryLane(day, month, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
@@ -7443,7 +7455,7 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getMemoryLane(requestParameters: AssetApiGetMemoryLaneRequest, options?: AxiosRequestConfig): AxiosPromise<Array<MemoryLaneResponseDto>> {
|
||||
return localVarFp.getMemoryLane(requestParameters.timestamp, options).then((request) => request(axios, basePath));
|
||||
return localVarFp.getMemoryLane(requestParameters.day, requestParameters.month, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
@@ -7888,11 +7900,18 @@ export interface AssetApiGetMapMarkersRequest {
|
||||
*/
|
||||
export interface AssetApiGetMemoryLaneRequest {
|
||||
/**
|
||||
* Get pictures for +24 hours from this time going back x years
|
||||
* @type {string}
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetApiGetMemoryLane
|
||||
*/
|
||||
readonly timestamp: string
|
||||
readonly day: number
|
||||
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetApiGetMemoryLane
|
||||
*/
|
||||
readonly month: number
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8398,7 +8417,7 @@ export class AssetApi extends BaseAPI {
|
||||
* @memberof AssetApi
|
||||
*/
|
||||
public getMemoryLane(requestParameters: AssetApiGetMemoryLaneRequest, options?: AxiosRequestConfig) {
|
||||
return AssetApiFp(this.configuration).getMemoryLane(requestParameters.timestamp, options).then((request) => request(this.axios, this.basePath));
|
||||
return AssetApiFp(this.configuration).getMemoryLane(requestParameters.day, requestParameters.month, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -87,8 +87,10 @@
|
||||
|
||||
onMount(async () => {
|
||||
if (!$memoryStore) {
|
||||
const localTime = new Date();
|
||||
const { data } = await api.assetApi.getMemoryLane({
|
||||
timestamp: DateTime.local().startOf('day').toISO() || '',
|
||||
month: localTime.getMonth() + 1,
|
||||
day: localTime.getDate(),
|
||||
});
|
||||
$memoryStore = data;
|
||||
}
|
||||
@@ -212,7 +214,7 @@
|
||||
|
||||
<div class="absolute left-8 top-4 text-sm font-medium text-white">
|
||||
<p>
|
||||
{DateTime.fromISO(currentMemory.assets[0].fileCreatedAt).toLocaleString(DateTime.DATE_FULL)}
|
||||
{DateTime.fromISO(currentMemory.assets[0].localDateTime).toLocaleString(DateTime.DATE_FULL)}
|
||||
</p>
|
||||
<p>
|
||||
{currentAsset.exifInfo?.city || ''}
|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
|
||||
<section id="asset-group-by-date" class="flex flex-wrap gap-x-12" bind:clientHeight={actualBucketHeight}>
|
||||
{#each assetsGroupByDate as groupAssets, groupIndex (groupAssets[0].id)}
|
||||
{@const groupTitle = formatGroupTitle(DateTime.fromISO(groupAssets[0].fileCreatedAt).startOf('day'))}
|
||||
{@const asset = groupAssets[0]}
|
||||
{@const groupTitle = formatGroupTitle(DateTime.fromISO(asset.localDateTime).startOf('day'))}
|
||||
<!-- Asset Group By Date -->
|
||||
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { DateTime } from 'luxon';
|
||||
import { api } from '@api';
|
||||
import ChevronLeft from 'svelte-material-icons/ChevronLeft.svelte';
|
||||
import ChevronRight from 'svelte-material-icons/ChevronRight.svelte';
|
||||
@@ -11,8 +10,10 @@
|
||||
$: shouldRender = $memoryStore?.length > 0;
|
||||
|
||||
onMount(async () => {
|
||||
const localTime = new Date();
|
||||
const { data } = await api.assetApi.getMemoryLane({
|
||||
timestamp: DateTime.local().startOf('day').toISO() || '',
|
||||
month: localTime.getMonth() + 1,
|
||||
day: localTime.getDate(),
|
||||
});
|
||||
$memoryStore = data;
|
||||
});
|
||||
|
||||
@@ -45,7 +45,7 @@ export function splitBucketIntoDateGroups(
|
||||
): AssetResponseDto[][] {
|
||||
return lodash
|
||||
.chain(assets)
|
||||
.groupBy((a) => new Date(a.fileCreatedAt).toLocaleDateString(locale, groupDateFormat))
|
||||
.groupBy((asset) => new Date(asset.localDateTime).toLocaleDateString(locale, groupDateFormat))
|
||||
.sortBy((group) => assets.indexOf(group[0]))
|
||||
.value();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user