╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │899 │ │869 - // the user's email, for authoring event commits │ │870 - pub fn userEmail(self: *Self) ![]const u8 { │ │871 - const user_id = self.data.user_id orelse return "user@haxy"; │ │872 - const moment = self.haxy_moment orelse return "user@haxy"; │ │873 - const user = (try evt.User.readById(evt.AdminDB, evt.admin_repo_opts.hash, moment, self.page_arena, user_id)) orelse unreachable;│ │900 + // the author for an event this session creates, or null when it may not │ │901 + // create one. local mode has no accounts, so it authors anonymously. │ │902 + pub fn eventAuthorEmail(self: *Self) !?[]const u8 { │ │903 + if (self.data.is_local) return "user@haxy"; // TODO: try the repo's git config user.email first │ │904 + const user_id = self.data.user_id orelse return null; │ │905 + const moment = self.haxy_moment orelse return null; │ │906 + const user = (try evt.User.readById(evt.AdminDB, evt.admin_repo_opts.hash, moment, self.page_arena, user_id)) orelse return null;│ │907 return user.event.email; │ │908 } │ │909 │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────╮ │src/ui/Auth.zig│ ╰───────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │32 logout: Logout.View, │ │33 session: *ui.Session, │ │34 │ │35 - pub fn init(allocator: std.mem.Allocator, data: *const Self, session: *ui.Session, users_tab_id: usize) !View {│ │36 - var login_view = try Login.View.init(allocator, &data.login, session, users_tab_id); │ │35 + pub fn init(allocator: std.mem.Allocator, data: *const Self, session: *ui.Session) !View { │ │36 + var login_view = try Login.View.init(allocator, &data.login, session); │ │37 errdefer login_view.deinit(allocator); │ │38 - var logout_view = try Logout.View.init(allocator, &data.logout, session, users_tab_id); │ │38 + var logout_view = try Logout.View.init(allocator, &data.logout, session); │ │39 errdefer logout_view.deinit(allocator); │ │40 return .{ │ │41 .focus = try Focus.create(allocator, .container), │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ────────────╮ │src/ui/Auth/Login.zig│ ╰─────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────╮ │31 data: *const Self, │ │32 session: *ui.Session, │ │33 nav_ids: [3]usize, │ │34 - // focus id of the header's "users" tab; on a successful submit we jump│ │35 - // focus there so the user isn't stranded on the login button. │ │36 - success_redirect_tab_id: usize, │ │34 │ │35 const username_index: usize = 0; │ │36 const password_index: usize = 1; │ ╰───────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │37 const button_index: usize = 2; │ │38 │ │42 - pub fn init(allocator: std.mem.Allocator, data: *const Self, session: *ui.Session, success_redirect_tab_id: usize) !View { │ │39 + pub fn init(allocator: std.mem.Allocator, data: *const Self, session: *ui.Session) !View { │ │40 var box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .rounded_corners = true, .direction = .vert });│ │41 errdefer box.deinit(allocator); │ │42 // marks this subtree as an HTML form scope for the web overlay │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────╮ │90 .data = data, │ │91 .session = session, │ │92 .nav_ids = nav_ids, │ │96 - .success_redirect_tab_id = success_redirect_tab_id,│ │93 }; │ │94 } │ │95 │ ╰───────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────╮ │148 if (current == button_index) { │ │149 switch (key) { │ │150 .enter => { │ │155 - try self.submit(allocator, root_focus);│ │151 + try self.submit(allocator); │ │152 return; │ │153 }, │ │154 .mouse => |mouse| { │ ╰────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────╮ │155 if (inp.leftClickOn(root_focus, child_id, mouse)) {│ │160 - try self.submit(allocator, root_focus); │ │156 + try self.submit(allocator); │ │157 return; │ │158 } │ │159 }, │ ╰────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────╮ │203 return null; │ │204 } │ │205 │ │210 - fn submit(self: *View, allocator: std.mem.Allocator, root_focus: *Focus) !void {│ │206 + fn submit(self: *View, allocator: std.mem.Allocator) !void { │ │207 if (comptime wasm) { │ │208 // no DB cursor available on the wasm render path │ │209 self.session.data.login_failure = .unknown_user; │ ╰─────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────╮ │242 self.session.data.user_id = user_id_stable; │ │243 self.session.data.login_failure = null; │ │244 │ │249 - // adopt the user's persisted prefs │ │250 - try self.session.loadUserPrefs(); │ │245 + // adopt the user's name and persisted prefs │ │246 + try self.session.loadUser(); │ │247 │ │248 // wipe the entered credentials so they don't linger if the│ │249 // user returns to this page after logging out │ ╰────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────╮ │250 username_input.clear(allocator); │ │251 password_input.clear(allocator); │ │252 │ │257 - // jump focus back to the users tab — the login button we │ │258 - // just pressed is about to be hidden by the tab-label swap │ │259 - root_focus.setFocus(self.success_redirect_tab_id); │ │253 + // leave the auth tab for the page it belongs to, where the │ │254 + // web's /login redirect also lands │ │255 + try self.session.navigate(self.session.data.current_page.pageRoot());│ │256 }, │ │257 } │ │258 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯