295 lines
7.6 KiB
Go
295 lines
7.6 KiB
Go
package routes
|
|
|
|
import (
|
|
"embed"
|
|
"html/template"
|
|
"log"
|
|
"math"
|
|
"net/http"
|
|
"slices"
|
|
|
|
"sunshine.industries/some-automoderation/rooms"
|
|
)
|
|
|
|
type brickState struct {
|
|
ColorClass template.CSS
|
|
TemplateType string
|
|
}
|
|
type personData struct {
|
|
Name string
|
|
IsSpeaker bool
|
|
IsMark bool
|
|
IsRaised bool
|
|
Raised rooms.HandGesture
|
|
Mark rooms.HandGesture
|
|
Index int
|
|
}
|
|
|
|
|
|
// data to be passed to "roomPeople" template
|
|
type roomTableData struct {
|
|
*rooms.Room
|
|
currentPerson rooms.PersonId
|
|
}
|
|
|
|
func (room *roomTableData) Persons() []personData {
|
|
total := room.Total()
|
|
persons := make([]personData, 0, total)
|
|
currentPersonIndex := slices.Index(room.Paricipants, room.currentPerson)
|
|
for i, pId := range room.Paricipants {
|
|
personData := personDataFromRoom(room, pId)
|
|
// to have index 0 for 'current person'
|
|
personData.Index = (i - currentPersonIndex + total) % total
|
|
persons = append(persons, personData)
|
|
}
|
|
return persons
|
|
}
|
|
func (r *roomTableData) Total() int {
|
|
return len(r.Paricipants)
|
|
}
|
|
func (r *roomTableData) Tangens() float64 {
|
|
total := r.Total()
|
|
if total == 2 {
|
|
return 1
|
|
}
|
|
if total == 1 {
|
|
return 500
|
|
}
|
|
return math.Tan(math.Pi / float64(r.Total())) // Math.tan(Math.PI/m);
|
|
}
|
|
|
|
type arrowData struct {
|
|
IsVisible bool
|
|
Height, Width int
|
|
Radius int
|
|
StartX, StartY int
|
|
EndX, EndY int
|
|
LargeArcFlag int
|
|
Angle1X, Angle1Y int
|
|
Angle2X, Angle2Y int
|
|
}
|
|
|
|
// arrow data - to draw SVG from current speaker to next speaker
|
|
func (r *roomTableData) ArrowData() arrowData {
|
|
// TODO figure out size to be around the people
|
|
// and this is somewhat a win
|
|
height, width := 150.0, 150.0
|
|
centerX, centerY := height/2, width/2
|
|
total := r.Total()
|
|
// speakerIndex := slices.Index(r.Paricipants, r.CurrentSpeaker)
|
|
currentPersonIndex := slices.Index(r.Paricipants, r.currentPerson)
|
|
nextSpeakerIndex, found, countedFromIndex := r.NextSpeakerIndex()
|
|
if !found {
|
|
return arrowData{}
|
|
}
|
|
startSector := countedFromIndex + total - currentPersonIndex
|
|
endSector := nextSpeakerIndex + total - currentPersonIndex
|
|
if endSector < startSector {
|
|
endSector += total
|
|
}
|
|
radius := 50.0
|
|
startAngle := 90 + float64(startSector)*(360.0/float64(total))
|
|
endAngle := 90 + float64(endSector)*(360.0/float64(total))
|
|
// if need to draw full circle
|
|
if startSector == endSector {
|
|
startAngle += 3 // a bit forward
|
|
endAngle += 357 // ~ a bit backward (almost full circle forward)
|
|
}
|
|
startAngleRad := startAngle * (math.Pi / float64(180))
|
|
endAngleRad := endAngle * (math.Pi / float64(180))
|
|
// endAngle is radius angle, so perpendicular gives direction of teh arrow
|
|
|
|
x1 := centerX + radius*math.Cos(startAngleRad)
|
|
y1 := centerY + radius*math.Sin(startAngleRad)
|
|
x2 := centerX + radius*math.Cos(endAngleRad)
|
|
y2 := centerY + radius*math.Sin(endAngleRad)
|
|
|
|
arrowAngleOffset := math.Pi / 4 // 45 degrees
|
|
arrowPointDirection := endAngleRad - math.Pi/2
|
|
arrowheadLen := 10.0
|
|
arrowMinusAngle := arrowPointDirection - arrowAngleOffset
|
|
arrowPlusAngle := arrowPointDirection + arrowAngleOffset
|
|
arrowMinusEndX := x2 + arrowheadLen*math.Cos(arrowMinusAngle)
|
|
arrowMinusEndY := y2 + arrowheadLen*math.Sin(arrowMinusAngle)
|
|
arrowPlusEndX := x2 + arrowheadLen*math.Cos(arrowPlusAngle)
|
|
arrowPlusEndY := y2 + arrowheadLen*math.Sin(arrowPlusAngle)
|
|
|
|
// indicates that the shorter of the two possible arcs should be used.
|
|
largeArcFlag := 0
|
|
//
|
|
if endAngleRad-startAngleRad > (math.Pi) {
|
|
// specifies that the longer arc should be chosen.
|
|
largeArcFlag = 1
|
|
}
|
|
return arrowData{
|
|
IsVisible: true,
|
|
Height: int(height),
|
|
Width: int(width),
|
|
Radius: int(radius),
|
|
StartX: int(x1),
|
|
StartY: int(y1),
|
|
EndX: int(x2),
|
|
EndY: int(y2),
|
|
LargeArcFlag: largeArcFlag,
|
|
Angle1X: int(arrowMinusEndX),
|
|
Angle1Y: int(arrowMinusEndY),
|
|
Angle2X: int(arrowPlusEndX),
|
|
Angle2Y: int(arrowPlusEndY),
|
|
}
|
|
}
|
|
|
|
func personDataFromRoom(room *roomTableData, pId rooms.PersonId) personData {
|
|
person, exists := room.AllKnownPeople[pId]
|
|
if !exists || !slices.Contains(room.Paricipants, pId) {
|
|
return personData{}
|
|
}
|
|
|
|
hand, handExists := room.ParticipantHands[pId]
|
|
var mark rooms.HandGesture
|
|
var markExists bool
|
|
for gesture := rooms.ChangeTopic; gesture <= rooms.Meta; gesture++ {
|
|
if room.Marks[gesture] == pId {
|
|
markExists = true
|
|
mark = gesture
|
|
}
|
|
}
|
|
isSpeaker := room.CurrentSpeaker == pId
|
|
|
|
return personData{
|
|
Name: person.Name,
|
|
IsSpeaker: isSpeaker,
|
|
IsRaised: handExists,
|
|
Raised: hand,
|
|
IsMark: markExists,
|
|
Mark: mark,
|
|
}
|
|
}
|
|
|
|
func (pData personData) BricksForPerson() []brickState {
|
|
var result = make([]brickState, 5)
|
|
for gesture := rooms.ChangeTopic; gesture <= rooms.Meta; gesture++ {
|
|
// for index := rooms.Meta; index >= rooms.ChangeTopic; index-- {
|
|
// log.Printf(">>>>> iteraging for %d", gesture)
|
|
// this results in iteration 4,3,2,1,0,255 wow
|
|
templateType := "inactiveBrick"
|
|
switch {
|
|
case pData.IsRaised && pData.IsMark && gesture == pData.Raised:
|
|
templateType = "markAndRaisedBrick"
|
|
case pData.IsMark && gesture == pData.Mark:
|
|
templateType = "markBrick"
|
|
case pData.IsSpeaker && gesture == pData.Raised:
|
|
templateType = "speakerBrick"
|
|
case pData.IsRaised && gesture == pData.Raised:
|
|
templateType = "raisedBrick"
|
|
}
|
|
|
|
result[gesture] = brickState{
|
|
ColorClass: gesture.GetGestureInfo().Color,
|
|
TemplateType: templateType,
|
|
}
|
|
}
|
|
|
|
slices.Reverse(result)
|
|
return result
|
|
}
|
|
|
|
func roomTemplatesPreview(
|
|
templateFs *embed.FS,
|
|
) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
type SingleBrickData struct {
|
|
ColorClass template.CSS
|
|
Name string
|
|
Gesture rooms.HandGesture
|
|
}
|
|
|
|
testPersonData := personData{
|
|
Name: "John Doe",
|
|
IsRaised: true,
|
|
Raised: rooms.Expand,
|
|
IsMark: true,
|
|
Mark: rooms.ProbingQ,
|
|
}
|
|
|
|
var person1 = rooms.Person{
|
|
Id: rooms.PersonId(100),
|
|
Name: "test person name 1",
|
|
}
|
|
var person2 = rooms.Person{
|
|
Id: rooms.PersonId(200),
|
|
Name: "test person name 2",
|
|
}
|
|
var person3 = rooms.Person{
|
|
Id: rooms.PersonId(300),
|
|
Name: "test person name 3",
|
|
}
|
|
var person4 = rooms.Person{
|
|
Id: rooms.PersonId(400),
|
|
Name: "test person name 4",
|
|
}
|
|
aRoom := rooms.Room{
|
|
Name: "test",
|
|
CurrentSpeaker: person3.Id,
|
|
AllKnownPeople: map[rooms.PersonId]rooms.Person{
|
|
person1.Id: person1,
|
|
person2.Id: person2,
|
|
person3.Id: person3,
|
|
person4.Id: person4,
|
|
},
|
|
Paricipants: []rooms.PersonId{
|
|
person1.Id,
|
|
person2.Id,
|
|
person3.Id,
|
|
person4.Id,
|
|
},
|
|
ParticipantHands: map[rooms.PersonId]rooms.HandGesture{
|
|
person3.Id: rooms.ClarifyingQ,
|
|
person2.Id: rooms.Meta,
|
|
person4.Id: rooms.ChangeTopic,
|
|
},
|
|
Marks: map[rooms.HandGesture]rooms.PersonId{
|
|
rooms.Expand: person1.Id,
|
|
rooms.ChangeTopic: person4.Id,
|
|
},
|
|
}
|
|
|
|
contentData := struct {
|
|
DefaultColor template.CSS
|
|
Gestures []rooms.HandGesture
|
|
ABrick brickState
|
|
TestPerson personData
|
|
ARoom *roomTableData
|
|
}{
|
|
DefaultColor: "--expand-color",
|
|
ABrick: brickState{
|
|
ColorClass: "--expand-color",
|
|
TemplateType: "raisedBrick",
|
|
},
|
|
Gestures: rooms.GesturesHighToLow[:],
|
|
TestPerson: testPersonData,
|
|
ARoom: &roomTableData{
|
|
Room: &aRoom,
|
|
currentPerson: aRoom.Paricipants[0],
|
|
},
|
|
}
|
|
|
|
pageData := pageData{
|
|
Header: headerData{Title: "look at the room templates"},
|
|
Content: contentData,
|
|
}
|
|
|
|
baseFile := "templates/base.gohtml"
|
|
tmpl := template.Must(template.New("").ParseFS(templateFs, baseFile,
|
|
"templates/tableTemplates.gohtml",
|
|
"templates/tableTemplatesPreview.gohtml",
|
|
))
|
|
|
|
err := tmpl.ExecuteTemplate(w, "full-page", pageData)
|
|
if err != nil {
|
|
log.Printf("yoyo, error %s", err)
|
|
}
|
|
|
|
}
|
|
}
|