X-Git-Url: https://gitweb.ps.run/chirp/blobdiff_plain/12f0f2f8e72e933531b0ac6865265461d97e2312..4440a97c5a3bc8dca03198dbe0d9474978aa8904:/src/main.zig diff --git a/src/main.zig b/src/main.zig index 74070d6..7fe3b63 100644 --- a/src/main.zig +++ b/src/main.zig @@ -31,7 +31,6 @@ const User = struct { display_name: DisplayName, password_hash: PasswordHash, posts: PostList, - replies: PostList, following: UserList, followers: UserList, @@ -98,8 +97,8 @@ fn parse_enum(comptime E: type, buf: []const u8, base: u8) !E { } // https://developer.mozilla.org/en-US/docs/Glossary/Percent-encoding -fn reencode(text: []const u8) !PostText { - var result = try PostText.init(0); +fn reencode(comptime T: type, text: []const u8) !T { + var result = try T.init(0); const len = @min(text.len, 1024); // TODO: PostText length @@ -167,6 +166,9 @@ fn decode(text: []const u8) !std.BoundedArray(u8, 1024) { } const Chirp = struct { + const PostsPerPage = 10; + const UsersPerPage = 10; + pub fn hash_password(password: []const u8) !PasswordHash { var hash_buffer = try PasswordHash.init(128); @@ -223,7 +225,6 @@ const Chirp = struct { .display_name = display_name, .password_hash = try hash_password(password), .posts = try PostList.init(txn), - .replies = try PostList.init(txn), .following = try UserList.init(txn), .followers = try UserList.init(txn), .post_lists = try PostListList.init(txn), @@ -285,7 +286,7 @@ const Chirp = struct { const posts = try Db.posts(txn); post_id = try db.Prng.gen(posts.dbi, PostId); - const decoded_text = try reencode(text); + const decoded_text = try reencode(PostText, text); try posts.put(post_id, Post{ .id = post_id, .parent_id = parent_id, @@ -328,11 +329,7 @@ const Chirp = struct { txn.abort(); const post_id = try append_post(env, user_id, user.posts, null, null, text); - - txn = try env.txn(); - var replies_view = try user.replies.open(txn); - try replies_view.append(post_id); - try txn.commit(); + _ = post_id; } fn comment(env: lmdb.Env, user_id: UserId, parent_post_id: PostId, text: []const u8) !void { @@ -347,7 +344,7 @@ const Chirp = struct { const post_id = try append_post(env, user_id, parent_post.comments, parent_post_id, null, text); txn = try env.txn(); - var replies_view = try user.replies.open(txn); + var replies_view = try user.posts.open(txn); try replies_view.append(post_id); try txn.commit(); } @@ -359,11 +356,7 @@ const Chirp = struct { txn.abort(); const post_id = try append_post(env, user_id, user.posts, null, quote_post_id, text); - - txn = try env.txn(); - var replies_view = try user.replies.open(txn); - try replies_view.append(post_id); - try txn.commit(); + _ = post_id; } fn vote(env: lmdb.Env, post_id: PostId, user_id: UserId, kind: Vote.Kind) !void { @@ -450,6 +443,75 @@ const Chirp = struct { // }}} // html {{{ +pub fn Paginate(comptime T: type) type { + return struct { + const Self = @This(); + + const IterateResult = T.Base.View.Iterator.Result; + + res: *http.Response, + view: T.View, + per_page: u64, + + it: T.Base.View.Iterator, + starting_idx: ?T.Base.Key, + count: u64 = 0, + + pub fn init(res: *http.Response, view: T.View, per_page: u64) !Self { + var it = view.reverse_iterator(); + if (res.req.get_param("starting_at")) |starting_at_str| { + it.idx = try parse_enum(T.Base.Key, starting_at_str, 16); + } + + if (it.idx == null) { + return error.InvalidIterator; + } + + return .{ + .res = res, + .view = view, + .per_page = per_page, + .it = it, + .starting_idx = it.idx.?, + }; + } + pub fn next(self: *Self) IterateResult { + if (self.it.next()) |kv| { + if (self.count < self.per_page) { + self.count += 1; + return kv; + } + } + return null; + } + pub fn write_navigation(self: *Self) !void { + const next_idx = self.it.next(); + + if (self.view.base.head.last != self.starting_idx) { + var prev_it = self.view.iterator(); + prev_it.idx = self.starting_idx.?; + var oldest_idx = self.starting_idx.?; + + var count: u64 = 0; + while (prev_it.next()) |kv| { + oldest_idx = kv.key; + + if (count > self.per_page) { + break; + } else { + count += 1; + } + } + + try self.res.write("Prev ", .{ self.res.req.target, @intFromEnum(oldest_idx) }); + } + + if (next_idx) |kv| { + try self.res.write("Next", .{ self.res.req.target, @intFromEnum(kv.key) }); + } + } + }; +} fn html_form(res: *http.Response, action: []const u8, inputs: anytype) !void { try res.write("
", .{action}); @@ -521,17 +583,13 @@ fn write_header(res: *http.Response, logged_in: ?Login) !void { \\ \\ \\ - \\
+ \\
\\
\\ \\ \\ - \\
+ \\

, .{}); - try html_form(res, "/quit", .{ - \\type="submit" value="Quit" - }); - try res.write("

", .{}); } } fn write_start(res: *http.Response) !void { @@ -540,6 +598,7 @@ fn write_start(res: *http.Response) !void { \\ \\ \\ + \\ \\