@@ -34,10 +34,11 @@ func losFromMap(in map[string]json.RawMessage) (*dbListOfSpeakers, error) {
34
34
}
35
35
36
36
type dbSpeakerWork struct {
37
- MeetingUserID int `json:"meeting_user_id"`
38
- Weight int `json:"weight"`
39
- BeginTime int `json:"begin_time"`
40
- EndTime int `json:"end_time"`
37
+ MeetingUserID int `json:"meeting_user_id"`
38
+ Weight int `json:"weight"`
39
+ BeginTime int `json:"begin_time"`
40
+ EndTime int `json:"end_time"`
41
+ StructureLevelListOfSpeakersID int `json:"structure_level_list_of_speakers_id"`
41
42
}
42
43
type dbSpeaker struct {
43
44
User string `json:"user"`
@@ -63,9 +64,6 @@ func speakerFromMap(in map[string]json.RawMessage) (*dbSpeaker, error) {
63
64
return nil , fmt .Errorf ("decoding speaker work data: %w" , err )
64
65
}
65
66
66
- if work .MeetingUserID == 0 {
67
- return nil , fmt .Errorf ("meeting_user_id is 0" )
68
- }
69
67
return & speaker , nil
70
68
}
71
69
@@ -178,6 +176,201 @@ func CurrentSpeakerChyron(store *projector.SlideStore) {
178
176
})
179
177
}
180
178
179
+ type dbStructureLevel struct {
180
+ Name string `json:"name"`
181
+ Color string `json:"color"`
182
+ }
183
+
184
+ func structureLevelFromMap (in map [string ]json.RawMessage ) (* dbStructureLevel , error ) {
185
+ bs , err := json .Marshal (in )
186
+ if err != nil {
187
+ return nil , fmt .Errorf ("encoding motion data: %w" , err )
188
+ }
189
+
190
+ var m dbStructureLevel
191
+ if err := json .Unmarshal (bs , & m ); err != nil {
192
+ return nil , fmt .Errorf ("decoding motion: %w" , err )
193
+ }
194
+ return & m , nil
195
+ }
196
+
197
+ type dbStructureLevelListOfSpeakers struct {
198
+ SpeakerIDs []int `json:"speaker_ids"`
199
+ StructureLevelID int `json:"structure_level_id"`
200
+ InitialTime int `json:"initial_time"`
201
+ RemainingTime int `json:"remaining_time"`
202
+ AdditionalTime int `json:"additional_time"`
203
+ CurrentStartTime int `json:"current_start_time"`
204
+ }
205
+
206
+ func structureLevelListOfSpeakersFromMap (in map [string ]json.RawMessage ) (* dbStructureLevelListOfSpeakers , error ) {
207
+ bs , err := json .Marshal (in )
208
+ if err != nil {
209
+ return nil , fmt .Errorf ("encoding motion data: %w" , err )
210
+ }
211
+
212
+ var m dbStructureLevelListOfSpeakers
213
+ if err := json .Unmarshal (bs , & m ); err != nil {
214
+ return nil , fmt .Errorf ("decoding motion: %w" , err )
215
+ }
216
+ return & m , nil
217
+ }
218
+
219
+ type structureLevelRepr struct {
220
+ ID int `json:"id"`
221
+ Name string `json:"name"`
222
+ Color string `json:"color"`
223
+ RemainingTime int `json:"remaining_time"`
224
+ CurrentStartTime int `json:"current_start_time"`
225
+ }
226
+
227
+ // CurrentStructureLevelList renders the current_structure_level_list slide.
228
+ func CurrentStructureLevelList (store * projector.SlideStore ) {
229
+ store .RegisterSliderFunc ("current_structure_level_list" , func (ctx context.Context , fetch * datastore.Fetcher , p7on * projector.Projection ) (encoded []byte , err error ) {
230
+ losID , _ , err := getLosID (ctx , p7on .ContentObjectID , fetch )
231
+ if err != nil {
232
+ return nil , fmt .Errorf ("error in getLosID: %w" , err )
233
+ }
234
+
235
+ var losContentObject string
236
+ fetch .Fetch (ctx , & losContentObject , "list_of_speakers/%d/content_object_id" , losID )
237
+ if err := fetch .Err (); err != nil {
238
+ return nil , fmt .Errorf ("getting content object for list of speakers %d: %w" , losID , err )
239
+ }
240
+
241
+ var title string
242
+ fetch .Fetch (ctx , & title , "%s/%s" , losContentObject , "title" )
243
+ if err := fetch .Err (); err != nil {
244
+ return nil , fmt .Errorf ("getting title for list of speakers content object %s: %w" , losContentObject , err )
245
+ }
246
+
247
+ var structureLevelListOfSpeakersIds []int
248
+ fetch .Fetch (ctx , & structureLevelListOfSpeakersIds , "list_of_speakers/%d/structure_level_list_of_speakers_ids" , losID )
249
+ if err := fetch .Err (); err != nil {
250
+ return nil , fmt .Errorf ("getting structure_level_list_of_speakers_ids for list of speakers %d: %w" , losID , err )
251
+ }
252
+
253
+ structureLevels := []structureLevelRepr {}
254
+ for _ , slsID := range structureLevelListOfSpeakersIds {
255
+ hasSpeaker , err := structureLevelHasSpeaker (ctx , fetch , slsID )
256
+ if err != nil {
257
+ return nil , fmt .Errorf ("checking speakers structure level los %d for list of speakers %d: %w" , slsID , losID , err )
258
+ }
259
+
260
+ if ! hasSpeaker {
261
+ continue
262
+ }
263
+
264
+ slsData := fetch .Object (ctx , fmt .Sprintf ("structure_level_list_of_speakers/%d" , slsID ), "structure_level_id" , "remaining_time" , "current_start_time" )
265
+ sls , err := structureLevelListOfSpeakersFromMap (slsData )
266
+ if err != nil {
267
+ return nil , fmt .Errorf ("parsing structure level los %d for list of speakers %d: %w" , slsID , losID , err )
268
+ }
269
+
270
+ slData := fetch .Object (ctx , fmt .Sprintf ("structure_level/%d" , sls .StructureLevelID ), "name" , "color" )
271
+ sl , err := structureLevelFromMap (slData )
272
+ if err != nil {
273
+ return nil , fmt .Errorf ("parsing structure level %d for list of speakers %d: %w" , sls .StructureLevelID , losID , err )
274
+ }
275
+
276
+ structureLevel := structureLevelRepr {
277
+ ID : sls .StructureLevelID ,
278
+ Name : sl .Name ,
279
+ Color : sl .Color ,
280
+ RemainingTime : sls .RemainingTime ,
281
+ CurrentStartTime : sls .CurrentStartTime ,
282
+ }
283
+ structureLevels = append (structureLevels , structureLevel )
284
+ }
285
+
286
+ out := struct {
287
+ Title string `json:"title"`
288
+ StructureLevels []structureLevelRepr `json:"structure_levels"`
289
+ }{
290
+ title ,
291
+ structureLevels ,
292
+ }
293
+
294
+ responseValue , err := json .Marshal (out )
295
+ if err != nil {
296
+ return nil , fmt .Errorf ("encoding response slide current_speaker_chyron: %w" , err )
297
+ }
298
+ return responseValue , nil
299
+ })
300
+ }
301
+
302
+ // CurrentSpeakingStructureLevel renders the current_speaking_structure_level slide.
303
+ func CurrentSpeakingStructureLevel (store * projector.SlideStore ) {
304
+ store .RegisterSliderFunc ("current_speaking_structure_level" , func (ctx context.Context , fetch * datastore.Fetcher , p7on * projector.Projection ) (encoded []byte , err error ) {
305
+ losID , _ , err := getLosID (ctx , p7on .ContentObjectID , fetch )
306
+ if err != nil {
307
+ return nil , fmt .Errorf ("error in getLosID: %w" , err )
308
+ }
309
+
310
+ slsID , err := getStructureLevelData (ctx , fetch , losID )
311
+ if err != nil {
312
+ return nil , fmt .Errorf ("error in getStructureLevelData: %w" , err )
313
+ }
314
+
315
+ if slsID != 0 {
316
+ slsData := fetch .Object (ctx , fmt .Sprintf ("structure_level_list_of_speakers/%d" , slsID ), "structure_level_id" , "remaining_time" , "current_start_time" )
317
+ sls , err := structureLevelListOfSpeakersFromMap (slsData )
318
+ if err != nil {
319
+ return nil , fmt .Errorf ("parsing structure level los %d for list of speakers %d: %w" , slsID , losID , err )
320
+ }
321
+
322
+ slData := fetch .Object (ctx , fmt .Sprintf ("structure_level/%d" , sls .StructureLevelID ), "name" , "color" )
323
+ sl , err := structureLevelFromMap (slData )
324
+ if err != nil {
325
+ return nil , fmt .Errorf ("parsing structure level %d for list of speakers %d: %w" , sls .StructureLevelID , losID , err )
326
+ }
327
+
328
+ out := structureLevelRepr {
329
+ ID : sls .StructureLevelID ,
330
+ Name : sl .Name ,
331
+ Color : sl .Color ,
332
+ RemainingTime : sls .RemainingTime ,
333
+ CurrentStartTime : sls .CurrentStartTime ,
334
+ }
335
+
336
+ responseValue , err := json .Marshal (out )
337
+ if err != nil {
338
+ return nil , fmt .Errorf ("encoding response slide current_speaking_structure_level: %w" , err )
339
+ }
340
+ return responseValue , nil
341
+ }
342
+
343
+ return []byte ("{}" ), nil
344
+ })
345
+ }
346
+
347
+ func structureLevelHasSpeaker (ctx context.Context , fetch * datastore.Fetcher , structureLevelLosID int ) (spoken bool , err error ) {
348
+ data := fetch .Object (ctx , fmt .Sprintf ("structure_level_list_of_speakers/%d" , structureLevelLosID ), "speaker_ids" , "initial_time" , "additional_time" , "remaining_time" , "current_start_time" )
349
+ sllos , err := structureLevelListOfSpeakersFromMap (data )
350
+ if err != nil {
351
+ return false , fmt .Errorf ("loading structure level list of speakers: %w" , err )
352
+ }
353
+
354
+ if sllos .InitialTime + sllos .AdditionalTime != sllos .RemainingTime || sllos .CurrentStartTime != 0 {
355
+ return true , nil
356
+ }
357
+
358
+ for _ , id := range sllos .SpeakerIDs {
359
+ speechState := datastore .String (ctx , fetch .FetchIfExist , "speaker/%d/speech_state" , id )
360
+ if err := fetch .Err (); err != nil {
361
+ return false , fmt .Errorf ("Error loading speach state %d %w" , id , err )
362
+ }
363
+
364
+ if speechState == "interposed_question" || speechState == "intervention" {
365
+ continue
366
+ }
367
+
368
+ return true , nil
369
+ }
370
+
371
+ return false , nil
372
+ }
373
+
181
374
// getLosID determines the losID and first current_projection of the reference_projector.
182
375
func getLosID (ctx context.Context , ContentObjectID string , fetch * datastore.Fetcher ) (losID int , referenceProjectorID int , err error ) {
183
376
parts := strings .Split (ContentObjectID , "/" )
@@ -219,6 +412,36 @@ func getLosID(ctx context.Context, ContentObjectID string, fetch *datastore.Fetc
219
412
return losID , referenceProjectorID , nil
220
413
}
221
414
415
+ func getStructureLevelData (ctx context.Context , fetch * datastore.Fetcher , losID int ) (id int , err error ) {
416
+ data := fetch .Object (ctx , fmt .Sprintf ("list_of_speakers/%d" , losID ), "speaker_ids" , "content_object_id" , "closed" )
417
+ los , err := losFromMap (data )
418
+ if err != nil {
419
+ return 0 , fmt .Errorf ("loading list of speakers: %w" , err )
420
+ }
421
+
422
+ fields := []string {
423
+ "begin_time" ,
424
+ "end_time" ,
425
+ "speech_state" ,
426
+ "structure_level_list_of_speakers_id" ,
427
+ }
428
+
429
+ for _ , id := range los .SpeakerIDs {
430
+ speaker , err := speakerFromMap (fetch .Object (ctx , fmt .Sprintf ("speaker/%d" , id ), fields ... ))
431
+ if err != nil {
432
+ return 0 , fmt .Errorf ("loading speaker %d: %w" , id , err )
433
+ }
434
+
435
+ if speaker .SpeakerWork .BeginTime == 0 || (speaker .SpeakerWork .BeginTime != 0 && speaker .SpeakerWork .EndTime != 0 ) || speaker .SpeechState == "interposed_question" || speaker .SpeakerWork .StructureLevelListOfSpeakersID == 0 {
436
+ continue
437
+ }
438
+
439
+ return speaker .SpeakerWork .StructureLevelListOfSpeakersID , nil
440
+ }
441
+
442
+ return 0 , nil
443
+ }
444
+
222
445
func getCurrentSpeakerData (ctx context.Context , fetch * datastore.Fetcher , losID int , meetingID int ) (shortName string , structureLevel string , err error ) {
223
446
data := fetch .Object (ctx , fmt .Sprintf ("list_of_speakers/%d" , losID ), "speaker_ids" , "content_object_id" , "closed" )
224
447
los , err := losFromMap (data )
@@ -242,17 +465,41 @@ func getCurrentSpeakerData(ctx context.Context, fetch *datastore.Fetcher, losID
242
465
continue
243
466
}
244
467
245
- var userID int
246
- fetch .FetchIfExist (ctx , & userID , "meeting_user/%d/user_id" , speaker .SpeakerWork .MeetingUserID )
247
- if err := fetch .Err (); err != nil {
248
- return "" , "" , fmt .Errorf ("getting user for meeting user %d: %w" , speaker .SpeakerWork .MeetingUserID , err )
249
- }
468
+ if speaker .SpeakerWork .MeetingUserID != 0 {
469
+ var userID int
470
+ fetch .FetchIfExist (ctx , & userID , "meeting_user/%d/user_id" , speaker .SpeakerWork .MeetingUserID )
471
+ if err := fetch .Err (); err != nil {
472
+ return "" , "" , fmt .Errorf ("getting user for meeting user %d: %w" , speaker .SpeakerWork .MeetingUserID , err )
473
+ }
250
474
251
- user , err := NewUser (ctx , fetch , userID , meetingID )
252
- if err != nil {
253
- return "" , "" , fmt .Errorf ("getting newUser: %w" , err )
475
+ user , err := NewUser (ctx , fetch , userID , meetingID )
476
+ if err != nil {
477
+ return "" , "" , fmt .Errorf ("getting newUser: %w" , err )
478
+ }
479
+
480
+ var structureLevelListOfSpeakersID int
481
+ fetch .FetchIfExist (ctx , & structureLevelListOfSpeakersID , "speaker/%d/structure_level_list_of_speakers_id" , id )
482
+ if err := fetch .Err (); err != nil {
483
+ return "" , "" , fmt .Errorf ("getting structure level for speaker %d: %w" , id , err )
484
+ }
485
+
486
+ structureLevelName := ""
487
+ if structureLevelListOfSpeakersID != 0 {
488
+ var structureLevelID int
489
+ fetch .FetchIfExist (ctx , & structureLevelID , "structure_level_list_of_speakers/%d/structure_level_id" , structureLevelListOfSpeakersID )
490
+ if err := fetch .Err (); err != nil {
491
+ return "" , "" , fmt .Errorf ("getting structure level for structure_level_list_of_speakers %d: %w" , structureLevelListOfSpeakersID , err )
492
+ }
493
+
494
+ fetch .Fetch (ctx , & structureLevelName , "structure_level/%d/name" , structureLevelID )
495
+ if err := fetch .Err (); err != nil {
496
+ return "" , "" , fmt .Errorf ("getting name for structure level name %d: %w" , structureLevelID , err )
497
+ }
498
+ }
499
+
500
+ return user .UserShortName (), structureLevelName , nil
254
501
}
255
- return user . UserShortName (), user . UserStructureLevel ( meetingID ) , nil
502
+ return "" , "" , nil
256
503
}
257
504
258
505
return shortName , structureLevel , nil
@@ -340,18 +587,20 @@ func getSpeakerLists(ctx context.Context, los *dbListOfSpeakers, meetingID int,
340
587
return nil , nil , fmt .Errorf ("loading speaker: %w" , err )
341
588
}
342
589
343
- var userID int
344
- fetch .FetchIfExist (ctx , & userID , "meeting_user/%d/user_id" , speaker .SpeakerWork .MeetingUserID )
345
- if err := fetch .Err (); err != nil {
346
- return nil , nil , fmt .Errorf ("getting user for meeting user %d: %w" , speaker .SpeakerWork .MeetingUserID , err )
347
- }
590
+ if speaker .SpeakerWork .MeetingUserID != 0 {
591
+ var userID int
592
+ fetch .FetchIfExist (ctx , & userID , "meeting_user/%d/user_id" , speaker .SpeakerWork .MeetingUserID )
593
+ if err := fetch .Err (); err != nil {
594
+ return nil , nil , fmt .Errorf ("getting user for meeting user %d: %w" , speaker .SpeakerWork .MeetingUserID , err )
595
+ }
348
596
349
- user , err := NewUser (ctx , fetch , userID , meetingID )
350
- if err != nil {
351
- return nil , nil , fmt .Errorf ("loading user: %w" , err )
352
- }
597
+ user , err := NewUser (ctx , fetch , userID , meetingID )
598
+ if err != nil {
599
+ return nil , nil , fmt .Errorf ("loading user: %w" , err )
600
+ }
353
601
354
- speaker .User = user .UserRepresentation (meetingID )
602
+ speaker .User = user .UserRepresentation (meetingID )
603
+ }
355
604
356
605
if speaker .SpeakerWork .BeginTime == 0 && speaker .SpeakerWork .EndTime == 0 {
357
606
* speakersWaiting = append (* speakersWaiting , * speaker )
0 commit comments