X-Git-Url: https://gitweb.ps.run/chirp/blobdiff_plain/159b5e88014eb1084a1a3be64d8b0259b409f74d..1b308659679ddf5c21bd1321116e7a690fe5abf3:/src/main.zig diff --git a/src/main.zig b/src/main.zig index 78c7cb0..80a174a 100644 --- a/src/main.zig +++ b/src/main.zig @@ -602,9 +602,6 @@ fn write_post(res: *http.Response, txn: lmdb.Txn, logged_in: ?Login, post_id: Po try res.write( \\🔁 {} , .{ @intFromEnum(post.id), quotes_view.len() }); - try res.write( - \\
- , .{}); // Save to List if (logged_in) |login| { @@ -626,7 +623,7 @@ fn write_post(res: *http.Response, txn: lmdb.Txn, logged_in: ?Login, post_id: Po // Comment field // TODO: maybe always show comment field and prompt for login if (options.show_comment_field and logged_in != null) { - try res.write("
", .{}); + try res.write("

", .{}); try html_form(res, "/comment", .{}, .{ .{ "type=\"hidden\" value=\"{x}\" name=\"post_id\"", .{@intFromEnum(post.id)} }, "type=\"text\" name=\"text\" placeholder=\"Text\"", @@ -683,8 +680,8 @@ fn write_timeline(res: *http.Response, txn: lmdb.Txn, logged_in: ?Login, user_li while (true) { var newest_post: ?Post = null; - var it = following.iterator(); - while (it.next()) |following_id| { + var following_it = following.iterator(); + while (following_it.next()) |following_id| { const followed_user = try users.get(following_id); const followed_posts = try followed_user.posts.open(txn); @@ -694,10 +691,11 @@ fn write_timeline(res: *http.Response, txn: lmdb.Txn, logged_in: ?Login, user_li var followed_posts_it = followed_posts.reverse_iterator(); while (followed_posts_it.next()) |followed_post_id| { - const last_post = try posts.get(followed_post_id); + const p = try posts.get(followed_post_id); - if ((prev_newest_post == null or last_post.time < prev_newest_post.?.time) and (newest_post == null or newest_post.?.time < last_post.time)) { - newest_post = last_post; + if ((prev_newest_post == null or p.time < prev_newest_post.?.time) and (newest_post == null or newest_post.?.time < p.time)) { + newest_post = p; + break; } } } @@ -782,7 +780,10 @@ const GET = struct { user.name.constSlice(), user.display_name.constSlice(), }); if (self.logged_in != null and user_id != self.logged_in.?.user.id) { - if (try followers.has(self.logged_in.?.user.id)) { + const login = self.logged_in.?; + + // follow/unfollow + if (try followers.has(login.user.id)) { try html_form(self.res, "/follow", .{}, .{ .{ "type=\"hidden\" name=\"user_id\" value=\"{x}\"", .{@intFromEnum(user_id)} }, \\type="submit" value="Unfollow" @@ -793,6 +794,21 @@ const GET = struct { \\type="submit" value="Follow" }); } + + // add to feed + const feeds_view = try login.user.feeds.open(self.txn); + try self.res.write("
", .{}); + try self.res.write("", .{}); + try self.res.write("", .{@intFromEnum(user_id)}); + try self.res.write("", .{}); + try self.res.write("
", .{}); } try self.res.write( \\ {} following @@ -885,13 +901,15 @@ const GET = struct { const referer = if (self.req.get_header("Referer")) |ref| ref else self.req.target; - try html_form(self.res, "/quote", .{}, .{ - .{ "type=\"hidden\" name=\"referer\" value=\"{s}\"", .{referer} }, - .{ "type=\"hidden\" name=\"post_id\" value=\"{x}\"", .{@intFromEnum(post.id)} }, - "type=\"text\" name=\"text\" placeholder=\"Text\"", - "type=\"submit\" value=\"Quote\"", - }); - try self.res.write("
", .{}); + if (self.logged_in != null) { + try html_form(self.res, "/quote", .{}, .{ + .{ "type=\"hidden\" name=\"referer\" value=\"{s}\"", .{referer} }, + .{ "type=\"hidden\" name=\"post_id\" value=\"{x}\"", .{@intFromEnum(post.id)} }, + "type=\"text\" name=\"text\" placeholder=\"Text\"", + "type=\"submit\" value=\"Quote\"", + }); + try self.res.write("
", .{}); + } const quotes_view = try post.quotes.open(self.txn); var it = quotes_view.iterator(); @@ -900,7 +918,7 @@ const GET = struct { try self.res.write("
", .{}); } } - pub fn @"/list/"(self: Self, args: struct { list_id: PostListList.Index }) !void { + pub fn @"/list/"(self: Self, args: struct { list_id: PostList.Index }) !void { try write_posts(self.res, self.txn, self.logged_in, PostList{ .idx = args.list_id }); } pub fn @"/lists"(self: Self) !void { @@ -926,6 +944,32 @@ const GET = struct { try self.res.write("not logged in", .{}); } } + pub fn @"/feed/"(self: Self, args: struct { feed_id: UserList.Index }) !void { + try write_timeline(self.res, self.txn, self.logged_in, UserList{ .idx = args.feed_id }); + } + pub fn @"/feeds"(self: Self) !void { + if (self.logged_in) |login| { + const feeds_view = try login.user.feeds.open(self.txn); + + try html_form(self.res, "/new_feed", .{}, .{ + "type=\"text\" name=\"name\"", + "type=\"submit\" value=\"Add\"", + }); + + try self.res.write("

", .{}); + + var it = feeds_view.iterator(); + while (it.next()) |kv| { + const name = kv.val.name; + const user_list = kv.val.list; + try self.res.write( + \\{s}
+ , .{ user_list.idx.?, name.constSlice() }); + } + } else { + try self.res.write("not logged in", .{}); + } + } pub fn @"/post"(self: Self) !void { if (self.logged_in) |login| { _ = login; @@ -1124,10 +1168,12 @@ const POST = struct { } } } + // TODO: add arguments instead of parsing manually pub fn @"/new_list"(self: Self) !void { if (self.logged_in) |login| { const name_str = self.req.get_value("name") orelse return error.NoName; const name = try Name.fromSlice(name_str); + // TODO: decode name var txn = try self.env.txn(); @@ -1154,7 +1200,6 @@ const POST = struct { const post_list = PostList{ .idx = list_id }; var post_list_view = try post_list.open(txn); - std.debug.print("adding {x} to {x}\n", .{ post_id, list_id }); if (try post_list_view.has(post_id)) { try post_list_view.del(post_id); } else { @@ -1162,6 +1207,43 @@ const POST = struct { } } } + pub fn @"/new_feed"(self: Self) !void { + if (self.logged_in) |login| { + const name_str = self.req.get_value("name") orelse return error.NoName; + const name = try Name.fromSlice(name_str); + + var txn = try self.env.txn(); + + const userlist = try UserList.init(txn); + try txn.commit(); + + txn = try self.env.txn(); + var feeds_view = try login.user.feeds.open(txn); + _ = try feeds_view.append(.{ .name = name, .list = userlist }); + try txn.commit(); + } + } + pub fn @"/feed_add"(self: Self) !void { + if (self.logged_in) |login| { + _ = login; + + const list_id_str = self.req.get_value("feed_id") orelse return error.NoListId; + const user_id_str = self.req.get_value("user_id") orelse return error.NoUserId; + const list_id = try std.fmt.parseUnsigned(UserList.Index, list_id_str, 16); + const user_id = try parse_enum(UserId, user_id_str, 16); + + const txn = try self.env.txn(); + defer txn.commit() catch {}; + + const user_list = UserList{ .idx = list_id }; + var user_list_view = try user_list.open(txn); + if (try user_list_view.has(user_id)) { + try user_list_view.del(user_id); + } else { + try user_list_view.append(user_id); + } + } + } pub fn @"/upvote"(self: Self) !void { const login = self.logged_in orelse return error.NotLoggedIn; @@ -1301,6 +1383,7 @@ fn handle_connection(server: *http.Server, env: lmdb.Env) !void { while (try server.next_request(&req_buffer)) |*_req| { var req: *http.Request = @constCast(_req); // std.debug.print("[{}]: {s}\n", .{ req.method, req.target }); + // std.debug.print("[{}]: {s}\n", .{ req.method, req.head.? }); // reponse var res = http.Response.init(req.fd, &res_head_buffer, &res_body_buffer);