╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ UserLogout.zig ───────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
12 // the logged-in user's page, or the login form when logged out 13 pub fn initView(allocator: std.mem.Allocator, session: *ui.Session) !ui.Widget { 14 if (session.data.user_id != null) return .{ .user_logout = try View.init(allocator, session) }; 15 return .{ .user_login = try ui.UserLogin.View.init(allocator, session) }; 16 } 17 18 // the user tab's label: the logged-in user's name, or "login" 19 pub fn tabLabel(session: *const ui.Session) []const u8 { 20 if (session.data.user_id == null) return "login"; 21 return session.data.user_name orelse unreachable; 22 } 23 24 pub const View = struct { 25 center: ui.widget.Center, 26 session: *ui.Session, 27 logout_id: usize, 28 29 pub fn init(allocator: std.mem.Allocator, session: *ui.Session) !View { 30 // the form box makes the web renderer post the button to /logout 31 var box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .vert }); 32 errdefer box.deinit(allocator); 33 box.getFocus().kind = .{ .custom = "form:logout" }; 34 35 var button = try wgt.TextBox.init(allocator, "logout", .{ .border_style = .single, .round_corners = true, .wrap_kind = .none }); 36 errdefer button.deinit(allocator); 37 button.getFocus().mode = .all; 38 // the renderer distinguishes plain clickables from buttons that 39 // should POST to a server route by this kind. 40 button.getFocus().kind = .{ .custom = "submit" }; 41 const logout_id = button.getFocus().id; 42 try box.children.put(allocator, logout_id, .{ 43 .widget = .{ .text_box = button }, 44 .rect = null, 45 .min_size = null, 46 }); 47 box.getFocus().child_id = logout_id; 48 49 return .{ 50 .center = try ui.widget.Center.init(allocator, .{ .box = box }), 51 .session = session, 52 .logout_id = logout_id, 53 }; 54 } 55 56 pub fn deinit(self: *View, allocator: std.mem.Allocator) void { 57 self.center.deinit(allocator); 58 } 59 60 pub fn build(self: *View, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void { 61 try self.center.build(allocator, constraint, root_focus); 62 } 63 64 pub fn input(self: *View, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void { 65 _ = allocator; 66 switch (key) { 67 .enter => try self.logOut(), 68 .mouse => |mouse| if (inp.leftClickOn(root_focus, self.logout_id, mouse)) try self.logOut(), 69 else => {}, 70 } 71 } 72 73 fn logOut(self: *View) !void { 74 self.session.logOut(); 75 // leave the user tab for the page it belongs to, where the web's 76 // /logout redirect also lands 77 try self.session.navigate(self.session.data.current_page.pageRoot()); 78 } 79 80 pub fn clearGrid(self: *View) void { 81 self.center.clearGrid(); 82 } 83 84 pub fn getGrid(self: View) ?Grid { 85 return self.center.getGrid(); 86 } 87 88 pub fn getFocus(self: *View) *Focus { 89 return self.center.getFocus(); 90 } 91 92 pub fn atTop(self: View) bool { 93 _ = self; 94 return true; 95 } 96 }; 97