Add args to timeline controller
This commit is contained in:
parent
4e81441a0d
commit
4773a86313
4 changed files with 109 additions and 18 deletions
|
@ -57,6 +57,39 @@ pub const Community = services.communities.Community;
|
|||
pub const CommunityQueryArgs = services.communities.QueryArgs;
|
||||
pub const CommunityQueryResult = services.communities.QueryResult;
|
||||
|
||||
pub const NoteQueryArgs = services.notes.QueryArgs;
|
||||
|
||||
pub const TimelineArgs = struct {
|
||||
pub const PageDirection = NoteQueryArgs.PageDirection;
|
||||
pub const Prev = NoteQueryArgs.Prev;
|
||||
|
||||
max_items: usize = 20,
|
||||
|
||||
created_before: ?DateTime = null,
|
||||
created_after: ?DateTime = null,
|
||||
|
||||
prev: ?Prev = null,
|
||||
|
||||
page_direction: PageDirection = .forward,
|
||||
|
||||
fn from(args: NoteQueryArgs) TimelineArgs {
|
||||
return .{
|
||||
.max_items = args.max_items,
|
||||
.created_before = args.created_before,
|
||||
.created_after = args.created_after,
|
||||
.prev = args.prev,
|
||||
.page_direction = args.page_direction,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const TimelineResult = struct {
|
||||
items: []services.notes.Note,
|
||||
|
||||
prev_page: TimelineArgs,
|
||||
next_page: TimelineArgs,
|
||||
};
|
||||
|
||||
pub fn isAdminSetup(db: sql.Db) !bool {
|
||||
_ = services.communities.adminCommunityId(db) catch |err| switch (err) {
|
||||
error.NotFound => return false,
|
||||
|
@ -352,18 +385,25 @@ fn ApiConn(comptime DbConn: type) type {
|
|||
return try services.communities.query(self.db, args, self.arena.allocator());
|
||||
}
|
||||
|
||||
pub fn globalTimeline(self: *Self) ![]services.notes.Note {
|
||||
const result = try services.notes.query(self.db, .{}, self.arena.allocator());
|
||||
return result.items;
|
||||
pub fn globalTimeline(self: *Self, args: TimelineArgs) !TimelineResult {
|
||||
const all_args = std.mem.zeroInit(NoteQueryArgs, args);
|
||||
const result = try services.notes.query(self.db, all_args, self.arena.allocator());
|
||||
return TimelineResult{
|
||||
.items = result.items,
|
||||
.prev_page = TimelineArgs.from(result.prev_page),
|
||||
.next_page = TimelineArgs.from(result.next_page),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn localTimeline(self: *Self) ![]services.notes.Note {
|
||||
const result = try services.notes.query(
|
||||
self.db,
|
||||
.{ .community_id = self.community.id },
|
||||
self.arena.allocator(),
|
||||
);
|
||||
return result.items;
|
||||
pub fn localTimeline(self: *Self, args: TimelineArgs) !TimelineResult {
|
||||
var all_args = std.mem.zeroInit(NoteQueryArgs, args);
|
||||
all_args.community_id = self.community.id;
|
||||
const result = try services.notes.query(self.db, all_args, self.arena.allocator());
|
||||
return TimelineResult{
|
||||
.items = result.items,
|
||||
.prev_page = TimelineArgs.from(result.prev_page),
|
||||
.next_page = TimelineArgs.from(result.next_page),
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ const max_max_items = 100;
|
|||
|
||||
pub const QueryArgs = struct {
|
||||
pub const PageDirection = common.PageDirection;
|
||||
pub const Prev = std.meta.Child(std.meta.field(@This(), .prev).field_type);
|
||||
pub const Prev = std.meta.Child(std.meta.fieldInfo(@This(), .prev).field_type);
|
||||
|
||||
max_items: usize = 20,
|
||||
|
||||
|
|
|
@ -1,11 +1,27 @@
|
|||
const std = @import("std");
|
||||
const api = @import("api");
|
||||
const query_utils = @import("../query.zig");
|
||||
|
||||
pub const global = struct {
|
||||
pub const method = .GET;
|
||||
pub const path = "/timelines/global";
|
||||
|
||||
pub fn handler(_: anytype, res: anytype, srv: anytype) !void {
|
||||
const results = try srv.globalTimeline();
|
||||
pub const Query = api.TimelineArgs;
|
||||
|
||||
try res.json(.ok, results);
|
||||
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
|
||||
const results = try srv.globalTimeline(req.query);
|
||||
|
||||
var link = std.ArrayList(u8).init(req.allocator);
|
||||
const link_writer = link.writer();
|
||||
defer link.deinit();
|
||||
|
||||
try writeLink(link_writer, srv.community, path, results.next_page, "next");
|
||||
try link_writer.writeByte(',');
|
||||
try writeLink(link_writer, srv.community, path, results.prev_page, "prev");
|
||||
|
||||
try res.headers.put("Link", link.items);
|
||||
|
||||
try res.json(.ok, results.items);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -13,9 +29,45 @@ pub const local = struct {
|
|||
pub const method = .GET;
|
||||
pub const path = "/timelines/local";
|
||||
|
||||
pub fn handler(_: anytype, res: anytype, srv: anytype) !void {
|
||||
const results = try srv.localTimeline();
|
||||
pub const Query = api.TimelineArgs;
|
||||
|
||||
try res.json(.ok, results);
|
||||
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
|
||||
const results = try srv.localTimeline(req.query);
|
||||
|
||||
var link = std.ArrayList(u8).init(req.allocator);
|
||||
const link_writer = link.writer();
|
||||
defer link.deinit();
|
||||
|
||||
try writeLink(link_writer, srv.community, path, results.next_page, "next");
|
||||
try link_writer.writeByte(',');
|
||||
try writeLink(link_writer, srv.community, path, results.prev_page, "prev");
|
||||
|
||||
try res.headers.put("Link", link.items);
|
||||
|
||||
try res.json(.ok, results.items);
|
||||
}
|
||||
};
|
||||
|
||||
// TOOD: unify with communities.zig
|
||||
fn writeLink(
|
||||
writer: anytype,
|
||||
community: api.Community,
|
||||
path: []const u8,
|
||||
params: anytype,
|
||||
rel: []const u8,
|
||||
) !void {
|
||||
// TODO: percent-encode
|
||||
try std.fmt.format(
|
||||
writer,
|
||||
"<{s}://{s}/{s}?",
|
||||
.{ @tagName(community.scheme), community.host, path },
|
||||
);
|
||||
|
||||
try query_utils.formatQuery(params, writer);
|
||||
|
||||
try std.fmt.format(
|
||||
writer,
|
||||
">; rel=\"{s}\"",
|
||||
.{rel},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -279,7 +279,6 @@ fn format(comptime prefix: []const u8, comptime name: []const u8, params: anytyp
|
|||
}
|
||||
},
|
||||
.Union => {
|
||||
//inline for (std.meta.tags(T)) |tag| {
|
||||
inline for (std.meta.fields(T)) |field| {
|
||||
const tag = @field(std.meta.Tag(T), field.name);
|
||||
const tag_name = field.name;
|
||||
|
|
Loading…
Reference in a new issue