summaryrefslogtreecommitdiff
path: root/src/models
diff options
context:
space:
mode:
Diffstat (limited to 'src/models')
-rw-r--r--src/models/entities/gallery-like.ts33
-rw-r--r--src/models/entities/gallery-post.ts79
-rw-r--r--src/models/index.ts4
-rw-r--r--src/models/repositories/gallery-like.ts25
-rw-r--r--src/models/repositories/gallery-post.ts113
5 files changed, 254 insertions, 0 deletions
diff --git a/src/models/entities/gallery-like.ts b/src/models/entities/gallery-like.ts
new file mode 100644
index 0000000000..7d084a2275
--- /dev/null
+++ b/src/models/entities/gallery-like.ts
@@ -0,0 +1,33 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+import { GalleryPost } from './gallery-post';
+
+@Entity()
+@Index(['userId', 'postId'], { unique: true })
+export class GalleryLike {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Column('timestamp with time zone')
+ public createdAt: Date;
+
+ @Index()
+ @Column(id())
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Column(id())
+ public postId: GalleryPost['id'];
+
+ @ManyToOne(type => GalleryPost, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public post: GalleryPost | null;
+}
diff --git a/src/models/entities/gallery-post.ts b/src/models/entities/gallery-post.ts
new file mode 100644
index 0000000000..f59cd671f3
--- /dev/null
+++ b/src/models/entities/gallery-post.ts
@@ -0,0 +1,79 @@
+import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+import { DriveFile } from './drive-file';
+
+@Entity()
+export class GalleryPost {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the GalleryPost.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The updated date of the GalleryPost.'
+ })
+ public updatedAt: Date;
+
+ @Column('varchar', {
+ length: 256,
+ })
+ public title: string;
+
+ @Column('varchar', {
+ length: 2048, nullable: true
+ })
+ public description: string | null;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The ID of author.'
+ })
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Index()
+ @Column({
+ ...id(),
+ array: true, default: '{}'
+ })
+ public fileIds: DriveFile['id'][];
+
+ @Index()
+ @Column('boolean', {
+ default: false,
+ comment: 'Whether the post is sensitive.'
+ })
+ public isSensitive: boolean;
+
+ @Index()
+ @Column('integer', {
+ default: 0
+ })
+ public likedCount: number;
+
+ @Index()
+ @Column('varchar', {
+ length: 128, array: true, default: '{}'
+ })
+ public tags: string[];
+
+ constructor(data: Partial<GalleryPost>) {
+ if (data == null) return;
+
+ for (const [k, v] of Object.entries(data)) {
+ (this as any)[k] = v;
+ }
+ }
+}
diff --git a/src/models/index.ts b/src/models/index.ts
index 213570a9c4..9d08e49858 100644
--- a/src/models/index.ts
+++ b/src/models/index.ts
@@ -43,6 +43,8 @@ import { UserSecurityKey } from './entities/user-security-key';
import { HashtagRepository } from './repositories/hashtag';
import { PageRepository } from './repositories/page';
import { PageLikeRepository } from './repositories/page-like';
+import { GalleryPostRepository } from './repositories/gallery-post';
+import { GalleryLikeRepository } from './repositories/gallery-like';
import { ModerationLogRepository } from './repositories/moderation-logs';
import { UsedUsername } from './entities/used-username';
import { ClipRepository } from './repositories/clip';
@@ -105,6 +107,8 @@ export const ReversiMatchings = getCustomRepository(ReversiMatchingRepository);
export const Logs = getRepository(Log);
export const Pages = getCustomRepository(PageRepository);
export const PageLikes = getCustomRepository(PageLikeRepository);
+export const GalleryPosts = getCustomRepository(GalleryPostRepository);
+export const GalleryLikes = getCustomRepository(GalleryLikeRepository);
export const ModerationLogs = getCustomRepository(ModerationLogRepository);
export const Clips = getCustomRepository(ClipRepository);
export const ClipNotes = getRepository(ClipNote);
diff --git a/src/models/repositories/gallery-like.ts b/src/models/repositories/gallery-like.ts
new file mode 100644
index 0000000000..e01c17cff5
--- /dev/null
+++ b/src/models/repositories/gallery-like.ts
@@ -0,0 +1,25 @@
+import { EntityRepository, Repository } from 'typeorm';
+import { GalleryLike } from '../entities/gallery-like';
+import { GalleryPosts } from '..';
+
+@EntityRepository(GalleryLike)
+export class GalleryLikeRepository extends Repository<GalleryLike> {
+ public async pack(
+ src: GalleryLike['id'] | GalleryLike,
+ me?: any
+ ) {
+ const like = typeof src === 'object' ? src : await this.findOneOrFail(src);
+
+ return {
+ id: like.id,
+ post: await GalleryPosts.pack(like.post || like.postId, me),
+ };
+ }
+
+ public packMany(
+ likes: any[],
+ me: any
+ ) {
+ return Promise.all(likes.map(x => this.pack(x, me)));
+ }
+}
diff --git a/src/models/repositories/gallery-post.ts b/src/models/repositories/gallery-post.ts
new file mode 100644
index 0000000000..f1d6fe6326
--- /dev/null
+++ b/src/models/repositories/gallery-post.ts
@@ -0,0 +1,113 @@
+import { EntityRepository, Repository } from 'typeorm';
+import { GalleryPost } from '../entities/gallery-post';
+import { SchemaType } from '../../misc/schema';
+import { Users, DriveFiles, GalleryLikes } from '..';
+import { awaitAll } from '../../prelude/await-all';
+import { User } from '../entities/user';
+
+export type PackedGalleryPost = SchemaType<typeof packedGalleryPostSchema>;
+
+@EntityRepository(GalleryPost)
+export class GalleryPostRepository extends Repository<GalleryPost> {
+ public async pack(
+ src: GalleryPost['id'] | GalleryPost,
+ me?: { id: User['id'] } | null | undefined,
+ ): Promise<PackedGalleryPost> {
+ const meId = me ? me.id : null;
+ const post = typeof src === 'object' ? src : await this.findOneOrFail(src);
+
+ return await awaitAll({
+ id: post.id,
+ createdAt: post.createdAt.toISOString(),
+ updatedAt: post.updatedAt.toISOString(),
+ userId: post.userId,
+ user: Users.pack(post.user || post.userId, me),
+ title: post.title,
+ description: post.description,
+ fileIds: post.fileIds,
+ files: DriveFiles.packMany(post.fileIds),
+ tags: post.tags.length > 0 ? post.tags : undefined,
+ isSensitive: post.isSensitive,
+ likedCount: post.likedCount,
+ isLiked: meId ? await GalleryLikes.findOne({ postId: post.id, userId: meId }).then(x => x != null) : undefined,
+ });
+ }
+
+ public packMany(
+ posts: GalleryPost[],
+ me?: { id: User['id'] } | null | undefined,
+ ) {
+ return Promise.all(posts.map(x => this.pack(x, me)));
+ }
+}
+
+export const packedGalleryPostSchema = {
+ type: 'object' as const,
+ optional: false as const, nullable: false as const,
+ properties: {
+ id: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ format: 'id',
+ example: 'xxxxxxxxxx',
+ },
+ createdAt: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ format: 'date-time',
+ },
+ updatedAt: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ format: 'date-time',
+ },
+ title: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ },
+ description: {
+ type: 'string' as const,
+ optional: false as const, nullable: true as const,
+ },
+ userId: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ format: 'id',
+ },
+ user: {
+ type: 'object' as const,
+ ref: 'User',
+ optional: false as const, nullable: false as const,
+ },
+ fileIds: {
+ type: 'array' as const,
+ optional: true as const, nullable: false as const,
+ items: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ format: 'id'
+ }
+ },
+ files: {
+ type: 'array' as const,
+ optional: true as const, nullable: false as const,
+ items: {
+ type: 'object' as const,
+ optional: false as const, nullable: false as const,
+ ref: 'DriveFile'
+ }
+ },
+ tags: {
+ type: 'array' as const,
+ optional: true as const, nullable: false as const,
+ items: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ }
+ },
+ isSensitive: {
+ type: 'boolean' as const,
+ optional: false as const, nullable: false as const,
+ },
+ }
+};