Add Share Inbox flow for unresolved WhatsApp imports

This commit is contained in:
Rijad Zuzo
2026-02-19 00:26:18 +01:00
parent d2205bd3d9
commit d70edb4c4c
9 changed files with 1278 additions and 113 deletions
+113
View File
@@ -480,6 +480,106 @@ class SharedMessageEntry {
}
}
enum SharedInboxReason { ambiguousProfileMatch, missingIdentity }
@immutable
class SharedInboxEntry {
const SharedInboxEntry({
required this.id,
required this.sourceApp,
required this.messageText,
required this.sharedAt,
required this.receivedAt,
required this.reason,
required this.candidateProfileIds,
required this.normalizedDisplayName,
this.sourceDisplayName,
this.sourceUserId,
this.sourceThreadId,
});
final String id;
final String sourceApp;
final String messageText;
final DateTime sharedAt;
final DateTime receivedAt;
final SharedInboxReason reason;
final List<String> candidateProfileIds;
final String normalizedDisplayName;
final String? sourceDisplayName;
final String? sourceUserId;
final String? sourceThreadId;
SharedInboxEntry copyWith({
String? id,
String? sourceApp,
String? messageText,
DateTime? sharedAt,
DateTime? receivedAt,
SharedInboxReason? reason,
List<String>? candidateProfileIds,
String? normalizedDisplayName,
String? sourceDisplayName,
String? sourceUserId,
String? sourceThreadId,
}) {
return SharedInboxEntry(
id: id ?? this.id,
sourceApp: sourceApp ?? this.sourceApp,
messageText: messageText ?? this.messageText,
sharedAt: sharedAt ?? this.sharedAt,
receivedAt: receivedAt ?? this.receivedAt,
reason: reason ?? this.reason,
candidateProfileIds: candidateProfileIds ?? this.candidateProfileIds,
normalizedDisplayName:
normalizedDisplayName ?? this.normalizedDisplayName,
sourceDisplayName: sourceDisplayName ?? this.sourceDisplayName,
sourceUserId: sourceUserId ?? this.sourceUserId,
sourceThreadId: sourceThreadId ?? this.sourceThreadId,
);
}
Map<String, dynamic> toJson() {
return <String, dynamic>{
'id': id,
'sourceApp': sourceApp,
'messageText': messageText,
'sharedAt': sharedAt.toUtc().toIso8601String(),
'receivedAt': receivedAt.toUtc().toIso8601String(),
'reason': reason.name,
'candidateProfileIds': candidateProfileIds,
'normalizedDisplayName': normalizedDisplayName,
'sourceDisplayName': sourceDisplayName,
'sourceUserId': sourceUserId,
'sourceThreadId': sourceThreadId,
};
}
factory SharedInboxEntry.fromJson(Map<String, dynamic> json) {
final String reasonName =
json['reason'] as String? ?? SharedInboxReason.missingIdentity.name;
return SharedInboxEntry(
id: json['id'] as String,
sourceApp: json['sourceApp'] as String,
messageText: json['messageText'] as String? ?? '',
sharedAt: DateTime.parse(json['sharedAt'] as String).toLocal(),
receivedAt: DateTime.parse(json['receivedAt'] as String).toLocal(),
reason: SharedInboxReason.values.firstWhere(
(SharedInboxReason item) => item.name == reasonName,
orElse: () => SharedInboxReason.missingIdentity,
),
candidateProfileIds:
(json['candidateProfileIds'] as List<dynamic>? ?? <dynamic>[])
.map((dynamic id) => '$id')
.toList(growable: false),
normalizedDisplayName: json['normalizedDisplayName'] as String? ?? '',
sourceDisplayName: json['sourceDisplayName'] as String?,
sourceUserId: json['sourceUserId'] as String?,
sourceThreadId: json['sourceThreadId'] as String?,
);
}
}
@immutable
class DashboardSummary {
const DashboardSummary({
@@ -505,6 +605,7 @@ class LocalDataState {
required this.tasks,
this.sourceLinks = const <SourceProfileLink>[],
this.sharedMessages = const <SharedMessageEntry>[],
this.sharedInbox = const <SharedInboxEntry>[],
});
final List<PersonProfile> people;
@@ -514,6 +615,7 @@ class LocalDataState {
final List<DashboardTask> tasks;
final List<SourceProfileLink> sourceLinks;
final List<SharedMessageEntry> sharedMessages;
final List<SharedInboxEntry> sharedInbox;
LocalDataState copyWith({
List<PersonProfile>? people,
@@ -523,6 +625,7 @@ class LocalDataState {
List<DashboardTask>? tasks,
List<SourceProfileLink>? sourceLinks,
List<SharedMessageEntry>? sharedMessages,
List<SharedInboxEntry>? sharedInbox,
}) {
return LocalDataState(
people: people ?? this.people,
@@ -532,6 +635,7 @@ class LocalDataState {
tasks: tasks ?? this.tasks,
sourceLinks: sourceLinks ?? this.sourceLinks,
sharedMessages: sharedMessages ?? this.sharedMessages,
sharedInbox: sharedInbox ?? this.sharedInbox,
);
}
@@ -574,6 +678,9 @@ class LocalDataState {
'sharedMessages': sharedMessages
.map((SharedMessageEntry entry) => entry.toJson())
.toList(growable: false),
'sharedInbox': sharedInbox
.map((SharedInboxEntry entry) => entry.toJson())
.toList(growable: false),
};
}
@@ -621,6 +728,12 @@ class LocalDataState {
SharedMessageEntry.fromJson(entry as Map<String, dynamic>),
)
.toList(growable: false),
sharedInbox: (json['sharedInbox'] as List<dynamic>? ?? <dynamic>[])
.map(
(dynamic entry) =>
SharedInboxEntry.fromJson(entry as Map<String, dynamic>),
)
.toList(growable: false),
);
}