╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────╮ │2358 color: bool = true, // false when NO_COLOR is set, which also hides the art │ │2359 // the terminal's reported default background, which the art blends toward │ │2360 terminal_background: ?Grid.Color.Rgb = null, │ │2361 - // port the web UI is served on, for the TUI/SSH footer's "http://localhost:<port>..."│ │2362 - // url. null on the web itself (no footer there). │ │2363 - web_port: ?u16 = null, │ │2361 + // the web UI's url, for the TUI/SSH footer. null on the web itself (no │ │2362 + // footer there). │ │2363 + web_url: ?[]const u8 = null, │ │2364 // the authorized_keys line of the key an ssh session connected with │ │2365 ssh_key: ?[]const u8 = null, │ │2366 // a host operation requested by a widget │ ╰────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │2583 // the selected ANSI art. the server serializes one image for WASM so │ │2584 // the browser does not need the whole build-generated collection. │ │2585 ansi_art: []const u8 = "", │ │2586 - // the bound git-service ports. absent in local mode, where remote urls │ │2587 - // are not shown. │ │2588 - git_http_port: ?u16 = null, │ │2589 - git_ssh_port: ?u16 = null, │ │2586 + // where git clones and pushes go. absent in local mode, where remote │ │2587 + // urls are not shown. │ │2588 + git_http_url: ?[]const u8 = null, │ │2589 + git_ssh_url: ?[]const u8 = null, │ │2590 git_ssh_prefix: []const u8 = "", │ │2591 // whether this session views a local repo or the server. unlike `local`│ │2592 // (the host-side filesystem source) this travels in the snapshot, so │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │3026 pub fn terminalWebUrl(allocator: std.mem.Allocator, session: *const Session, path: []const u8) ![]const u8 {│ │3027 // an absolute url is already complete │ │3028 if (!std.mem.startsWith(u8, path, "/")) return path; │ │3029 - return if (session.web_port) |port| │ │3030 - try allocator.print("http://localhost:{d}{s}", .{ port, path }) │ │3029 + return if (session.web_url) |web_url| │ │3030 + try allocator.print("{s}{s}", .{ web_url, path }) │ │3031 else │ │3032 path; │ │3033 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │3342 try box.children.put(allocator, id, .{ .widget = .{ .background = background }, .rect = null, .min_size = null }); │ │3343 break :bg_blk id; │ │3344 }; │ │3345 - if (session.web_port != null) { │ │3345 + if (session.web_url != null) { │ │3346 var footer = try widget.Footer.init(allocator, session); │ │3347 errdefer footer.deinit(allocator); │ │3348 try box.children.put(allocator, footer.getFocus().id, .{ .widget = .{ .footer = footer }, .rect = null, .min_size = .{ .width = null, .height = 1 } });│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────────────╮ │src/ui/Repo/Patches.zig│ ╰───────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │939 const status_kind = entry.record.event.status.kind(); │ │940 const target_branch = entry.record.event.target_branch; │ │941 │ │942 - if (status_kind != .merged and entry.fork_exists) if (session.data.git_ssh_port) |port| { │ │943 - const url = try aa.print("ssh://localhost:{d}/{s}+{s}", .{ port, entry.fork_identity, entry.id }); │ │942 + if (status_kind != .merged and entry.fork_exists) if (session.data.git_ssh_url) |ssh_url| { │ │943 + const url = try aa.print("{s}/{s}+{s}", .{ ssh_url, entry.fork_identity, entry.id }); │ │944 const push_command = try aa.print("git push {s} HEAD:patch", .{url}); │ │945 const clone_command = try aa.print("git clone {s}", .{url}); │ │946 const merge_command = try aa.print("git fetch '{s}' refs/heads/patch && git merge FETCH_HEAD", .{url});│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ───────────╮ │src/ui/Repo/Undo.zig│ ╰────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────╮ │370 │ │371 // the sub header holds the command that clears the history. a server │ │372 // without ssh has no way to. │ │373 - if (session.data.git_ssh_port) |port| { │ │373 + if (session.data.git_ssh_url) |ssh_url| { │ │374 var header_scroll = try ui.widget.HeaderScroll.init(allocator, session);│ │375 errdefer header_scroll.deinit(allocator); │ │376 { │ ╰─────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │377 const aa = session.page_arena.allocator(); │ │378 - const command = try aa.print("git push ssh://localhost:{d}/{s} :" ++ push.clear_undo_ref, .{ port, data.identity });│ │378 + const command = try aa.print("git push {s}/{s} :" ++ push.clear_undo_ref, .{ ssh_url, data.identity }); │ │379 var copyable_text = try ui.widget.CopyableText.init(allocator, session, &.{.{ │ │380 .text = command, │ │381 .copyable_text = try aa.print("{s}{s}", .{ session.data.git_ssh_prefix, command }), │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ────────╮ │src/ui/widget.zig│ ╰─────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │331 errdefer box.deinit(allocator); │ │332 │ │333 // built first so the text can center over it │ │334 - var remote_maybe: ?CopyableText = if (session.data.host_kind == .server and handle.canWrite()) if (session.data.git_ssh_port) |port| blk: { │ │334 + var remote_maybe: ?CopyableText = if (session.data.host_kind == .server and handle.canWrite()) if (session.data.git_ssh_url) |ssh_url| blk: {│ │335 // only repo pages flag a repo without commits │ │336 const identity = switch (handle.location) { │ │337 .repo => |identity| identity, │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │338 .fork => unreachable, │ │339 }; │ │340 const aa = session.page_arena.allocator(); │ │341 - const url = try aa.print("ssh://localhost:{d}/{s}", .{ port, identity });│ │341 + const url = try aa.print("{s}/{s}", .{ ssh_url, identity }); │ │342 break :blk try CopyableText.init(allocator, session, &.{.{ │ │343 .text = url, │ │344 .copyable_text = try aa.print("git remote add origin {s}", .{url}), │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2133 var ssh_index: ?usize = null; │ │2134 switch (handle.location) { │ │2135 .repo => |identity| { │ │2136 - const http_port = if (handle.read_access == .public) session.data.git_http_port else null;│ │2137 - if (http_port) |port| { │ │2138 - const url = try aa.print("http://localhost:{d}/{s}", .{ port, identity }); │ │2136 + const http_url = if (handle.read_access == .public) session.data.git_http_url else null; │ │2137 + if (http_url) |base| { │ │2138 + const url = try aa.print("{s}/{s}", .{ base, identity }); │ │2139 choices[count] = .{ │ │2140 .selector = "http", │ │2141 .text = url, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯