╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ──────╮ │src/ui/User.zig│ ╰───────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │162 } else |_| {} │ │163 try forks.append(arena.allocator(), .{ │ │164 .id = try arena.allocator().dupe(u8, &fork_id_hex), │ │158 - .target = target_repo.event, │ │165 + .repo_name = record.event.repo_name, │ │166 + .access = if (target) |value| value.repo.event.read_access else null,│ │167 .title = title, │ │168 }); │ │169 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │245 try items.append(aa, .{ .text = "← previous", .link = try aa.print("a:/{s}/forks/start:{d}", .{ data.user.name, data.forks_start -| page_size }) });│ │246 for (data.forks) |fork_item| { │ │247 // the fork route names the forker │ │240 - const identity = try aa.print("{s}:{s}", .{ data.user.name, fork_item.target.name }); │ │248 + const identity = try aa.print("{s}:{s}", .{ data.user.name, fork_item.repo_name }); │ │249 const route = ui.RoutablePage.forkPatchRoute(identity, fork_item.id) orelse return error.RouteTooLong; │ │250 try items.append(aa, .{ │ │243 - .text = try aa.print("{s} - {s}", .{ fork_item.target.name, fork_item.title }), │ │251 + .text = try aa.print("{s} - {s}", .{ fork_item.repo_name, fork_item.title }), │ │252 .link = try aa.print("a:{s}", .{try route.toUrl(session.page_arena)}), │ │245 - .bottom_label = if (fork_item.target.read_access == .private) "(private)" else "", │ │253 + .bottom_label = if (fork_item.access) |access| if (access == .private) "(private)" else "" else "(repo deleted)", │ │254 }); │ │255 } │ │256 if (data.forks_next_start) |next_start| │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ───────────────────╮ │src/ui/UserNotifications.zig│ ╰────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │79 const repos_label = "view repos"; │ │80 const logout_label = "logout"; │ │81 │ │82 -// the notifications, user settings and ssh keys sub tabs over their content, with the logout button across from them │ │82 +// the notifications, user settings, ssh keys and delete sub tabs over their content, with the logout button across from them│ │83 pub const View = struct { │ │84 box: wgt.Box(ui.Widget), │ │85 data: *const Self, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────╮ │86 session: *ui.Session, │ │87 // the sub tabs' ids then the repos and logout buttons', in header order│ │88 - control_ids: [5]usize, │ │88 + control_ids: [6]usize, │ │89 // the sub tab whose content shows │ │90 view_index: usize, │ │91 │ ╰────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 92 const header_index = 0; │ │ 93 const content_index = 1; │ │ 94 // the sub tabs come first in `control_ids` │ │ 95 - const tab_count = 3; │ │ 96 - const repos_index = 3; │ │ 97 - const logout_index = 4; │ │ 95 + const tab_count = 4; │ │ 96 + const repos_index = 4; │ │ 97 + const logout_index = 5; │ │ 98 │ │ 99 // `user_route` is the page's user tab route │ │100 pub fn init(allocator: std.mem.Allocator, data: *const Self, session: *ui.Session, user_route: ui.RoutablePage) !View {│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────╮ │101 var box = try wgt.Box(ui.Widget).init(allocator, .{ .border = null, .direction = .vert });│ │102 errdefer box.deinit(allocator); │ │103 │ │104 - var control_ids: [5]usize = undefined; │ │104 + var control_ids: [6]usize = undefined; │ │105 const settings_route = user_route.withUserTab(.{ .view = .settings }); │ │106 const keys_route = user_route.withUserTab(.{ .view = .keys }); │ │107 + const delete_route = user_route.withUserTab(.{ .view = .delete }); │ │108 { │ │109 var header_scroll = try ui.widget.HeaderScroll.init(allocator, session); │ │110 errdefer header_scroll.deinit(allocator); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │111 const header = header_scroll.row(); │ │112 const on_tab = std.meta.activeTag(session.data.current_page) == std.meta.activeTag(user_route); │ │112 - const routes = [_]ui.RoutablePage{ user_route.withUserTab(.{}), settings_route, keys_route }; │ │113 - for ([_]ui.RoutablePage.UserView{ .notifications, .settings, .keys }, [_][]const u8{ "notifications", "user settings", "ssh keys" }, routes, 0..) |view, label, route, index| { │ │113 + const routes = [_]ui.RoutablePage{ user_route.withUserTab(.{}), settings_route, keys_route, delete_route }; │ │114 + for ([_]ui.RoutablePage.UserView{ .notifications, .settings, .keys, .delete }, [_][]const u8{ "notifications", "user settings", "ssh keys", "delete user" }, routes, 0..) |view, label, route, index| {│ │115 var tab = try wgt.TextBox.init(allocator, label, .{ .border = .hidden, .round_corners = true, .wrap_kind = .none }); │ │116 errdefer tab.deinit(allocator); │ │117 tab.getFocus().mode = .all; │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │194 errdefer keys.deinit(allocator); │ │195 try stack.children.put(allocator, keys.getFocus().id, .{ .user_keys = keys }); │ │196 } │ │197 + { │ │198 + var delete = try ui.Delete.View.init(allocator, .{ .target = .{ .user = session.data.user_name orelse unreachable } }, session, delete_route);│ │199 + errdefer delete.deinit(allocator); │ │200 + try stack.children.put(allocator, delete.getFocus().id, .{ .delete_form = delete }); │ │201 + } │ │202 stack.getFocus().child_id = stack.children.keys()[@backingInt(data.view)]; │ │203 try box.children.put(allocator, stack.getFocus().id, .{ .widget = .{ .stack = stack }, .rect = null, .min_size = null }); │ │204 } │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ────────╮ │src/ui/widget.zig│ ╰─────────────────╯ ╭─────────────────────────────────────────────────────────────────────────╮ │80 user_settings: ui.UserSettings.View, │ │81 user_keys: ui.UserKeys.View, │ │82 user_notifications: ui.UserNotifications.View, │ │83 + delete_form: ui.Delete.View, │ │84 footer: Footer, │ │85 │ │86 pub fn deinit(self: *Widget, allocator: std.mem.Allocator) void {│ ╰─────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │123 pub fn atTop(self: *Widget, root_focus: *Focus) bool { │ │124 return switch (self.*) { │ │125 inline .home_about, .home_users, .user_repos, .flow_box_scroll, .new_repo, .new_user, .user_login, .user_notifications, .quit, .repo_files, .repo_commits, .diff_view, .repo_refs, .repo_issues, .repo_patches, .repo_discussions, .repo_events, .repo_undo, .repo_settings, .repo_settings_form, .repo_members, .repo_branches, .user_keys => |*view| view.atTop(),│ │125 - inline .repo_patch_detail, .user_settings => |*view| view.atTop(root_focus), │ │126 + inline .repo_patch_detail, .user_settings, .delete_form => |*view| view.atTop(root_focus), │ │127 else => false, │ │128 }; │ │129 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯