Want to contribute? Fork me on Codeberg.org!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

77 lines
1.9 KiB

package clients
import (
"fmt"
"git.elnu.com/ElnuDev/jichanorg/httputils"
)
type Client = chan []httputils.SseEvent
const EventWord = "word"
const EventPlayerCount = "players"
const EventNavigate = "navigate"
type ClientSet struct {
clients map[Client]bool
}
func NewClientSet() ClientSet {
return ClientSet{make(map[Client]bool)}
}
func (clients ClientSet) Broadcast(events ...httputils.SseEvent) {
for client := range clients.clients {
client <- events
}
}
func (clients ClientSet) PlayerCount() int {
return len(clients.clients)
}
func (clients ClientSet) PlayerCountEvent(offset int) httputils.SseEvent {
playerCount := clients.PlayerCount() + offset
var data string
if playerCount == 0 {
data = "No players online."
} else {
data = fmt.Sprintf("%d player%s online.", playerCount, map[bool]string{true: "", false: "s"}[playerCount == 1])
}
return httputils.SseEvent{EventName: EventPlayerCount, Data: data}
}
func (clients ClientSet) BroadcastPlayerCount(offset int) {
clients.Broadcast(clients.PlayerCountEvent(offset))
}
func (clients ClientSet) BroadcastWord(word string) {
clients.Broadcast(
httputils.SseEvent{
EventName: EventWord,
Data: fmt.Sprintf("<div>%s</div>", word),
},
httputils.SseEvent{
EventName: EventNavigate,
Data: fmt.Sprintf("https://jisho.org/search/%s", word),
},
)
}
func (clients ClientSet) Connect(client Client) {
// Channels are blocking.
// Client initialization is waiting for connect() to complete.
// If we try to braodcast to it before connect() is done,
// the channel handling logic wouldn't have started yet,
// and broadcast() would be freeze.
// Therefore, we must broadcast an offset player count first,
// then actually add the client.
clients.BroadcastPlayerCount(1)
clients.clients[client] = true
}
func (clients ClientSet) Disconnect(client Client) {
delete(clients.clients, client)
clients.BroadcastPlayerCount(0)
}