diff --git a/src/api/lib.zig b/src/api/lib.zig index 5db4791..21f9249 100644 --- a/src/api/lib.zig +++ b/src/api/lib.zig @@ -492,6 +492,11 @@ fn ApiConn(comptime DbConn: type) type { defer util.deepFree(self.arena.allocator(), result); } + pub fn unfollow(self: *Self, followee: Uuid) !void { + const result = try services.follows.delete(self.db, self.user_id orelse return error.NoToken, followee, self.arena.allocator()); + defer util.deepFree(self.arena.allocator(), result); + } + pub fn getClusterMeta(self: *Self) !ClusterMeta { return try self.db.queryRow( ClusterMeta, diff --git a/src/api/services/follows.zig b/src/api/services/follows.zig index dc4f5c7..7da65b7 100644 --- a/src/api/services/follows.zig +++ b/src/api/services/follows.zig @@ -33,6 +33,17 @@ pub fn create(db: anytype, followed_by_id: Uuid, followee_id: Uuid, alloc: std.m }; } +pub fn delete(db: anytype, followed_by_id: Uuid, followee_id: Uuid, alloc: std.mem.Allocator) !void { + // TODO: Measure count and report success + db.exec( + \\DELETE FROM follow + \\WHERE followed_by_id = $1 AND followee_id = $2 + , + .{ followed_by_id, followee_id }, + alloc, + ) catch return error.DatabaseFailure; +} + const max_max_items = 100; pub const QueryArgs = struct { diff --git a/src/main/controllers.zig b/src/main/controllers.zig index 38c81ae..e88ed3b 100644 --- a/src/main/controllers.zig +++ b/src/main/controllers.zig @@ -50,6 +50,7 @@ const routes = .{ timelines.local, timelines.home, follows.create, + follows.delete, follows.query_followers, follows.query_following, } ++ web.routes; diff --git a/src/main/controllers/api/users/follows.zig b/src/main/controllers/api/users/follows.zig index 8665718..6e3e6e7 100644 --- a/src/main/controllers/api/users/follows.zig +++ b/src/main/controllers/api/users/follows.zig @@ -19,6 +19,21 @@ pub const create = struct { } }; +pub const delete = struct { + pub const method = .DELETE; + pub const path = "/api/v0/users/:id/follow"; + + pub const Args = struct { + id: Uuid, + }; + + pub fn handler(req: anytype, res: anytype, srv: anytype) !void { + try srv.unfollow(req.args.id); + + try res.json(.ok, .{}); + } +}; + pub const query_followers = struct { pub const method = .GET; pub const path = "/api/v0/users/:id/followers";