@@ -5,66 +5,55 @@ import { useChannelStateContext, useMessageInputContext } from '../../../../cont
55import type { LocalMessage } from 'stream-chat' ;
66import { useLegacyThreadContext } from '../../../Thread' ;
77
8- class FixedSizeQueueCache < T > {
9- private elements : Array < T > ;
8+ class FixedSizeQueueCache < K , T > {
9+ private keys : Array < K > ;
1010 private size : number ;
11+ private valueByKey : Map < K , T > ;
1112 constructor ( size : number ) {
1213 if ( ! size ) throw new Error ( 'Size must be greater than 0' ) ;
13- this . elements = [ ] ;
14+ this . keys = [ ] ;
1415 this . size = size ;
16+ this . valueByKey = new Map ( ) ;
1517 }
1618
17- add ( ...values : T [ ] ) {
18- const pushableValues =
19- values . length > this . size ? values . slice ( values . length - this . size ) : values ;
19+ add ( key : K , value : T ) {
20+ const index = this . keys . indexOf ( key ) ;
2021
21- if ( pushableValues . length === this . size ) {
22- // this.elements.splice(0, this.size - 1);
23- this . elements . length = 0 ;
24- this . elements . push ( ...pushableValues ) ;
25- } else {
26- for ( const value of pushableValues ) {
27- if ( this . elements . length >= this . size ) {
28- this . elements . shift ( ) ;
29- }
22+ if ( index > - 1 ) {
23+ this . keys . splice ( this . keys . indexOf ( key ) , 1 ) ;
24+ } else if ( this . keys . length >= this . size ) {
25+ const elementKey = this . keys . shift ( ) ;
3026
31- this . elements . push ( value ) ;
27+ if ( elementKey ) {
28+ this . valueByKey . delete ( elementKey ) ;
3229 }
3330 }
34- }
3531
36- // returns value without shifting it to the end of the array
37- peek ( predicate : ( element : T ) => boolean ) {
38- // start searching from the most recent (end of array)
39- for ( let index = 0 ; index < this . elements . length ; index ++ ) {
40- const element = this . elements [ this . elements . length - 1 - index ] ;
41- const predicateResult = predicate ( element ) ;
32+ this . keys . push ( key ) ;
33+ this . valueByKey . set ( key , value ) ;
34+ }
4235
43- if ( predicateResult ) return element ;
44- }
36+ peek ( key : K ) {
37+ const value = this . valueByKey . get ( key ) ;
4538
46- return null ;
39+ return value ;
4740 }
4841
49- get ( predicate : ( element : T ) => boolean ) {
50- const foundElement = this . peek ( predicate ) ;
42+ get ( key : K ) {
43+ const foundElement = this . peek ( key ) ;
5144
52- if ( foundElement && this . elements . indexOf ( foundElement ) !== this . size - 1 ) {
53- this . elements . splice ( this . elements . indexOf ( foundElement ) , 1 ) ;
54- this . elements . push ( foundElement ) ;
45+ if ( foundElement && this . keys . indexOf ( key ) !== this . size - 1 ) {
46+ this . keys . splice ( this . keys . indexOf ( key ) , 1 ) ;
47+ this . keys . push ( key ) ;
5548 }
5649
5750 return foundElement ;
5851 }
59-
60- toArray ( ) {
61- return [ ...this . elements ] ;
62- }
6352}
6453
6554export type UseMessageComposerParams = unknown ;
6655
67- const queueCache = new FixedSizeQueueCache < MessageComposer > ( 64 ) ;
56+ const queueCache = new FixedSizeQueueCache < string , MessageComposer > ( 64 ) ;
6857// eslint-disable-next-line @typescript-eslint/no-unused-vars
6958export const useMessageComposer = ( _unused : UseMessageComposerParams = { } ) => {
7059 const { channel } = useChannelStateContext ( ) ;
@@ -99,7 +88,7 @@ export const useMessageComposer = (_unused: UseMessageComposerParams = {}) => {
9988 if ( cachedEditedMessage ) {
10089 const tag = `edited-message-${ cachedEditedMessage . id } ` ;
10190
102- const element = queueCache . get ( ( element ) => element . tag === tag ) ;
91+ const element = queueCache . get ( tag ) ;
10392 if ( element ) return element ;
10493
10594 const c = new MessageComposer ( {
@@ -108,15 +97,13 @@ export const useMessageComposer = (_unused: UseMessageComposerParams = {}) => {
10897 tag,
10998 } ) ;
11099
111- // FIXME: don't like this side effect here
112- queueCache . add ( c ) ;
113100 return c ;
114101 } else if ( threadInstance ) {
115102 return threadInstance . messageComposer ;
116103 } else if ( cachedParentMessage ) {
117104 const tag = `parent-message-${ cachedParentMessage . id } ` ;
118105
119- const element = queueCache . get ( ( element ) => element . tag === tag ) ;
106+ const element = queueCache . get ( tag ) ;
120107 if ( element ) return element ;
121108
122109 const c = new MessageComposer ( {
@@ -126,7 +113,6 @@ export const useMessageComposer = (_unused: UseMessageComposerParams = {}) => {
126113 threadId : cachedParentMessage . id ,
127114 } ) ;
128115
129- queueCache . add ( c ) ;
130116 return c ;
131117 } else if ( channel ) {
132118 return channel . messageComposer ;
@@ -142,6 +128,10 @@ export const useMessageComposer = (_unused: UseMessageComposerParams = {}) => {
142128 threadInstance ,
143129 ] ) ;
144130
131+ if ( ! queueCache . peek ( messageComposer . tag ) ) {
132+ queueCache . add ( messageComposer . tag , messageComposer ) ;
133+ }
134+
145135 useEffect ( ( ) => {
146136 messageComposer . registerSubscriptions ( ) ;
147137 return ( ) => {
0 commit comments