Skip to content

Commit ccd1437

Browse files
authored
Merge pull request #13 from hfidelis/@refactor
@refactor
2 parents e5b5755 + 493da0c commit ccd1437

File tree

6 files changed

+134
-105
lines changed

6 files changed

+134
-105
lines changed

src/services/post/post.ts

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { Octokit } from 'octokit'
2+
3+
interface Post {
4+
slug: string
5+
lang: string
6+
content: string
7+
}
8+
9+
interface File {
10+
download_url: string
11+
name: string
12+
}
13+
14+
class PostService {
15+
private static instance: PostService
16+
17+
private octokit = new Octokit()
18+
private owner: string = 'hfidelis'
19+
private repo: string = 'learning-in-public'
20+
private path: string = 'posts'
21+
22+
private GITHUB_DATA: { [key: string]: string } = {
23+
owner: this.owner,
24+
repo: this.repo,
25+
path: this.path,
26+
}
27+
private GITHUB_REQUEST: string = 'GET /repos/{owner}/{repo}/contents/{path}'
28+
29+
private constructor() {}
30+
31+
public static getInstance(): PostService {
32+
if (!PostService.instance) {
33+
PostService.instance = new PostService()
34+
}
35+
36+
return PostService.instance
37+
}
38+
39+
private getPostContent = async (link: string): Promise<string> => {
40+
try {
41+
const rawContent = await fetch(link)
42+
43+
return await rawContent.text()
44+
} catch (_) {
45+
throw new Error('Error fetching post content')
46+
}
47+
}
48+
49+
public getAllPosts = async () => {
50+
try {
51+
const postsContent = {}
52+
53+
const { data } = await this.octokit.request(this.GITHUB_REQUEST, this.GITHUB_DATA) as any
54+
55+
const mappedFiles = data.map((file: any) => {
56+
const fileData: File = {
57+
download_url: file.download_url,
58+
name: file.name,
59+
}
60+
61+
return fileData
62+
})
63+
64+
const promises = mappedFiles.map(async (file: File): Promise<Post> => {
65+
const content: string = await this.getPostContent(file.download_url)
66+
67+
const [ slug, lang ]= file.name.replace('md', '').split('.')
68+
69+
return { slug, lang, content }
70+
})
71+
72+
const results: Array<Post> = await Promise.all(promises)
73+
74+
results.forEach((post: Post): void => {
75+
if (!(post.slug in postsContent)) {
76+
postsContent[post.slug] = {}
77+
}
78+
79+
postsContent[post.slug][post.lang] = post.content
80+
})
81+
82+
return postsContent
83+
} catch (_) {
84+
throw new Error('Error fetching posts')
85+
}
86+
}
87+
88+
public getPostData = async (slug: string): Promise<{ [key: string]: string }> => {
89+
try {
90+
const posts = await this.getAllPosts()
91+
92+
if (!(slug in posts)) {
93+
throw new Error('Post not found')
94+
}
95+
96+
return posts[slug]
97+
} catch (_) {
98+
throw new Error('Error fetching post content')
99+
}
100+
}
101+
}
102+
103+
const postService = PostService.getInstance()
104+
105+
export default postService

src/services/posts/posts.ts

Lines changed: 0 additions & 84 deletions
This file was deleted.

src/views/blog/Blog.vue

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
import { ref, onMounted, watch } from 'vue'
33
import { useDark } from '@vueuse/core'
44
import { mdiNoteRemove } from '@mdi/js'
5-
import { getAllPosts } from '@/services/posts/posts'
65
76
import Layout from '@/layout/Layout.vue'
7+
import postService from '@/services/post/post'
88
import PostPreview from '@/components/post-preview/PostPreview.vue'
99
1010
export default {
@@ -21,15 +21,19 @@ export default {
2121
const currentLocale = ref<string>(this.$i18n.locale.toLowerCase())
2222
2323
const fetchPosts = (): void => {
24-
getAllPosts().then((contents): void => {
25-
posts.value = contents
26-
})
27-
.catch((): void => {
28-
isError.value = true
29-
})
30-
.finally((): void => {
31-
setTimeout(() => { isLoading.value = false }, 500)
32-
})
24+
postService
25+
.getAllPosts()
26+
.then((contents): void => {
27+
posts.value = contents
28+
})
29+
.catch((): void => {
30+
isError.value = true
31+
})
32+
.finally((): void => {
33+
setTimeout(() => {
34+
isLoading.value = false
35+
}, 500)
36+
})
3337
}
3438
3539
watch(

src/views/post/Post.vue

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { useDark } from '@vueuse/core'
44
import { mdiNoteRemove } from '@mdi/js'
55
import { MdPreview } from 'md-editor-v3'
66
import { ref, watch, onMounted } from 'vue'
7-
import { getPostContents } from '@/services/posts/posts'
87
98
import 'md-editor-v3/lib/preview.css'
9+
import postService from '@/services/post/post'
1010
1111
export default {
1212
components: {
@@ -24,16 +24,20 @@ export default {
2424
const fetchPostData = (): void => {
2525
const { slug } = route.params
2626
27-
getPostContents(slug as string).then((contents): void => {
28-
postContents.value = contents
29-
currentContent.value = contents[currentLocale.value]
30-
})
31-
.catch((): void => {
32-
isError.value = true
33-
})
34-
.finally((): void => {
35-
setTimeout(() => { isLoading.value = false }, 500)
36-
})
27+
postService
28+
.getPostData(slug as string)
29+
.then((contents: { [key: string]: string }): void => {
30+
postContents.value = contents
31+
currentContent.value = contents[currentLocale.value]
32+
})
33+
.catch((): void => {
34+
isError.value = true
35+
})
36+
.finally((): void => {
37+
setTimeout(() => {
38+
isLoading.value = false
39+
}, 500)
40+
})
3741
}
3842
3943
watch(

0 commit comments

Comments
 (0)