From bc3a306c00d1ed89fce8346ee1ee737cfd0d19bd Mon Sep 17 00:00:00 2001
From: Sebastian Mark <smark@posteo.net>
Date: Sat, 19 Oct 2024 18:15:16 +0200
Subject: [PATCH 1/5] feat: add pause and resume functionality
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- implement pause and resume commands in the Pomodoro package
- modify timer logic to handle paused state
- adjust client command handling for pause and resume actions
- update HTML to include pause/resume button

🤖
---
 index.html                            | 39 ++++++++++++++++++++++++---
 internal/pomodoro/pomodoro.go         | 31 ++++++++++++++++++++-
 internal/pomodoro/timer.go            | 35 +++++++++++++-----------
 internal/websocket/client_commands.go | 11 +++++++-
 4 files changed, 94 insertions(+), 22 deletions(-)

diff --git a/index.html b/index.html
index 58fa15c..5bde13c 100644
--- a/index.html
+++ b/index.html
@@ -23,12 +23,14 @@
 	<h1>Pomodoro Timer</h1>
 	<div id="timer">Connecting to server...</div>
 
-	<!-- Buttons to start and stop the timer -->
+	<!-- Buttons to start, pause/resume, and stop the timer -->
 	<button id="startButton">Start</button>
-	<button id="stopButton">Stop</button>
+	<button id="pauseResumeButton" style="display: none;">Pause</button>
+	<button id="stopButton" style="display: none;">Stop</button>
 
 	<script>
 		var ws = new WebSocket("ws://localhost:8080/ws");
+		var isPaused = false; // Track if the timer is paused
 
 		ws.onopen = function () {
 			document.getElementById("timer").innerText = "Connected to server.";
@@ -57,14 +59,43 @@
 			return minutes.toString().padStart(2, '0') + ":" + remainingSeconds.toString().padStart(2, '0');
 		}
 
-		// Send start command to the server
+		// Start Button Click Event
 		document.getElementById("startButton").addEventListener("click", function () {
 			ws.send(JSON.stringify({command: "start"}));
+
+			// Hide start button and show pause/resume and stop buttons
+			document.getElementById("startButton").style.display = "none";
+			document.getElementById("pauseResumeButton").style.display = "inline-block";
+			document.getElementById("stopButton").style.display = "inline-block";
+
+			// Set the pause/resume button to show "Pause" initially
+			isPaused = false;
+			document.getElementById("pauseResumeButton").innerText = "Pause";
 		});
 
-		// Send stop command to the server
+		// Pause/Resume Button Click Event
+		document.getElementById("pauseResumeButton").addEventListener("click", function () {
+			if (isPaused) {
+				// If paused, send resume command and update button text
+				ws.send(JSON.stringify({command: "resume"}));
+				document.getElementById("pauseResumeButton").innerText = "Pause";
+				isPaused = false;
+			} else {
+				// If running, send pause command and update button text
+				ws.send(JSON.stringify({command: "pause"}));
+				document.getElementById("pauseResumeButton").innerText = "Resume";
+				isPaused = true;
+			}
+		});
+
+		// Stop Button Click Event
 		document.getElementById("stopButton").addEventListener("click", function () {
 			ws.send(JSON.stringify({command: "stop"}));
+
+			// Reset buttons after stopping
+			document.getElementById("startButton").style.display = "inline-block";
+			document.getElementById("pauseResumeButton").style.display = "none";
+			document.getElementById("stopButton").style.display = "none";
 		});
 	</script>
 </body>
diff --git a/internal/pomodoro/pomodoro.go b/internal/pomodoro/pomodoro.go
index 65705fe..3010244 100644
--- a/internal/pomodoro/pomodoro.go
+++ b/internal/pomodoro/pomodoro.go
@@ -13,12 +13,20 @@ const (
 )
 
 var pomodoroRunning bool
+var pomodoroPaused bool
+
+var pomodoroStopChannel = make(chan bool, 1)
+var pomodoroPauseChannel = make(chan bool, 1)
+var pomodoroResumeChannel = make(chan bool, 1)
+
 var mu sync.Mutex // to synchronize access to shared state
 
 // RunPomodoroTimer iterates the Pomodoro work/break sessions.
 func RunPomodoroTimer(clients map[*websocket.Conn]bool) {
 	mu.Lock()
 	pomodoroRunning = true
+	pomodoroPaused = false
+	mu.Unlock()
 
 	for session := 1; session <= sessions; session++ {
 		if !startTimer(clients, workDuration, "Work", session) {
@@ -35,11 +43,32 @@ func RunPomodoroTimer(clients map[*websocket.Conn]bool) {
 		}
 	}
 
+	mu.Lock()
 	pomodoroRunning = false
 	mu.Unlock()
 }
 
-// IsPomodoroRunning returns the status of the timer.
+// StopPomodoro sends a signal to stop the running Pomodoro timer.
+func StopPomodoro() {
+	pomodoroStopChannel <- true
+}
+
+func PausePomodoro() {
+	pomodoroPauseChannel <- true
+}
+
+func ResumePomodoro() {
+	pomodoroResumeChannel <- true
+}
+
 func IsPomodoroRunning() bool {
+	mu.Lock()
+	defer mu.Unlock() // Ensures that the mutex is unlocked after the function is done
 	return pomodoroRunning
 }
+
+func IsPomodoroPaused() bool {
+	mu.Lock()
+	defer mu.Unlock() // Ensures that the mutex is unlocked after the function is done
+	return pomodoroPaused
+}
diff --git a/internal/pomodoro/timer.go b/internal/pomodoro/timer.go
index c7d931b..28a7f09 100644
--- a/internal/pomodoro/timer.go
+++ b/internal/pomodoro/timer.go
@@ -7,24 +7,32 @@ import (
 	"time"
 )
 
-var timerStopChannel = make(chan bool, 1)
-
 // startTimer runs the countdown and broadcasts every second.
 func startTimer(clients map[*websocket.Conn]bool, remainingSeconds int, mode string, session int) bool {
 	for remainingSeconds > 0 {
 		select {
-		case <-timerStopChannel:
+		case <-pomodoroStopChannel:
 			return false // Stop the timer if a stop command is received
+		case <-pomodoroPauseChannel:
+			mu.Lock()
+			pomodoroPaused = true
+			mu.Unlock()
+		case <-pomodoroResumeChannel:
+			mu.Lock()
+			pomodoroPaused = false
+			mu.Unlock()
 		default:
 			// Broadcast the current state to all clients
-			broadcast.BroadcastMessage(clients, models.BroadcastMessage{
-				Mode:       mode,
-				Session:    session,
-				MaxSession: sessions,
-				TimeLeft:   remainingSeconds,
-			})
-			time.Sleep(time.Second)
-			remainingSeconds--
+			if !pomodoroPaused {
+				broadcast.BroadcastMessage(clients, models.BroadcastMessage{
+					Mode:       mode,
+					Session:    session,
+					MaxSession: sessions,
+					TimeLeft:   remainingSeconds,
+				})
+				time.Sleep(time.Second)
+				remainingSeconds--
+			}
 		}
 	}
 
@@ -38,8 +46,3 @@ func startTimer(clients map[*websocket.Conn]bool, remainingSeconds int, mode str
 
 	return true
 }
-
-// StopTimer sends a signal to stop the running Pomodoro timer.
-func StopTimer() {
-	timerStopChannel <- true
-}
diff --git a/internal/websocket/client_commands.go b/internal/websocket/client_commands.go
index 41855bf..74f2b4a 100644
--- a/internal/websocket/client_commands.go
+++ b/internal/websocket/client_commands.go
@@ -34,8 +34,17 @@ func handleClientCommands(ws *websocket.Conn) {
 			}
 		case "stop":
 			if pomodoro.IsPomodoroRunning() {
-				pomodoro.StopTimer() // Stop the timer in the Pomodoro package
+				pomodoro.StopPomodoro() // Stop the timer in the Pomodoro package
+			}
+		case "pause":
+			if pomodoro.IsPomodoroRunning() && !pomodoro.IsPomodoroPaused() {
+				pomodoro.PausePomodoro() // Pause the timer
+			}
+		case "resume":
+			if pomodoro.IsPomodoroRunning() && pomodoro.IsPomodoroPaused() {
+				pomodoro.ResumePomodoro() // Resume the timer
 			}
 		}
+
 	}
 }

From ffc6913344213ebfb7c891b29aba04ca1efaf040 Mon Sep 17 00:00:00 2001
From: Sebastian Mark <smark@posteo.net>
Date: Sun, 20 Oct 2024 10:02:00 +0200
Subject: [PATCH 2/5] break: change the "stop" command to "reset"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- change stop channel to reset channel
- create ResetPomodoro function
- broadcast reset message to all clients
- rename stop button to reset button in index.html

🤖
---
 index.html                            | 10 +++++-----
 internal/pomodoro/pomodoro.go         | 24 ++++++++++++++++++++----
 internal/pomodoro/timer.go            |  4 ++--
 internal/websocket/client_commands.go |  2 +-
 4 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/index.html b/index.html
index 5bde13c..248ca61 100644
--- a/index.html
+++ b/index.html
@@ -26,7 +26,7 @@
 	<!-- Buttons to start, pause/resume, and stop the timer -->
 	<button id="startButton">Start</button>
 	<button id="pauseResumeButton" style="display: none;">Pause</button>
-	<button id="stopButton" style="display: none;">Stop</button>
+	<button id="resetButton" style="display: none;">Reset</button>
 
 	<script>
 		var ws = new WebSocket("ws://localhost:8080/ws");
@@ -66,7 +66,7 @@
 			// Hide start button and show pause/resume and stop buttons
 			document.getElementById("startButton").style.display = "none";
 			document.getElementById("pauseResumeButton").style.display = "inline-block";
-			document.getElementById("stopButton").style.display = "inline-block";
+			document.getElementById("resetButton").style.display = "inline-block";
 
 			// Set the pause/resume button to show "Pause" initially
 			isPaused = false;
@@ -88,14 +88,14 @@
 			}
 		});
 
-		// Stop Button Click Event
-		document.getElementById("stopButton").addEventListener("click", function () {
+		// Reset Button Click Event
+		document.getElementById("resetButton").addEventListener("click", function () {
 			ws.send(JSON.stringify({command: "stop"}));
 
 			// Reset buttons after stopping
 			document.getElementById("startButton").style.display = "inline-block";
 			document.getElementById("pauseResumeButton").style.display = "none";
-			document.getElementById("stopButton").style.display = "none";
+			document.getElementById("resetButton").style.display = "none";
 		});
 	</script>
 </body>
diff --git a/internal/pomodoro/pomodoro.go b/internal/pomodoro/pomodoro.go
index 3010244..6297d45 100644
--- a/internal/pomodoro/pomodoro.go
+++ b/internal/pomodoro/pomodoro.go
@@ -1,6 +1,8 @@
 package pomodoro
 
 import (
+	"git.smsvc.net/pomodoro/GoTomato/internal/broadcast"
+	"git.smsvc.net/pomodoro/GoTomato/pkg/models"
 	"github.com/gorilla/websocket"
 	"sync"
 )
@@ -15,7 +17,7 @@ const (
 var pomodoroRunning bool
 var pomodoroPaused bool
 
-var pomodoroStopChannel = make(chan bool, 1)
+var pomodoroResetChannel = make(chan bool, 1)
 var pomodoroPauseChannel = make(chan bool, 1)
 var pomodoroResumeChannel = make(chan bool, 1)
 
@@ -48,9 +50,23 @@ func RunPomodoroTimer(clients map[*websocket.Conn]bool) {
 	mu.Unlock()
 }
 
-// StopPomodoro sends a signal to stop the running Pomodoro timer.
-func StopPomodoro() {
-	pomodoroStopChannel <- true
+// ResetPomodoro resets the running Pomodoro timer.
+func ResetPomodoro(clients map[*websocket.Conn]bool) {
+	mu.Lock()
+	pomodoroRunning = false // Reset the running state
+	pomodoroPaused = false  // Reset the paused state
+	mu.Unlock()
+
+	// Broadcast the reset message to all clients
+	broadcast.BroadcastMessage(clients, models.BroadcastMessage{
+		Mode:       "none",
+		Session:    0,
+		MaxSession: 0,
+		TimeLeft:   0,
+	})
+
+	// Send a reset signal to stop any running timers
+	pomodoroResetChannel <- true
 }
 
 func PausePomodoro() {
diff --git a/internal/pomodoro/timer.go b/internal/pomodoro/timer.go
index 28a7f09..6a8e39b 100644
--- a/internal/pomodoro/timer.go
+++ b/internal/pomodoro/timer.go
@@ -11,8 +11,8 @@ import (
 func startTimer(clients map[*websocket.Conn]bool, remainingSeconds int, mode string, session int) bool {
 	for remainingSeconds > 0 {
 		select {
-		case <-pomodoroStopChannel:
-			return false // Stop the timer if a stop command is received
+		case <-pomodoroResetChannel:
+			return false
 		case <-pomodoroPauseChannel:
 			mu.Lock()
 			pomodoroPaused = true
diff --git a/internal/websocket/client_commands.go b/internal/websocket/client_commands.go
index 74f2b4a..50fab15 100644
--- a/internal/websocket/client_commands.go
+++ b/internal/websocket/client_commands.go
@@ -34,7 +34,7 @@ func handleClientCommands(ws *websocket.Conn) {
 			}
 		case "stop":
 			if pomodoro.IsPomodoroRunning() {
-				pomodoro.StopPomodoro() // Stop the timer in the Pomodoro package
+				pomodoro.ResetPomodoro(Clients) // Reset Pomodoro
 			}
 		case "pause":
 			if pomodoro.IsPomodoroRunning() && !pomodoro.IsPomodoroPaused() {

From 4471c86a0cf340178639ef97e331a14d11cb8df2 Mon Sep 17 00:00:00 2001
From: Sebastian Mark <smark@posteo.net>
Date: Sun, 20 Oct 2024 11:06:37 +0200
Subject: [PATCH 3/5] fix: prevent concurrent write to websocket connection
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- refactor client handling and message broadcasting
- replace Client struct
- implement SendMessage method in Client struct for safer message sending
- update client map to use *models.Client instead of bool
- adjust BroadcastMessage and RunPomodoroTimer functions to use new client type

🤖
---
 internal/broadcast/broadcast.go          |  9 ++++---
 internal/pomodoro/pomodoro.go            |  4 ++--
 internal/pomodoro/timer.go               |  2 +-
 internal/websocket/client_commands.go    | 12 ++++++++++
 internal/websocket/handle_connections.go |  8 +++----
 pkg/models/{types.go => broadcast.go}    |  5 ----
 pkg/models/client.go                     | 30 ++++++++++++++++++++++++
 7 files changed, 53 insertions(+), 17 deletions(-)
 rename pkg/models/{types.go => broadcast.go} (75%)
 create mode 100644 pkg/models/client.go

diff --git a/internal/broadcast/broadcast.go b/internal/broadcast/broadcast.go
index deb3010..229ae67 100644
--- a/internal/broadcast/broadcast.go
+++ b/internal/broadcast/broadcast.go
@@ -8,7 +8,7 @@ import (
 )
 
 // BroadcastMessage sends a message to all connected WebSocket clients.
-func BroadcastMessage(clients map[*websocket.Conn]bool, message models.BroadcastMessage) {
+func BroadcastMessage(clients map[*websocket.Conn]*models.Client, message models.BroadcastMessage) {
 	// Marshal the message into JSON format
 	jsonMessage, err := json.Marshal(message)
 	if err != nil {
@@ -17,12 +17,11 @@ func BroadcastMessage(clients map[*websocket.Conn]bool, message models.Broadcast
 	}
 
 	// Iterate over all connected clients and broadcast the message
-	for client := range clients {
-		err := client.WriteMessage(websocket.TextMessage, jsonMessage)
+	for _, client := range clients {
+		err := client.SendMessage(websocket.TextMessage, jsonMessage)
 		if err != nil {
 			log.Printf("Error broadcasting to client: %v", err)
-			client.Close()
-			delete(clients, client) // Remove the client if an error occurs
+			// The client is responsible for closing itself on error
 		}
 	}
 }
diff --git a/internal/pomodoro/pomodoro.go b/internal/pomodoro/pomodoro.go
index 6297d45..0cf8514 100644
--- a/internal/pomodoro/pomodoro.go
+++ b/internal/pomodoro/pomodoro.go
@@ -24,7 +24,7 @@ var pomodoroResumeChannel = make(chan bool, 1)
 var mu sync.Mutex // to synchronize access to shared state
 
 // RunPomodoroTimer iterates the Pomodoro work/break sessions.
-func RunPomodoroTimer(clients map[*websocket.Conn]bool) {
+func RunPomodoroTimer(clients map[*websocket.Conn]*models.Client) {
 	mu.Lock()
 	pomodoroRunning = true
 	pomodoroPaused = false
@@ -51,7 +51,7 @@ func RunPomodoroTimer(clients map[*websocket.Conn]bool) {
 }
 
 // ResetPomodoro resets the running Pomodoro timer.
-func ResetPomodoro(clients map[*websocket.Conn]bool) {
+func ResetPomodoro(clients map[*websocket.Conn]*models.Client) {
 	mu.Lock()
 	pomodoroRunning = false // Reset the running state
 	pomodoroPaused = false  // Reset the paused state
diff --git a/internal/pomodoro/timer.go b/internal/pomodoro/timer.go
index 6a8e39b..b71f770 100644
--- a/internal/pomodoro/timer.go
+++ b/internal/pomodoro/timer.go
@@ -8,7 +8,7 @@ import (
 )
 
 // startTimer runs the countdown and broadcasts every second.
-func startTimer(clients map[*websocket.Conn]bool, remainingSeconds int, mode string, session int) bool {
+func startTimer(clients map[*websocket.Conn]*models.Client, remainingSeconds int, mode string, session int) bool {
 	for remainingSeconds > 0 {
 		select {
 		case <-pomodoroResetChannel:
diff --git a/internal/websocket/client_commands.go b/internal/websocket/client_commands.go
index 50fab15..91ee750 100644
--- a/internal/websocket/client_commands.go
+++ b/internal/websocket/client_commands.go
@@ -6,10 +6,22 @@ import (
 	"git.smsvc.net/pomodoro/GoTomato/pkg/models"
 	"github.com/gorilla/websocket"
 	"log"
+	"sync"
 )
 
+// Clients is a map of connected WebSocket clients, where each client is represented by the Client struct
+var Clients = make(map[*websocket.Conn]*models.Client)
+var mu sync.Mutex // Mutex to protect access to the Clients map
+
 // handleClientCommands listens for commands from WebSocket clients and dispatches to the timer.
 func handleClientCommands(ws *websocket.Conn) {
+	// Create a new Client and add it to the Clients map
+	mu.Lock()
+	Clients[ws] = &models.Client{
+		Conn: ws,
+	}
+	mu.Unlock()
+
 	for {
 		_, message, err := ws.ReadMessage()
 		if err != nil {
diff --git a/internal/websocket/handle_connections.go b/internal/websocket/handle_connections.go
index a7d6cfc..0b8f63e 100644
--- a/internal/websocket/handle_connections.go
+++ b/internal/websocket/handle_connections.go
@@ -1,14 +1,12 @@
 package websocket
 
 import (
+	"git.smsvc.net/pomodoro/GoTomato/pkg/models"
 	"github.com/gorilla/websocket"
 	"log"
 	"net/http"
 )
 
-// Map to track connected clients
-var Clients = make(map[*websocket.Conn]bool)
-
 // Upgrader to upgrade HTTP requests to WebSocket connections
 var upgrader = websocket.Upgrader{
 	CheckOrigin: func(r *http.Request) bool { return true },
@@ -25,7 +23,9 @@ func HandleConnections(w http.ResponseWriter, r *http.Request) {
 	defer ws.Close()
 
 	// Register the new client
-	Clients[ws] = true
+	Clients[ws] = &models.Client{
+		Conn: ws, // Store the WebSocket connection
+	}
 
 	// Listen for commands from the connected client
 	handleClientCommands(ws)
diff --git a/pkg/models/types.go b/pkg/models/broadcast.go
similarity index 75%
rename from pkg/models/types.go
rename to pkg/models/broadcast.go
index ea04e21..78463b9 100644
--- a/pkg/models/types.go
+++ b/pkg/models/broadcast.go
@@ -7,8 +7,3 @@ type BroadcastMessage struct {
 	MaxSession int    `json:"max_session"` // Total number of sessions
 	TimeLeft   int    `json:"time_left"`   // Remaining time in seconds
 }
-
-// ClientCommand represents a command from the client (start/stop).
-type ClientCommand struct {
-	Command string `json:"command"`
-}
diff --git a/pkg/models/client.go b/pkg/models/client.go
new file mode 100644
index 0000000..8d5c3e9
--- /dev/null
+++ b/pkg/models/client.go
@@ -0,0 +1,30 @@
+package models
+
+import (
+	"github.com/gorilla/websocket"
+	"log"
+	"sync"
+)
+
+// ClientCommand represents a command from the client (start/stop).
+type ClientCommand struct {
+	Command string `json:"command"`
+}
+
+type Client struct {
+	Conn  *websocket.Conn
+	Mutex sync.Mutex
+}
+
+// It automatically locks and unlocks the mutex to ensure that only one goroutine can write at a time.
+func (c *Client) SendMessage(messageType int, data []byte) error {
+	c.Mutex.Lock()
+	defer c.Mutex.Unlock()
+
+	err := c.Conn.WriteMessage(messageType, data)
+	if err != nil {
+		log.Printf("Error writing to WebSocket: %v", err)
+		c.Conn.Close() // Close the connection on error
+	}
+	return err
+}

From b62e92b5a402384f64205576003dd3891a86d169 Mon Sep 17 00:00:00 2001
From: Sebastian Mark <smark@posteo.net>
Date: Sun, 20 Oct 2024 11:26:23 +0200
Subject: [PATCH 4/5] fix: resolve race condition in pause/resume check

- replace direct check of pomodoroPaused with IsPomodoroPaused function
---
 internal/pomodoro/timer.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/internal/pomodoro/timer.go b/internal/pomodoro/timer.go
index b71f770..69627c3 100644
--- a/internal/pomodoro/timer.go
+++ b/internal/pomodoro/timer.go
@@ -23,7 +23,7 @@ func startTimer(clients map[*websocket.Conn]*models.Client, remainingSeconds int
 			mu.Unlock()
 		default:
 			// Broadcast the current state to all clients
-			if !pomodoroPaused {
+			if !IsPomodoroPaused() {
 				broadcast.BroadcastMessage(clients, models.BroadcastMessage{
 					Mode:       mode,
 					Session:    session,

From 3d5cb29c54b2a17455e20189695706c381a28dbb Mon Sep 17 00:00:00 2001
From: Sebastian Mark <smark@posteo.net>
Date: Sun, 20 Oct 2024 11:27:28 +0200
Subject: [PATCH 5/5] chore: cleanup pause/resume functions

---
 internal/pomodoro/pomodoro.go | 7 +++++++
 internal/pomodoro/timer.go    | 8 ++------
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/internal/pomodoro/pomodoro.go b/internal/pomodoro/pomodoro.go
index 0cf8514..c8a3b03 100644
--- a/internal/pomodoro/pomodoro.go
+++ b/internal/pomodoro/pomodoro.go
@@ -70,10 +70,17 @@ func ResetPomodoro(clients map[*websocket.Conn]*models.Client) {
 }
 
 func PausePomodoro() {
+	mu.Lock()
+	pomodoroPaused = true
+	mu.Unlock()
+
 	pomodoroPauseChannel <- true
 }
 
 func ResumePomodoro() {
+	mu.Lock()
+	pomodoroPaused = false
+	mu.Unlock()
 	pomodoroResumeChannel <- true
 }
 
diff --git a/internal/pomodoro/timer.go b/internal/pomodoro/timer.go
index 69627c3..96595b3 100644
--- a/internal/pomodoro/timer.go
+++ b/internal/pomodoro/timer.go
@@ -14,13 +14,9 @@ func startTimer(clients map[*websocket.Conn]*models.Client, remainingSeconds int
 		case <-pomodoroResetChannel:
 			return false
 		case <-pomodoroPauseChannel:
-			mu.Lock()
-			pomodoroPaused = true
-			mu.Unlock()
+			// Nothing to set here, just waiting for the signal
 		case <-pomodoroResumeChannel:
-			mu.Lock()
-			pomodoroPaused = false
-			mu.Unlock()
+			// Nothing to set here, just waiting for the signal
 		default:
 			// Broadcast the current state to all clients
 			if !IsPomodoroPaused() {