diff options
Diffstat (limited to 'gui/src/app.rs')
| -rw-r--r-- | gui/src/app.rs | 79 |
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 | ||
| 1418 | fn tagline(game: &str) -> &'static str { | 1408 | /// One plain sentence: how to play, not the house's rules sheet. |
| 1419 | match game { | 1409 | fn 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 | |||
| 1428 | fn 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 | } |
