Skip to content

Commit

Permalink
탬플릿 gql
Browse files Browse the repository at this point in the history
  • Loading branch information
robin-maki committed Jun 24, 2024
1 parent 9afb004 commit 67949fd
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 16 deletions.
1 change: 1 addition & 0 deletions apps/website/src/lib/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export const PostState = {
DRAFT: 'DRAFT',
EPHEMERAL: 'EPHEMERAL',
PUBLISHED: 'PUBLISHED',
TEMPLATE: 'TEMPLATE',
} as const;

export const PostSynchronizationKind = {
Expand Down
65 changes: 49 additions & 16 deletions apps/website/src/lib/server/graphql/schemas/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
BookmarkGroups,
database,
inArray,
notInArray,
PostComments,
PostContentSnapshots,
PostContentStates,
Expand Down Expand Up @@ -71,7 +72,7 @@ import {
useFirstRow,
useFirstRowOrThrow,
} from '$lib/server/utils';
import { base36To10, createEmptyTiptapDocumentNode } from '$lib/utils';
import { base36To10, createEmptyTiptapDocumentNode, getMetadataFromTiptapDocument } from '$lib/utils';
import { PublishPostInputSchema } from '$lib/validations/post';
import { builder } from '../builder';
import { pubsub } from '../pubsub';
Expand Down Expand Up @@ -1003,6 +1004,8 @@ const CreatePostInput = builder.inputType('CreatePostInput', {
fields: (t) => ({
spaceId: t.id({ required: false }),
collectionId: t.id({ required: false }),
isTemplate: t.boolean({ defaultValue: false }),
usingTemplate: t.id({ required: false }),
}),
});

Expand Down Expand Up @@ -1279,23 +1282,49 @@ builder.mutationFields((t) => ({
}

return await database.transaction(async (tx) => {
const publishOptions = input.usingTemplate
? await database
.select({
visibility: Posts.visibility,
discloseStats: Posts.discloseStats,
receiveFeedback: Posts.receiveFeedback,
receivePatronage: Posts.receivePatronage,
receiveTagContribution: Posts.receiveTagContribution,
protectContent: Posts.protectContent,
})
.from(Posts)
.where(and(eq(Posts.id, input.usingTemplate)))
.then(useFirstRowOrThrow(new NotFoundError()))
: ({
visibility: 'PUBLIC',
discloseStats: true,
receiveFeedback: true,
receivePatronage: true,
receiveTagContribution: true,
protectContent: true,
} as const);

const [post] = await tx
.insert(Posts)
.values({
permalink,
userId: context.session.userId,
spaceId: input.spaceId,
state: 'EPHEMERAL',
visibility: 'PUBLIC',
discloseStats: true,
receiveFeedback: true,
receivePatronage: true,
receiveTagContribution: true,
protectContent: true,
state: input.isTemplate ? 'TEMPLATE' : 'EPHEMERAL',
...publishOptions,
})
.returning({ id: Posts.id });

const node = createEmptyTiptapDocumentNode();
const metadata = input.usingTemplate
? await tx
.select({ content: PostContentStates.content })
.from(PostContentStates)
.where(eq(PostContentStates.postId, input.usingTemplate))
.then((rows) => getMetadataFromTiptapDocument(rows[0].content))
: null;

const node = metadata?.doc ?? createEmptyTiptapDocumentNode();

const doc = prosemirrorToYDoc(node, 'content');
const update = Y.encodeStateAsUpdateV2(doc);
const vector = Y.encodeStateVector(doc);
Expand All @@ -1307,10 +1336,10 @@ builder.mutationFields((t) => ({
vector,
upToSeq: 0n,
content: node.toJSON(),
text: '',
characters: 0,
images: 0,
files: 0,
text: metadata?.text ?? '',
characters: metadata?.characters ?? 0,
images: metadata?.images ?? 0,
files: metadata?.files ?? 0,
});

await tx.insert(PostContentSnapshots).values({
Expand Down Expand Up @@ -1350,7 +1379,7 @@ builder.mutationFields((t) => ({
.where(
and(
eq(Posts.id, input.postId),
ne(Posts.state, 'DELETED'),
notInArray(Posts.state, ['DELETED', 'TEMPLATE']),
or(eq(Spaces.state, 'ACTIVE'), isNull(Spaces.id)),
),
);
Expand Down Expand Up @@ -1519,7 +1548,9 @@ builder.mutationFields((t) => ({
.select({ userId: Posts.userId, space: { id: Spaces.id } })
.from(Posts)
.innerJoin(Spaces, eq(Spaces.id, Posts.spaceId))
.where(and(eq(Posts.id, input.postId), eq(Posts.state, 'PUBLISHED'), eq(Spaces.state, 'ACTIVE')));
.where(
and(eq(Posts.id, input.postId), inArray(Posts.state, ['PUBLISHED', 'TEMPLATE']), eq(Spaces.state, 'ACTIVE')),
);

if (posts.length === 0) {
throw new NotFoundError();
Expand Down Expand Up @@ -1565,7 +1596,9 @@ builder.mutationFields((t) => ({
.select({ userId: Posts.userId, space: { id: Spaces.id } })
.from(Posts)
.innerJoin(Spaces, eq(Spaces.id, Posts.spaceId))
.where(and(eq(Posts.id, input.postId), eq(Posts.state, 'PUBLISHED'), eq(Spaces.state, 'ACTIVE')));
.where(
and(eq(Posts.id, input.postId), inArray(Posts.state, ['PUBLISHED', 'TEMPLATE']), eq(Spaces.state, 'ACTIVE')),
);

if (posts.length === 0) {
throw new NotFoundError();
Expand Down
22 changes: 22 additions & 0 deletions apps/website/src/lib/server/graphql/schemas/template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { and, eq } from 'drizzle-orm';
import { database, Posts } from '$lib/server/database';
import { builder } from '../builder';
import { Post } from './post';

builder.inputType('CreateTemplateBasedPostInput', {
fields: (t) => ({
templateId: t.id(),
}),
});

builder.queryFields((t) => ({
templatePosts: t.withAuth({ user: true }).field({
type: [Post],
resolve: async (_, __, context) => {
return await database
.select()
.from(Posts)
.where(and(eq(Posts.state, 'TEMPLATE'), eq(Posts.userId, context.session.userId)));
},
}),
}));
1 change: 1 addition & 0 deletions apps/website/src/lib/utils/tiptap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const getMetadataFromTiptapDocument = (content: JSONContent) => {
});

return {
doc,
text,
characters,
images,
Expand Down

0 comments on commit 67949fd

Please sign in to comment.