Skip to content

Commit 1c761fc

Browse files
authored
Fix transcript speaker editing and persistence (#6348)
## Summary - preserve stable backend transcript segment ids through desktop decoding, local storage, and Firestore speaker assignment updates - fix the transcript speaker rename flow by centering dismissable sheets reliably and exposing speaker labels as real accessible buttons - add desktop automation hooks and regression tests used to verify the speaker rename flow on the Mac mini ## Testing - xcrun swift test -c debug --package-path Desktop --filter TranscriptSpeakerAssignmentTests - Mac mini manual verification: clicked transcript speaker label in Omi Dev, confirmed `Name Speaker` sheet opened, saved a speaker assignment, reopened the conversation, restarted Omi Dev, and confirmed the renamed speaker persisted instead of reverting to `Speaker 1`
2 parents fe1615e + 681f721 commit 1c761fc

69 files changed

Lines changed: 827 additions & 584 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

app/lib/backend/http/api/action_items.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,9 @@ Future<ActionItemsResponse> getConversationActionItems(String conversationId) as
204204
var body = utf8.decode(response.bodyBytes);
205205
var data = jsonDecode(body);
206206
return ActionItemsResponse(
207-
actionItems:
208-
(data['action_items'] as List<dynamic>).map((item) => ActionItemWithMetadata.fromJson(item)).toList(),
207+
actionItems: (data['action_items'] as List<dynamic>)
208+
.map((item) => ActionItemWithMetadata.fromJson(item))
209+
.toList(),
209210
hasMore: false, // Conversation-specific calls don't have pagination
210211
);
211212
} else {

app/lib/backend/http/api/conversations.dart

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@ Future<List<ServerConversation>> getConversations({
6161
if (response.statusCode == 200) {
6262
// decode body bytes to utf8 string and then parse json so as to avoid utf8 char issues
6363
var body = utf8.decode(response.bodyBytes);
64-
var memories =
65-
(jsonDecode(body) as List<dynamic>).map((conversation) => ServerConversation.fromJson(conversation)).toList();
64+
var memories = (jsonDecode(body) as List<dynamic>)
65+
.map((conversation) => ServerConversation.fromJson(conversation))
66+
.toList();
6667
Logger.debug('getConversations length: ${memories.length}');
6768
return memories;
6869
} else {
@@ -171,8 +172,9 @@ class TranscriptsResponse {
171172
deepgram: (json['deepgram'] as List<dynamic>).map((segment) => TranscriptSegment.fromJson(segment)).toList(),
172173
soniox: (json['soniox'] as List<dynamic>).map((segment) => TranscriptSegment.fromJson(segment)).toList(),
173174
whisperx: (json['whisperx'] as List<dynamic>).map((segment) => TranscriptSegment.fromJson(segment)).toList(),
174-
speechmatics:
175-
(json['speechmatics'] as List<dynamic>).map((segment) => TranscriptSegment.fromJson(segment)).toList(),
175+
speechmatics: (json['speechmatics'] as List<dynamic>)
176+
.map((segment) => TranscriptSegment.fromJson(segment))
177+
.toList(),
176178
);
177179
}
178180
}
@@ -393,11 +395,7 @@ Future<SyncLocalFilesResponse> syncLocalFilesV2(
393395
if (conversationId != null) {
394396
url += '?conversation_id=${Uri.encodeQueryComponent(conversationId)}';
395397
}
396-
var response = await makeMultipartApiCall(
397-
url: url,
398-
files: files,
399-
onUploadProgress: onUploadProgress,
400-
);
398+
var response = await makeMultipartApiCall(url: url, files: files, onUploadProgress: onUploadProgress);
401399

402400
// Fast-path responses (no async job created)
403401
if (response.statusCode == 200) {

app/lib/backend/http/clock_skew_detector.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ class ClockSkewDetector {
4040
final event = parseResponse(response);
4141
if (event == null) return;
4242

43-
final msg = 'Clock skew detected: skew_seconds=${event.skewSeconds}, '
43+
final msg =
44+
'Clock skew detected: skew_seconds=${event.skewSeconds}, '
4445
'server_time=${event.serverTime}, '
4546
'client_time=${event.clientTime}';
4647
Logger.warning(msg);

app/lib/backend/http/shared.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ Future<String> getAuthHeader() async {
2626
DateTime? expiry = DateTime.fromMillisecondsSinceEpoch(SharedPreferencesUtil().tokenExpirationTime);
2727
bool hasAuthToken = SharedPreferencesUtil().authToken.isNotEmpty;
2828

29-
bool isExpirationDateValid = !(expiry.isBefore(DateTime.now()) ||
30-
expiry.isAtSameMomentAs(DateTime.fromMillisecondsSinceEpoch(0)) ||
31-
(expiry.isBefore(DateTime.now().add(const Duration(minutes: 5))) && expiry.isAfter(DateTime.now())));
29+
bool isExpirationDateValid =
30+
!(expiry.isBefore(DateTime.now()) ||
31+
expiry.isAtSameMomentAs(DateTime.fromMillisecondsSinceEpoch(0)) ||
32+
(expiry.isBefore(DateTime.now().add(const Duration(minutes: 5))) && expiry.isAfter(DateTime.now())));
3233

3334
if (!hasAuthToken || !isExpirationDateValid) {
3435
final refreshedToken = await AuthService.instance.getIdToken();

app/lib/backend/schema/action_item.dart

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,9 @@ class ActionItemsResponse {
118118

119119
factory ActionItemsResponse.fromJson(Map<String, dynamic> json) {
120120
return ActionItemsResponse(
121-
actionItems:
122-
(json['action_items'] as List<dynamic>).map((item) => ActionItemWithMetadata.fromJson(item)).toList(),
121+
actionItems: (json['action_items'] as List<dynamic>)
122+
.map((item) => ActionItemWithMetadata.fromJson(item))
123+
.toList(),
123124
hasMore: json['has_more'],
124125
);
125126
}
@@ -133,10 +134,12 @@ class PendingSyncResponse {
133134

134135
factory PendingSyncResponse.fromJson(Map<String, dynamic> json) {
135136
return PendingSyncResponse(
136-
pendingExport:
137-
(json['pending_export'] as List<dynamic>).map((item) => ActionItemWithMetadata.fromJson(item)).toList(),
138-
syncedItems:
139-
(json['synced_items'] as List<dynamic>).map((item) => ActionItemWithMetadata.fromJson(item)).toList(),
137+
pendingExport: (json['pending_export'] as List<dynamic>)
138+
.map((item) => ActionItemWithMetadata.fromJson(item))
139+
.toList(),
140+
syncedItems: (json['synced_items'] as List<dynamic>)
141+
.map((item) => ActionItemWithMetadata.fromJson(item))
142+
.toList(),
140143
);
141144
}
142145
}

app/lib/l10n/app_localizations.dart

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ abstract class AppLocalizations {
156156
Locale('tr'),
157157
Locale('uk'),
158158
Locale('vi'),
159-
Locale('zh')
159+
Locale('zh'),
160160
];
161161

162162
/// The app title displayed in various places
@@ -16778,41 +16778,41 @@ class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations>
1677816778

1677916779
@override
1678016780
bool isSupported(Locale locale) => <String>[
16781-
'ar',
16782-
'bg',
16783-
'ca',
16784-
'cs',
16785-
'da',
16786-
'de',
16787-
'el',
16788-
'en',
16789-
'es',
16790-
'et',
16791-
'fi',
16792-
'fr',
16793-
'hi',
16794-
'hu',
16795-
'id',
16796-
'it',
16797-
'ja',
16798-
'ko',
16799-
'lt',
16800-
'lv',
16801-
'ms',
16802-
'nl',
16803-
'no',
16804-
'pl',
16805-
'pt',
16806-
'ro',
16807-
'ru',
16808-
'sk',
16809-
'sv',
16810-
'th',
16811-
'tr',
16812-
'uk',
16813-
'vi',
16814-
'zh'
16815-
].contains(locale.languageCode);
16781+
'ar',
16782+
'bg',
16783+
'ca',
16784+
'cs',
16785+
'da',
16786+
'de',
16787+
'el',
16788+
'en',
16789+
'es',
16790+
'et',
16791+
'fi',
16792+
'fr',
16793+
'hi',
16794+
'hu',
16795+
'id',
16796+
'it',
16797+
'ja',
16798+
'ko',
16799+
'lt',
16800+
'lv',
16801+
'ms',
16802+
'nl',
16803+
'no',
16804+
'pl',
16805+
'pt',
16806+
'ro',
16807+
'ru',
16808+
'sk',
16809+
'sv',
16810+
'th',
16811+
'tr',
16812+
'uk',
16813+
'vi',
16814+
'zh',
16815+
].contains(locale.languageCode);
1681616816

1681716817
@override
1681816818
bool shouldReload(_AppLocalizationsDelegate old) => false;
@@ -16891,8 +16891,10 @@ AppLocalizations lookupAppLocalizations(Locale locale) {
1689116891
return AppLocalizationsZh();
1689216892
}
1689316893

16894-
throw FlutterError('AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
16895-
'an issue with the localizations generation tool. Please file an issue '
16896-
'on GitHub with a reproducible sample app and the gen-l10n configuration '
16897-
'that was used.');
16894+
throw FlutterError(
16895+
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
16896+
'an issue with the localizations generation tool. Please file an issue '
16897+
'on GitHub with a reproducible sample app and the gen-l10n configuration '
16898+
'that was used.',
16899+
);
1689816900
}

app/lib/l10n/app_localizations_ar.dart

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,12 +1696,7 @@ class AppLocalizationsAr extends AppLocalizations {
16961696

16971697
@override
16981698
String devicesFoundNearby(int count) {
1699-
String _temp0 = intl.Intl.pluralLogic(
1700-
count,
1701-
locale: localeName,
1702-
other: 'أجهزة',
1703-
one: 'جهاز',
1704-
);
1699+
String _temp0 = intl.Intl.pluralLogic(count, locale: localeName, other: 'أجهزة', one: 'جهاز');
17051700
return '$count $_temp0 تم العثور عليها بالقرب منك';
17061701
}
17071702

app/lib/l10n/app_localizations_bg.dart

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1713,12 +1713,7 @@ class AppLocalizationsBg extends AppLocalizations {
17131713

17141714
@override
17151715
String devicesFoundNearby(int count) {
1716-
String _temp0 = intl.Intl.pluralLogic(
1717-
count,
1718-
locale: localeName,
1719-
other: 'УСТРОЙСТВА',
1720-
one: 'УСТРОЙСТВО',
1721-
);
1716+
String _temp0 = intl.Intl.pluralLogic(count, locale: localeName, other: 'УСТРОЙСТВА', one: 'УСТРОЙСТВО');
17221717
return '$count $_temp0 НАМЕРЕНИ НАБЛИЗО';
17231718
}
17241719

app/lib/l10n/app_localizations_ca.dart

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,12 +1719,7 @@ class AppLocalizationsCa extends AppLocalizations {
17191719

17201720
@override
17211721
String devicesFoundNearby(int count) {
1722-
String _temp0 = intl.Intl.pluralLogic(
1723-
count,
1724-
locale: localeName,
1725-
other: 'DISPOSITIUS',
1726-
one: 'DISPOSITIU',
1727-
);
1722+
String _temp0 = intl.Intl.pluralLogic(count, locale: localeName, other: 'DISPOSITIUS', one: 'DISPOSITIU');
17281723
return '$count $_temp0 TROBATS A PROP';
17291724
}
17301725

app/lib/l10n/app_localizations_cs.dart

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,12 +1710,7 @@ class AppLocalizationsCs extends AppLocalizations {
17101710

17111711
@override
17121712
String devicesFoundNearby(int count) {
1713-
String _temp0 = intl.Intl.pluralLogic(
1714-
count,
1715-
locale: localeName,
1716-
other: 'ZAŘÍZENÍ',
1717-
one: 'ZAŘÍZENÍ',
1718-
);
1713+
String _temp0 = intl.Intl.pluralLogic(count, locale: localeName, other: 'ZAŘÍZENÍ', one: 'ZAŘÍZENÍ');
17191714
return '$count $_temp0 NALEZENO V BLÍZKOSTI';
17201715
}
17211716

0 commit comments

Comments
 (0)