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
const all_events = Array.from(args.database.getAllEvents());
const conversationLists = new DM_List(args.ctx);
const err = conversationLists.addEvents(all_events);
const err = conversationLists.addEvents(all_events, false);
if (err instanceof InvalidEvent) {
console.error(err);
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.model.dm.isGroupMessage = event.isGroupChat;
app.conversationLists.markRead(event.pubkey.hex, event.isGroupChat);
} else if (event.type == "BackToContactList") {
model.dm.currentEditor = undefined;
} else if (event.type == "PinConversation") {
@ -482,7 +483,7 @@ export async function* Database_Update(
}
profileSyncer.add(...changes_events.map((e) => e.pubkey));
convoLists.addEvents(changes_events);
convoLists.addEvents(changes_events, true);
for (let e of changes_events) {
const t = getTags(e).lamport_timestamp;
if (t) {

View File

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

View File

@ -18,9 +18,12 @@ export class DM_List implements ConversationListRetriever, NewMessageChecker {
public readonly ctx: NostrAccountContext,
) {}
has(hex: string, isGourpChat: boolean): number {
// return this.newMessages.get(hex) || 0;
return 0;
newNessageCount(hex: string, isGourpChat: boolean): number {
return this.newMessages.get(hex) || 0;
}
markRead(hex: string, isGourpChat: boolean): void {
this.newMessages.set(hex, 0);
}
*getStrangers() {
@ -70,89 +73,100 @@ export class DM_List implements ConversationListRetriever, NewMessageChecker {
addEvents(
events: NostrEvent[],
newEvents: boolean,
) {
let i = 0;
for (const event of events) {
if (event.kind != NostrKind.DIRECT_MESSAGE) {
continue;
}
let whoAm_I_TalkingTo = "";
if (event.pubkey == this.ctx.publicKey.hex) {
// I am the sender
whoAm_I_TalkingTo = getTags(event).p[0];
if (whoAm_I_TalkingTo == undefined) {
return new InvalidEvent(event, `event ${event.id} does not have p tags`);
}
} else if (getTags(event).p[0] == this.ctx.publicKey.hex) {
// I am the receiver
whoAm_I_TalkingTo = event.pubkey;
} else {
// I am neither. Possible because other user has used this device before
continue;
const err = this.addEvent({
...event,
kind: event.kind,
}, newEvents);
if (err instanceof Error) {
return err;
}
}
}
this.newMessages.set(whoAm_I_TalkingTo, this.has(whoAm_I_TalkingTo, false) + 1);
private addEvent(event: NostrEvent<NostrKind.DIRECT_MESSAGE>, newEvent: boolean) {
let whoAm_I_TalkingTo = "";
if (event.pubkey == this.ctx.publicKey.hex) {
// I am the sender
whoAm_I_TalkingTo = getTags(event).p[0];
if (whoAm_I_TalkingTo == undefined) {
return new InvalidEvent(event, `event ${event.id} does not have p tags`);
}
} else if (getTags(event).p[0] == this.ctx.publicKey.hex) {
// I am the receiver
whoAm_I_TalkingTo = event.pubkey;
} else {
// I am neither. Possible because other user has used this device before
return;
}
const userInfo = this.convoSummaries.get(whoAm_I_TalkingTo);
if (userInfo) {
if (whoAm_I_TalkingTo == this.ctx.publicKey.hex) {
// talking to myself
if (userInfo.newestEventSendByMe) {
if (event.created_at > userInfo.newestEventSendByMe?.created_at) {
userInfo.newestEventSendByMe = event;
userInfo.newestEventReceivedByMe = event;
}
} else {
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);
if (userInfo) {
if (whoAm_I_TalkingTo == this.ctx.publicKey.hex) {
// talking to myself
if (userInfo.newestEventSendByMe) {
if (event.created_at > userInfo.newestEventSendByMe?.created_at) {
userInfo.newestEventSendByMe = event;
userInfo.newestEventReceivedByMe = event;
}
} else {
if (this.ctx.publicKey.hex == event.pubkey) {
// I am the sender
if (userInfo.newestEventSendByMe) {
if (event.created_at > userInfo.newestEventSendByMe.created_at) {
userInfo.newestEventSendByMe = event;
}
} else {
userInfo.newestEventSendByMe = event;
userInfo.newestEventReceivedByMe = event;
}
} else {
if (this.ctx.publicKey.hex == event.pubkey) {
// I am the sender
if (userInfo.newestEventSendByMe) {
if (event.created_at > userInfo.newestEventSendByMe.created_at) {
userInfo.newestEventSendByMe = event;
}
} else {
// I am the receiver
if (userInfo.newestEventReceivedByMe) {
if (event.created_at > userInfo.newestEventReceivedByMe.created_at) {
userInfo.newestEventReceivedByMe = event;
}
} else {
userInfo.newestEventSendByMe = event;
}
} else {
// I am the receiver
if (userInfo.newestEventReceivedByMe) {
if (event.created_at > userInfo.newestEventReceivedByMe.created_at) {
userInfo.newestEventReceivedByMe = event;
}
}
}
} else {
const pubkey = PublicKey.FromHex(whoAm_I_TalkingTo);
if (pubkey instanceof Error) {
return new InvalidEvent(event, pubkey.message);
}
const newUserInfo: ConversationSummary = {
pubkey,
newestEventReceivedByMe: undefined,
newestEventSendByMe: undefined,
};
if (whoAm_I_TalkingTo == this.ctx.publicKey.hex) {
// talking to myself
newUserInfo.newestEventSendByMe = event;
newUserInfo.newestEventReceivedByMe = event;
} else {
if (this.ctx.publicKey.hex == event.pubkey) {
// I am the sender
newUserInfo.newestEventSendByMe = event;
} else {
// I am the receiver
newUserInfo.newestEventReceivedByMe = event;
userInfo.newestEventReceivedByMe = event;
}
}
this.convoSummaries.set(whoAm_I_TalkingTo, newUserInfo);
}
} else {
const pubkey = PublicKey.FromHex(whoAm_I_TalkingTo);
if (pubkey instanceof Error) {
return new InvalidEvent(event, pubkey.message);
}
const newUserInfo: ConversationSummary = {
pubkey,
newestEventReceivedByMe: undefined,
newestEventSendByMe: undefined,
};
if (whoAm_I_TalkingTo == this.ctx.publicKey.hex) {
// talking to myself
newUserInfo.newestEventSendByMe = event;
newUserInfo.newestEventReceivedByMe = event;
} else {
if (this.ctx.publicKey.hex == event.pubkey) {
// I am the sender
newUserInfo.newestEventSendByMe = event;
} else {
// I am the receiver
newUserInfo.newestEventReceivedByMe = event;
}
}
this.convoSummaries.set(whoAm_I_TalkingTo, newUserInfo);
}
}
}

View File

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