Teams-style chat list, contact name resolution, and fixes
UI:
- Rework the conversation list to a Teams/Outlook-style row: single-line
preview, right-aligned timestamp, unread dot, and a neutral elevated
rounded fill (drawn by a Border that wraps the whole row) for hover/select.
- Smooth the Chats/Calls/Stories rail indicator by suppressing the content
frame's transition, which competed with the indicator animation.
Contact names:
- Fetch + decrypt Signal profile names (ProfileCipher, ProfileService,
ProfileNameStore, GET /v1/profile) when a peer has no synced name.
- Capture each contact's profileKey from the link'n'sync backup and the
contacts sync (un-reserve ContactDetails.profileKey) so names can be
resolved; fall back to the phone number before a raw ACI.
Other:
- Report the device to Signal as "Wingnal: {machine name}".
- Resolve build warnings: target Wingnal.Service at net8.0-windows (CA1416),
initialize zkgroup credential fields (CS8618), hoist a stackalloc (CA2014).
- Skip the live chat-connect diagnostic test by default (it logged in as the
real account and disconnected the app).
- Bump app version 1.0.1.0 -> 1.0.2.0.
This commit is contained in:
@@ -18,12 +18,15 @@ public sealed class BackupImporter
|
||||
{
|
||||
private readonly MessageStore _messages;
|
||||
private readonly ContactsStore _contacts;
|
||||
private readonly ProfileKeyStore? _profileKeys;
|
||||
private readonly string _ownAci;
|
||||
|
||||
public BackupImporter(MessageStore messages, ContactsStore contacts, string ownAci)
|
||||
public BackupImporter(MessageStore messages, ContactsStore contacts, string ownAci,
|
||||
ProfileKeyStore? profileKeys = null)
|
||||
{
|
||||
_messages = messages;
|
||||
_contacts = contacts;
|
||||
_profileKeys = profileKeys;
|
||||
_ownAci = ownAci.ToLowerInvariant();
|
||||
}
|
||||
|
||||
@@ -56,6 +59,13 @@ public sealed class BackupImporter
|
||||
recipients[r.Id] = new ResolvedPeer(aci, name);
|
||||
string? number = r.Contact.E164 != 0 ? "+" + r.Contact.E164 : null;
|
||||
_contacts.Upsert(new StoreContact(aci, number, name, InboxPosition: 0));
|
||||
// Keep the profile key so an un-named contact's profile name can still be fetched
|
||||
// and decrypted later (the modern contacts sync no longer carries these).
|
||||
if (_profileKeys is not null && r.Contact.HasProfileKey)
|
||||
{
|
||||
byte[] pk = r.Contact.ProfileKey.ToByteArray();
|
||||
if (pk.Length == 32) _profileKeys.Store(aci, pk);
|
||||
}
|
||||
contactCount++;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -24,13 +24,16 @@ public sealed class MessageHistoryImporter
|
||||
private readonly SignalRestClient _rest;
|
||||
private readonly MessageStore _messages;
|
||||
private readonly ContactsStore _contacts;
|
||||
private readonly ProfileKeyStore? _profileKeys;
|
||||
|
||||
public MessageHistoryImporter(SignalAccount account, SignalRestClient rest, MessageStore messages, ContactsStore contacts)
|
||||
public MessageHistoryImporter(SignalAccount account, SignalRestClient rest, MessageStore messages,
|
||||
ContactsStore contacts, ProfileKeyStore? profileKeys = null)
|
||||
{
|
||||
_account = account;
|
||||
_rest = rest;
|
||||
_messages = messages;
|
||||
_contacts = contacts;
|
||||
_profileKeys = profileKeys;
|
||||
}
|
||||
|
||||
/// <param name="ShouldRetry">True when the failure was transient (timed out / network / parse error)
|
||||
@@ -80,7 +83,7 @@ public sealed class MessageHistoryImporter
|
||||
|
||||
MessageBackupKey key = BackupKey.ForLinkAndSync(ephemeral, aci);
|
||||
BackupContents backup = BackupReader.Read(file, key);
|
||||
BackupImporter.ImportSummary summary = new BackupImporter(_messages, _contacts, _account.Aci).Import(backup);
|
||||
BackupImporter.ImportSummary summary = new BackupImporter(_messages, _contacts, _account.Aci, _profileKeys).Import(backup);
|
||||
|
||||
FileLog.Write($"link'n'sync: imported {summary.Messages} message(s), {summary.Contacts} contact(s)");
|
||||
return new Result(true, summary, $"imported {summary.Messages} messages, {summary.Contacts} contacts");
|
||||
|
||||
Reference in New Issue
Block a user