summaryrefslogtreecommitdiffstats
path: root/gui/src/app.rs
diff options
context:
space:
mode:
Diffstat (limited to 'gui/src/app.rs')
-rw-r--r--gui/src/app.rs79
1 files changed, 30 insertions, 49 deletions
diff --git a/gui/src/app.rs b/gui/src/app.rs
index f0efd3e..af64e5e 100644
--- a/gui/src/app.rs
+++ b/gui/src/app.rs
@@ -49,6 +49,7 @@ pub struct ZaganApp {
49 notices: VecDeque<Notice>, 49 notices: VecDeque<Notice>,
50 awaiting: Option<Instant>, 50 awaiting: Option<Instant>,
51 need_info: bool, 51 need_info: bool,
52 was_logged_in: bool,
52 pending_login: Option<(String, String)>, 53 pending_login: Option<(String, String)>,
53 /// Displayed balance while a result animation runs: stake deducted, no 54 /// Displayed balance while a result animation runs: stake deducted, no
54 /// winnings yet. The view already knows the outcome; the player must not. 55 /// winnings yet. The view already knows the outcome; the player must not.
@@ -62,7 +63,6 @@ struct Session {
62 host: String, 63 host: String,
63 fingerprint: Option<String>, 64 fingerprint: Option<String>,
64 ping_ms: f32, 65 ping_ms: f32,
65 server_version: String,
66 latest: String, 66 latest: String,
67 url: String, 67 url: String,
68 user: Option<String>, 68 user: Option<String>,
@@ -186,6 +186,7 @@ impl ZaganApp {
186 notices: VecDeque::new(), 186 notices: VecDeque::new(),
187 awaiting: None, 187 awaiting: None,
188 need_info: false, 188 need_info: false,
189 was_logged_in: false,
189 pending_login: None, 190 pending_login: None,
190 balance_hold: None, 191 balance_hold: None,
191 balance: None, 192 balance: None,
@@ -348,7 +349,7 @@ impl ZaganApp {
348 reply, 349 reply,
349 }); 350 });
350 } 351 }
351 Event::Connected(connected) => self.connected(ctx, connected), 352 Event::Connected(connected) => self.connected(connected),
352 Event::Failed { 353 Event::Failed {
353 addr, 354 addr,
354 failure, 355 failure,
@@ -376,7 +377,7 @@ impl ZaganApp {
376 } 377 }
377 } 378 }
378 379
379 fn connected(&mut self, ctx: &Context, connected: Connected) { 380 fn connected(&mut self, connected: Connected) {
380 self.connect.pending = false; 381 self.connect.pending = false;
381 self.connect.error = None; 382 self.connect.error = None;
382 self.core.set_connected(true); 383 self.core.set_connected(true);
@@ -393,19 +394,14 @@ impl ZaganApp {
393 host: connected.addr, 394 host: connected.addr,
394 fingerprint: connected.fingerprint, 395 fingerprint: connected.fingerprint,
395 ping_ms: connected.elapsed_ms, 396 ping_ms: connected.elapsed_ms,
396 server_version: connected.server_version,
397 latest: connected.latest, 397 latest: connected.latest,
398 url: connected.url, 398 url: connected.url,
399 user: connected.user, 399 user: connected.user,
400 }); 400 });
401 401
402 self.need_info = self.session.as_ref().is_some_and(|s| s.user.is_some()); 402 self.need_info = false;
403 self.was_logged_in = false;
403 self.account = None; 404 self.account = None;
404 if self.need_info {
405 let effects = self.core.command(Command::Info);
406 self.apply(ctx, effects);
407 self.need_info = false;
408 }
409 } 405 }
410 406
411 fn failed(&mut self, addr: String, failure: Failure, message: String) { 407 fn failed(&mut self, addr: String, failure: Failure, message: String) {
@@ -511,7 +507,6 @@ impl ZaganApp {
511 let command = if registering { 507 let command = if registering {
512 Command::Register { user, credential } 508 Command::Register { user, credential }
513 } else { 509 } else {
514 self.need_info = true;
515 if self.login.remember { 510 if self.login.remember {
516 self.pending_login = Some((user.clone(), credential.clone())); 511 self.pending_login = Some((user.clone(), credential.clone()));
517 } 512 }
@@ -522,19 +517,26 @@ impl ZaganApp {
522 } 517 }
523 518
524 fn tick(&mut self, ctx: &Context) { 519 fn tick(&mut self, ctx: &Context) {
525 // Request deadline, mirroring the terminal's socket timeout. 520 // Fetch the account and balance once each time a session signs in.
526 if self.need_info 521 let signed_in = self
527 && self 522 .core
528 .session 523 .view()
529 .as_ref() 524 .as_ref()
530 .is_some_and(|session| session.user.is_some()) 525 .is_some_and(|view| matches!(view, View::Lobby(lobby) if lobby.user.is_some()));
531 && self.account.is_none() 526 if signed_in != self.was_logged_in {
532 { 527 self.was_logged_in = signed_in;
528 if signed_in {
529 self.need_info = true;
530 }
531 }
532 if self.need_info && signed_in {
533 let effects = self.core.command(Command::Info); 533 let effects = self.core.command(Command::Info);
534 self.apply(ctx, effects); 534 self.apply(ctx, effects);
535 self.need_info = false; 535 self.need_info = false;
536 } 536 }
537 537
538 // Request deadline, mirroring the terminal's socket timeout.
539
538 if let Some(sent) = self.awaiting { 540 if let Some(sent) = self.awaiting {
539 if sent.elapsed() > REQUEST_TIMEOUT { 541 if sent.elapsed() > REQUEST_TIMEOUT {
540 self.awaiting = None; 542 self.awaiting = None;
@@ -1351,13 +1353,7 @@ fn lobby_screen(ui: &mut Ui, app: &mut ZaganApp, lobby: &LobbyView) {
1351 ui.add_space(theme::SPACE_2); 1353 ui.add_space(theme::SPACE_2);
1352 ui.horizontal(|ui| { 1354 ui.horizontal(|ui| {
1353 if let Some(session) = &app.session { 1355 if let Some(session) = &app.session {
1354 widgets::note( 1356 widgets::note(ui, &format!("Signed in to {}", session.host));
1355 ui,
1356 &format!(
1357 "Signed in to {} · server v{}",
1358 session.host, session.server_version
1359 ),
1360 );
1361 } 1357 }
1362 ui.with_layout(Layout::right_to_left(Align::Center), |ui| { 1358 ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
1363 if widgets::ghost(ui, "Forget saved login") { 1359 if widgets::ghost(ui, "Forget saved login") {
@@ -1396,15 +1392,9 @@ fn game_card(ui: &mut Ui, app: &mut ZaganApp, key: &str, name: &str) {
1396 .font(theme::sans(22.0)) 1392 .font(theme::sans(22.0))
1397 .color(theme::TEXT), 1393 .color(theme::TEXT),
1398 ); 1394 );
1399 ui.add_space(2.0);
1400 widgets::note(ui, tagline(key));
1401 ui.add_space(theme::SPACE_1); 1395 ui.add_space(theme::SPACE_1);
1402 ui.label( 1396 widgets::note(ui, how_to(key));
1403 RichText::new(meta(key)) 1397 ui.add_space(theme::SPACE_4);
1404 .font(theme::mono(10.0))
1405 .color(theme::TEXT_FAINT),
1406 );
1407 ui.add_space(theme::SPACE_3);
1408 if widgets::primary(ui, "PLAY", true, 110.0, 36.0) { 1398 if widgets::primary(ui, "PLAY", true, 110.0, 36.0) {
1409 let effects = app.core.command(Command::Play { 1399 let effects = app.core.command(Command::Play {
1410 game: key.to_string(), 1400 game: key.to_string(),
@@ -1415,22 +1405,13 @@ fn game_card(ui: &mut Ui, app: &mut ZaganApp, key: &str, name: &str) {
1415 }); 1405 });
1416} 1406}
1417 1407
1418fn tagline(game: &str) -> &'static str { 1408/// One plain sentence: how to play, not the house's rules sheet.
1419 match game { 1409fn how_to(game: &str) -> &'static str {
1420 "slots" => "Five reels, five paylines, one lever.",
1421 "roulette" => "The European wheel, thirty-seven pockets.",
1422 "blackjack" => "Six decks, dealer stands on seventeen. Pays 3:2.",
1423 "crash" => "The multiplier rises. Cash out before it busts.",
1424 _ => "",
1425 }
1426}
1427
1428fn meta(game: &str) -> &'static str {
1429 match game { 1410 match game {
1430 "slots" => "MIN 10 KR · RTP 96%", 1411 "slots" => "Spin the reels. Three or more matching symbols from the left win.",
1431 "roulette" => "MIN 10 KR · SINGLE ZERO", 1412 "roulette" => "Put chips on the table, then spin. Straight numbers pay the most.",
1432 "blackjack" => "MIN 10 KR · S17 · 3:2", 1413 "blackjack" => "Get closer to 21 than the dealer without going over.",
1433 "crash" => "MIN 10 KR · 1% EDGE", 1414 "crash" => "Start the round, then cash out before the multiplier crashes.",
1434 _ => "", 1415 _ => "",
1435 } 1416 }
1436} 1417}