private void RefreshUserInfo() { userDataGetter = Promise.AwaitPromise(interactor.UserInfo()); // Get basic user info userDataGetter.Subscribe = p => { var data = p.Value.Split('&'); username = data[0].FromBase64String(); isAdministrator = bool.Parse(data[1]); }; }
private void RefreshAccountList() { accountsGetter = Promise.AwaitPromise(interactor.ListUserAccounts()); // Get accounts associated with this user accountsGetter.Subscribe = p => { var data = p.Value.Split('&'); accounts = new List <string>(); accounts.AddRange(data); }; }
void CreateAccount() { bool hasError = false; if (accountType == -1) { hasError = true; account_create.Inputs[1].SelectBackgroundColor = ConsoleColor.Red; account_create.Inputs[1].BackgroundColor = ConsoleColor.DarkRed; controller.Popup(GetIntlString("SE_acc_nosel"), 2500, ConsoleColor.Red); } if (account_create.Inputs[0].Text.Length == 0) { account_create.Inputs[0].SelectBackgroundColor = ConsoleColor.Red; account_create.Inputs[0].BackgroundColor = ConsoleColor.DarkRed; if (!hasError) { controller.Popup(GetIntlString("ERR_empty"), 3000, ConsoleColor.Red); } } else if (!hasError) { void AlreadyExists() => controller.Popup(GetIntlString("SE_account_exists").Replace("$0", account_create.Inputs[0].Text), 2500, ConsoleColor.Red, () => Hide(account_create)); var act = AccountLookup(account_create.Inputs[0].Text); if (act != null) { AlreadyExists(); } else { Show("account_stall"); Promise accountPromise = Promise.AwaitPromise(interactor.CreateAccount(account_create.Inputs[0].Text, accountType == 0)); accountPromise.Subscribe = p => { if (bool.Parse(p.Value)) { controller.Popup(GetIntlString("SE_account_success"), 750, ConsoleColor.Green, () => Hide(account_create)); accountChange = true; } else { AlreadyExists(); } Hide("account_stall"); }; } } }
private void ViewAccountListener(View listener) { ButtonView view = listener as ButtonView; void ShowAccountData(string name, decimal balance, Account.AccountType type) { // Build dialog view manually var show = new DialogView( new ViewData("DialogView") // Layout parameters .SetAttribute("padding_left", 2) .SetAttribute("padding_right", 2) .SetAttribute("padding_top", 1) .SetAttribute("padding_bottom", 1) .SetAttribute("border", (int)ConsoleColor.DarkGreen) // Option buttons .AddNested(new ViewData("Options").AddNestedSimple("Option", GetIntlString("GENERIC_dismiss")).AddNestedSimple("Option", GetIntlString("SE_account_delete"))) // Message .AddNestedSimple("Text", GetIntlString("SE_info") .Replace("$0", name) .Replace("$1", GetIntlString(type == Account.AccountType.Savings ? "SE_acc_saving" : "SE_acc_checking")) .Replace("$2", balance.ToTruncatedString())), // No translation (it's already handled) LangManager.NO_LANG); show.RegisterSelectListener((_, s, l) => { if (s == 0) { Hide(show); } else { var ynDialog = GetView <DialogView>("yn"); ynDialog.Text = GetIntlString("SE_account_delete_warn"); ynDialog.RegisterSelectListener((v, i, str) => { var stall = GetView <TextView>("stall"); stall.Text = GetIntlString("SE_account_delete_stall"); Show(stall); if (i == 1) { Promise p = Promise.AwaitPromise(interactor.CloseAccount(name)); p.Subscribe = deleteAwait => { if (bool.Parse(deleteAwait.Value)) { accountChange = true; controller.Popup(GetIntlString("SE_account_delete_success"), 1500, ConsoleColor.Green, () => { bool closed = false; controller.CloseIf(predV => closed = !closed && predV is ListView); Hide(show); }); } else { controller.Popup(GetIntlString("SE_account_delete_fail"), 2000, ConsoleColor.Red); } Hide(stall); }; } }); Show(ynDialog); } }); Show(show); } // TODO: Show account info var account = AccountLookup(view.Text); if (account == null) { // TODO: Get account data from server + cache data Show("data_fetch"); Promise info_promise = Promise.AwaitPromise(interactor.AccountInfo(view.Text)); info_promise.Subscribe = evt => { Hide("data_fetch"); if (evt.Value.StartsWith("ERROR") || !Account.TryParse(evt.Value, out var act)) { controller.Popup(GetIntlString("GENERIC_error"), 3000, ConsoleColor.Red); } else { // Cache result (don't cache savings accounts because their value updates pretty frequently) if (act.type != Account.AccountType.Savings) { accountDataCache.Enqueue(new Tuple <string, Account>(view.Text, act)); } ShowAccountData(view.Text, act.balance, act.type); } }; } else { ShowAccountData(account.Item1, account.Item2.balance, account.Item2.type); } }
private void SetupSubmissionEvents() { // Setup options menu events options_add.SetEvent(_ => Show(account_create)); options_update.SetEvent(v => Show(password_update)); options_tx.SetEvent(v => Show(transfer)); options_delete.SetEvent(v => Show(account_delete)); // Other events account_delete.RegisterSelectListener((v, i, s) => { Hide(v); if (i == 1) { Show("delete_stall"); Promise deletion = Promise.AwaitPromise(interactor.DeleteUser()); deletion.Subscribe = p => { Hide("delete_stall"); if (bool.Parse(p.Value)) { controller.Popup(GetIntlString("SE_delete_success"), 2500, ConsoleColor.Green, () => manager.LoadContext(new WelcomeContext(manager, interactor))); } else { controller.Popup(GetIntlString("SE_delete_failure"), 1500, ConsoleColor.Red); } }; } }); account_create.SubmissionsListener = inputView => { if (inputView.SelectedField == 1) { Show(accountTypes); // Show account type selection menu } else { CreateAccount(); } }; success.RegisterSelectListener((v, i, s) => HandleLogout()); options_exit.SetEvent(v => Show("exit_prompt")); options_view.SetEvent(v => { if (accountChange) { RefreshAccountList(); } if (!accountsGetter.HasValue) { Show("data_fetch"); } accountsGetter.Subscribe = p => { accountsGetter.Unsubscribe(); Hide("data_fetch"); Show(GenerateList(p.Value.Split('&').ForEach(Support.FromBase64String), ViewAccountListener)); }; }); password_update.SubmissionsListener = v => { bool hasError = v.Inputs[0].Text.Length == 0; if (hasError) { // Notify user, as well as mark the errant input field v.Inputs[0].SelectBackgroundColor = ConsoleColor.Red; v.Inputs[0].BackgroundColor = ConsoleColor.DarkRed; controller.Popup(GetIntlString("ERR_empty"), 3000, ConsoleColor.Red); } if (v.Inputs[1].Text.Length == 0) { v.Inputs[1].SelectBackgroundColor = ConsoleColor.Red; v.Inputs[1].BackgroundColor = ConsoleColor.DarkRed; if (!hasError) { controller.Popup(GetIntlString("ERR_empty"), 3000, ConsoleColor.Red); } return; // No need to continue, we have notified the user. There is no valid information to operate on past this point } if (!v.Inputs[0].Text.Equals(v.Inputs[1].Text)) { controller.Popup(GetIntlString("SU_mismatch"), 3000, ConsoleColor.Red); return; } Show("update_stall"); Task <Promise> t = interactor.UpdatePassword(v.Inputs[0].Text); Promise.AwaitPromise(t).Subscribe = p => { Hide("update_stall"); Hide("password_update"); v.Inputs[0].ClearText(); v.Inputs[1].ClearText(); v.SelectedField = 0; }; }; transfer.SubmissionsListener = v => { switch (v.SelectedField) { case 0: if (accountChange) { accountsGetter = Promise.AwaitPromise(interactor.ListUserAccounts()); } Show("data_fetch"); accountsGetter.Subscribe = p => { accountsGetter.Unsubscribe(); Hide("data_fetch"); Show(GenerateList(p.Value.Split('&').ForEach(Support.FromBase64String), sel => v.Inputs[0].Text = acc1 = (sel as ButtonView).Text, true)); }; break; case 1: Show("data_fetch"); Promise remoteUserGetter = Promise.AwaitPromise(interactor.ListUsers()); remoteUserGetter.Subscribe = p => { remoteUserGetter.Unsubscribe(); Hide("data_fetch"); Show(GenerateList(p.Value.Split('&').ForEach(Support.FromBase64String), sel => v.Inputs[1].Text = user = (sel as ButtonView).Text, true)); }; break; case 2: if (user == null) { controller.Popup(GetIntlString("SE_user_noselect"), 2000, ConsoleColor.Red); } else { Show("data_fetch"); Promise remoteAccountsGetter = Promise.AwaitPromise(interactor.ListAccounts(user)); remoteAccountsGetter.Subscribe = p => { remoteAccountsGetter.Unsubscribe(); Hide("data_fetch"); Show(GenerateList(p.Value.Split('&').ForEach(Support.FromBase64String), sel => v.Inputs[2].Text = acc2 = (sel as ButtonView).Text, true)); }; } break; case 3: case 4: Show("verify_stall"); bool error = false; if (acc1 == null) { controller.Popup(GetIntlString("SE_account_noselect"), 1500, ConsoleColor.Red); error = true; v.Inputs[0].BackgroundColor = ConsoleColor.Red; v.Inputs[0].SelectBackgroundColor = ConsoleColor.DarkRed; } if (acc2 == null) { if (!error) { controller.Popup(GetIntlString("SE_account_noselect"), 1500, ConsoleColor.Red); } error = true; v.Inputs[2].BackgroundColor = ConsoleColor.Red; v.Inputs[2].SelectBackgroundColor = ConsoleColor.DarkRed; } if (user == null) { if (!error) { controller.Popup(GetIntlString("SE_account_nouser"), 1500, ConsoleColor.Red); } error = true; v.Inputs[1].BackgroundColor = ConsoleColor.DarkRed; v.Inputs[1].SelectBackgroundColor = ConsoleColor.Red; } userDataGetter = Promise.AwaitPromise(interactor.UserInfo()); userDataGetter.Subscribe = p => { userDataGetter.Unsubscribe(); var account = AccountLookup("SE_balance_toohigh"); if (account == null) { accountsGetter = Promise.AwaitPromise(interactor.AccountInfo(acc1)); } accountsGetter.Subscribe = result => { accountsGetter.Unsubscribe(); var resultData = p.Value.Split('&'); Hide("verify_stall"); decimal d; if (result.Value.StartsWith("ERROR") || !Account.TryParse(result.Value, out var act)) { controller.Popup(GetIntlString("GENERIC_error"), 1500, ConsoleColor.Red); } else if ((d = decimal.Parse(v.Inputs[3].Text)) > act.balance && (!bool.Parse(resultData[1]) || !acc1.Equals(acc2))) { controller.Popup(GetIntlString("SE_balance_toohigh").Replace("$0", act.balance.ToString()), 3000, ConsoleColor.Red); } else { Promise txPromise = Promise.AwaitPromise(interactor.CreateTransaction(acc1, user, acc2, d, v.Inputs[4].Text.Length == 0 ? null : v.Inputs[4].Text)); accountChange = true; accountDataCache.Clear(); txPromise.Subscribe = txResult => { if (txResult.Value.StartsWith("ERROR")) { controller.Popup(GetIntlString("GENERIC_error"), 1500, ConsoleColor.Red); } else { controller.Popup(GetIntlString("SE_tx_success"), 2000, ConsoleColor.Green, () => Hide("transfer")); } }; } }; }; break; } }; exit_prompt.RegisterSelectListener((v, i, s) => { if (i == 0) { Hide("exit_prompt"); } else { HandleLogout(); } }); }
public NetContext(ContextManager manager) : base(manager, "Networking", "Common") { // Just close when anything is selected and "submitted" RegisterSelectListeners((s, i, v) => controller.CloseView(s), "EmptyFieldError", "IPError", "PortError", "ConnectionError"); bool connecting = false; GetView <InputView>("NetConnect").OnBackEvent = _ => Show("quit"); GetView <InputView>("NetConnect").SubmissionsListener = i => { if (connecting) { controller.Popup("Already connecting!", 1000, ConsoleColor.DarkRed); return; } bool ip = ParseIP(i.Inputs[0].Text) != null, port = short.TryParse(i.Inputs[1].Text, out short prt) && prt > 0; if (ip && port) { connecting = true; // Connect to server here BankNetInteractor ita = new BankNetInteractor(i.Inputs[0].Text, prt); Promise verify; try { verify = Promise.AwaitPromise(ita.CheckIdentity(new RSA(Resources.e_0x100, Resources.n_0x100), provider.NextUShort())); } catch { Show("ConnectionError"); connecting = false; return; } verify.Subscribe = p => { void load() => manager.LoadContext(new WelcomeContext(manager, ita)); // Add condition check for remote peer verification if (bool.Parse(p.Value)) { controller.Popup(GetIntlString("NC_verified"), 1000, ConsoleColor.Green, load); } else { controller.Popup(GetIntlString("verror"), 5000, ConsoleColor.Red, load); } }; DialogView identityNotify = GetView <DialogView>("IdentityVerify"); identityNotify.RegisterSelectListener( (vw, ix, nm) => { Hide(identityNotify); connecting = false; verify.Subscribe = null; // Clear subscription #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed ita.CancelAll(); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed connecting = false; }); Show(identityNotify); } else if (i.Inputs[0].Text.Length == 0 || i.Inputs[1].Text.Length == 0) { Show("EmptyFieldError"); } else if (!ip) { Show("IPError"); } else { Show("PortError"); } }; }
public WelcomeContext(ContextManager manager, BankNetInteractor connection) : base(manager, "Setup", "Common") { this.interactor = connection; // Prepare events and stuff // Just close when anything is selected and "submitted" RegisterSelectListeners((s, i, v) => controller.CloseView(s), "DuplicateAccountError", "EmptyFieldError", "IPError", "PortError", "AuthError", "PasswordMismatchError"); // If Escape key is pressed, suggest to controller to terminate GetView("WelcomeScreen").OnBackEvent = v => Show("quit"); GetView <InputView>("Login").SubmissionsListener = i => { bool success = true; foreach (var input in i.Inputs) { if (input.Text.Length == 0) { success = false; input.SelectBackgroundColor = ConsoleColor.Red; input.BackgroundColor = ConsoleColor.DarkRed; } } if (success) { // Authenticate against server here Show("AuthWait"); try { promise = Promise.AwaitPromise(interactor.Authenticate(i.Inputs[0].Text, i.Inputs[1].Text)); } catch { Hide("AuthWait"); Show("ConnectionError"); return; } //promise = prom.Result; promise.Subscribe = response => { Hide("AuthWait"); if (response.Value.StartsWith("ERROR") || response.Value.Equals("False")) // Auth failure or general error { Show("AuthError"); } else { forceDestroy = false; manager.LoadContext(new SessionContext(manager, interactor)); } }; } else { Show("EmptyFieldError"); } }; // For a smooth effect GetView <InputView>("Login").InputListener = (v, c, i, t) => { c.BackgroundColor = v.DefaultBackgroundColor; c.SelectBackgroundColor = v.DefaultSelectBackgroundColor; return(true); }; GetView <InputView>("Register").SubmissionsListener = i => { bool success = true, mismatch = false; foreach (var input in i.Inputs) { if (input.Text.Length == 0) { success = false; input.SelectBackgroundColor = ConsoleColor.Red; input.BackgroundColor = ConsoleColor.DarkRed; } } mismatch = !i.Inputs[1].Text.Equals(i.Inputs[2].Text); if (success && !mismatch) { void a() { Show("RegWait"); try { promise = Promise.AwaitPromise(interactor.Register(i.Inputs[0].Text, i.Inputs[1].Text)); } catch { Hide("RegWait"); Show("ConnectionError"); return; } promise.Subscribe = response => { Hide("RegWait"); if (!bool.Parse(response.Value)) { Show("DuplicateAccountError"); } else { forceDestroy = false; manager.LoadContext(new SessionContext(manager, interactor)); } }; } if (i.Inputs[1].Text.Length < 5 || i.Inputs[1].Text.StartsWith("asdfasdf") || i.Inputs[1].Text.StartsWith("asdf1234")) { var warning = GetView <DialogView>("WeakPasswordWarning"); warning.RegisterSelectListener((wrn, idx, sel) => { Hide(warning); if (idx == 0) { a(); } }); Show(warning); } else { a(); } } else if (mismatch) { Show("PasswordMismatchError"); } else { Show("EmptyFieldError"); } }; GetView <InputView>("Register").InputListener = (v, c, i, t) => { c.BackgroundColor = v.DefaultBackgroundColor; c.SelectBackgroundColor = v.DefaultSelectBackgroundColor; return(true); }; }