Skip to content

Commit

Permalink
feat: add markdown rendering feature
Browse files Browse the repository at this point in the history
  • Loading branch information
atjsh committed Nov 17, 2023
1 parent 14a4a68 commit 7597245
Show file tree
Hide file tree
Showing 8 changed files with 496 additions and 38 deletions.
449 changes: 447 additions & 2 deletions web-client/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions web-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@js-temporal/polyfill": "^0.4.4",
"crypto-js": "^4.1.1",
"js-cookie": "^3.0.5",
"micromark": "^4.0.0",
"reset-css": "^5.0.2",
"return-fetch": "^0.4.5",
"svelte-persisted-store": "^0.7.0"
Expand Down
1 change: 1 addition & 0 deletions web-client/src/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
// place files you want to import through the `$lib` alias in this folder.
export * from './api';
export * from './post/post-utils';
54 changes: 28 additions & 26 deletions web-client/src/lib/post/post-form.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script lang="ts">
import { micromark } from 'micromark';
import type { PostContentType } from '../api';
import { getContentTypeLabel } from './post-utils';
export let errorMessage: string | undefined;
export let availableCategories: { id: number; name: string }[];
Expand All @@ -10,15 +12,18 @@
private?: boolean;
content?: string;
contentType?: PostContentType;
} = {
categoryId: availableCategories[0]?.id,
title: '',
private: true,
content: '',
contentType: 'html'
} = {};
let postValues = {
categoryId: defaultPostValues.categoryId ?? availableCategories[0]?.id,
title: defaultPostValues.title ?? '',
private: defaultPostValues.private ?? true,
content: defaultPostValues.content ?? '',
contentType: defaultPostValues.contentType ?? 'html'
};
let postValues = defaultPostValues;
$: renderedContent =
postValues.contentType == 'md' ? micromark(postValues.content) : postValues.content;
</script>

<form method="post">
Expand All @@ -43,11 +48,22 @@
name="title"
id="title"
required
placeholder="enter title"
placeholder="제목을 입력하세요..."
bind:value={postValues.title}
/>
</div>

<div class="form-section">
<h2>
<label for="contentType">컨텐츠 타입</label>
</h2>

<select name="contentType" id="contentType" bind:value={postValues.contentType}>
<option value="html">{getContentTypeLabel('html')}</option>
<option value="md">{getContentTypeLabel('md')}</option>
</select>
</div>

<div class="form-section">
<h2>
<label for="content">내용</label>
Expand All @@ -61,11 +77,12 @@
cols="30"
rows="10"
required
placeholder="enter your content (HTML) ..."
placeholder="{postValues.contentType &&
getContentTypeLabel(postValues.contentType)} 양식으로 내용을 입력하세요..."
bind:value={postValues.content}
/>
<div class="html-preview">
{@html postValues.content}
{@html renderedContent}
</div>
</div>
</div>
Expand All @@ -76,22 +93,7 @@
</h2>

<input type="checkbox" name="isPrivate" id="isPrivate" bind:checked={postValues.private} />
{#if postValues.private}
<label for="isPrivate">게시글을 비공개 상태로 저장</label>
{:else}
<label for="isPrivate">게시글을 공개 상태로 저장</label>
{/if}
</div>

<div class="form-section">
<h2>
<label for="contentType">컨텐츠 타입</label>
</h2>

<select name="contentType" id="contentType" bind:value={postValues.contentType}>
<option value="html">HTML</option>
<option value="markdown">Markdown</option>
</select>
<label for="isPrivate">게시글을 비공개 상태로 저장</label>
</div>

<div class="buttons">
Expand Down
10 changes: 10 additions & 0 deletions web-client/src/lib/post/post-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { PostContentType } from '../api';

export function getContentTypeLabel(contentType: PostContentType) {
switch (contentType) {
case 'html':
return 'HTML';
case 'md':
return 'Markdown';
}
}
6 changes: 5 additions & 1 deletion web-client/src/routes/post/[postId]/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { getCurrentAuthedWriterId, getPost, type GetPostResponseData } from '$li
import CryptoJS from 'crypto-js';
import type { PageServerLoad } from './$types';
import { error } from '@sveltejs/kit';
import { micromark } from 'micromark';

export const load: PageServerLoad = async ({ cookies, params }) => {
const { postId } = params;
Expand Down Expand Up @@ -36,7 +37,10 @@ export const load: PageServerLoad = async ({ cookies, params }) => {
}

return {
post,
post: {
...post,
renderedContent: post.content_type === 'md' ? micromark(post.content) : post.content
},
isWriter
};
};
6 changes: 1 addition & 5 deletions web-client/src/routes/post/[postId]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,7 @@

<div class="post-container">
<div class="post-content">
{#if data.post.content_type === 'html'}
{@html data.post.content}
{:else}
{@html data.post.content}
{/if}
{@html data.post.renderedContent}
</div>
</div>

Expand Down
7 changes: 3 additions & 4 deletions web-client/src/routes/post/[postId]/raw/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<script lang="ts">
import { getContentTypeLabel } from '../../../../lib';
import type { PageServerData } from './$types';
export let data: PageServerData;
</script>

<article>
<div>
<h1>{data.post.title} (raw)</h1>
<h1><code>{data.post.title} (Raw {getContentTypeLabel(data.post.content_type)})</code></h1>
<div>
{new Date(data.post.created_at).toLocaleDateString('ko-KR', { timeZone: 'UTC' })}
</div>
Expand All @@ -32,9 +33,7 @@
</div>

<div class="post-container">
<pre class="post-content">
{data.post.content}
</pre>
<pre class="post-content">{data.post.content}</pre>
</div>

<div class="bottom-menu">
Expand Down

0 comments on commit 7597245

Please sign in to comment.