feat: logout route and button
This commit is contained in:
parent
1297fcf35d
commit
83e81ec011
|
@ -117,6 +117,16 @@ gestureIteration:
|
||||||
r.CurrentSpeaker = nextSpeakerId
|
r.CurrentSpeaker = nextSpeakerId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Room) PersonToStandUpFromTable(p PersonId) {
|
||||||
|
r.ReleaseHand(p)
|
||||||
|
if slices.Contains(r.Paricipants, p) {
|
||||||
|
updated := slices.DeleteFunc(r.Paricipants, func(sittingPerson PersonId) bool {
|
||||||
|
return sittingPerson == p
|
||||||
|
})
|
||||||
|
r.Paricipants = updated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// find place to start - separate function
|
// find place to start - separate function
|
||||||
// current speaker level, searched gesture level, room marks
|
// current speaker level, searched gesture level, room marks
|
||||||
// if search level >= current speaker start from speaker
|
// if search level >= current speaker start from speaker
|
||||||
|
|
|
@ -4,7 +4,12 @@ type baseData struct {
|
||||||
Title string
|
Title string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type headerData struct {
|
||||||
|
Title string
|
||||||
|
}
|
||||||
|
|
||||||
type pageData struct {
|
type pageData struct {
|
||||||
Base baseData
|
Base baseData
|
||||||
Content interface {}
|
Content any
|
||||||
|
Header headerData
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,10 +30,13 @@ func indexPageRoute(
|
||||||
SessionToken sessions.SessionData
|
SessionToken sessions.SessionData
|
||||||
}
|
}
|
||||||
|
|
||||||
data := pageData {
|
data := pageData{
|
||||||
Base: baseData{
|
Base: baseData{
|
||||||
Title: "hello base template title",
|
Title: "hello base template title",
|
||||||
},
|
},
|
||||||
|
Header: headerData{
|
||||||
|
Title: session.RoomId,
|
||||||
|
},
|
||||||
Content: MainData{
|
Content: MainData{
|
||||||
fmt.Sprintf("%+v", session),
|
fmt.Sprintf("%+v", session),
|
||||||
"hello!",
|
"hello!",
|
||||||
|
|
|
@ -7,7 +7,9 @@ import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"sunshine.industries/some-automoderation/rooms"
|
"sunshine.industries/some-automoderation/rooms"
|
||||||
"sunshine.industries/some-automoderation/sessions"
|
"sunshine.industries/some-automoderation/sessions"
|
||||||
|
@ -30,6 +32,8 @@ func registerLoginRoutes(
|
||||||
http.HandleFunc("/login/join", joinRoomHandler(templateFs, sessionSM, roomsM))
|
http.HandleFunc("/login/join", joinRoomHandler(templateFs, sessionSM, roomsM))
|
||||||
http.HandleFunc("/login/create", createRoomHandler(templateFs, sessionSM, roomsM))
|
http.HandleFunc("/login/create", createRoomHandler(templateFs, sessionSM, roomsM))
|
||||||
http.HandleFunc("/login/room-name-check", checkRoomName(templateFs, roomsM))
|
http.HandleFunc("/login/room-name-check", checkRoomName(templateFs, roomsM))
|
||||||
|
http.Handle("/logout", authedPageMiddleware(sessionSM,
|
||||||
|
http.HandlerFunc(logoutRoute(sessionSM, roomsM))))
|
||||||
}
|
}
|
||||||
|
|
||||||
const authCookieName = "auth"
|
const authCookieName = "auth"
|
||||||
|
@ -89,7 +93,7 @@ func renderLoginPage(w http.ResponseWriter) {
|
||||||
baseFile := "templates/base.gohtml"
|
baseFile := "templates/base.gohtml"
|
||||||
templFile := "templates/login.gohtml"
|
templFile := "templates/login.gohtml"
|
||||||
tmpl := template.Must(template.ParseFS(templateFs, templFile, baseFile))
|
tmpl := template.Must(template.ParseFS(templateFs, templFile, baseFile))
|
||||||
data := pageData {
|
data := pageData{
|
||||||
Base: baseData{
|
Base: baseData{
|
||||||
Title: "login",
|
Title: "login",
|
||||||
},
|
},
|
||||||
|
@ -138,7 +142,7 @@ func createRoomHandler(templateFs *embed.FS,
|
||||||
log.Printf("what am i to do? error saving room %s", err)
|
log.Printf("what am i to do? error saving room %s", err)
|
||||||
// todo return error notice somehow
|
// todo return error notice somehow
|
||||||
}
|
}
|
||||||
newSessionId, err := sessionSM.Save(newRoom.Name, person.Id)
|
newSessionId, err := sessionSM.Save(r.Context(), newRoom.Name, person.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("what am i to do? error saving session %s", err)
|
log.Printf("what am i to do? error saving session %s", err)
|
||||||
// todo return error notice somehow
|
// todo return error notice somehow
|
||||||
|
@ -261,7 +265,10 @@ func joinRoomHandler(templateFs *embed.FS,
|
||||||
|
|
||||||
err = roomsM.Update(r.Context(), room.Name, func(fromRoom rooms.Room) (toRoom rooms.Room) {
|
err = roomsM.Update(r.Context(), room.Name, func(fromRoom rooms.Room) (toRoom rooms.Room) {
|
||||||
toRoom = fromRoom
|
toRoom = fromRoom
|
||||||
|
if !slices.Contains(toRoom.Paricipants, person.Id) {
|
||||||
|
// consequtive login from additional devices
|
||||||
toRoom.Paricipants = append(toRoom.Paricipants, person.Id)
|
toRoom.Paricipants = append(toRoom.Paricipants, person.Id)
|
||||||
|
}
|
||||||
return toRoom
|
return toRoom
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -272,7 +279,7 @@ func joinRoomHandler(templateFs *embed.FS,
|
||||||
return // error sitting a new person
|
return // error sitting a new person
|
||||||
}
|
}
|
||||||
|
|
||||||
newSessionId, err := sessionSM.Save(room.Name, person.Id)
|
newSessionId, err := sessionSM.Save(r.Context(), room.Name, person.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("/login/submit > error saving session %s", err)
|
log.Printf("/login/submit > error saving session %s", err)
|
||||||
}
|
}
|
||||||
|
@ -291,3 +298,41 @@ func joinRoomHandler(templateFs *embed.FS,
|
||||||
w.Header().Add("HX-Redirect", "/")
|
w.Header().Add("HX-Redirect", "/")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func logoutRoute(sessionSM sessions.SessionManagement,
|
||||||
|
roomsM rooms.RoomManager) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
session, found := getContextSession(r.Context())
|
||||||
|
if !found {
|
||||||
|
log.Printf("/logout session not found, it's ok.")
|
||||||
|
// though this is under middleware for now, should be impossible
|
||||||
|
// TODO return error i guess
|
||||||
|
w.Header().Add("HX-Redirect", "/")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
http.SetCookie(w, &http.Cookie{
|
||||||
|
Name: authCookieName,
|
||||||
|
Expires: time.Now().Add(-time.Hour),
|
||||||
|
Value: "",
|
||||||
|
Secure: true,
|
||||||
|
HttpOnly: true,
|
||||||
|
Path: "/",
|
||||||
|
})
|
||||||
|
err := sessionSM.Remove(r.Context(), session.SessionId)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("/logout error deleting session: %s", err)
|
||||||
|
}
|
||||||
|
err = roomsM.Update(r.Context(), session.RoomId, func(fromRoom rooms.Room) (toRoom rooms.Room) {
|
||||||
|
toRoom = fromRoom
|
||||||
|
toRoom.PersonToStandUpFromTable(session.PersonId)
|
||||||
|
return toRoom
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("/logout error removing person from table: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("/logout deleting session %+v", session)
|
||||||
|
|
||||||
|
w.Header().Add("HX-Redirect", "/")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -223,6 +223,9 @@ func roomPageRoute(
|
||||||
Title: "room-lala-from-base",
|
Title: "room-lala-from-base",
|
||||||
},
|
},
|
||||||
Content: contentData,
|
Content: contentData,
|
||||||
|
Header: headerData{
|
||||||
|
Title: room.Name,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err = tmpl.ExecuteTemplate(w, "full-page", data)
|
err = tmpl.ExecuteTemplate(w, "full-page", data)
|
||||||
|
|
|
@ -550,6 +550,10 @@ video {
|
||||||
display: grid;
|
display: grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.h-14 {
|
||||||
|
height: 3.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.h-full {
|
.h-full {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
@ -562,6 +566,10 @@ video {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flex-none {
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
|
||||||
.grid-cols-2 {
|
.grid-cols-2 {
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
}
|
}
|
||||||
|
@ -641,10 +649,25 @@ video {
|
||||||
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bg-yellow-200 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(254 240 138 / var(--tw-bg-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
.p-4 {
|
.p-4 {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.px-2 {
|
||||||
|
padding-left: 0.5rem;
|
||||||
|
padding-right: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.py-1 {
|
||||||
|
padding-top: 0.25rem;
|
||||||
|
padding-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
.text-xl {
|
.text-xl {
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
line-height: 1.75rem;
|
line-height: 1.75rem;
|
||||||
|
|
|
@ -22,7 +22,16 @@
|
||||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||||
<!-- Place favicon.ico in the root directory -->
|
<!-- Place favicon.ico in the root directory -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body
|
||||||
|
class="flex flex-col"
|
||||||
|
>
|
||||||
|
<nav class="bg-yellow-200 flex-none h-14">
|
||||||
|
{{if .Header.Title}} Room name: "{{.Header.Title}}"{{end}}
|
||||||
|
<button
|
||||||
|
class="bg-white border-2 rounded py-1 px-2"
|
||||||
|
hx-get="/logout"
|
||||||
|
>Logout</button>
|
||||||
|
</nav>
|
||||||
<!--[if lt IE 8]>
|
<!--[if lt IE 8]>
|
||||||
<p class="browserupgrade">
|
<p class="browserupgrade">
|
||||||
You are using an <strong>outdated</strong> browser. Please
|
You are using an <strong>outdated</strong> browser. Please
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
<div id="controls" class="bg-green-300">
|
<div id="controls" class="bg-green-300">
|
||||||
<p>Room name is "{{ .Room.Name }}"</p>
|
|
||||||
{{ range .Gestures }}
|
{{ range .Gestures }}
|
||||||
<button
|
<button
|
||||||
hx-get="{{ .Url }}"
|
hx-get="{{ .Url }}"
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
|
||||||
"sunshine.industries/some-automoderation/rooms"
|
"sunshine.industries/some-automoderation/rooms"
|
||||||
|
|
||||||
|
@ -19,11 +20,10 @@ type SessionData struct {
|
||||||
|
|
||||||
type SessionManagement interface {
|
type SessionManagement interface {
|
||||||
Get(sessionId int) SessionData
|
Get(sessionId int) SessionData
|
||||||
Save(roomName string, personId rooms.PersonId) (int, error)
|
Save(ctx context.Context, roomName string, personId rooms.PersonId) (int, error)
|
||||||
|
Remove(ctx context.Context, sessionId int) error
|
||||||
}
|
}
|
||||||
|
|
||||||
var ctx = context.Background()
|
|
||||||
|
|
||||||
const sessionPrefix = "session"
|
const sessionPrefix = "session"
|
||||||
|
|
||||||
func sessionIdToKey(sessionId int) string {
|
func sessionIdToKey(sessionId int) string {
|
||||||
|
@ -37,7 +37,7 @@ type RedisSM struct {
|
||||||
func (redisSM RedisSM) Get(sessionId int) SessionData {
|
func (redisSM RedisSM) Get(sessionId int) SessionData {
|
||||||
var foundSession SessionData
|
var foundSession SessionData
|
||||||
redisKey := sessionIdToKey(sessionId)
|
redisKey := sessionIdToKey(sessionId)
|
||||||
err := redisSM.Rdb.HGetAll(ctx, redisKey).Scan(&foundSession)
|
err := redisSM.Rdb.HGetAll(context.TODO(), redisKey).Scan(&foundSession)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("> error reading %s : %s", redisKey, err)
|
log.Printf("> error reading %s : %s", redisKey, err)
|
||||||
return SessionData{}
|
return SessionData{}
|
||||||
|
@ -45,7 +45,7 @@ func (redisSM RedisSM) Get(sessionId int) SessionData {
|
||||||
log.Printf("> successfully found %d %+v", sessionId, foundSession)
|
log.Printf("> successfully found %d %+v", sessionId, foundSession)
|
||||||
return foundSession
|
return foundSession
|
||||||
}
|
}
|
||||||
func (redisSM RedisSM) Save(roomName string, personId rooms.PersonId) (int, error) {
|
func (redisSM RedisSM) Save(ctx context.Context, roomName string, personId rooms.PersonId) (int, error) {
|
||||||
randId := rand.Int()
|
randId := rand.Int()
|
||||||
newSession := SessionData{
|
newSession := SessionData{
|
||||||
SessionId: randId,
|
SessionId: randId,
|
||||||
|
@ -53,6 +53,8 @@ func (redisSM RedisSM) Save(roomName string, personId rooms.PersonId) (int, erro
|
||||||
PersonId: personId,
|
PersonId: personId,
|
||||||
}
|
}
|
||||||
err := redisSM.Rdb.HSet(ctx, sessionIdToKey(randId), newSession).Err()
|
err := redisSM.Rdb.HSet(ctx, sessionIdToKey(randId), newSession).Err()
|
||||||
|
redisSM.Rdb.Expire(ctx, sessionIdToKey(randId), 24 * time.Hour)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("> error! saving session %+v %s", newSession, err)
|
log.Printf("> error! saving session %+v %s", newSession, err)
|
||||||
return 0, fmt.Errorf("error saving new session: %+v with %s", newSession, err)
|
return 0, fmt.Errorf("error saving new session: %+v with %s", newSession, err)
|
||||||
|
@ -60,13 +62,22 @@ func (redisSM RedisSM) Save(roomName string, personId rooms.PersonId) (int, erro
|
||||||
return randId, nil
|
return randId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (redisSM RedisSM) Remove(ctx context.Context, sessionId int) error {
|
||||||
|
err := redisSM.Rdb.Del(ctx, sessionIdToKey(sessionId)).Err()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
type DummySM struct{}
|
type DummySM struct{}
|
||||||
|
|
||||||
func (d DummySM) Get(sessionId int) SessionData {
|
func (d DummySM) Get(sessionId int) SessionData {
|
||||||
log.Printf("get dummy session by %d", sessionId)
|
log.Printf("get dummy session by %d", sessionId)
|
||||||
return SessionData{}
|
return SessionData{}
|
||||||
}
|
}
|
||||||
func (d DummySM) Save(roomName string, personId rooms.PersonId) (int, error) {
|
func (d DummySM) Save(ctx context.Context, roomName string, personId rooms.PersonId) (int, error) {
|
||||||
log.Printf("save dummy session with %s %d", roomName, personId)
|
log.Printf("save dummy session with %s %d", roomName, personId)
|
||||||
return 1, nil
|
return 1, nil
|
||||||
}
|
}
|
||||||
|
func (d DummySM) Remove(ctx context.Context, sessionId int) error {
|
||||||
|
log.Printf("deleting session %d", sessionId)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue