@@ -5,66 +5,55 @@ import { useChannelStateContext, useMessageInputContext } from '../../../../cont
5
5
import type { LocalMessage } from 'stream-chat' ;
6
6
import { useLegacyThreadContext } from '../../../Thread' ;
7
7
8
- class FixedSizeQueueCache < T > {
9
- private elements : Array < T > ;
8
+ class FixedSizeQueueCache < K , T > {
9
+ private keys : Array < K > ;
10
10
private size : number ;
11
+ private valueByKey : Map < K , T > ;
11
12
constructor ( size : number ) {
12
13
if ( ! size ) throw new Error ( 'Size must be greater than 0' ) ;
13
- this . elements = [ ] ;
14
+ this . keys = [ ] ;
14
15
this . size = size ;
16
+ this . valueByKey = new Map ( ) ;
15
17
}
16
18
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 ) ;
20
21
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 ( ) ;
30
26
31
- this . elements . push ( value ) ;
27
+ if ( elementKey ) {
28
+ this . valueByKey . delete ( elementKey ) ;
32
29
}
33
30
}
34
- }
35
31
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
+ }
42
35
43
- if ( predicateResult ) return element ;
44
- }
36
+ peek ( key : K ) {
37
+ const value = this . valueByKey . get ( key ) ;
45
38
46
- return null ;
39
+ return value ;
47
40
}
48
41
49
- get ( predicate : ( element : T ) => boolean ) {
50
- const foundElement = this . peek ( predicate ) ;
42
+ get ( key : K ) {
43
+ const foundElement = this . peek ( key ) ;
51
44
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 ) ;
55
48
}
56
49
57
50
return foundElement ;
58
51
}
59
-
60
- toArray ( ) {
61
- return [ ...this . elements ] ;
62
- }
63
52
}
64
53
65
54
export type UseMessageComposerParams = unknown ;
66
55
67
- const queueCache = new FixedSizeQueueCache < MessageComposer > ( 64 ) ;
56
+ const queueCache = new FixedSizeQueueCache < string , MessageComposer > ( 64 ) ;
68
57
// eslint-disable-next-line @typescript-eslint/no-unused-vars
69
58
export const useMessageComposer = ( _unused : UseMessageComposerParams = { } ) => {
70
59
const { channel } = useChannelStateContext ( ) ;
@@ -99,7 +88,7 @@ export const useMessageComposer = (_unused: UseMessageComposerParams = {}) => {
99
88
if ( cachedEditedMessage ) {
100
89
const tag = `edited-message-${ cachedEditedMessage . id } ` ;
101
90
102
- const element = queueCache . get ( ( element ) => element . tag === tag ) ;
91
+ const element = queueCache . get ( tag ) ;
103
92
if ( element ) return element ;
104
93
105
94
const c = new MessageComposer ( {
@@ -108,15 +97,13 @@ export const useMessageComposer = (_unused: UseMessageComposerParams = {}) => {
108
97
tag,
109
98
} ) ;
110
99
111
- // FIXME: don't like this side effect here
112
- queueCache . add ( c ) ;
113
100
return c ;
114
101
} else if ( threadInstance ) {
115
102
return threadInstance . messageComposer ;
116
103
} else if ( cachedParentMessage ) {
117
104
const tag = `parent-message-${ cachedParentMessage . id } ` ;
118
105
119
- const element = queueCache . get ( ( element ) => element . tag === tag ) ;
106
+ const element = queueCache . get ( tag ) ;
120
107
if ( element ) return element ;
121
108
122
109
const c = new MessageComposer ( {
@@ -126,7 +113,6 @@ export const useMessageComposer = (_unused: UseMessageComposerParams = {}) => {
126
113
threadId : cachedParentMessage . id ,
127
114
} ) ;
128
115
129
- queueCache . add ( c ) ;
130
116
return c ;
131
117
} else if ( channel ) {
132
118
return channel . messageComposer ;
@@ -142,6 +128,10 @@ export const useMessageComposer = (_unused: UseMessageComposerParams = {}) => {
142
128
threadInstance ,
143
129
] ) ;
144
130
131
+ if ( ! queueCache . peek ( messageComposer . tag ) ) {
132
+ queueCache . add ( messageComposer . tag , messageComposer ) ;
133
+ }
134
+
145
135
useEffect ( ( ) => {
146
136
messageComposer . registerSubscriptions ( ) ;
147
137
return ( ) => {
0 commit comments