Skip to content

Commit

Permalink
Implement part of current_list_of_speakers slide (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
bastianjoel authored Jan 22, 2025
1 parent 026c952 commit 3f923f9
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 15 deletions.
112 changes: 99 additions & 13 deletions pkg/projector/slide/current_list_of_speakers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import (
"context"
"fmt"
"html/template"
"reflect"
"sort"
"strconv"
"strings"

"github.com/OpenSlides/openslides-projector-service/pkg/datastore"
"github.com/OpenSlides/openslides-projector-service/pkg/models"
Expand All @@ -15,45 +19,127 @@ func CurrentListOfSpeakersSlideHandler(ctx context.Context, req *projectionReque
content := make(chan string)
projection := req.Projection

var meeting models.Meeting
q := datastore.Collection(req.DB, &models.Meeting{}).With("speaker_ids", nil).SetFqids(projection.ContentObjectID)
speakersQ := q.GetSubquery("speaker_ids")
referenceProjectorId := 0
refProjectorSub, err := datastore.Collection(req.DB, &models.Meeting{}).SetFqids(projection.ContentObjectID).SetFields("reference_projector_id").SubscribeField(&referenceProjectorId)
if err != nil {
return nil, fmt.Errorf("failed to subscribe reference projector id: %w", err)
}

var projector models.Projector
projectorQ := datastore.Collection(req.DB, &models.Projector{}).With("current_projection_ids", nil)
projectorSub, err := projectorQ.SubscribeOne(&projector)
if err != nil {
return nil, fmt.Errorf("failed to subscribe reference projector: %w", err)
}

projectionsQ := projectorQ.GetSubquery("current_projection_ids")
projectionsQ.With("content_object_id", nil)

var los models.ListOfSpeakers
losQ := datastore.Collection(req.DB, &models.ListOfSpeakers{}).With("speaker_ids", nil)
losSub, err := losQ.SubscribeOne(&los)
if err != nil {
return nil, fmt.Errorf("failed to subscribe list of speakers: %w", err)
}

speakersQ := losQ.GetSubquery("speaker_ids")
meetingUsersQ := speakersQ.With("meeting_user_id", nil)
meetingUsersQ.With("user_id", nil)

losSub, err := q.SubscribeOne(&meeting)
if err != nil {
return nil, fmt.Errorf("CurrentListOfSpeakersSlideHandler: %w", err)
stable := false
if projection.Stable != nil {
stable = *projection.Stable
}

go func() {
content <- getCurrentListOfSpeakersSlideContent(&meeting)
for {
select {
case <-refProjectorSub.Channel:
if referenceProjectorId > 0 {
projectorQ.SetIds(referenceProjectorId)
if err := projectorSub.Reload(); err != nil {
log.Err(err).Msg("Reference projector load failed")
}
}
case <-projectorSub.Channel:
for _, p := range projector.CurrentProjections() {
if p.ContentObjectID == "" {
continue
}

for range <-losSub.Channel {
content <- getCurrentListOfSpeakersSlideContent(&meeting)
losId := p.ContentObject().Get("list_of_speakers_id")
if losId != nil {
v := reflect.ValueOf(losId)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}

losQ.SetIds(int(v.Int()))
if err := losSub.Reload(); err != nil {
log.Err(err).Msg("Reference projector load failed")
}
break
}
}
case <-losSub.Channel:
if los.ID != 0 {
println("send new", len(los.SpeakerIDs))
content <- getCurrentListOfSpeakersSlideContent(&los, stable)
}
}
}
}()

return content, nil
}

func getCurrentListOfSpeakersSlideContent(los *models.Meeting) string {
func getCurrentListOfSpeakersSlideContent(los *models.ListOfSpeakers, overlay bool) string {
tmpl, err := template.ParseFiles("templates/slides/current-list-of-speakers.html")
if err != nil {
log.Error().Err(err).Msg("could not load current-list-of-speakers template")
return ""
}

speakers := []string{}
type speakerListItem struct {
Number int
Name string
Weight int
}
speakers := []speakerListItem{}
for _, speaker := range los.Speakers() {
username := speaker.MeetingUser().User().Username
speakers = append(speakers, username)
nameParts := []string{}
if firstName := speaker.MeetingUser().User().FirstName; firstName != nil {
nameParts = append(nameParts, *firstName)
}
if lastName := speaker.MeetingUser().User().LastName; lastName != nil {
nameParts = append(nameParts, *lastName)
}

if len(nameParts) == 0 {
nameParts = append(nameParts, "User "+strconv.Itoa(speaker.MeetingUser().User().ID))
}

weight := 0
if speaker.Weight != nil {
weight = *speaker.Weight
}

speakers = append([]speakerListItem{{
Number: weight + 1,
Name: strings.Join(nameParts, " "),
Weight: weight,
}}, speakers...)
}

sort.Slice(speakers, func(i, j int) bool {
return speakers[i].Weight < speakers[j].Weight
})

var content bytes.Buffer
err = tmpl.Execute(&content, map[string]interface{}{
"ListOfSpeakers": los,
"Speakers": speakers,
"Overlay": overlay,
})
if err != nil {
log.Error().Err(err).Msg("could not execute current-list-of-speakers template")
Expand Down
10 changes: 8 additions & 2 deletions templates/slides/current-list-of-speakers.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
<div class="content">
<div class="content{{if .Overlay}} overlay{{end}}">
{{if .Overlay}}
<h3>
List of speakers
</h3>
{{else}}
<h1 class="projector_h1">
List of speakers
</h1>
{{end}}
<div class="detail-view-text">
{{range $index, $element := .Speakers}}
<div class="speaker">
{{ $index }}. {{$element}}
{{ $element.Number }}. {{ $element.Name }}
</div>
{{end}}
</div>
Expand Down
21 changes: 21 additions & 0 deletions web/projector.css
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@ body {
margin-top: 20px;
}

#slides .slide > .content.overlay {
position: fixed;
right: 50px;
bottom: 20px;
background-color: #d3d3d3;
width: 37%;
height: 210px;
z-index: 20;
border-radius: 7px;
border: 1px solid #999;
padding: 10px 10px 10px 25px;
box-shadow: 3px 3px 10px 1px rgba(0, 0, 0, 0.5);
overflow: hidden;
}

#footer {
position: fixed;
width: 100%;
Expand All @@ -80,6 +95,12 @@ h1 {
padding-bottom: 10px;
}

h3 {
margin-top: 0;
margin-bottom: 10px;
font-weight: 500;
}

#projector-page {
width: 100vw;
height: 100vh;
Expand Down

0 comments on commit 3f923f9

Please sign in to comment.