Skip to content

Commit

Permalink
Introduce title property and handle thread.updated
Browse files Browse the repository at this point in the history
  • Loading branch information
arnautov-anton committed Jan 5, 2025
1 parent 2ff8348 commit 6b7fb82
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 2 deletions.
27 changes: 25 additions & 2 deletions src/thread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export type ThreadState<SCG extends ExtendableGenerics = DefaultGenerics> = {
read: ThreadReadState;
replies: Array<FormatMessageResponse<SCG>>;
replyCount: number;
title: string;
updatedAt: Date | null;
};

Expand Down Expand Up @@ -87,12 +88,15 @@ export class Thread<SCG extends ExtendableGenerics = DefaultGenerics> {
: [];

this.state = new StateStore<ThreadState<SCG>>({
// local only
active: false,
isLoading: false,
isStateStale: false,
// 99.9% should never change
channel,
createdAt: new Date(threadData.created_at),
// rest
deletedAt: threadData.deleted_at ? new Date(threadData.deleted_at) : null,
isLoading: false,
isStateStale: false,
pagination: repliesPaginationFromInitialThread(threadData),
parentMessage: formatMessage(threadData.parent_message),
participants: threadData.thread_participants,
Expand All @@ -102,6 +106,7 @@ export class Thread<SCG extends ExtendableGenerics = DefaultGenerics> {
replies: threadData.latest_replies.map(formatMessage),
replyCount: threadData.reply_count ?? 0,
updatedAt: threadData.updated_at ? new Date(threadData.updated_at) : null,
title: threadData.title,
});

this.id = threadData.parent_message_id;
Expand Down Expand Up @@ -186,6 +191,7 @@ export class Thread<SCG extends ExtendableGenerics = DefaultGenerics> {
return;
}

this.unsubscribeFunctions.add(this.subscribeThreadUpdated());
this.unsubscribeFunctions.add(this.subscribeMarkActiveThreadRead());
this.unsubscribeFunctions.add(this.subscribeReloadActiveStaleThread());
this.unsubscribeFunctions.add(this.subscribeMarkThreadStale());
Expand All @@ -195,6 +201,23 @@ export class Thread<SCG extends ExtendableGenerics = DefaultGenerics> {
this.unsubscribeFunctions.add(this.subscribeMessageUpdated());
};

private subscribeThreadUpdated = () => {
return this.client.on('thread.updated', (event) => {
if (!event.thread || event.thread.parent_message_id !== this.id) {
return;
}

const threadData = event.thread;

this.state.partialNext({
title: threadData.title,
updatedAt: new Date(threadData.updated_at),
deletedAt: threadData.deleted_at ? new Date(threadData.deleted_at) : null,
// TODO: handle custom data - ideally one property (like `custom`)
});
}).unsubscribe;
};

private subscribeMarkActiveThreadRead = () => {
return this.state.subscribeWithSelector(
(nextValue) => ({
Expand Down
39 changes: 39 additions & 0 deletions test/unit/threads.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,44 @@ describe('Threads 2.0', () => {
thread.unregisterSubscriptions();
});

describe('Event: thread.updated', () => {
it('ignores incoming event if the data do not match (parent_message_id)', () => {
const thread = createTestThread({ title: 'A' });
thread.registerSubscriptions();

const stateBefore = thread.state.getLatestValue();
expect(stateBefore.title).to.eq('A');

client.dispatchEvent({
// @ts-expect-error
type: 'thread.updated',
thread: generateThreadResponse(channelResponse, generateMsg(), { title: 'B' }),
});

const stateAfter = thread.state.getLatestValue();
expect(stateAfter.title).to.eq('A');
});

it('correctly updates thread-level properties', () => {
const thread = createTestThread({ title: 'A' });
thread.registerSubscriptions();

const stateBefore = thread.state.getLatestValue();
expect(stateBefore.title).to.eq('A');

client.dispatchEvent({
// @ts-expect-error
type: 'thread.updated',
thread: generateThreadResponse(channelResponse, generateMsg({ id: parentMessageResponse.id }), {
title: 'B',
}),
});

const stateAfter = thread.state.getLatestValue();
expect(stateAfter.title).to.eq('B');
});
});

describe('Event: user.watching.stop', () => {
it('ignores incoming event if the data do not match (channel or user.id)', () => {
const thread = createTestThread();
Expand Down Expand Up @@ -1207,6 +1245,7 @@ describe('Threads 2.0', () => {
await threadManager.reload();
expect(stubbedQueryThreads.calledWithMatch({ limit: 25 })).to.be.true;
});

it('skips reload if there were no updates since the latest reload', async () => {
threadManager.state.partialNext({ ready: true });
await threadManager.reload();
Expand Down

0 comments on commit 6b7fb82

Please sign in to comment.