@@ -28,9 +28,14 @@ type chatUI struct {
28
28
CanvasObject fyne.CanvasObject
29
29
Panel * Panel
30
30
List * widget.List
31
+ ItemHeight map [streamcontrol.ChatMessageID ]uint
32
+ TotalListHeight uint
31
33
MessagesHistoryLocker sync.Mutex
32
34
MessagesHistory []api.ChatMessage
33
35
EnableButtons bool
36
+ ReverseOrder bool
37
+ OnAdd func (context.Context , api.ChatMessage )
38
+ OnRemove func (context.Context , api.ChatMessage )
34
39
35
40
CapabilitiesCacheLocker sync.Mutex
36
41
CapabilitiesCache map [streamcontrol.PlatformName ]map [streamcontrol.Capability ]struct {}
@@ -44,6 +49,7 @@ type chatUI struct {
44
49
func newChatUI (
45
50
ctx context.Context ,
46
51
enableButtons bool ,
52
+ reverseOrder bool ,
47
53
panel * Panel ,
48
54
) (_ret * chatUI , _err error ) {
49
55
logger .Debugf (ctx , "newChatUI" )
@@ -52,7 +58,9 @@ func newChatUI(
52
58
ui := & chatUI {
53
59
Panel : panel ,
54
60
EnableButtons : enableButtons ,
61
+ ReverseOrder : reverseOrder ,
55
62
CapabilitiesCache : make (map [streamcontrol.PlatformName ]map [streamcontrol.Capability ]struct {}),
63
+ ItemHeight : map [streamcontrol.ChatMessageID ]uint {},
56
64
ctx : ctx ,
57
65
}
58
66
if err := ui .init (ctx ); err != nil {
@@ -173,6 +181,9 @@ func (ui *chatUI) onReceiveMessage(
173
181
) {
174
182
logger .Debugf (ctx , "onReceiveMessage(ctx, %s)" , spew .Sdump (msg ))
175
183
defer func () { logger .Tracef (ctx , "/onReceiveMessage(ctx, %s)" , spew .Sdump (msg )) }()
184
+ if onAdd := ui .OnAdd ; onAdd != nil {
185
+ defer onAdd (ctx , msg )
186
+ }
176
187
ui .MessagesHistoryLocker .Lock ()
177
188
defer ui .MessagesHistoryLocker .Unlock ()
178
189
ui .MessagesHistory = append (ui .MessagesHistory , msg )
@@ -290,7 +301,12 @@ func (ui *chatUI) listUpdateItem(
290
301
ctx := context .TODO ()
291
302
ui .MessagesHistoryLocker .Lock ()
292
303
defer ui .MessagesHistoryLocker .Unlock ()
293
- entryID := len (ui .MessagesHistory ) - 1 - rowID
304
+ var entryID int
305
+ if ui .ReverseOrder {
306
+ entryID = len (ui .MessagesHistory ) - 1 - rowID
307
+ } else {
308
+ entryID = rowID
309
+ }
294
310
if entryID < 0 || entryID >= len (ui .MessagesHistory ) {
295
311
logger .Errorf (ctx , "invalid entry ID: %d" , entryID )
296
312
return
@@ -306,51 +322,53 @@ func (ui *chatUI) listUpdateItem(
306
322
containerPtr := obj .(* fyne.Container )
307
323
objs := containerPtr .Objects
308
324
label := objs [0 ].(* widget.Label )
309
- subContainer := objs [1 ].(* fyne.Container )
310
- banUserButton := subContainer .Objects [0 ].(* widget.Button )
311
- banUserButton .OnTapped = func () {
312
- w := dialog .NewConfirm (
313
- "Banning an user" ,
314
- fmt .Sprintf ("Are you sure you want to ban user '%s' on '%s'" , msg .UserID , msg .Platform ),
315
- func (b bool ) {
316
- if ! b {
317
- return
318
- }
319
- ui .onBanClicked (msg .Platform , msg .UserID )
320
- },
321
- ui .Panel .mainWindow ,
322
- )
323
- w .Show ()
324
- }
325
- if _ , ok := platCaps [streamcontrol .CapabilityBanUser ]; ! ok {
326
- banUserButton .Disable ()
327
- } else {
328
- banUserButton .Enable ()
329
- }
330
- removeMsgButton := subContainer .Objects [1 ].(* widget.Button )
331
- removeMsgButton .OnTapped = func () {
332
- w := dialog .NewConfirm (
333
- "Removing a message" ,
334
- fmt .Sprintf ("Are you sure you want to remove the message from '%s' on '%s'" , msg .UserID , msg .Platform ),
335
- func (b bool ) {
336
- if ! b {
337
- return
338
- }
339
- // TODO: think of consistency with onBanClicked
340
- ui .onRemoveClicked (entryID )
341
- },
342
- ui .Panel .mainWindow ,
343
- )
344
- w .Show ()
345
- }
346
- if _ , ok := platCaps [streamcontrol .CapabilityDeleteChatMessage ]; ! ok {
347
- removeMsgButton .Disable ()
348
- } else {
349
- removeMsgButton .Enable ()
325
+ if ui .EnableButtons {
326
+ subContainer := objs [1 ].(* fyne.Container )
327
+ banUserButton := subContainer .Objects [0 ].(* widget.Button )
328
+ banUserButton .OnTapped = func () {
329
+ w := dialog .NewConfirm (
330
+ "Banning an user" ,
331
+ fmt .Sprintf ("Are you sure you want to ban user '%s' on '%s'" , msg .UserID , msg .Platform ),
332
+ func (b bool ) {
333
+ if ! b {
334
+ return
335
+ }
336
+ ui .onBanClicked (msg .Platform , msg .UserID )
337
+ },
338
+ ui .Panel .mainWindow ,
339
+ )
340
+ w .Show ()
341
+ }
342
+ if _ , ok := platCaps [streamcontrol .CapabilityBanUser ]; ! ok {
343
+ banUserButton .Disable ()
344
+ } else {
345
+ banUserButton .Enable ()
346
+ }
347
+ removeMsgButton := subContainer .Objects [1 ].(* widget.Button )
348
+ removeMsgButton .OnTapped = func () {
349
+ w := dialog .NewConfirm (
350
+ "Removing a message" ,
351
+ fmt .Sprintf ("Are you sure you want to remove the message from '%s' on '%s'" , msg .UserID , msg .Platform ),
352
+ func (b bool ) {
353
+ if ! b {
354
+ return
355
+ }
356
+ // TODO: think of consistency with onBanClicked
357
+ ui .onRemoveClicked (entryID )
358
+ },
359
+ ui .Panel .mainWindow ,
360
+ )
361
+ w .Show ()
362
+ }
363
+ if _ , ok := platCaps [streamcontrol .CapabilityDeleteChatMessage ]; ! ok {
364
+ removeMsgButton .Disable ()
365
+ } else {
366
+ removeMsgButton .Enable ()
367
+ }
350
368
}
351
369
label .SetText (fmt .Sprintf (
352
370
"%s: %s: %s: %s" ,
353
- msg .CreatedAt .Format ("15:04" ),
371
+ msg .CreatedAt .Format ("15:04:05 " ),
354
372
msg .Platform ,
355
373
msg .Username ,
356
374
msg .Message ,
@@ -359,6 +377,10 @@ func (ui *chatUI) listUpdateItem(
359
377
requiredHeight := containerPtr .MinSize ().Height
360
378
logger .Tracef (ctx , "%d: requiredHeight == %f" , rowID , requiredHeight )
361
379
380
+ prevHeight := ui .ItemHeight [msg .MessageID ]
381
+ ui .TotalListHeight += uint (requiredHeight ) - prevHeight
382
+ ui .ItemHeight [msg .MessageID ] = uint (requiredHeight )
383
+
362
384
// TODO: think of how to get rid of this racy hack:
363
385
observability .Go (ctx , func () { ui .List .SetItemHeight (rowID , requiredHeight ) })
364
386
}
@@ -391,7 +413,13 @@ func (ui *chatUI) onRemoveClicked(
391
413
return
392
414
}
393
415
msg := ui .MessagesHistory [itemID ]
416
+ if onRemove := ui .OnRemove ; onRemove != nil {
417
+ defer onRemove (ctx , msg )
418
+ }
394
419
ui .MessagesHistory = append (ui .MessagesHistory [:itemID ], ui .MessagesHistory [itemID + 1 :]... )
420
+ prevHeight := ui .ItemHeight [msg .MessageID ]
421
+ ui .TotalListHeight -= prevHeight
422
+ delete (ui .ItemHeight , msg .MessageID )
395
423
err := ui .Panel .chatMessageRemove (ui .ctx , msg .Platform , msg .MessageID )
396
424
if err != nil {
397
425
ui .Panel .DisplayError (err )
0 commit comments