Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 50 additions & 2 deletions app/lib/backend/http/api/conversations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ Future<ServerConversation?> reProcessConversationServer(String conversationId, {
return null;
}

Future<bool> deleteConversationServer(String conversationId) async {
Future<bool> deleteConversationServer(String conversationId, {bool permanent = false}) async {
var response = await makeApiCall(
url: '${Env.apiBaseUrl}v1/conversations/$conversationId?cascade=true',
url: '${Env.apiBaseUrl}v1/conversations/$conversationId?cascade=true&permanent=$permanent',
headers: {},
method: 'DELETE',
body: '',
Expand All @@ -127,6 +127,54 @@ Future<bool> deleteConversationServer(String conversationId) async {
return response.statusCode == 204;
}

Future<List<ServerConversation>> getTrashedConversationsServer({int limit = 50}) async {
var response = await makeApiCall(
url: '${Env.apiBaseUrl}v1/trash/conversations?limit=$limit',
headers: {},
method: 'GET',
body: '',
);
if (response == null) return [];
if (response.statusCode == 200) {
final list = jsonDecode(response.body) as List;
return list.map((item) => ServerConversation.fromJson(item)).toList();
}
return [];
}

Future<bool> restoreConversationServer(String conversationId) async {
var response = await makeApiCall(
url: '${Env.apiBaseUrl}v1/trash/conversations/$conversationId/restore',
headers: {},
method: 'POST',
body: '',
);
if (response == null) return false;
return response.statusCode == 204;
}

Future<bool> permanentlyDeleteTrashedConversationServer(String conversationId) async {
var response = await makeApiCall(
url: '${Env.apiBaseUrl}v1/trash/conversations/$conversationId',
headers: {},
method: 'DELETE',
body: '',
);
if (response == null) return false;
return response.statusCode == 204;
}

Future<bool> emptyTrashServer({int olderThanDays = 0}) async {
var response = await makeApiCall(
url: '${Env.apiBaseUrl}v1/trash/conversations?older_than_days=$olderThanDays',
headers: {},
method: 'DELETE',
body: '',
);
if (response == null) return false;
return response.statusCode == 204;
}

Future<bool> unlinkCalendarEvent(String conversationId) async {
var response = await makeApiCall(
url: '${Env.apiBaseUrl}v1/conversations/$conversationId/calendar-event',
Expand Down
3 changes: 3 additions & 0 deletions app/lib/backend/schema/conversation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ class ServerConversation {

ConversationStatus status;
bool discarded;
DateTime? deletedAt;
final bool deleted;
final bool isLocked;
bool starred;
Expand All @@ -279,6 +280,7 @@ class ServerConversation {
this.photos = const [],
this.audioFiles = const [],
this.discarded = false,
this.deletedAt,
this.deleted = false,
this.source,
this.language,
Expand Down Expand Up @@ -311,6 +313,7 @@ class ServerConversation {
: [],
audioFiles: ((json['audio_files'] ?? []) as List<dynamic>).map((af) => AudioFile.fromJson(af)).toList(),
discarded: json['discarded'] ?? false,
deletedAt: json['deleted_at'] != null ? DateTime.parse(json['deleted_at']).toLocal() : null,
source: json['source'] != null ? ConversationSource.values.asNameMap()[json['source']] : ConversationSource.omi,
language: json['language'],
deleted: json['deleted'] ?? false,
Expand Down
52 changes: 52 additions & 0 deletions app/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -11022,5 +11022,57 @@
"syncCustomSttWarningMessage": "You use your own transcription provider. Syncing these recordings transcribes them on Omi's servers instead, and they count toward your plan's transcription limit.",
"@syncCustomSttWarningMessage": {
"description": "Body warning that syncing transcribes on Omi servers and counts toward the plan limit"
},
"trash": "Trash",
"@trash": {
"description": "Navigation label for the trash / soft-delete page"
},
"trashIsEmpty": "Trash is empty",
"@trashIsEmpty": {
"description": "Placeholder text when there are no trashed conversations"
},
"deletedConversationsAppearHere": "Deleted conversations appear here",
"@deletedConversationsAppearHere": {
"description": "Subtitle placeholder when trash is empty"
},
"deletePermanentlyTitle": "Delete permanently?",
"@deletePermanentlyTitle": {
"description": "Title for permanent delete confirmation dialog"
},
"deletePermanentlyMessage": "This conversation will be permanently deleted and cannot be recovered.",
"@deletePermanentlyMessage": {
"description": "Message for permanent delete confirmation dialog"
},
"deletePermanently": "Delete",
"@deletePermanently": {
"description": "Button label to permanently delete a conversation from trash"
},
"emptyTrash": "Empty Trash",
"@emptyTrash": {
"description": "Button label to empty all trashed conversations"
},
"emptyTrashTitle": "Empty Trash?",
"@emptyTrashTitle": {
"description": "Title for empty trash confirmation dialog"
},
"emptyTrashMessage": "All trashed conversations will be permanently deleted.",
"@emptyTrashMessage": {
"description": "Message for empty trash confirmation dialog"
},
"deletedDate": "Deleted {date}",
"@deletedDate": {
"description": "Shows when a conversation was deleted, e.g. 'Deleted 15/3/2025'"
},
"restore": "Restore",
"@restore": {
"description": "Tooltip for restore button"
},
"deletePermanentlyTooltip": "Delete permanently",
"@deletePermanentlyTooltip": {
"description": "Tooltip for permanent delete button"
},
"recently": "Recently",
"@recently": {
"description": "Label shown when deletion date is not available"
}
}
78 changes: 78 additions & 0 deletions app/lib/l10n/app_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17378,6 +17378,84 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'You use your own transcription provider. Syncing these recordings transcribes them on Omi\'s servers instead, and they count toward your plan\'s transcription limit.'**
String get syncCustomSttWarningMessage;

/// Navigation label for the trash / soft-delete page
///
/// In en, this message translates to:
/// **'Trash'**
String get trash;

/// Placeholder text when there are no trashed conversations
///
/// In en, this message translates to:
/// **'Trash is empty'**
String get trashIsEmpty;

/// Subtitle placeholder when trash is empty
///
/// In en, this message translates to:
/// **'Deleted conversations appear here'**
String get deletedConversationsAppearHere;

/// Title for permanent delete confirmation dialog
///
/// In en, this message translates to:
/// **'Delete permanently?'**
String get deletePermanentlyTitle;

/// Message for permanent delete confirmation dialog
///
/// In en, this message translates to:
/// **'This conversation will be permanently deleted and cannot be recovered.'**
String get deletePermanentlyMessage;

/// Button label to permanently delete a conversation from trash
///
/// In en, this message translates to:
/// **'Delete'**
String get deletePermanently;

/// Button label to empty all trashed conversations
///
/// In en, this message translates to:
/// **'Empty Trash'**
String get emptyTrash;

/// Title for empty trash confirmation dialog
///
/// In en, this message translates to:
/// **'Empty Trash?'**
String get emptyTrashTitle;

/// Message for empty trash confirmation dialog
///
/// In en, this message translates to:
/// **'All trashed conversations will be permanently deleted.'**
String get emptyTrashMessage;

/// Shows when a conversation was deleted, e.g. 'Deleted 15/3/2025'
///
/// In en, this message translates to:
/// **'Deleted {date}'**
String deletedDate(Object date);

/// Tooltip for restore button
///
/// In en, this message translates to:
/// **'Restore'**
String get restore;

/// Tooltip for permanent delete button
///
/// In en, this message translates to:
/// **'Delete permanently'**
String get deletePermanentlyTooltip;

/// Label shown when deletion date is not available
///
/// In en, this message translates to:
/// **'Recently'**
String get recently;
}

class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
Expand Down
41 changes: 41 additions & 0 deletions app/lib/l10n/app_localizations_ar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9268,4 +9268,45 @@ class AppLocalizationsAr extends AppLocalizations {
@override
String get syncCustomSttWarningMessage =>
'أنت تستخدم مزوّد النسخ الخاص بك. مزامنة هذه التسجيلات تنسخها على خوادم Omi بدلاً من ذلك، وتُحتسب ضمن حد النسخ في باقتك.';

@override
String get trash => 'Trash';

@override
String get trashIsEmpty => 'Trash is empty';

@override
String get deletedConversationsAppearHere => 'Deleted conversations appear here';

@override
String get deletePermanentlyTitle => 'Delete permanently?';

@override
String get deletePermanentlyMessage => 'This conversation will be permanently deleted and cannot be recovered.';

@override
String get deletePermanently => 'Delete';

@override
String get emptyTrash => 'Empty Trash';

@override
String get emptyTrashTitle => 'Empty Trash?';

@override
String get emptyTrashMessage => 'All trashed conversations will be permanently deleted.';

@override
String deletedDate(Object date) {
return 'Deleted $date';
}

@override
String get restore => 'Restore';

@override
String get deletePermanentlyTooltip => 'Delete permanently';

@override
String get recently => 'Recently';
}
41 changes: 41 additions & 0 deletions app/lib/l10n/app_localizations_be.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9351,4 +9351,45 @@ class AppLocalizationsBe extends AppLocalizations {
@override
String get syncCustomSttWarningMessage =>
'Вы карыстаецеся ўласным сэрвісам транскрыпцыі. Сінхранізацыя гэтых запісаў транскрыбуе іх на серверах Omi, і яны залічацца ў ліміт транскрыпцыі вашага тарыфу.';

@override
String get trash => 'Trash';

@override
String get trashIsEmpty => 'Trash is empty';

@override
String get deletedConversationsAppearHere => 'Deleted conversations appear here';

@override
String get deletePermanentlyTitle => 'Delete permanently?';

@override
String get deletePermanentlyMessage => 'This conversation will be permanently deleted and cannot be recovered.';

@override
String get deletePermanently => 'Delete';

@override
String get emptyTrash => 'Empty Trash';

@override
String get emptyTrashTitle => 'Empty Trash?';

@override
String get emptyTrashMessage => 'All trashed conversations will be permanently deleted.';

@override
String deletedDate(Object date) {
return 'Deleted $date';
}

@override
String get restore => 'Restore';

@override
String get deletePermanentlyTooltip => 'Delete permanently';

@override
String get recently => 'Recently';
}
41 changes: 41 additions & 0 deletions app/lib/l10n/app_localizations_bg.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9358,4 +9358,45 @@ class AppLocalizationsBg extends AppLocalizations {
@override
String get syncCustomSttWarningMessage =>
'Използвате собствен доставчик за транскрипция. Синхронизирането на тези записи ги транскрибира на сървърите на Omi и те се отчитат към лимита за транскрипция на вашия план.';

@override
String get trash => 'Trash';

@override
String get trashIsEmpty => 'Trash is empty';

@override
String get deletedConversationsAppearHere => 'Deleted conversations appear here';

@override
String get deletePermanentlyTitle => 'Delete permanently?';

@override
String get deletePermanentlyMessage => 'This conversation will be permanently deleted and cannot be recovered.';

@override
String get deletePermanently => 'Delete';

@override
String get emptyTrash => 'Empty Trash';

@override
String get emptyTrashTitle => 'Empty Trash?';

@override
String get emptyTrashMessage => 'All trashed conversations will be permanently deleted.';

@override
String deletedDate(Object date) {
return 'Deleted $date';
}

@override
String get restore => 'Restore';

@override
String get deletePermanentlyTooltip => 'Delete permanently';

@override
String get recently => 'Recently';
}
Loading