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(
\\ {} 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);