Skip to content

Conversation

@midzelis
Copy link
Collaborator

Description

Recent change introduced caused regression - days were sorted by localDateTime instead of fileCreatedAt. This change fixes that regression.

  • adds fileCreateAt, fileCreatedAtTimeZone, dayGroup to TimeBucketAssetResponseDto
  • refactors, renames date utilities in timeline-util.ts
  • moves TimeBucketAssetResponseDto to TImelineAsset routine to timeline-util, since thats where other TimelineAsset transforms are also performed
  • updates tests
  • addresses TODO in getTimelineBucket - returns a short date-only version of the timeBucket
  • typos

docs and new tests in diff PR

Fixes # (issue)

Comment on lines 85 to 86
@ApiProperty({ type: 'array', items: { type: 'string', nullable: true } })
fileCreatedAtTimeZone!: string[];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need the time zone? I thought the plan was fileCreatedAt + local day?

Copy link
Collaborator Author

@midzelis midzelis May 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it turns out, local day is a little problematic. The asset-store actually has multiple data sources, 1) loading time-buckets from the /api - but also, 2) websocket updates, and 3) manually updates calling addAsset or updateAssets, or updateAssetOperation (a result from some ui-actions)

Since loading assets or updating assets in this way do not use a TimeBucketAssetResponseDto - we can't really use dayGroup. In fact, we could probably just drop dayGroup from the TimeBucketAssetResponseDto - kept it in for now, since @zackpollard specifically requested it. Not sure if based on this new info would you change your mind?

The new technique is to send timeZone with fileCreatedDate. With fileCreatedDate always being UTC, it can be used directly for sorting. With the TZ info, we can derive localDateTime from the UTC by converting the UTC back to tz-relative date, and then dropping the TZ. (TimelineAsset dosn't store tz in its plainDateFormats anyways) this derived localDateTime is used for grouping days/months - and for the day's formatted date string (title/heading). the timeZone is only a little bit bigger than the day (which is a plain number), and frequently repeated, so with compression, it should also not be a big deal for time-bucket api response

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timeZone can be in one of many formats, including longer ones like America/New_York. It's a little unfortunate if we need to include it. It definitely shouldn't be in addition to the dayGroup.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Latest approach removes need for dayGroup and timeZone, instead, we calculate the utcOffset (in minutes) server side, in the db, and send a up to 3 digit number (as a json-number) over the wire. Client side, we apply the offset to get back to a full localDateTime. Ideally, this should perform better than doing the date/timezone transformations in the db. The db is limited to doing a trivial arithmetic operations. The on-the-wire size minimal (comparable to dayGroup) and its easy to derive client-side. Additionally, it gives us the full localDateTime.

@github-actions
Copy link
Contributor

Deploying preview environment to https://pr-18732.preview.internal.immich.cloud/

@alextran1502
Copy link
Member

Tested and confirmed the ordering issue. has been fixed

@midzelis midzelis requested a review from mertalev May 30, 2025 00:35
@alextran1502
Copy link
Member

@midzelis Can you help resolve the conflict of the PR?

@mertalev @zackpollard can you help with a review and stamp if they look good from your end?

midzelis added 2 commits June 5, 2025 02:52
- Resolved conflict in assets-store.svelte.ts: kept HEAD refactor and added missing isSelectingAllAssets export
- Resolved conflict in asset-factory.ts: kept HEAD imports for TimelineAsset and fromISODateTimeUTCToObject
)::real / 3600 as "localOffsetHours",
"assets"."ownerId",
"assets"."status",
"assets"."fileCreatedAt",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you add at time zone 'utc', it will remove the +00:00 offset in these timestamps. It's a nice improvement if the client can handle that

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice try, but web specs are kinda messed up. ...

When the time zone offset is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time. The interpretation as a UTC time is due to a historical spec error that was not consistent with ISO 8601 but could not be changed due to web compatibility. See Broken Parser – A Web Reality Issue.

Server can't know what the users's browser's tz is set to, so even if we wanted to, server could not send a version of a date-time string without a zone in a way that would be consistent for the client.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DateTime can interpret it as UTC though, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it should. I'll update

Copy link
Member

@zackpollard zackpollard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Comment on lines 8 to 13
@ApiProperty({
type: 'string',
format: 'uuid',
required: false,
description: 'Filter assets by specific user ID',
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit annoying that you repeat a lot of stuff here that's already in the other decorators. I thought you can just add a comment above the field and it'll automatically turn it into a description? So like

// Filter assets by specific user Id
@ValidateUUID({ optional: true })
userId?: string;

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Latest commit pushes the descriptions into the existing decorator (and the changes needed in the custom decorators)

Adding comments above the decorator did not work, for either the custom decorators, or in the case of the response dtos that did not have any decorator.

The commit represents the minimal changes needed to add descriptions to all the relevant timeline dtos.

@midzelis midzelis added the documentation Improvements or additions to documentation label Jun 5, 2025
@alextran1502 alextran1502 merged commit 55f4e93 into main Jun 6, 2025
56 checks passed
@alextran1502 alextran1502 deleted the localDateTime_regression branch June 6, 2025 01:56
@github-actions github-actions bot removed the preview label Jun 6, 2025
savely-krasovsky pushed a commit to savely-krasovsky/immich that referenced this pull request Jun 8, 2025
* fix: regression: sort day by fileCreatedAt again

* lint

* e2e test

* inline function

* e2e

* Address comments. Drop dayGroup and timezone in favor of localOffsetMinutes

* lint and some api-doc

* lint, more api-doc

* format

* Move minutes to fractional hours

* make sql

* merge/conflict

* merge fallout, review comments

* spelling

* drop offset from returned date

* move description into decorator where possible, regen api
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog:bugfix documentation Improvements or additions to documentation 🗄️server 🖥️web

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants