╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ─────────────╮ │src/ui/User/Header.zig│ ╰──────────────────────╯ ╭────────────────────────────────────────────────────╮ │12 const repos_tab_label = "repos"; │ │13 const forks_tab_label = "forks"; │ │14 const settings_tab_label = "settings"; │ │15 +const new_repo_tab_label = "new repo"; │ │16 │ │17 pub const AuthTab = @import("./../AuthTab.zig");│ │18 │ ╰────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │104 const repos_link = if (current_tag == .user_repos) current_link else try std.fmt.allocPrint(aa, "ai:/user/{s}", .{data.name}); │ │105 const forks_link = if (current_tag == .user_forks) current_link else try std.fmt.allocPrint(aa, "ai:/user/{s}/forks", .{data.name}); │ │106 const settings_link = if (current_tag == .user_settings) current_link else try std.fmt.allocPrint(aa, "ai:/user/{s}/settings", .{data.name});│ │107 + const new_repo_link = if (current_tag == .user_new_repo) current_link else try std.fmt.allocPrint(aa, "ai:/user/{s}/new-repo", .{data.name});│ │108 const auth_link = if (current_tag == .user_auth) current_link else try std.fmt.allocPrint(aa, "ai:/user/{s}/auth", .{data.name}); │ │109 │ │110 // the tab matching the current page is focused initially; matching by │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────╮ │111 // link (rather than position) keeps this robust to tab changes.│ │112 const selected_link: []const u8 = switch (current_page) { │ │113 .user_settings => settings_link, │ │114 + .user_new_repo => new_repo_link, │ │115 .user_auth => auth_link, │ │116 .user_forks => forks_link, │ │117 else => repos_link, │ ╰─────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────╮ │148 }); │ │149 } │ │150 │ │148 - // spacer pushes settings + auth to the right │ │151 + // spacer pushes settings, new repo and auth to the right│ │152 { │ │153 var spacer = try ui.widget.Spacer.init(allocator); │ │154 errdefer spacer.deinit(allocator); │ ╰──────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │157 .rect = null, │ │158 .min_size = null, │ │159 .flex = .grow, │ │160 + }); │ │161 + } │ │162 + │ │163 + // new repo tab. repos are created for the logged-in user. │ │164 + if (session.data.user_id != null) { │ │165 + var text_box = try wgt.TextBox.init(allocator, new_repo_tab_label, .{ .border_style = .single, .round_corners = true, .wrap_kind = .none });│ │166 + errdefer text_box.deinit(allocator); │ │167 + text_box.getFocus().mode = .all; │ │168 + text_box.getFocus().kind = .{ .custom = new_repo_link }; │ │169 + try tab_ids.put(allocator, text_box.getFocus().id, {}); │ │170 + if (std.mem.eql(u8, new_repo_link, selected_link)) selected_tab = text_box.getFocus().id; │ │171 + try tabs_box.children.put(allocator, text_box.getFocus().id, .{ │ │172 + .widget = .{ .text_box = text_box }, │ │173 + .rect = null, │ │174 + .min_size = .{ .width = new_repo_tab_label.len + 2, .height = null }, │ │175 }); │ │176 } │ │177 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ────────╮ │src/ui/widget.zig│ ╰─────────────────╯ ╭──────────────────────────────────────────────╮ │69 home_users: ui.Home.Users.View, │ │70 auth_tab: ui.Home.Header.AuthTab.View,│ │71 home_settings: ui.Home.Settings.View, │ │72 + new_repo: ui.NewRepo.View, │ │73 home_auth: ui.Home.Auth.View, │ │74 auth_login: ui.Home.Auth.Login.View, │ │75 auth_logout: ui.Home.Auth.Logout.View,│ ╰──────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │114 // whether moving up should return to the page header │ │115 pub fn atTop(self: *Widget, root_focus: *Focus) bool { │ │116 return switch (self.*) { │ │116 - inline .home_about, .home_users, .user_repos, .flow_box_scroll, .home_settings, .auth_login, .auth_logout, .quit, .repo_files, .repo_commits, .diff_view, .repo_refs, .repo_issues, .repo_patches, .repo_discussions, .repo_events, .repo_undo => |*view| view.atTop(), │ │117 + inline .home_about, .home_users, .user_repos, .flow_box_scroll, .home_settings, .new_repo, .auth_login, .auth_logout, .quit, .repo_files, .repo_commits, .diff_view, .repo_refs, .repo_issues, .repo_patches, .repo_discussions, .repo_events, .repo_undo => |*view| view.atTop(),│ │118 inline .home_auth, .repo_patch_detail => |*view| view.atTop(root_focus), │ │119 else => false, │ │120 }; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │948 // focused option, so a click selects on the web too. │ │949 pub const Radio = struct { │ │950 box: wgt.Box(Widget), │ │951 + name: []const u8, │ │952 values: []const []const u8, │ │953 │ │954 pub fn init(allocator: std.mem.Allocator, session: *ui.Session, name: []const u8, values: []const []const u8, initial: []const u8) !Radio {│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │962 if (std.mem.eql(u8, value, initial)) box.getFocus().child_id = option.getFocus().id; │ │963 try box.children.put(allocator, option.getFocus().id, .{ .widget = .{ .text_box = option }, .rect = null, .min_size = .{ .width = try xitui.width.displayWidth(value) + 2, .height = 3 } });│ │964 } │ │963 - return .{ .box = box, .values = values }; │ │965 + return .{ .box = box, .name = name, .values = values }; │ │966 } │ │967 │ │968 pub fn deinit(self: *Radio, allocator: std.mem.Allocator) void { │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ added ───────────╮ │src/ui/NewRepo.zig│ ╰──────────────────╯ ╭──────╮ │next →│ ╰──────╯