fix(chat): render message timestamps in device-local time

Live chat bubbles read createdAt.hour/.minute directly, but server created_at (UTC, ISO-Z) was parsed without .toLocal() while optimistic sends used DateTime.now() (local). On any non-UTC device, your own messages showed local time and received/history messages showed UTC within the same conversation. Add .toLocal() at the history-load + incoming-WS parse sites in both apps so bubbles match the optimistic path and the transcript view. Session timer math was already tz-safe (Dart .difference uses absolute instants).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-01 22:26:57 +08:00
parent 6fd98ca99c
commit 6e87e9b6da
2 changed files with 10 additions and 4 deletions

View File

@@ -214,7 +214,9 @@ class MitraChat extends _$MitraChat {
content: m['content'] as String,
type: m['type'] as String? ?? MessageType.text,
status: m['status'] as String? ?? MessageStatus.sent,
createdAt: DateTime.parse(m['created_at'] as String),
// Server sends UTC (ISO-8601 with Z); render in device-local time so
// bubbles match optimistic sends (DateTime.now()) + the transcript view.
createdAt: DateTime.parse(m['created_at'] as String).toLocal(),
)).toList();
final token = ref.read(authBridgeProvider).accessToken;
@@ -329,7 +331,8 @@ class MitraChat extends _$MitraChat {
content: data['content'] as String,
type: data['message_type'] as String? ?? MessageType.text,
status: MessageStatus.sent,
createdAt: DateTime.parse(data['created_at'] as String),
// UTC from server → device-local for display (see history-load note).
createdAt: DateTime.parse(data['created_at'] as String).toLocal(),
);
state = current.copyWith(messages: [...current.messages, msg]);
markDelivered([msg.id]);