[Upd] User states
This commit is contained in:
parent
d07202386f
commit
ec019a4dff
16 changed files with 667 additions and 87 deletions
19
packages/cache/src/sync.test.tsx
vendored
Normal file
19
packages/cache/src/sync.test.tsx
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { removeMissingContactSnapshots } from "./sync";
|
||||
|
||||
describe("authoritative contact cache updates", () => {
|
||||
it("removes missing users and keeps the latest authoritative set", () => {
|
||||
const contacts = [{ UserId: 2 }, { UserId: 3 }, { UserId: 4 }];
|
||||
expect(removeMissingContactSnapshots(contacts, [3, 99])).toEqual([
|
||||
{ UserId: 2 },
|
||||
{ UserId: 4 },
|
||||
]);
|
||||
});
|
||||
|
||||
it("does not let a delayed state notification recreate a removed contact", () => {
|
||||
const contacts = [{ UserId: 2 }];
|
||||
const afterMissing = removeMissingContactSnapshots(contacts, [2]);
|
||||
expect(removeMissingContactSnapshots(afterMissing, [])).toEqual([]);
|
||||
});
|
||||
});
|
||||
57
packages/cache/src/sync.tsx
vendored
57
packages/cache/src/sync.tsx
vendored
|
|
@ -12,6 +12,14 @@ function isError(message: ProtocolMessage) {
|
|||
return message.type.startsWith("Error");
|
||||
}
|
||||
|
||||
export function removeMissingContactSnapshots<T extends { UserId: number }>(
|
||||
contacts: T[],
|
||||
missingUserIds: readonly number[],
|
||||
): T[] {
|
||||
const missing = new Set(missingUserIds);
|
||||
return contacts.filter((contact) => !missing.has(contact.UserId));
|
||||
}
|
||||
|
||||
export default function CacheSync() {
|
||||
const { addInterceptor, contextReady, freshContacts, subscribePush } =
|
||||
useMTP();
|
||||
|
|
@ -37,6 +45,20 @@ export default function CacheSync() {
|
|||
[accountId],
|
||||
);
|
||||
|
||||
const removeMissingContacts = useCallback(
|
||||
async (userIds: number[]) => {
|
||||
if (userIds.length === 0) return;
|
||||
const cache = secureCache();
|
||||
const contacts = await cache.contacts.get();
|
||||
if (!contacts) return;
|
||||
const remaining = removeMissingContactSnapshots(contacts, userIds);
|
||||
if (remaining.length === contacts.length) return;
|
||||
await cache.contacts.replace(remaining);
|
||||
await cache.conversations.replaceSelected(remaining);
|
||||
},
|
||||
[secureCache],
|
||||
);
|
||||
|
||||
const replaceMessage = useCallback(
|
||||
async (
|
||||
partnerId: number,
|
||||
|
|
@ -110,6 +132,15 @@ export default function CacheSync() {
|
|||
const request = (data ?? {}) as Record<string, unknown>;
|
||||
const result = response.data as Record<string, unknown>;
|
||||
|
||||
if (type === "GetStates" && Array.isArray(result.MissingUserIds)) {
|
||||
await removeMissingContacts(
|
||||
result.MissingUserIds.filter(
|
||||
(userId): userId is number => typeof userId === "number",
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === "GetUserData") {
|
||||
await createCache(String(accountId)).profiles.put(
|
||||
result as unknown as UserProfile,
|
||||
|
|
@ -196,7 +227,14 @@ export default function CacheSync() {
|
|||
return;
|
||||
}
|
||||
},
|
||||
[accountId, insertMessage, removeMessage, replaceMessage, secureCache],
|
||||
[
|
||||
accountId,
|
||||
insertMessage,
|
||||
removeMissingContacts,
|
||||
removeMessage,
|
||||
replaceMessage,
|
||||
secureCache,
|
||||
],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -210,6 +248,14 @@ export default function CacheSync() {
|
|||
async (message: ProtocolMessage) => {
|
||||
if (!accountId || isError(message)) return;
|
||||
const data = message.data as Record<string, unknown>;
|
||||
if (message.type === "GetStates" && Array.isArray(data.MissingUserIds)) {
|
||||
await removeMissingContacts(
|
||||
data.MissingUserIds.filter(
|
||||
(userId): userId is number => typeof userId === "number",
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (message.type === "MessageLive") {
|
||||
await insertMessage(
|
||||
Number(data.SenderId),
|
||||
|
|
@ -263,7 +309,14 @@ export default function CacheSync() {
|
|||
await replaceMessage(partnerId, sendTime, { Reactions: reactions });
|
||||
}
|
||||
},
|
||||
[accountId, insertMessage, removeMessage, replaceMessage, secureCache],
|
||||
[
|
||||
accountId,
|
||||
insertMessage,
|
||||
removeMessage,
|
||||
removeMissingContacts,
|
||||
replaceMessage,
|
||||
secureCache,
|
||||
],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue