Add solo button

This commit is contained in:
Ian Gulliver
2020-11-25 22:41:05 +00:00
parent d7495aa83b
commit 82da61bd86
4 changed files with 112 additions and 32 deletions

71
main.go
View File

@@ -20,21 +20,22 @@ import (
) )
type activeRequest struct { type activeRequest struct {
RoomId string `json:"room_id"` RoomId string `json:"room_id"`
AdminSecret string `json:"admin_secret"` AdminSecret string `json:"admin_secret"`
ClientId string `json:"client_id"` ClientId string `json:"client_id"`
Active bool `json:"active"` Active bool `json:"active"`
Solo bool `json:"solo"`
} }
type adminRequest struct { type adminRequest struct {
RoomId string `json:"room_id"` RoomId string `json:"room_id"`
AdminSecret string `json:"admin_secret"` AdminSecret string `json:"admin_secret"`
ClientId string `json:"client_id"` ClientId string `json:"client_id"`
} }
type resetRequest struct { type resetRequest struct {
RoomId string `json:"room_id"` RoomId string `json:"room_id"`
AdminSecret string `json:"admin_secret"` AdminSecret string `json:"admin_secret"`
} }
type announceRequest struct { type announceRequest struct {
@@ -61,11 +62,11 @@ type removeRequest struct {
} }
type client struct { type client struct {
ClientId string `json:"client_id"` ClientId string `json:"client_id"`
Name string `json:"name"` Name string `json:"name"`
Admin bool `json:"admin"` Admin bool `json:"admin"`
Active bool `json:"active"` Active bool `json:"active"`
ActiveStart int64 `json:"active_start"` ActiveStart int64 `json:"active_start"`
room *room room *room
lastSeen time.Time lastSeen time.Time
@@ -94,10 +95,10 @@ type controlEvent struct {
} }
type room struct { type room struct {
roomId string roomId string
timerStart time.Time timerStart time.Time
clientById map[string]*client clientById map[string]*client
present map[*presentState]bool present map[*presentState]bool
} }
type presentState struct { type presentState struct {
@@ -212,7 +213,7 @@ func active(w http.ResponseWriter, r *http.Request) {
return return
} }
c.Active = req.Active c.Active = req.Active || req.Solo
if c.Active { if c.Active {
c.ActiveStart = time.Now().Unix() c.ActiveStart = time.Now().Unix()
} else { } else {
@@ -222,6 +223,22 @@ func active(w http.ResponseWriter, r *http.Request) {
rm.sendAdminEvent(&adminEvent{ rm.sendAdminEvent(&adminEvent{
Client: c, Client: c,
}) })
if req.Solo {
for _, iter := range rm.clientById {
if iter == c {
continue
}
if iter.Active {
iter.Active = false
iter.ActiveStart = 0
iter.update()
rm.sendAdminEvent(&adminEvent{
Client: iter,
})
}
}
}
} }
func admin(w http.ResponseWriter, r *http.Request) { func admin(w http.ResponseWriter, r *http.Request) {
@@ -476,9 +493,9 @@ func (c *client) remove() {
func (c *client) update() { func (c *client) update() {
e := &event{ e := &event{
StandardEvent: &standardEvent{ StandardEvent: &standardEvent{
Active: c.Active, Active: c.Active,
ActiveStart: c.ActiveStart, ActiveStart: c.ActiveStart,
TimerStart: c.room.timerStart.Unix(), TimerStart: c.room.timerStart.Unix(),
}, },
} }
if c.Admin { if c.Admin {
@@ -489,10 +506,10 @@ func (c *client) update() {
func newRoom(roomId string) *room { func newRoom(roomId string) *room {
return &room{ return &room{
roomId: roomId, roomId: roomId,
timerStart: time.Now(), timerStart: time.Now(),
clientById: map[string]*client{}, clientById: map[string]*client{},
present: map[*presentState]bool{}, present: map[*presentState]bool{},
} }
} }
@@ -514,8 +531,8 @@ func (rm *room) getClient(clientId string) *client {
c := rm.clientById[clientId] c := rm.clientById[clientId]
if c == nil { if c == nil {
c = &client{ c = &client{
ClientId: clientId, ClientId: clientId,
room: rm, room: rm,
} }
rm.clientById[clientId] = c rm.clientById[clientId] = c

View File

@@ -42,7 +42,8 @@ tfoot tr {
} }
.admin, .admin,
.active { .active,
.solo {
cursor: pointer; cursor: pointer;
opacity: 0.3; opacity: 0.3;
user-select: none; user-select: none;

View File

@@ -166,6 +166,7 @@ function renderAdmin(roomId, adminSecret, prnt, es) {
create(head1, "th", "Active Time"); create(head1, "th", "Active Time");
create(head1, "th", "👑"); create(head1, "th", "👑");
create(head1, "th", "👆"); create(head1, "th", "👆");
create(head1, "th", "🌟");
const body = create(table, "tbody"); const body = create(table, "tbody");
const rows = new Map(); const rows = new Map();
es.addEventListener("open", () => { es.addEventListener("open", () => {
@@ -188,6 +189,7 @@ function renderAdmin(roomId, adminSecret, prnt, es) {
} }
row = document.createElement("tr"); row = document.createElement("tr");
row.dataset.name = client.name; row.dataset.name = client.name;
row.dataset.active = client.active ? "active" : "";
row.dataset.activeStart = client.active_start; row.dataset.activeStart = client.active_start;
let before = null; let before = null;
for (const iter of body.children) { for (const iter of body.children) {
@@ -211,9 +213,19 @@ function renderAdmin(roomId, adminSecret, prnt, es) {
}); });
const activeCell = create(row, "td", "👆", client.active ? ["active", "enable"] : ["active"]); const activeCell = create(row, "td", "👆", client.active ? ["active", "enable"] : ["active"]);
activeCell.addEventListener("click", () => { activeCell.addEventListener("click", () => {
active(roomId, adminSecret, client.client_id, !activeCell.classList.contains("enable")); active(roomId, adminSecret, client.client_id, !activeCell.classList.contains("enable"), false);
});
const soloCell = create(row, "td", "🌟", ["solo"]);
soloCell.addEventListener("click", () => {
if (soloCell.classList.contains("enable")) {
active(roomId, adminSecret, client.client_id, false, false);
}
else {
active(roomId, adminSecret, client.client_id, true, true);
}
}); });
rows.set(client.client_id, row); rows.set(client.client_id, row);
setSolo(rows);
}); });
setInterval(() => { setInterval(() => {
const now = new Date(); const now = new Date();
@@ -227,12 +239,29 @@ function renderAdmin(roomId, adminSecret, prnt, es) {
} }
}, 250); }, 250);
} }
function active(roomId, adminSecret, clientId, val) { function setSolo(rows) {
let activeCount = 0;
for (const row of rows.values()) {
if (row.dataset.active === "active") {
activeCount++;
}
}
for (const row of rows.values()) {
if (activeCount === 1 && row.dataset.active === "active") {
row.children[4].classList.add("enable");
}
else {
row.children[4].classList.remove("enable");
}
}
}
function active(roomId, adminSecret, clientId, val, solo) {
const req = { const req = {
room_id: roomId, room_id: roomId,
admin_secret: adminSecret, admin_secret: adminSecret,
client_id: clientId, client_id: clientId,
active: val, active: val,
solo,
}; };
fetch("api/active", { fetch("api/active", {
method: "POST", method: "POST",

View File

@@ -3,6 +3,7 @@ interface ActiveRequest {
admin_secret: string; admin_secret: string;
client_id: string; client_id: string;
active: boolean; active: boolean;
solo: boolean;
} }
interface AdminRequest { interface AdminRequest {
@@ -267,6 +268,7 @@ function renderAdmin(roomId: string, adminSecret: string, prnt: HTMLElement, es:
create(head1, "th", "Active Time"); create(head1, "th", "Active Time");
create(head1, "th", "👑"); create(head1, "th", "👑");
create(head1, "th", "👆"); create(head1, "th", "👆");
create(head1, "th", "🌟");
const body = create(table, "tbody"); const body = create(table, "tbody");
@@ -298,6 +300,7 @@ function renderAdmin(roomId: string, adminSecret: string, prnt: HTMLElement, es:
row = document.createElement("tr") as HTMLTableRowElement; row = document.createElement("tr") as HTMLTableRowElement;
row.dataset.name = client.name; row.dataset.name = client.name;
row.dataset.active = client.active ? "active" : "";
row.dataset.activeStart = client.active_start; row.dataset.activeStart = client.active_start;
let before = null; let before = null;
@@ -325,10 +328,21 @@ function renderAdmin(roomId: string, adminSecret: string, prnt: HTMLElement, es:
const activeCell = create(row, "td", "👆", client.active ? ["active", "enable"] : ["active"]) as HTMLTableCellElement; const activeCell = create(row, "td", "👆", client.active ? ["active", "enable"] : ["active"]) as HTMLTableCellElement;
activeCell.addEventListener("click", () => { activeCell.addEventListener("click", () => {
active(roomId, adminSecret, client.client_id, !activeCell.classList.contains("enable")); active(roomId, adminSecret, client.client_id, !activeCell.classList.contains("enable"), false);
});
const soloCell = create(row, "td", "🌟", ["solo"]) as HTMLTableCellElement;
soloCell.addEventListener("click", () => {
if (soloCell.classList.contains("enable")) {
active(roomId, adminSecret, client.client_id, false, false);
} else {
active(roomId, adminSecret, client.client_id, true, true);
}
}); });
rows.set(client.client_id, row); rows.set(client.client_id, row);
setSolo(rows);
}); });
setInterval(() => { setInterval(() => {
@@ -345,12 +359,31 @@ function renderAdmin(roomId: string, adminSecret: string, prnt: HTMLElement, es:
}, 250); }, 250);
} }
function active(roomId: string, adminSecret: string, clientId: string, val: boolean) { function setSolo(rows: Map<string, HTMLTableRowElement>) {
let activeCount = 0;
for (const row of rows.values()) {
if (row.dataset.active === "active") {
activeCount++;
}
}
for (const row of rows.values()) {
if (activeCount === 1 && row.dataset.active === "active") {
row.children[4].classList.add("enable");
} else {
row.children[4].classList.remove("enable");
}
}
}
function active(roomId: string, adminSecret: string, clientId: string, val: boolean, solo: boolean) {
const req: ActiveRequest = { const req: ActiveRequest = {
room_id: roomId, room_id: roomId,
admin_secret: adminSecret, admin_secret: adminSecret,
client_id: clientId, client_id: clientId,
active: val, active: val,
solo,
}; };
fetch("api/active", { fetch("api/active", {