using VoiceCat.Core; using UIKit; namespace VoiceCat.iOS; internal sealed class RootViewController : UIViewController { private readonly AppModel model; private UIViewController? current; internal RootViewController(AppModel model) { this.model = model; model.Changed += Refresh; model.IdentityRequested += ShowIdentity; } public override void ViewDidLoad() { base.ViewDidLoad(); View!.BackgroundColor = UIColor.SystemBackground; Refresh(); } private void Refresh() { bool main = model.IsConnected; if (current is MainTabController && main || current is UINavigationController && !main) return; UIViewController next = main ? new MainTabController(model) : new UINavigationController(new ServerListController(model)); if (current is not null) { current.WillMoveToParentViewController(null); current.View!.RemoveFromSuperview(); current.RemoveFromParentViewController(); } UIView rootView = View!, nextView = next.View!; AddChildViewController(next); nextView.Frame = rootView.Bounds; nextView.AutoresizingMask = UIViewAutoresizing.All; rootView.AddSubview(nextView); next.DidMoveToParentViewController(this); current = next; } private void ShowIdentity(ServerIdentityChallenge challenge) { UIAlertController alert = UIAlertController.Create(challenge.Status == VoiceCat.Crypto.TofuStatus.Mismatch ? "Server Identity Changed" : "New Server Identity", $"{challenge.Host}:{challenge.Port}\n\nSHA-256\n{challenge.CertificateFingerprint}", UIAlertControllerStyle.Alert); alert.AddAction(UIAlertAction.Create("Reject", UIAlertActionStyle.Destructive, _ => model.ResolveIdentity(false))); alert.AddAction(UIAlertAction.Create("Trust", UIAlertActionStyle.Default, _ => model.ResolveIdentity(true))); PresentViewController(alert, true, null); } }