11using Codebreaker . ViewModels ;
2+ using Codebreaker . ViewModels . Messages ;
23using CommunityToolkit . Mvvm . Messaging ;
34using Microsoft . UI . Xaml . Media . Animation ;
45using Microsoft . UI . Xaml . Shapes ;
@@ -8,44 +9,45 @@ namespace CodeBreaker.WinUI.Views.Pages;
89/// <summary>
910/// An empty page that can be used on its own or navigated to within a Frame.
1011/// </summary>
11- public sealed partial class GamePage : Page , IRecipient < GameMoveMessage >
12+ public sealed partial class GamePage : Page ,
13+ IRecipient < MakeMoveMessage > ,
14+ IRecipient < GameStartedMessage > ,
15+ IRecipient < GameEndedMessage > ,
16+ IRecipient < GameCancelledMessage >
1217{
1318 public GamePageViewModel ViewModel { get ; }
1419
1520 public GamePage ( )
1621 {
1722 ViewModel = App . GetService < GamePageViewModel > ( ) ;
18- InitializeComponent ( ) ;
19- WeakReferenceMessenger . Default . Register ( this ) ;
23+ WeakReferenceMessenger . Default . RegisterAll ( this ) ;
2024 WeakReferenceMessenger . Default . UnregisterAllOnUnloaded ( this ) ;
21- ViewModel . PropertyChanged += ViewModel_PropertyChanged ;
25+ InitializeComponent ( ) ;
2226 this . GoToState ( "Start" , false ) ;
2327 }
2428
25- private void ViewModel_PropertyChanged ( object ? sender , System . ComponentModel . PropertyChangedEventArgs e )
26- {
27- if ( e . PropertyName != nameof ( GamePageViewModel . GameStatus ) )
28- return ;
29+ public void Receive ( GameStartedMessage message ) =>
30+ this . GoToState ( "Playing" ) ;
2931
30- var stateName = ViewModel . GameStatus switch
31- {
32- GameMode . Started or GameMode . MoveSet => "Playing" ,
33- GameMode . Won or GameMode . Lost => "Finished" ,
34- _ => "Start" ,
35- } ;
36- this . GoToState ( stateName ) ;
32+ public async void Receive ( GameEndedMessage message )
33+ {
34+ this . GoToState ( "Finished" ) ;
35+ await Task . Delay ( 1000 ) ;
36+ ScrollPegListToBottom ( ) ;
3737 }
3838
39- public void Receive ( GameMoveMessage message )
39+ public void Receive ( MakeMoveMessage message )
4040 {
41- if ( message . GameMoveValue is not GameMoveValue . Completed )
41+ // Move must be completed
42+ if ( ! message . IsSet )
4243 return ;
4344
44- var selectionAndKeyPegs = message . SelectionAndKeyPegs ?? throw new InvalidOperationException ( ) ;
4545 var animationService = ConnectedAnimationService . GetForCurrentView ( ) ;
4646 animationService . DefaultDuration = TimeSpan . FromMilliseconds ( 500 ) ;
47- var container = listGameMoves . ItemContainerGenerator . ContainerFromItem ( selectionAndKeyPegs ) ;
48- this . FindItemsOfType < Ellipse > ( container )
47+ listGameMoves
48+ . ItemContainerGenerator
49+ . ContainerFromIndex ( listGameMoves . Items . Count - 1 )
50+ . FindChildrenRecursively < Ellipse > ( )
4951 . Foreach ( ( ellipse , i ) =>
5052 {
5153 ConnectedAnimation ? animation = animationService . GetAnimation ( $ "guess{ i } ") ;
@@ -58,8 +60,17 @@ public void Receive(GameMoveMessage message)
5860 animation . TryStart ( ellipse ) ;
5961 } ) ;
6062
61- // Scroll to bottom
63+ ScrollPegListToBottom ( ) ;
64+ }
65+
66+ private void ScrollPegListToBottom ( )
67+ {
6268 PegScrollViewer . UpdateLayout ( ) ;
63- PegScrollViewer . ScrollToVerticalOffset ( PegScrollViewer . ScrollableHeight ) ;
69+ PegScrollViewer . ChangeView ( null , PegScrollViewer . ScrollableHeight , null , false ) ;
70+ }
71+
72+ public void Receive ( GameCancelledMessage message )
73+ {
74+ this . GoToState ( "Start" ) ;
6475 }
6576}
0 commit comments