1
1
import { LinkPreviewsManager } from './linkPreviewsManager' ;
2
2
import { AttachmentManager } from './attachmentManager' ;
3
3
import { TextComposer } from './textComposer' ;
4
- import { Channel } from '../channel' ;
5
4
import { StateStore } from '../store' ;
6
5
import { formatMessage , generateUUIDv4 } from '../utils' ;
6
+ import type { Channel } from '../channel' ;
7
7
import type {
8
- DefaultGenerics ,
9
8
DraftMessage ,
10
9
DraftResponse ,
11
10
EventTypes ,
12
- ExtendableGenerics ,
13
11
FormatMessageResponse ,
14
12
MessageResponse ,
15
13
MessageResponseBase ,
@@ -21,10 +19,10 @@ import { mergeWith } from '../utils/mergeWith';
21
19
1/ decide whether lastChange timestamp is necessary
22
20
*/
23
21
24
- export type MessageComposerState < SCG extends ExtendableGenerics = DefaultGenerics > = {
22
+ export type MessageComposerState = {
25
23
id : string ;
26
24
lastChange : Date | null ;
27
- quotedMessage : FormatMessageResponse < SCG > | null ;
25
+ quotedMessage : FormatMessageResponse | null ;
28
26
} ;
29
27
30
28
export type MessageComposerConfig = {
@@ -34,26 +32,25 @@ export type MessageComposerConfig = {
34
32
urlPreviewEnabled ?: boolean ;
35
33
} ;
36
34
37
- export type MessageComposerOptions < SCG extends ExtendableGenerics = DefaultGenerics > = {
38
- channel : Channel < SCG > ;
39
- composition ?: DraftResponse < SCG > | MessageResponse < SCG > | FormatMessageResponse < SCG > ;
35
+ export type MessageComposerOptions = {
36
+ channel : Channel ;
37
+ composition ?: DraftResponse | MessageResponse | FormatMessageResponse ;
40
38
config ?: Partial < MessageComposerConfig > ;
41
39
threadId ?: string ;
42
40
} ;
43
41
44
- const isMessageDraft = < SCG extends ExtendableGenerics = DefaultGenerics > (
45
- composition : DraftResponse < SCG > | MessageResponse < SCG > | FormatMessageResponse < SCG > ,
46
- ) : composition is DraftResponse < SCG > => ! ! composition . message ;
42
+ const isMessageDraft = ( composition : unknown ) : composition is DraftResponse =>
43
+ ! ! ( composition as { message ?: DraftMessage } ) . message ;
47
44
48
- const initState = < SCG extends ExtendableGenerics = DefaultGenerics > (
49
- composition ?: DraftResponse < SCG > | MessageResponse < SCG > | FormatMessageResponse < SCG > ,
50
- ) : MessageComposerState < SCG > =>
45
+ const initState = (
46
+ composition ?: DraftResponse | MessageResponse | FormatMessageResponse ,
47
+ ) : MessageComposerState =>
51
48
composition
52
49
? {
53
50
id : isMessageDraft ( composition ) ? composition . message . id : composition . id ,
54
51
lastChange : new Date ( ) ,
55
52
quotedMessage : composition . quoted_message
56
- ? formatMessage ( composition . quoted_message as MessageResponseBase < SCG > )
53
+ ? formatMessage ( composition . quoted_message as MessageResponseBase )
57
54
: null ,
58
55
}
59
56
: {
@@ -67,28 +64,31 @@ const DEFAULT_COMPOSER_CONFIG: MessageComposerConfig = {
67
64
urlPreviewEnabled : false ,
68
65
} ;
69
66
70
- export class MessageComposer < SCG extends ExtendableGenerics = DefaultGenerics > {
71
- channel : Channel < SCG > ;
67
+ export class MessageComposer {
68
+ channel : Channel ;
72
69
config : MessageComposerConfig ;
73
- state : StateStore < MessageComposerState < SCG > > ;
74
- attachmentManager : AttachmentManager < SCG > ;
75
- linkPreviewsManager : LinkPreviewsManager < SCG > ;
76
- // todo: mediaRecorder: MediaRecorderController<SCG> ;
77
- textComposer : TextComposer < SCG > ;
70
+ state : StateStore < MessageComposerState > ;
71
+ attachmentManager : AttachmentManager ;
72
+ linkPreviewsManager : LinkPreviewsManager ;
73
+ // todo: mediaRecorder: MediaRecorderController;
74
+ textComposer : TextComposer ;
78
75
threadId : string | null ;
79
76
private unsubscribeFunctions : Set < ( ) => void > = new Set ( ) ;
80
77
81
- constructor ( { channel, composition, config = { } , threadId } : MessageComposerOptions < SCG > ) {
78
+ constructor ( { channel, composition, config = { } , threadId } : MessageComposerOptions ) {
82
79
this . channel = channel ;
83
80
this . threadId = threadId ?? null ;
84
81
// todo: solve ts-ignore
85
- // @ts -ignore
86
- this . config = mergeWith ( config , DEFAULT_COMPOSER_CONFIG ) ;
87
- const message = composition && ( isMessageDraft ( composition ) ? composition . message : composition ) ;
88
- this . attachmentManager = new AttachmentManager < SCG > ( { channel, message } ) ;
89
- this . linkPreviewsManager = new LinkPreviewsManager < SCG > ( { client : channel . getClient ( ) , message } ) ;
90
- this . textComposer = new TextComposer < SCG > ( { composer : this , message } ) ;
91
- this . state = new StateStore < MessageComposerState < SCG > > ( initState < SCG > ( composition ) ) ;
82
+ this . config = mergeWith ( DEFAULT_COMPOSER_CONFIG , config ) ;
83
+ const message =
84
+ composition && ( isMessageDraft ( composition ) ? composition . message : composition ) ;
85
+ this . attachmentManager = new AttachmentManager ( { channel, message } ) ;
86
+ this . linkPreviewsManager = new LinkPreviewsManager ( {
87
+ client : channel . getClient ( ) ,
88
+ message,
89
+ } ) ;
90
+ this . textComposer = new TextComposer ( { composer : this , message } ) ;
91
+ this . state = new StateStore < MessageComposerState > ( initState ( composition ) ) ;
92
92
}
93
93
94
94
get client ( ) {
@@ -103,8 +103,12 @@ export class MessageComposer<SCG extends ExtendableGenerics = DefaultGenerics> {
103
103
return this . state . getLatestValue ( ) . quotedMessage ;
104
104
}
105
105
106
- initState = ( { composition } : { composition ?: DraftResponse < SCG > | MessageResponse < SCG > } = { } ) => {
107
- const message = composition && ( composition . message as DraftMessage < SCG > | MessageResponseBase < SCG > ) ;
106
+ initState = ( {
107
+ composition,
108
+ } : { composition ?: DraftResponse | MessageResponse } = { } ) => {
109
+ const message = isMessageDraft ( composition )
110
+ ? composition . message
111
+ : ( composition as MessageResponse ) ;
108
112
this . attachmentManager . initState ( { message } ) ;
109
113
this . linkPreviewsManager . initState ( { message } ) ;
110
114
this . textComposer . initState ( { message } ) ;
@@ -133,7 +137,12 @@ export class MessageComposer<SCG extends ExtendableGenerics = DefaultGenerics> {
133
137
134
138
private subscribeMessageUpdated = ( ) => {
135
139
// todo: test the impact of 'reaction.new', 'reaction.deleted', 'reaction.updated'
136
- const eventTypes : EventTypes [ ] = [ 'message.updated' , 'reaction.new' , 'reaction.deleted' , 'reaction.updated' ] ;
140
+ const eventTypes : EventTypes [ ] = [
141
+ 'message.updated' ,
142
+ 'reaction.new' ,
143
+ 'reaction.deleted' ,
144
+ 'reaction.updated' ,
145
+ ] ;
137
146
138
147
const unsubscribeFunctions = eventTypes . map (
139
148
( eventType ) =>
@@ -163,25 +172,32 @@ export class MessageComposer<SCG extends ExtendableGenerics = DefaultGenerics> {
163
172
164
173
private subscribeDraftUpdated = ( ) =>
165
174
this . client . on ( 'draft.updated' , ( event ) => {
166
- const draft = event . draft as DraftResponse < SCG > ;
167
- if ( ! draft || draft . parent_id !== this . threadId || draft . message . id !== this . id ) return ;
175
+ const draft = event . draft as DraftResponse ;
176
+ if ( ! draft || draft . parent_id !== this . threadId || draft . message . id !== this . id )
177
+ return ;
168
178
this . initState ( { composition : draft } ) ;
169
179
} ) . unsubscribe ;
170
180
171
181
private subscribeDraftDeleted = ( ) =>
172
182
this . client . on ( 'draft.deleted' , ( event ) => {
173
- const draft = event . draft as DraftResponse < SCG > ;
174
- if ( ! draft || draft . parent_id !== this . threadId || draft . message . id !== this . id ) return ;
183
+ const draft = event . draft as DraftResponse ;
184
+ if ( ! draft || draft . parent_id !== this . threadId || draft . message . id !== this . id )
185
+ return ;
175
186
this . clear ( ) ;
176
187
} ) . unsubscribe ;
177
188
178
189
private subscribeTextChanged = ( ) =>
179
190
this . textComposer . state . subscribe ( ( nextValue , previousValue ) => {
180
- if ( ! this . config . urlPreviewEnabled || ! nextValue . text || nextValue . text === previousValue ?. text ) return ;
191
+ if (
192
+ ! this . config . urlPreviewEnabled ||
193
+ ! nextValue . text ||
194
+ nextValue . text === previousValue ?. text
195
+ )
196
+ return ;
181
197
this . linkPreviewsManager . findAndEnrichUrls ( nextValue . text ) ;
182
198
} ) ;
183
199
184
- setQuotedMessage = ( quotedMessage : FormatMessageResponse < SCG > | null ) => {
200
+ setQuotedMessage = ( quotedMessage : FormatMessageResponse | null ) => {
185
201
this . state . partialNext ( { quotedMessage } ) ;
186
202
} ;
187
203
0 commit comments