diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2021-04-24 22:38:24 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-04-24 22:38:24 +0900 |
| commit | fec3c70886c13a267814e7eba5d2dd9aa807687b (patch) | |
| tree | d88fcd2904b964a30a925be6e1b26e1e51ee329d /src/server/api/endpoints/gallery | |
| parent | Tweak UI (diff) | |
| download | sharkey-fec3c70886c13a267814e7eba5d2dd9aa807687b.tar.gz sharkey-fec3c70886c13a267814e7eba5d2dd9aa807687b.tar.bz2 sharkey-fec3c70886c13a267814e7eba5d2dd9aa807687b.zip | |
Gallery (#7194)
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
Diffstat (limited to 'src/server/api/endpoints/gallery')
| -rw-r--r-- | src/server/api/endpoints/gallery/featured.ts | 29 | ||||
| -rw-r--r-- | src/server/api/endpoints/gallery/popular.ts | 28 | ||||
| -rw-r--r-- | src/server/api/endpoints/gallery/posts.ts | 43 | ||||
| -rw-r--r-- | src/server/api/endpoints/gallery/posts/create.ts | 76 | ||||
| -rw-r--r-- | src/server/api/endpoints/gallery/posts/like.ts | 71 | ||||
| -rw-r--r-- | src/server/api/endpoints/gallery/posts/show.ts | 43 | ||||
| -rw-r--r-- | src/server/api/endpoints/gallery/posts/unlike.ts | 54 |
7 files changed, 344 insertions, 0 deletions
diff --git a/src/server/api/endpoints/gallery/featured.ts b/src/server/api/endpoints/gallery/featured.ts new file mode 100644 index 0000000000..d09000cc71 --- /dev/null +++ b/src/server/api/endpoints/gallery/featured.ts @@ -0,0 +1,29 @@ +import define from '../../define'; +import { GalleryPosts } from '../../../../models'; + +export const meta = { + tags: ['gallery'], + + requireCredential: false as const, + + res: { + type: 'array' as const, + optional: false as const, nullable: false as const, + items: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'GalleryPost', + } + }, +}; + +export default define(meta, async (ps, me) => { + const query = GalleryPosts.createQueryBuilder('post') + .andWhere('post.createdAt > :date', { date: new Date(Date.now() - (1000 * 60 * 60 * 24 * 3)) }) + .andWhere('post.likedCount > 0') + .orderBy('post.likedCount', 'DESC'); + + const posts = await query.take(10).getMany(); + + return await GalleryPosts.packMany(posts, me); +}); diff --git a/src/server/api/endpoints/gallery/popular.ts b/src/server/api/endpoints/gallery/popular.ts new file mode 100644 index 0000000000..e240b14d27 --- /dev/null +++ b/src/server/api/endpoints/gallery/popular.ts @@ -0,0 +1,28 @@ +import define from '../../define'; +import { GalleryPosts } from '../../../../models'; + +export const meta = { + tags: ['gallery'], + + requireCredential: false as const, + + res: { + type: 'array' as const, + optional: false as const, nullable: false as const, + items: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'GalleryPost', + } + }, +}; + +export default define(meta, async (ps, me) => { + const query = GalleryPosts.createQueryBuilder('post') + .andWhere('post.likedCount > 0') + .orderBy('post.likedCount', 'DESC'); + + const posts = await query.take(10).getMany(); + + return await GalleryPosts.packMany(posts, me); +}); diff --git a/src/server/api/endpoints/gallery/posts.ts b/src/server/api/endpoints/gallery/posts.ts new file mode 100644 index 0000000000..656765d80a --- /dev/null +++ b/src/server/api/endpoints/gallery/posts.ts @@ -0,0 +1,43 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import define from '../../define'; +import { makePaginationQuery } from '../../common/make-pagination-query'; +import { GalleryPosts } from '../../../../models'; + +export const meta = { + tags: ['gallery'], + + params: { + limit: { + validator: $.optional.num.range(1, 100), + default: 10 + }, + + sinceId: { + validator: $.optional.type(ID), + }, + + untilId: { + validator: $.optional.type(ID), + }, + }, + + res: { + type: 'array' as const, + optional: false as const, nullable: false as const, + items: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'GalleryPost', + } + }, +}; + +export default define(meta, async (ps, me) => { + const query = makePaginationQuery(GalleryPosts.createQueryBuilder('post'), ps.sinceId, ps.untilId) + .innerJoinAndSelect('post.user', 'user'); + + const posts = await query.take(ps.limit!).getMany(); + + return await GalleryPosts.packMany(posts, me); +}); diff --git a/src/server/api/endpoints/gallery/posts/create.ts b/src/server/api/endpoints/gallery/posts/create.ts new file mode 100644 index 0000000000..d1ae68b126 --- /dev/null +++ b/src/server/api/endpoints/gallery/posts/create.ts @@ -0,0 +1,76 @@ +import $ from 'cafy'; +import * as ms from 'ms'; +import define from '../../../define'; +import { ID } from '../../../../../misc/cafy-id'; +import { DriveFiles, GalleryPosts } from '../../../../../models'; +import { genId } from '../../../../../misc/gen-id'; +import { GalleryPost } from '../../../../../models/entities/gallery-post'; +import { ApiError } from '../../../error'; + +export const meta = { + tags: ['gallery'], + + requireCredential: true as const, + + kind: 'write:gallery', + + limit: { + duration: ms('1hour'), + max: 300 + }, + + params: { + title: { + validator: $.str.min(1), + }, + + description: { + validator: $.optional.nullable.str, + }, + + fileIds: { + validator: $.arr($.type(ID)).unique().range(1, 32), + }, + + isSensitive: { + validator: $.optional.bool, + default: false, + }, + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'GalleryPost', + }, + + errors: { + + } +}; + +export default define(meta, async (ps, user) => { + const files = (await Promise.all(ps.fileIds.map(fileId => + DriveFiles.findOne({ + id: fileId, + userId: user.id + }) + ))).filter(file => file != null); + + if (files.length === 0) { + throw new Error(); + } + + const post = await GalleryPosts.insert(new GalleryPost({ + id: genId(), + createdAt: new Date(), + updatedAt: new Date(), + title: ps.title, + description: ps.description, + userId: user.id, + isSensitive: ps.isSensitive, + fileIds: files.map(file => file.id) + })).then(x => GalleryPosts.findOneOrFail(x.identifiers[0])); + + return await GalleryPosts.pack(post, user); +}); diff --git a/src/server/api/endpoints/gallery/posts/like.ts b/src/server/api/endpoints/gallery/posts/like.ts new file mode 100644 index 0000000000..3bf37c13e3 --- /dev/null +++ b/src/server/api/endpoints/gallery/posts/like.ts @@ -0,0 +1,71 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import define from '../../../define'; +import { ApiError } from '../../../error'; +import { GalleryPosts, GalleryLikes } from '../../../../../models'; +import { genId } from '@/misc/gen-id'; + +export const meta = { + tags: ['gallery'], + + requireCredential: true as const, + + kind: 'write:gallery-likes', + + params: { + postId: { + validator: $.type(ID), + } + }, + + errors: { + noSuchPost: { + message: 'No such post.', + code: 'NO_SUCH_POST', + id: '56c06af3-1287-442f-9701-c93f7c4a62ff' + }, + + yourPost: { + message: 'You cannot like your post.', + code: 'YOUR_POST', + id: 'f78f1511-5ebc-4478-a888-1198d752da68' + }, + + alreadyLiked: { + message: 'The post has already been liked.', + code: 'ALREADY_LIKED', + id: '40e9ed56-a59c-473a-bf3f-f289c54fb5a7' + }, + } +}; + +export default define(meta, async (ps, user) => { + const post = await GalleryPosts.findOne(ps.postId); + if (post == null) { + throw new ApiError(meta.errors.noSuchPost); + } + + if (post.userId === user.id) { + throw new ApiError(meta.errors.yourPost); + } + + // if already liked + const exist = await GalleryLikes.findOne({ + postId: post.id, + userId: user.id + }); + + if (exist != null) { + throw new ApiError(meta.errors.alreadyLiked); + } + + // Create like + await GalleryLikes.insert({ + id: genId(), + createdAt: new Date(), + postId: post.id, + userId: user.id + }); + + GalleryPosts.increment({ id: post.id }, 'likedCount', 1); +}); diff --git a/src/server/api/endpoints/gallery/posts/show.ts b/src/server/api/endpoints/gallery/posts/show.ts new file mode 100644 index 0000000000..17628544b7 --- /dev/null +++ b/src/server/api/endpoints/gallery/posts/show.ts @@ -0,0 +1,43 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import define from '../../../define'; +import { ApiError } from '../../../error'; +import { GalleryPosts } from '@/models'; + +export const meta = { + tags: ['gallery'], + + requireCredential: false as const, + + params: { + postId: { + validator: $.type(ID), + }, + }, + + errors: { + noSuchPost: { + message: 'No such post.', + code: 'NO_SUCH_POST', + id: '1137bf14-c5b0-4604-85bb-5b5371b1cd45' + }, + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'GalleryPost' + } +}; + +export default define(meta, async (ps, me) => { + const post = await GalleryPosts.findOne({ + id: ps.postId, + }); + + if (post == null) { + throw new ApiError(meta.errors.noSuchPost); + } + + return await GalleryPosts.pack(post, me); +}); diff --git a/src/server/api/endpoints/gallery/posts/unlike.ts b/src/server/api/endpoints/gallery/posts/unlike.ts new file mode 100644 index 0000000000..155949ae3d --- /dev/null +++ b/src/server/api/endpoints/gallery/posts/unlike.ts @@ -0,0 +1,54 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import define from '../../../define'; +import { ApiError } from '../../../error'; +import { GalleryPosts, GalleryLikes } from '../../../../../models'; + +export const meta = { + tags: ['gallery'], + + requireCredential: true as const, + + kind: 'write:gallery-likes', + + params: { + postId: { + validator: $.type(ID), + } + }, + + errors: { + noSuchPost: { + message: 'No such post.', + code: 'NO_SUCH_POST', + id: 'c32e6dd0-b555-4413-925e-b3757d19ed84' + }, + + notLiked: { + message: 'You have not liked that post.', + code: 'NOT_LIKED', + id: 'e3e8e06e-be37-41f7-a5b4-87a8250288f0' + }, + } +}; + +export default define(meta, async (ps, user) => { + const post = await GalleryPosts.findOne(ps.postId); + if (post == null) { + throw new ApiError(meta.errors.noSuchPost); + } + + const exist = await GalleryLikes.findOne({ + postId: post.id, + userId: user.id + }); + + if (exist == null) { + throw new ApiError(meta.errors.notLiked); + } + + // Delete like + await GalleryLikes.delete(exist.id); + + GalleryPosts.decrement({ id: post.id }, 'likedCount', 1); +}); |