╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────╮ │2837 // a page built under another login is rebuilt rather than restored│ │2838 if (!std.meta.eql(entry.user_id, session.userId())) { │ │2839 try self.rebuild(allocator, session); │ │2889 - return; │ │2840 + return true; │ │2841 } │ │2842 chooseAnsiArtForNavigation(session); │ │2892 - return; │ │2843 + return true; │ │2844 } │ │2845 session.back = .unavailable; │ │2846 // nothing to go back to; switch to the quit confirmation │ ╰─────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────╮ │2865 else => {}, │ │2866 } │ │2867 } │ │2917 - return; │ │2868 + return false; │ │2869 } │ │2870 │ │2871 // forward navigation: navigate() set next_page to the page to move to (a│ ╰───────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────╮ │2872 // cross-page link or tab change crossing pages) │ │2873 if (session.next_page) |route| { │ │2874 session.next_page = null; │ │2924 - if (session.haxy_moment == null and session.local == null) return; │ │2875 + if (session.haxy_moment == null and session.local == null) return false;│ │2876 const previous_route = session.data.current_page; │ │2877 // the page we navigated to becomes the current page │ │2878 session.data.current_page = route; │ ╰──────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────╮ │2894 self.root = new_root; │ │2895 self.arena = arena; │ │2896 self.user_id = session.userId();│ │2897 + return true; │ │2898 } │ │2899 + return false; │ │2900 } │ │2901 }; │ │2902 │ ╰──────────────────────────────────────────────────╯ ╭ changed ─────────────╮ │src/ui/Auth/Logout.zig│ ╰──────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │19 center: ui.widget.Center, │ │20 data: *const Self, │ │21 session: *ui.Session, │ │22 - ansi_id: usize, │ │22 logout_id: usize, │ │23 │ │25 - const ansi_index: usize = 0; │ │26 - │ │24 pub fn init(allocator: std.mem.Allocator, data: *const Self, session: *ui.Session) !View { │ │28 - var box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .round_corners = true, .direction = .vert }); │ │29 - errdefer box.deinit(allocator); │ │30 - │ │31 - const ansi_id = try addButton(allocator, &box, "form:ansi", ansiLabel(session)); │ │32 - │ │33 - { │ │34 - var gap = try wgt.Text.init(allocator, " "); │ │35 - errdefer gap.deinit(allocator); │ │36 - try box.children.put(allocator, gap.getFocus().id, .{ │ │37 - .widget = .{ .text = gap }, │ │38 - .rect = null, │ │39 - .min_size = null, │ │40 - }); │ │41 - } │ │42 - │ │43 - const logout_id = try addButton(allocator, &box, "form:logout", "logout"); │ │44 - │ │45 - box.getFocus().child_id = box.children.keys()[ansi_index]; │ │46 - │ │47 - return .{ │ │48 - .center = try ui.widget.Center.init(allocator, .{ .box = box }), │ │49 - .data = data, │ │50 - .session = session, │ │51 - .ansi_id = ansi_id, │ │52 - .logout_id = logout_id, │ │53 - }; │ │54 - } │ │55 - │ │56 - // each button sits in its own form box so the web renderer posts it to its own route │ │57 - fn addButton(allocator: std.mem.Allocator, parent: *wgt.Box(ui.Widget), form: []const u8, label: []const u8) !usize { │ │25 + // the form box makes the web renderer post the button to /logout │ │26 var box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .vert }); │ │27 errdefer box.deinit(allocator); │ │60 - box.getFocus().kind = .{ .custom = form }; │ │28 + box.getFocus().kind = .{ .custom = "form:logout" }; │ │29 │ │62 - var button = try wgt.TextBox.init(allocator, label, .{ .border_style = .single, .round_corners = true, .wrap_kind = .none }); │ │30 + var button = try wgt.TextBox.init(allocator, "logout", .{ .border_style = .single, .round_corners = true, .wrap_kind = .none });│ │31 errdefer button.deinit(allocator); │ │32 button.getFocus().mode = .all; │ │33 // the renderer distinguishes plain clickables from buttons that │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────╮ │34 // should POST to a server route by this kind. │ │35 button.getFocus().kind = .{ .custom = "submit" };│ │68 - const button_id = button.getFocus().id; │ │69 - try box.children.put(allocator, button_id, .{ │ │36 + const logout_id = button.getFocus().id; │ │37 + try box.children.put(allocator, logout_id, .{ │ │38 .widget = .{ .text_box = button }, │ │39 .rect = null, │ │40 .min_size = null, │ ╰─────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────╮ │41 }); │ │74 - box.getFocus().child_id = button_id; │ │42 + box.getFocus().child_id = logout_id; │ │43 │ │76 - try parent.children.put(allocator, box.getFocus().id, .{ │ │77 - .widget = .{ .box = box }, │ │78 - .rect = null, │ │79 - .min_size = null, │ │80 - }); │ │81 - return button_id; │ │44 + return .{ │ │45 + .center = try ui.widget.Center.init(allocator, .{ .box = box }),│ │46 + .data = data, │ │47 + .session = session, │ │48 + .logout_id = logout_id, │ │49 + }; │ │50 } │ │51 │ │52 pub fn deinit(self: *View, allocator: std.mem.Allocator) void { │ ╰────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │54 } │ │55 │ │56 pub fn build(self: *View, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void {│ │89 - const ansi_box = &self.center.child.box.children.values()[ansi_index].widget.box; │ │90 - try ansi_box.children.values()[0].widget.text_box.setContent(allocator, ansiLabel(self.session)); │ │57 try self.center.build(allocator, constraint, root_focus); │ │58 } │ │59 │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 60 pub fn input(self: *View, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void { │ │ 61 _ = allocator; │ │ 96 - const focused_id = if (self.atTop()) self.ansi_id else self.logout_id; │ │ 62 switch (key) { │ │ 98 - .arrow_up => root_focus.setFocus(self.ansi_id), │ │ 99 - .arrow_down => root_focus.setFocus(self.logout_id), │ │100 - .enter => try self.activate(focused_id), │ │101 - .mouse => |mouse| if (inp.leftClickOn(root_focus, focused_id, mouse)) try self.activate(focused_id),│ │ 63 + .enter => try self.logOut(), │ │ 64 + .mouse => |mouse| if (inp.leftClickOn(root_focus, self.logout_id, mouse)) try self.logOut(), │ │ 65 else => {}, │ │ 66 } │ │ 67 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────╮ │ 68 │ │106 - fn activate(self: *View, button_id: usize) !void { │ │107 - if (button_id == self.ansi_id) { │ │108 - try self.session.push(.toggle_ansi); │ │109 - return; │ │110 - } │ │ 69 + fn logOut(self: *View) !void { │ │ 70 self.session.logOut(); │ │ 71 // leave the auth tab for the page it belongs to, where the web's│ │ 72 // /logout redirect also lands │ ╰──────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯