unread count (#362)

This commit is contained in:
BlowaterNostr 2023-12-22 21:03:59 +08:00 committed by GitHub
parent 46eb9f3eb1
commit 6b1dc315bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 71 deletions

View File

@ -163,7 +163,7 @@ export class App {
// init conversation list // init conversation list
const all_events = Array.from(args.database.getAllEvents()); const all_events = Array.from(args.database.getAllEvents());
const conversationLists = new DM_List(args.ctx); const conversationLists = new DM_List(args.ctx);
const err = conversationLists.addEvents(all_events); const err = conversationLists.addEvents(all_events, false);
if (err instanceof InvalidEvent) { if (err instanceof InvalidEvent) {
console.error(err); console.error(err);
await args.database.remove(err.event.id); await args.database.remove(err.event.id);

View File

@ -165,6 +165,7 @@ export async function* UI_Interaction_Update(args: {
} }
app.popOverInputChan.put({ children: undefined }); app.popOverInputChan.put({ children: undefined });
app.model.dm.isGroupMessage = event.isGroupChat; app.model.dm.isGroupMessage = event.isGroupChat;
app.conversationLists.markRead(event.pubkey.hex, event.isGroupChat);
} else if (event.type == "BackToContactList") { } else if (event.type == "BackToContactList") {
model.dm.currentEditor = undefined; model.dm.currentEditor = undefined;
} else if (event.type == "PinConversation") { } else if (event.type == "PinConversation") {
@ -482,7 +483,7 @@ export async function* Database_Update(
} }
profileSyncer.add(...changes_events.map((e) => e.pubkey)); profileSyncer.add(...changes_events.map((e) => e.pubkey));
convoLists.addEvents(changes_events); convoLists.addEvents(changes_events, true);
for (let e of changes_events) { for (let e of changes_events) {
const t = getTags(e).lamport_timestamp; const t = getTags(e).lamport_timestamp;
if (t) { if (t) {

View File

@ -38,7 +38,7 @@ for (let i = 0; i < 20; i++) {
["p", PrivateKey.Generate().toPublicKey().hex], ["p", PrivateKey.Generate().toPublicKey().hex],
], ],
}) as NostrEvent; }) as NostrEvent;
const err = dm_list.addEvents([event]); const err = dm_list.addEvents([event], false);
if (err instanceof Error) { if (err instanceof Error) {
fail(err.message); fail(err.message);
} }
@ -49,7 +49,7 @@ const otherConfig = OtherConfig.Empty(new Channel(), ctx, new LamportTime());
const view = () => const view = () =>
render( render(
<ConversationList <ConversationList
hasNewMessages={new Set()} hasNewMessages={dm_list}
eventBus={testEventBus} eventBus={testEventBus}
emit={testEventBus.emit} emit={testEventBus.emit}
profileGetter={database} profileGetter={database}

View File

@ -18,9 +18,12 @@ export class DM_List implements ConversationListRetriever, NewMessageChecker {
public readonly ctx: NostrAccountContext, public readonly ctx: NostrAccountContext,
) {} ) {}
has(hex: string, isGourpChat: boolean): number { newNessageCount(hex: string, isGourpChat: boolean): number {
// return this.newMessages.get(hex) || 0; return this.newMessages.get(hex) || 0;
return 0; }
markRead(hex: string, isGourpChat: boolean): void {
this.newMessages.set(hex, 0);
} }
*getStrangers() { *getStrangers() {
@ -70,13 +73,23 @@ export class DM_List implements ConversationListRetriever, NewMessageChecker {
addEvents( addEvents(
events: NostrEvent[], events: NostrEvent[],
newEvents: boolean,
) { ) {
let i = 0;
for (const event of events) { for (const event of events) {
if (event.kind != NostrKind.DIRECT_MESSAGE) { if (event.kind != NostrKind.DIRECT_MESSAGE) {
continue; continue;
} }
const err = this.addEvent({
...event,
kind: event.kind,
}, newEvents);
if (err instanceof Error) {
return err;
}
}
}
private addEvent(event: NostrEvent<NostrKind.DIRECT_MESSAGE>, newEvent: boolean) {
let whoAm_I_TalkingTo = ""; let whoAm_I_TalkingTo = "";
if (event.pubkey == this.ctx.publicKey.hex) { if (event.pubkey == this.ctx.publicKey.hex) {
// I am the sender // I am the sender
@ -89,10 +102,12 @@ export class DM_List implements ConversationListRetriever, NewMessageChecker {
whoAm_I_TalkingTo = event.pubkey; whoAm_I_TalkingTo = event.pubkey;
} else { } else {
// I am neither. Possible because other user has used this device before // I am neither. Possible because other user has used this device before
continue; return;
} }
this.newMessages.set(whoAm_I_TalkingTo, this.has(whoAm_I_TalkingTo, false) + 1); if (newEvent && this.ctx.publicKey.hex != event.pubkey) {
this.newMessages.set(whoAm_I_TalkingTo, this.newNessageCount(whoAm_I_TalkingTo, false) + 1);
}
const userInfo = this.convoSummaries.get(whoAm_I_TalkingTo); const userInfo = this.convoSummaries.get(whoAm_I_TalkingTo);
if (userInfo) { if (userInfo) {
@ -155,7 +170,6 @@ export class DM_List implements ConversationListRetriever, NewMessageChecker {
} }
} }
} }
}
export const sortUserInfo = (a: ConversationSummary, b: ConversationSummary) => { export const sortUserInfo = (a: ConversationSummary, b: ConversationSummary) => {
return sortScore(b) - sortScore(a); return sortScore(b) - sortScore(a);

View File

@ -39,7 +39,8 @@ export type ContactUpdate =
| StartCreateGroupChat; | StartCreateGroupChat;
export interface NewMessageChecker { export interface NewMessageChecker {
has(hex: string, isGourpChat: boolean): number; newNessageCount(hex: string, isGourpChat: boolean): number;
markRead(hex: string, isGourpChat: boolean): void;
} }
type Props = { type Props = {
@ -103,7 +104,10 @@ export class ConversationList extends Component<Props, State> {
for (const conversationSummary of listToRender) { for (const conversationSummary of listToRender) {
convoListToRender.push({ convoListToRender.push({
conversation: conversationSummary, conversation: conversationSummary,
newMessageCount: props.hasNewMessages.has(conversationSummary.pubkey.hex, isGroupChat), newMessageCount: props.hasNewMessages.newNessageCount(
conversationSummary.pubkey.hex,
isGroupChat,
),
}); });
} }