v3: follows, notifications, invite-only registration, unread markers
This commit is contained in:
108
api/routes/follows.ts
Normal file
108
api/routes/follows.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import { Router } from "@oak/oak";
|
||||
import { authMiddleware } from "../middleware/auth.ts";
|
||||
import {
|
||||
type APIResponse,
|
||||
type Dump,
|
||||
type FollowStatus,
|
||||
type PaginatedData,
|
||||
} from "../model/interfaces.ts";
|
||||
import {
|
||||
followPlaylist,
|
||||
followUser,
|
||||
getFollowedPlaylistsDumpFeed,
|
||||
getFollowedUsersDumpFeed,
|
||||
getFollowStatus,
|
||||
unfollowPlaylist,
|
||||
unfollowUser,
|
||||
} from "../services/follow-service.ts";
|
||||
|
||||
const router = new Router({ prefix: "/api/follows" });
|
||||
|
||||
// Static routes first to prevent Oak matching "status"/"feed" as a :param
|
||||
|
||||
// GET /api/follows/status
|
||||
router.get("/status", authMiddleware, (ctx) => {
|
||||
const status = getFollowStatus(ctx.state.user.userId as string);
|
||||
const body: APIResponse<FollowStatus> = { success: true, data: status };
|
||||
ctx.response.body = body;
|
||||
});
|
||||
|
||||
// GET /api/follows/feed/users?page=&limit=
|
||||
router.get("/feed/users", authMiddleware, (ctx) => {
|
||||
const page = Math.max(
|
||||
1,
|
||||
parseInt(ctx.request.url.searchParams.get("page") ?? "1") || 1,
|
||||
);
|
||||
const limit = Math.min(
|
||||
Math.max(
|
||||
1,
|
||||
parseInt(ctx.request.url.searchParams.get("limit") ?? "20") || 20,
|
||||
),
|
||||
100,
|
||||
);
|
||||
const { items, total } = getFollowedUsersDumpFeed(
|
||||
ctx.state.user.userId as string,
|
||||
page,
|
||||
limit,
|
||||
);
|
||||
const data: PaginatedData<Dump> = {
|
||||
items,
|
||||
total,
|
||||
hasMore: page * limit < total,
|
||||
};
|
||||
const body: APIResponse<PaginatedData<Dump>> = { success: true, data };
|
||||
ctx.response.body = body;
|
||||
});
|
||||
|
||||
// GET /api/follows/feed/playlists?page=&limit=
|
||||
router.get("/feed/playlists", authMiddleware, (ctx) => {
|
||||
const page = Math.max(
|
||||
1,
|
||||
parseInt(ctx.request.url.searchParams.get("page") ?? "1") || 1,
|
||||
);
|
||||
const limit = Math.min(
|
||||
Math.max(
|
||||
1,
|
||||
parseInt(ctx.request.url.searchParams.get("limit") ?? "20") || 20,
|
||||
),
|
||||
100,
|
||||
);
|
||||
const { items, total } = getFollowedPlaylistsDumpFeed(
|
||||
ctx.state.user.userId as string,
|
||||
page,
|
||||
limit,
|
||||
);
|
||||
const data: PaginatedData<Dump> = {
|
||||
items,
|
||||
total,
|
||||
hasMore: page * limit < total,
|
||||
};
|
||||
const body: APIResponse<PaginatedData<Dump>> = { success: true, data };
|
||||
ctx.response.body = body;
|
||||
});
|
||||
|
||||
// POST /api/follows/users/:userId
|
||||
router.post("/users/:userId", authMiddleware, (ctx) => {
|
||||
followUser(ctx.state.user.userId as string, ctx.params.userId);
|
||||
ctx.response.status = 204;
|
||||
});
|
||||
|
||||
// DELETE /api/follows/users/:userId
|
||||
router.delete("/users/:userId", authMiddleware, (ctx) => {
|
||||
unfollowUser(ctx.state.user.userId as string, ctx.params.userId);
|
||||
ctx.response.status = 204;
|
||||
});
|
||||
|
||||
// POST /api/follows/playlists/:playlistId
|
||||
router.post("/playlists/:playlistId", authMiddleware, (ctx) => {
|
||||
followPlaylist(ctx.state.user.userId as string, ctx.params.playlistId);
|
||||
ctx.response.status = 204;
|
||||
});
|
||||
|
||||
// DELETE /api/follows/playlists/:playlistId
|
||||
router.delete("/playlists/:playlistId", authMiddleware, (ctx) => {
|
||||
unfollowPlaylist(ctx.state.user.userId as string, ctx.params.playlistId);
|
||||
ctx.response.status = 204;
|
||||
});
|
||||
|
||||
export default router;
|
||||
Reference in New Issue
Block a user