-
Notifications
You must be signed in to change notification settings - Fork 12
feat(category): change news category page posts data source from GraphQL to JSON #1452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
21eb58b
18acadd
bb52898
945111f
0268a74
2278ff5
f2691db
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,8 @@ import { | |
| fetchCategoryByCategorySlug, | ||
| fetchPostsByCategorySlug, | ||
| fetchPremiumPostsByCategorySlug, | ||
| fetchNewsCategoryInfo, | ||
| fetchNewsCategoryPostsJSON, | ||
| } from '../../utils/api/category' | ||
| import { useDisplayAd } from '../../hooks/useDisplayAd' | ||
| import { getCategoryOfWineSlug, getLogTraceObject } from '../../utils' | ||
|
|
@@ -188,6 +190,7 @@ const RENDER_PAGE_SIZE = 12 | |
| * @param {number} props.postsCount | ||
| * @param {boolean} props.isPremium | ||
| * @param {Object} props.headerData | ||
| * @param {boolean} props.isNewsCategory | ||
| * @returns {React.ReactElement} | ||
| */ | ||
| export default function Category({ | ||
|
|
@@ -196,6 +199,7 @@ export default function Category({ | |
| category, | ||
| isPremium, | ||
| headerData, | ||
| isNewsCategory, | ||
| }) { | ||
| const categoryName = category.name || '' | ||
| const { shouldShowAd, isLogInProcessFinished } = useDisplayAd() | ||
|
|
@@ -263,6 +267,7 @@ export default function Category({ | |
| category={category} | ||
| renderPageSize={RENDER_PAGE_SIZE} | ||
| isPremium={isPremium} | ||
| isNewsCategory={isNewsCategory} | ||
| /> | ||
|
|
||
| {shouldShowAd && isNotWineCategory ? ( | ||
|
|
@@ -298,15 +303,28 @@ export async function getServerSideProps({ query, req, res }) { | |
| isMemberOnly: false, | ||
| state: 'inactive', | ||
| } | ||
| try { | ||
| const { data } = await fetchCategoryByCategorySlug(categorySlug) | ||
| category = data.category || category | ||
| } catch (error) { | ||
| logGqlError( | ||
| error, | ||
| `Error occurs while getting category data in category page (${categorySlug})`, | ||
| globalLogFields | ||
| ) | ||
|
|
||
| const isNewsCategory = | ||
| categorySlug.startsWith('news') || categorySlug.startsWith('news?') | ||
|
|
||
| if (isNewsCategory) { | ||
| try { | ||
| const { data } = await fetchNewsCategoryInfo() | ||
| category = data.category || category | ||
| } catch (error) { | ||
| console.error('Error fetching news category:', error) | ||
| } | ||
| } else { | ||
| try { | ||
| const { data } = await fetchCategoryByCategorySlug(categorySlug) | ||
| category = data.category || category | ||
| } catch (error) { | ||
| logGqlError( | ||
| error, | ||
| `Error occurs while getting category data in category page (${categorySlug})`, | ||
| globalLogFields | ||
| ) | ||
| } | ||
| } | ||
|
Comment on lines
+310
to
328
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 這段程式碼透過 const fetchCategoryPromise = isNewsCategory
? fetchNewsCategoryInfo()
: fetchCategoryByCategorySlug(categorySlug)
const categoryResponses = await Promise.allSettled([fetchCategoryPromise])
const categoryResult = processSettledResult(
categoryResponses[0],
(res) => res?.data?.category,
`Error occurs while getting category data in category page (${categorySlug})`,
globalLogFields
)
category = categoryResult || category |
||
|
|
||
| // handle category state, if `inactive` -> redirect to 404 | ||
|
|
@@ -360,7 +378,9 @@ export async function getServerSideProps({ query, req, res }) { | |
| `Error occurs while getting premium post data in category page (categorySlug: ${categorySlug})`, | ||
| globalLogFields | ||
| ) | ||
| } else { | ||
| } | ||
|
|
||
| if (!isNewsCategory && !isPremium) { | ||
| const responses = await Promise.allSettled([ | ||
| fetchHeaderDataInDefaultPageLayout(), | ||
| fetchPostsByCategorySlug(categorySlug, RENDER_PAGE_SIZE * 2, 0), | ||
|
|
@@ -389,6 +409,25 @@ export async function getServerSideProps({ query, req, res }) { | |
| ) | ||
| } | ||
|
|
||
| if (isNewsCategory && !isPremium) { | ||
| const responses = await Promise.allSettled([ | ||
| fetchHeaderDataInDefaultPageLayout(), | ||
| ]) | ||
|
|
||
| // handle header data | ||
| ;[sectionsData, topicsData] = processSettledResult( | ||
| responses[0], | ||
| getSectionAndTopicFromDefaultHeaderData, | ||
| `Error occurs while getting header data in category page (categorySlug: ${categorySlug})`, | ||
| globalLogFields | ||
| ) | ||
|
|
||
| // handle fetch post data | ||
| const { data } = await fetchNewsCategoryPostsJSON() | ||
| posts = data.posts.items || [] | ||
| postsCount = data.posts.counts || 0 | ||
| } | ||
|
Comment on lines
+412
to
+429
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 此處直接呼叫 if (isNewsCategory && !isPremium) {
const responses = await Promise.allSettled([
fetchHeaderDataInDefaultPageLayout(),
fetchNewsCategoryPostsJSON(),
])
// handle header data
;[sectionsData, topicsData] = processSettledResult(
responses[0],
getSectionAndTopicFromDefaultHeaderData,
`Error occurs while getting header data in category page (categorySlug: ${categorySlug})`,
globalLogFields
)
// handle fetch post data
const postsWrapper = processSettledResult(
responses[1],
(res) => res?.data?.posts,
`Error occurs while getting news category posts in category page (categorySlug: ${categorySlug})`,
globalLogFields
)
posts = postsWrapper?.items || []
postsCount = postsWrapper?.counts || 0
} |
||
|
|
||
| // handle fetch post data | ||
| if (posts.length === 0) { | ||
| // fetchPost return empty array -> wrong authorId -> 404 | ||
|
|
@@ -408,6 +447,7 @@ export async function getServerSideProps({ query, req, res }) { | |
| category, | ||
| isPremium, | ||
| headerData: { sectionsData, topicsData }, | ||
| isNewsCategory, | ||
| } | ||
| return { props } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,12 @@ | ||
| import client from '../../apollo/apollo-client' | ||
| import { fetchCategorySections } from '../../apollo/query/categroies' | ||
| import { fetchPosts } from '../../apollo/query/posts' | ||
| import axios from 'axios' | ||
| import { | ||
| API_TIMEOUT, | ||
| URL_STATIC_NEWS_CATEGORY_INFO, | ||
| URL_STATIC_NEWS_CATEGORY_POSTS, | ||
| } from '../../config/index.mjs' | ||
|
|
||
| export function fetchPostsByCategorySlug(categorySlug, take, skip) { | ||
| return client.query({ | ||
|
|
@@ -17,6 +23,55 @@ export function fetchPostsByCategorySlug(categorySlug, take, skip) { | |
| }) | ||
| } | ||
|
|
||
| export async function fetchNewsCategoryInfo() { | ||
| try { | ||
| const response = await axios({ | ||
| method: 'get', | ||
| url: URL_STATIC_NEWS_CATEGORY_INFO, | ||
| timeout: API_TIMEOUT, | ||
| }) | ||
| return response | ||
| } catch (err) { | ||
| console.error('Error fetching news category info: ', JSON.stringify(err)) | ||
| } | ||
|
Comment on lines
+34
to
+36
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
} catch (err) {
console.error('Error fetching news category info: ', JSON.stringify(err))
throw err
} |
||
| } | ||
|
|
||
| export async function fetchNewsCategoryPostsJSON(page = 1, take = 24) { | ||
| const POSTS_PER_JSON = 120 | ||
| const TAKE_PER_JSON = POSTS_PER_JSON / take | ||
| const jsonFileOrder = Math.ceil(page / TAKE_PER_JSON) | ||
| const jsonUrl = `${URL_STATIC_NEWS_CATEGORY_POSTS}_${jsonFileOrder}.json` | ||
|
|
||
| try { | ||
| const response = await axios({ | ||
| method: 'get', | ||
| url: jsonUrl, | ||
| timeout: API_TIMEOUT, | ||
| }) | ||
|
|
||
| const jsonIndex = (page - 1) % TAKE_PER_JSON | ||
| const startIndex = jsonIndex * take | ||
| const endIndex = startIndex + take | ||
| const postItems = response.data.posts.items.slice(startIndex, endIndex) | ||
|
|
||
| return { | ||
| data: { | ||
| posts: { | ||
| items: jsonFileOrder <= 4 ? postItems : [], | ||
| counts: | ||
| response.data.posts.counts.posts + | ||
| response.data.posts.counts.externals, | ||
| }, | ||
| }, | ||
| } | ||
| } catch (err) { | ||
| console.error( | ||
| 'Failed to fetch JSON of URL_STATIC_NEWS_CATEGORY_POSTS: ', | ||
| JSON.stringify(err) | ||
| ) | ||
|
Comment on lines
+68
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
|
Comment on lines
+67
to
+72
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
|
|
||
| export function fetchPremiumPostsByCategorySlug(categorySlug, take, skip) { | ||
| return client.query({ | ||
| query: fetchPosts, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
判斷是否為「新聞」分類的邏輯
categorySlug.startsWith('news') || categorySlug.startsWith('news?')可能不夠穩健。categorySlug是從 URL 路徑中解析而來,不包含查詢參數(query string)。因此,對於/category/news?page=2這樣的 URL,categorySlug的值會是news。startsWith('news?')這個條件可能永遠不會為真,或者會意外匹配到名為news-something的分類。建議將判斷條件修改為更精確的categorySlug === 'news',以符合預期行為。