╭ changed ───────────╮ │src/ui/Repo/Undo.zig│ ╰────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │55 const moment = try DB.HashMap(.read_only).init(cursor); │ │56 const record = try xit.undo.read(opts, moment, &buffer); │ │57 var description: std.Io.Writer.Allocating = .init(aa); │ │58 - const detail = if (record) |value| try eventDetail(opts, arena, identity, value, moment) else null; │ │58 + const detail = if (record) |value| try eventDetail(opts, arena, identity, value, moment, remaining) else null;│ │59 if (detail) |value| { │ │60 try description.writer.writeAll(value.description); │ │61 } else if (record) |value| { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │92 identity: []const u8, │ │93 record: xit.undo.UndoRecord, │ │94 moment: rp.Repo(.xit, opts).DB.HashMap(.read_only), │ │95 + history_index: u64, │ │96 ) !?Detail { │ │97 if (std.mem.eql(u8, record.action, evt.merge_undo_action)) return .{ .action = "merge events", .description = "merged the events ref from a remote" };│ │98 if (!std.mem.eql(u8, record.action, evt.undo_action)) return null; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 99 │ │100 const description = "updated the event database"; │ │100 - const batch = try momentBatch(opts, moment) orelse return .{ .action = "events", .description = description }; │ │101 + const count = try momentEventCount(opts, moment) orelse return .{ .action = "events", .description = description }; │ │102 │ │103 + // the page reads the transaction's own moment, so the url names the │ │104 + // transaction rather than the state it produced │ │105 const aa = arena.allocator(); │ │103 - const route = ui.RoutablePage.repoEventsRoute(identity, .active, null, "", batch.index) orelse return error.RouteTooLong; │ │106 + const route = ui.RoutablePage.repoEventsRoute(identity, .active, null, "", history_index) orelse return error.RouteTooLong;│ │107 return .{ │ │105 - .action = try std.fmt.allocPrint(aa, "events ({d})", .{batch.count}), │ │108 + .action = try std.fmt.allocPrint(aa, "events ({d})", .{count}), │ │109 .description = description, │ │110 .events = .{ │ │108 - .label = try std.fmt.allocPrint(aa, "view events ({d})", .{batch.count}), │ │111 + .label = try std.fmt.allocPrint(aa, "view events ({d})", .{count}), │ │112 .link = try std.fmt.allocPrint(aa, "a:{s}", .{try route.toUrl(arena)}), │ │113 }, │ │114 }; │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │115 } │ │113 - │ │114 -const Batch = struct { index: u64, count: u64 }; │ │116 │ │116 -// the events the transaction's moment wrote, or null when it wrote none │ │117 -fn momentBatch(comptime opts: rp.RepoOpts(.xit), moment: rp.Repo(.xit, opts).DB.HashMap(.read_only)) !?Batch { │ │117 +// how many events the transaction's moment wrote, or null when it wrote none │ │118 +fn momentEventCount(comptime opts: rp.RepoOpts(.xit), moment: rp.Repo(.xit, opts).DB.HashMap(.read_only)) !?u64 { │ │119 const DB = rp.Repo(.xit, opts).DB; │ │120 const haxy_moment = evt.currentMomentFromRepoMoment(opts.hash, moment) catch return null; │ │121 const index_cursor = try haxy_moment.getCursor(hash.hashInt(opts.hash, evt.moment_index_key)) orelse return null;│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │121 - const moment_index = try index_cursor.readUint(); │ │122 - const ids = try evt.momentEventIds(DB, opts.hash, haxy_moment, moment_index) orelse return null; │ │123 - return .{ .index = moment_index, .count = try ids.count() }; │ │122 + const ids = try evt.momentEventIds(DB, opts.hash, haxy_moment, try index_cursor.readUint()) orelse return null;│ │123 + return try ids.count(); │ │124 } │ │125 │ │126 pub fn formatTimestamp(aa: std.mem.Allocator, timestamp: i64) ![]const u8 { │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯