Skip to content

Commit 7a682aa

Browse files
authored
Merge pull request #17 from KalleLindblad/main
Added toggle to hide chat and change between SM/VM
2 parents 0f60dec + d8d9981 commit 7a682aa

File tree

8 files changed

+200
-5
lines changed

8 files changed

+200
-5
lines changed

cards-SM.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const smExclusive = [
1717
`Någon jämkar sig`,
1818
`SM börjar minst 15 min sent`,
1919
`"SMingo!"`,
20+
`Kandidat/motionär presenterar i max 20 sekunder`,
2021
`SM tar mer än 2 timmar`,
2122
`SM tar mer än 4 timmar`,
2223
`Styrelsen har smugit in en oseriös att-sats`,

cards-VM.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@ import commonCards from "./cards.ts";
33
const vmExclusive = [
44
`Et val är klart på under 5 minuter`,
55
`En val tar mer än 30 minuter`,
6-
`Folk blir påminda att fokusera på valkandidaternas positiva sidor`,
76
`"Hej VM!"`,
87
`Kandidat presenterar i max 20 sekunder`,
9-
`Någon däremot? "Nej"`,
108
`VM börjar minst 15 min sent`,
119
`"VMingo!"`,
1210
`VM tar mer än 3 timmar`,
1311
`Valkandidat dyker inte upp på VM`,
1412
`"Ni har ju alla läst valhandlingarna men ..."`,
13+
`Det saknas kandidater, vakantställning`,
1514
];
1615

1716
export default [...commonCards, ...vmExclusive];

cards.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
const commonCards = [
22
`Ändring i föredragningslistan`,
3-
`Det saknas kandidater, vakantställning`,
43
`Det sker en sakupplysning`,
54
`"Det var bättre förr"`,
65
`Diskussion på samma punkt över en timme`,
@@ -41,13 +40,13 @@ const commonCards = [
4140
`Elektroniskt röstningssystem strular`,
4241
`Wikipediasidan för Schulze visas på skärmen`,
4342
`"De här borde lösas bättre till nästa år"`,
44-
`Kandidat/motionär presenterar i max 20 sekunder`,
4543
`Talman börjar argumentera för en ståndpunkt i sakfråga`,
4644
`Talman citerar mötesordningen fel`,
4745
`Talman glömmer vilken punkt mötet är på`,
4846
`Talman mumlar`,
4947
`Talman suckar högljutt åt någons förslag`,
5048
`Ordningsfråga`,
49+
`Någon däremot? "Nej"`,
5150
];
5251

5352
export default commonCards;

components/AdminPage.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ const AdminPage: FC = () => (
2525
<option value="updated">Recently updated</option>
2626
</select>
2727
</label>
28+
<label class="admin-field">
29+
<span class="admin-label">Card Set</span>
30+
<select id="cardSetToggle" class="admin-input">
31+
<option value="VM">VM (Valmöte)</option>
32+
<option value="SM">SM (Sektionsmöte)</option>
33+
</select>
34+
</label>
2835
</div>
2936
</section>
3037
<div class="admin-content">

components/HomePage.tsx

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,49 @@ const HomePage: FC<HomePageProps> = ({
7272
}
7373
})();
7474
`.replace(/</g, "\u003c");
75+
76+
const toggleScript = `
77+
(() => {
78+
const STORAGE_KEY_UI = 'smingo_hide_ui';
79+
80+
const chatPanel = document.querySelector('.chat-panel');
81+
const highlightBanner = document.getElementById('highlightBanner');
82+
const toggleBtn = document.getElementById('toggleUI');
83+
84+
// Load saved preference
85+
const uiHidden = localStorage.getItem(STORAGE_KEY_UI) === 'true';
86+
87+
function updateUIVisibility(hidden) {
88+
if (chatPanel) {
89+
chatPanel.style.display = hidden ? 'none' : '';
90+
chatPanel.setAttribute('aria-hidden', hidden ? 'true' : 'false');
91+
}
92+
if (highlightBanner) {
93+
highlightBanner.style.display = hidden ? 'none' : '';
94+
highlightBanner.setAttribute('aria-hidden', hidden ? 'true' : 'false');
95+
}
96+
if (toggleBtn) {
97+
toggleBtn.classList.toggle('ui-toggle-button--hidden', hidden);
98+
toggleBtn.title = hidden ? 'Show chat and banner' : 'Hide chat and banner';
99+
toggleBtn.textContent = hidden ? '💬' : '✖️';
100+
}
101+
102+
localStorage.setItem(STORAGE_KEY_UI, hidden.toString());
103+
}
104+
105+
// Set initial state
106+
updateUIVisibility(uiHidden);
107+
108+
// Add event listener
109+
if (toggleBtn) {
110+
toggleBtn.addEventListener('click', () => {
111+
const isCurrentlyHidden = chatPanel && chatPanel.style.display === 'none';
112+
updateUIVisibility(!isCurrentlyHidden);
113+
});
114+
}
115+
})();
116+
`.replace(/</g, "\u003c");
117+
75118
const boardNavItems: readonly BoardNavbarItem[] = [
76119
{ id: "bingo", label: "Bräde" },
77120
{ id: "toplist", label: "Topplista" },
@@ -95,6 +138,15 @@ const HomePage: FC<HomePageProps> = ({
95138
</header>
96139
<div class="home-columns">
97140
<ChatPanel userId={userDisplayName} />
141+
<button
142+
id="toggleUI"
143+
type="button"
144+
class="ui-toggle-button"
145+
title="Toggle chat and banner"
146+
aria-label="Toggle chat panel and banner"
147+
>
148+
✖️
149+
</button>
98150
<section
99151
id="boardSection"
100152
class="board-section"
@@ -118,6 +170,10 @@ const HomePage: FC<HomePageProps> = ({
118170
type="module"
119171
dangerouslySetInnerHTML={{ __html: boardNavScript }}
120172
></script>
173+
<script
174+
type="module"
175+
dangerouslySetInnerHTML={{ __html: toggleScript }}
176+
></script>
121177
<script type="module" src="/assets/chat-app.js"></script>
122178
</div>
123179
);

main.tsx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import Layout from "./components/Layout.tsx";
99
import HomePage from "./components/HomePage.tsx";
1010
import AdminPage from "./components/AdminPage.tsx";
1111
import TalmanPage from "./components/TalmanPage.tsx";
12-
import cards from "./cards-SM.ts";
12+
import cardsVM from "./cards-VM.ts";
13+
import cardsSM from "./cards-SM.ts";
1314
import { setupAdminSocket, setupPlayerSocket } from "./server/chat.ts";
1415
import { handleUploadRequest } from "./server/upload.ts";
1516
import { cookieSecret, DEV_MODE, loginRedirectUrl } from "./server/config.ts";
@@ -21,6 +22,9 @@ import {
2122
} from "./server/auth.ts";
2223
import { createSeededRandom } from "./server/random.ts";
2324

25+
// Global configuration state
26+
let currentCardSet: "VM" | "SM" = "SM"; // Default to SM
27+
2428
const smingoCss = Deno.readTextFileSync(
2529
new URL("./public/smingo.css", import.meta.url),
2630
);
@@ -45,6 +49,25 @@ app.post("/api/upload", async (c: Context) => {
4549
return handleUploadRequest(c);
4650
});
4751

52+
// API endpoints for card set management
53+
app.get("/api/cardset", async (c: Context) => {
54+
const session = await ensureAdminSession(c);
55+
if (session instanceof Response) return session;
56+
return c.json({ cardSet: currentCardSet });
57+
});
58+
59+
app.post("/api/cardset", async (c: Context) => {
60+
const session = await ensureAdminSession(c);
61+
if (session instanceof Response) return session;
62+
63+
const body = await c.req.json();
64+
if (body.cardSet === "SM" || body.cardSet === "VM") {
65+
currentCardSet = body.cardSet;
66+
return c.json({ success: true, cardSet: currentCardSet });
67+
}
68+
return c.json({ success: false, error: "Invalid card set" }, 400);
69+
});
70+
4871
app.get("/assets/smingo.css", () =>
4972
new Response(smingoCss, {
5073
headers: {
@@ -124,6 +147,7 @@ app.get("/callback/:code", async (c: Context) => {
124147
});
125148

126149
app.get("/", async (c: Context) => {
150+
const cards = currentCardSet === "SM" ? cardsSM : cardsVM;
127151
const things = cards.toSorted();
128152

129153
const session = await ensurePlayerSession(c);

public/js/admin-app.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
const detailEl = document.getElementById("adminDetail");
66
const searchInput = document.getElementById("adminSearch");
77
const sortSelect = document.getElementById("adminSort");
8+
const cardSetToggle = document.getElementById("cardSetToggle");
89
const socketUrl =
910
(window.location.protocol === "https:" ? "wss://" : "ws://") +
1011
window.location.host + "/ws?role=admin";
@@ -510,6 +511,50 @@
510511
});
511512
}
512513

514+
// Card set toggle functionality
515+
async function loadCardSet() {
516+
try {
517+
const response = await fetch('/api/cardset');
518+
if (response.ok) {
519+
const data = await response.json();
520+
if (cardSetToggle) {
521+
cardSetToggle.value = data.cardSet;
522+
}
523+
}
524+
} catch (error) {
525+
console.error('Failed to load card set:', error);
526+
}
527+
}
528+
529+
async function saveCardSet(cardSet) {
530+
try {
531+
const response = await fetch('/api/cardset', {
532+
method: 'POST',
533+
headers: {
534+
'Content-Type': 'application/json',
535+
},
536+
body: JSON.stringify({ cardSet }),
537+
});
538+
if (response.ok) {
539+
console.log(`Card set changed to: ${cardSet}`);
540+
} else {
541+
console.error('Failed to save card set');
542+
}
543+
} catch (error) {
544+
console.error('Failed to save card set:', error);
545+
}
546+
}
547+
548+
if (cardSetToggle) {
549+
cardSetToggle.addEventListener("change", () => {
550+
const newCardSet = cardSetToggle.value;
551+
saveCardSet(newCardSet);
552+
});
553+
}
554+
555+
// Load initial card set
556+
loadCardSet();
557+
513558
connect();
514559

515560
window.addEventListener("beforeunload", () => {

public/smingo.css

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,70 @@ body {
5757
margin-bottom: 4px;
5858
}
5959

60+
.player-meta {
61+
display: flex;
62+
align-items: center;
63+
gap: 8px;
64+
}
65+
66+
.ui-toggle-button {
67+
position: fixed;
68+
top: 20px;
69+
left: 340px;
70+
z-index: 1000;
71+
background: rgba(255, 255, 255, 0.95);
72+
border: 2px solid #ddd;
73+
border-radius: 50%;
74+
padding: 0;
75+
width: 36px;
76+
height: 36px;
77+
font-size: 16px;
78+
cursor: pointer;
79+
transition: all 0.3s ease;
80+
display: flex;
81+
align-items: center;
82+
justify-content: center;
83+
backdrop-filter: blur(4px);
84+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
85+
}
86+
87+
.ui-toggle-button:hover {
88+
background: rgba(240, 240, 240, 0.95);
89+
border-color: #bbb;
90+
transform: scale(1.05);
91+
}
92+
93+
.ui-toggle-button--hidden {
94+
position: fixed;
95+
top: 20px;
96+
left: 20px;
97+
background: rgba(0, 122, 204, 0.95);
98+
border-color: #007acc;
99+
color: white;
100+
}
101+
102+
.ui-toggle-button--hidden:hover {
103+
background: rgba(0, 90, 153, 0.95);
104+
border-color: #005a99;
105+
}
106+
107+
@media (max-width: 960px) {
108+
.ui-toggle-button {
109+
left: 16px;
110+
top: 16px;
111+
width: 32px;
112+
height: 32px;
113+
font-size: 14px;
114+
}
115+
116+
.ui-toggle-button--hidden {
117+
top: 16px;
118+
left: 16px;
119+
width: 32px;
120+
height: 32px;
121+
}
122+
}
123+
60124
.highlight-banner {
61125
position: relative;
62126
width: 100%;

0 commit comments

Comments
 (0)