neiam
/koco
public · Issues · Pulls · Labels · Forks · Compare · Actions failure · Badges · Packages
⭐
Log in to mark this repository.
fmt
6b0f8c2 · gmorell · 2026-01-12 02:44
Files changed
modified
src/main.rs
+42
−34
@@ -144,7 +144,7 @@ struct ConfigUIState {
| 144 | 144 | new_password: String, |
| 145 | 145 | new_events: bool, |
| 146 | 146 | new_events_port: String, |
| 147 | − | |
| 147 | + | |
| 148 | 148 | // For MQTT config |
| 149 | 149 | mqtt_enabled: bool, |
| 150 | 150 | mqtt_host: String, |
@@ -163,7 +163,7 @@ impl ConfigUIState {
| 163 | 163 | self.events = instance.events; |
| 164 | 164 | self.events_port = instance.events_port.to_string(); |
| 165 | 165 | } |
| 166 | − | |
| 166 | + | |
| 167 | 167 | fn load_mqtt_config(&mut self, config: &KocoConfig) { |
| 168 | 168 | self.mqtt_enabled = config.mqtt_enabled; |
| 169 | 169 | self.mqtt_host = config.mqtt_host.clone(); |
@@ -521,7 +521,7 @@ impl Koco {
| 521 | 521 | if !config.instances.is_empty() { |
| 522 | 522 | config_ui_state.load_from_instance(&config.instances[0]); |
| 523 | 523 | } |
| 524 | − | |
| 524 | + | |
| 525 | 525 | config_ui_state.load_mqtt_config(&config); |
| 526 | 526 | |
| 527 | 527 | let now_playing = Arc::new(Mutex::new(NowPlaying::default())); |
@@ -860,21 +860,20 @@ impl Koco {
| 860 | 860 | while let Some(msg_opt) = stream.next().await { |
| 861 | 861 | if let Some(msg) = msg_opt { |
| 862 | 862 | info!("Received MQTT message: {}", msg.payload_str()); |
| 863 | − | |
| 864 | 863 | // Parse the theme payload |
| 865 | 864 | if let Ok(payload) = serde_json::from_str::<serde_json::Value>(&msg.payload_str()) { |
| 866 | 865 | if let Some(theme_name) = payload.get("theme").and_then(|t| t.as_str()) { |
| 867 | 866 | info!("Received theme update: {}", theme_name); |
| 868 | − | |
| 867 | + | |
| 869 | 868 | // Update config with new theme |
| 870 | 869 | if let Ok(mut cfg) = config.lock() { |
| 871 | 870 | // Search for theme by name (case-insensitive) |
| 872 | 871 | let matching_theme = cfg.themes.iter() |
| 873 | 872 | .find(|t| t.name.eq_ignore_ascii_case(theme_name)); |
| 874 | − | |
| 873 | + | |
| 875 | 874 | if let Some(theme) = matching_theme { |
| 876 | 875 | let theme_name_found = theme.name.clone(); |
| 877 | − | |
| 876 | + | |
| 878 | 877 | if cfg.current_theme != theme_name_found { |
| 879 | 878 | cfg.current_theme = theme_name_found.clone(); |
| 880 | 879 | if let Err(e) = cfg.save() { |
@@ -1164,13 +1163,16 @@ impl Koco {
| 1164 | 1163 | // MQTT Configuration |
| 1165 | 1164 | ui.heading("MQTT Theme Synchronization"); |
| 1166 | 1165 | ui.add_space(5.0); |
| 1167 | − | |
| 1166 | + | |
| 1168 | 1167 | ui.label("Subscribe to theme updates from theme-sender"); |
| 1169 | 1168 | ui.add_space(10.0); |
| 1170 | − | |
| 1171 | − ui.checkbox(&mut self.config_ui_state.mqtt_enabled, "Enable MQTT Subscription"); | |
| 1169 | + | |
| 1170 | + ui.checkbox( | |
| 1171 | + &mut self.config_ui_state.mqtt_enabled, | |
| 1172 | + "Enable MQTT Subscription", | |
| 1173 | + ); | |
| 1172 | 1174 | ui.add_space(10.0); |
| 1173 | − | |
| 1175 | + | |
| 1174 | 1176 | if self.config_ui_state.mqtt_enabled { |
| 1175 | 1177 | ui.horizontal(|ui| { |
| 1176 | 1178 | ui.label("MQTT Host:"); |
@@ -1178,45 +1180,51 @@ impl Koco {
| 1178 | 1180 | }); |
| 1179 | 1181 | ui.label("Example: tcp://localhost:1883"); |
| 1180 | 1182 | ui.add_space(5.0); |
| 1181 | − | |
| 1183 | + | |
| 1182 | 1184 | ui.horizontal(|ui| { |
| 1183 | 1185 | ui.label("Topic:"); |
| 1184 | 1186 | ui.text_edit_singleline(&mut self.config_ui_state.mqtt_topic); |
| 1185 | 1187 | }); |
| 1186 | 1188 | ui.label("Example: neiam/sync/theme"); |
| 1187 | 1189 | ui.add_space(5.0); |
| 1188 | − | |
| 1190 | + | |
| 1189 | 1191 | ui.horizontal(|ui| { |
| 1190 | 1192 | ui.label("Username (optional):"); |
| 1191 | − ui.text_edit_singleline(&mut self.config_ui_state.mqtt_username); | |
| 1193 | + ui.text_edit_singleline( | |
| 1194 | + &mut self.config_ui_state.mqtt_username, | |
| 1195 | + ); | |
| 1192 | 1196 | }); |
| 1193 | − | |
| 1197 | + | |
| 1194 | 1198 | ui.horizontal(|ui| { |
| 1195 | 1199 | ui.label("Password (optional):"); |
| 1196 | 1200 | ui.add( |
| 1197 | − egui::TextEdit::singleline(&mut self.config_ui_state.mqtt_password) | |
| 1198 | − .password(true), | |
| 1201 | + egui::TextEdit::singleline( | |
| 1202 | + &mut self.config_ui_state.mqtt_password, | |
| 1203 | + ) | |
| 1204 | + .password(true), | |
| 1199 | 1205 | ); |
| 1200 | 1206 | }); |
| 1201 | 1207 | } |
| 1202 | − | |
| 1208 | + | |
| 1203 | 1209 | ui.add_space(15.0); |
| 1204 | − | |
| 1210 | + | |
| 1205 | 1211 | if ui.button("Save MQTT Configuration").clicked() { |
| 1206 | 1212 | self.config.mqtt_enabled = self.config_ui_state.mqtt_enabled; |
| 1207 | 1213 | self.config.mqtt_host = self.config_ui_state.mqtt_host.clone(); |
| 1208 | 1214 | self.config.mqtt_topic = self.config_ui_state.mqtt_topic.clone(); |
| 1209 | − self.config.mqtt_username = if self.config_ui_state.mqtt_username.is_empty() { | |
| 1210 | − None | |
| 1211 | − } else { | |
| 1212 | − Some(self.config_ui_state.mqtt_username.clone()) | |
| 1213 | − }; | |
| 1214 | − self.config.mqtt_password = if self.config_ui_state.mqtt_password.is_empty() { | |
| 1215 | − None | |
| 1216 | − } else { | |
| 1217 | − Some(self.config_ui_state.mqtt_password.clone()) | |
| 1218 | − }; | |
| 1219 | − | |
| 1215 | + self.config.mqtt_username = | |
| 1216 | + if self.config_ui_state.mqtt_username.is_empty() { | |
| 1217 | + None | |
| 1218 | + } else { | |
| 1219 | + Some(self.config_ui_state.mqtt_username.clone()) | |
| 1220 | + }; | |
| 1221 | + self.config.mqtt_password = | |
| 1222 | + if self.config_ui_state.mqtt_password.is_empty() { | |
| 1223 | + None | |
| 1224 | + } else { | |
| 1225 | + Some(self.config_ui_state.mqtt_password.clone()) | |
| 1226 | + }; | |
| 1227 | + | |
| 1220 | 1228 | if let Err(e) = self.config.save() { |
| 1221 | 1229 | warn!("Failed to save config: {}", e); |
| 1222 | 1230 | } else { |
@@ -1260,12 +1268,12 @@ impl eframe::App for Koco {
| 1260 | 1268 | ctx.request_repaint(); |
| 1261 | 1269 | } |
| 1262 | 1270 | } |
| 1263 | − | |
| 1271 | + | |
| 1264 | 1272 | // Request periodic repaints to check for MQTT theme updates |
| 1265 | 1273 | if self.config.mqtt_enabled { |
| 1266 | 1274 | ctx.request_repaint_after(std::time::Duration::from_millis(100)); |
| 1267 | 1275 | } |
| 1268 | − | |
| 1276 | + | |
| 1269 | 1277 | // Update window title with now-playing info |
| 1270 | 1278 | let window_title = if let Ok(np) = self.now_playing.lock() { |
| 1271 | 1279 | if !np.title.is_empty() { |
@@ -1289,7 +1297,7 @@ impl eframe::App for Koco {
| 1289 | 1297 | // Handle mouse scroll events for volume control |
| 1290 | 1298 | ctx.input(|i| { |
| 1291 | 1299 | let scroll_delta = i.smooth_scroll_delta.y; |
| 1292 | − | |
| 1300 | + | |
| 1293 | 1301 | if scroll_delta > 0.0 { |
| 1294 | 1302 | // Scroll up = volume up |
| 1295 | 1303 | if let Err(e) = instance.send_key("volumeup") { |
@@ -1302,7 +1310,7 @@ impl eframe::App for Koco {
| 1302 | 1310 | } |
| 1303 | 1311 | } |
| 1304 | 1312 | }); |
| 1305 | − | |
| 1313 | + | |
| 1306 | 1314 | // Handle keyboard input including Page Up/Down for volume |
| 1307 | 1315 | ctx.input(|i| { |
| 1308 | 1316 | if i.key_pressed(egui::Key::PageUp) |
Parents: 4b251af