diff --git a/ui/src/common/interface.ts b/ui/src/common/interface.ts index 6072ff00..35ad1149 100644 --- a/ui/src/common/interface.ts +++ b/ui/src/common/interface.ts @@ -54,6 +54,7 @@ export interface TagInfo extends TagBase { } export interface QuestionParams { title: string; + url_title?: string; content: string; html: string; tags: Tag[]; @@ -396,6 +397,7 @@ export interface SearchParams { export interface SearchResItem { object_type: string; object: { + url_title?: string; id: string; question_id?: string; title: string; @@ -455,6 +457,7 @@ export interface TimelineItem { export interface TimelineObject { title: string; + url_title?: string; object_type: string; question_id: string; answer_id: string; @@ -470,6 +473,7 @@ export interface TimelineRes { export interface ReviewItem { type: 'question' | 'answer' | 'tag'; info: { + url_title?: string; object_id: string; title: string; content: string; diff --git a/ui/src/components/HotQuestions/index.tsx b/ui/src/components/HotQuestions/index.tsx index b8a63654..a27eff4d 100644 --- a/ui/src/components/HotQuestions/index.tsx +++ b/ui/src/components/HotQuestions/index.tsx @@ -30,7 +30,7 @@ const HotQuestions: FC = () => {
{li.title}
{li.answer_count > 0 ? ( diff --git a/ui/src/components/Operate/index.tsx b/ui/src/components/Operate/index.tsx index 00bd65f8..1dfa3f46 100644 --- a/ui/src/components/Operate/index.tsx +++ b/ui/src/components/Operate/index.tsx @@ -19,6 +19,7 @@ interface IProps { qid: string; aid?: string; title: string; + slugTitle: string; hasAnswer?: boolean; isAccepted: boolean; callback: (type: string) => void; @@ -29,6 +30,7 @@ const Index: FC = ({ qid, aid = '', title, + slugTitle, isAccepted = false, hasAnswer = false, memberActions = [], @@ -159,7 +161,13 @@ const Index: FC = ({ return (
- + {memberActions?.map((item) => { if (item.action === 'edit') { return ( diff --git a/ui/src/components/QuestionList/index.tsx b/ui/src/components/QuestionList/index.tsx index 694300d5..6a6305d3 100644 --- a/ui/src/components/QuestionList/index.tsx +++ b/ui/src/components/QuestionList/index.tsx @@ -123,7 +123,7 @@ const QuestionList: FC = ({ source }) => {
{li.title} {li.status === 2 ? ` [${t('closed')}]` : ''} diff --git a/ui/src/components/Share/index.tsx b/ui/src/components/Share/index.tsx index 9cb9e042..6b644a60 100644 --- a/ui/src/components/Share/index.tsx +++ b/ui/src/components/Share/index.tsx @@ -13,21 +13,25 @@ interface IProps { qid: any; aid?: any; title: string; + slugTitle: string; } -const Index: FC = ({ type, qid, aid, title }) => { +const Index: FC = ({ type, qid, aid, title, slugTitle = '' }) => { const user = loggedUserInfoStore((state) => state.user); const [show, setShow] = useState(false); const [showTip, setShowTip] = useState(false); const [canSystemShare, setSystemShareState] = useState(false); const { t } = useTranslation(); - + // FIXME: pathFactory let baseUrl = type === 'question' - ? `${window.location.origin}${pathFactory.questionLanding(qid, title)}` + ? `${window.location.origin}${pathFactory.questionLanding( + qid, + slugTitle, + )}` : `${window.location.origin}${pathFactory.answerLanding({ questionId: qid, - questionTitle: title, + slugTitle, answerId: aid, })}`; if (user.id) { diff --git a/ui/src/pages/Admin/Answers/index.tsx b/ui/src/pages/Admin/Answers/index.tsx index f2a3f01a..805b1fbb 100644 --- a/ui/src/pages/Admin/Answers/index.tsx +++ b/ui/src/pages/Admin/Answers/index.tsx @@ -130,7 +130,7 @@ const Answers: FC = () => { { { diff --git a/ui/src/pages/Questions/Ask/components/SearchQuestion/index.tsx b/ui/src/pages/Questions/Ask/components/SearchQuestion/index.tsx index eb382c94..b2123482 100644 --- a/ui/src/pages/Questions/Ask/components/SearchQuestion/index.tsx +++ b/ui/src/pages/Questions/Ask/components/SearchQuestion/index.tsx @@ -29,7 +29,7 @@ const SearchQuestion = ({ similarQuestions }) => { as="a" className="link-dark" key={item.id} - href={pathFactory.questionLanding(item.id, item.title)} + href={pathFactory.questionLanding(item.id, item.url_title)} target="_blank"> {item.title} diff --git a/ui/src/pages/Questions/Ask/index.tsx b/ui/src/pages/Questions/Ask/index.tsx index 73529a5d..e4bc9cfd 100644 --- a/ui/src/pages/Questions/Ask/index.tsx +++ b/ui/src/pages/Questions/Ask/index.tsx @@ -237,7 +237,7 @@ const Ask = () => { edit_summary: formData.edit_summary.value, }) .then((res) => { - navigate(pathFactory.questionLanding(qid, params.title), { + navigate(pathFactory.questionLanding(qid, params.url_title), { state: { isReview: res?.wait_for_review }, }); }) @@ -264,7 +264,7 @@ const Ask = () => { html: editorRef2.current.getHtml(), }) .then(() => { - navigate(pathFactory.questionLanding(id, params.title)); + navigate(pathFactory.questionLanding(id, params.url_title)); }) .catch((err) => { if (err.isError) { @@ -273,7 +273,7 @@ const Ask = () => { } }); } else { - navigate(pathFactory.questionLanding(id, params.title)); + navigate(pathFactory.questionLanding(id)); } } } diff --git a/ui/src/pages/Questions/Detail/components/Answer/index.tsx b/ui/src/pages/Questions/Detail/components/Answer/index.tsx index d35669ff..6a63d624 100644 --- a/ui/src/pages/Questions/Detail/components/Answer/index.tsx +++ b/ui/src/pages/Questions/Detail/components/Answer/index.tsx @@ -23,6 +23,7 @@ interface Props { /** is author */ isAuthor: boolean; questionTitle: string; + slugTitle: string; isLogged: boolean; callback: (type: string) => void; } @@ -32,6 +33,7 @@ const Index: FC = ({ isAuthor, isLogged, questionTitle = '', + slugTitle, callback, }) => { const { t } = useTranslation('translation', { @@ -114,6 +116,7 @@ const Index: FC = ({ type="answer" isAccepted={data.adopted === 2} title={questionTitle} + slugTitle={slugTitle} callback={callback} /> diff --git a/ui/src/pages/Questions/Detail/components/Question/index.tsx b/ui/src/pages/Questions/Detail/components/Question/index.tsx index b33e0e73..2cd8a0de 100644 --- a/ui/src/pages/Questions/Detail/components/Question/index.tsx +++ b/ui/src/pages/Questions/Detail/components/Question/index.tsx @@ -65,7 +65,7 @@ const Index: FC = ({ data, initPage, hasAnswer, isLogged }) => { + to={pathFactory.questionLanding(data.id, data.url_title)}> {data.title} {data.status === 2 ? ` [${t('closed', { keyPrefix: 'question' })}]` @@ -129,6 +129,7 @@ const Index: FC = ({ data, initPage, hasAnswer, isLogged }) => { type="question" memberActions={data?.member_actions} title={data.title} + slugTitle={data.url_title} hasAnswer={hasAnswer} isAccepted={Boolean(data?.accepted_answer_id)} callback={initPage} diff --git a/ui/src/pages/Questions/Detail/components/RelatedQuestions/index.tsx b/ui/src/pages/Questions/Detail/components/RelatedQuestions/index.tsx index 2e29913e..b8627372 100644 --- a/ui/src/pages/Questions/Detail/components/RelatedQuestions/index.tsx +++ b/ui/src/pages/Questions/Detail/components/RelatedQuestions/index.tsx @@ -32,7 +32,7 @@ const Index: FC = ({ id }) => { action key={item.id} as={Link} - to={pathFactory.questionLanding(item.id, item.title)}> + to={pathFactory.questionLanding(item.id, item.url_title)}>
{item.title}
{item.answer_count > 0 && (
{ key={item?.id} data={item} questionTitle={question?.title || ''} + slugTitle={question?.url_title} isAuthor={isAuthor} callback={initPage} isLogged={isLogged} diff --git a/ui/src/pages/Questions/EditAnswer/index.tsx b/ui/src/pages/Questions/EditAnswer/index.tsx index 29390574..f5733851 100644 --- a/ui/src/pages/Questions/EditAnswer/index.tsx +++ b/ui/src/pages/Questions/EditAnswer/index.tsx @@ -115,7 +115,7 @@ const Index = () => { navigate( pathFactory.answerLanding({ questionId: qid, - questionTitle: data?.question?.title, + slugTitle: data?.question?.url_title, answerId: aid, }), { @@ -147,7 +147,7 @@ const Index = () => {
{data?.question.title}
diff --git a/ui/src/pages/Review/index.tsx b/ui/src/pages/Review/index.tsx index b92d8bbf..c328a823 100644 --- a/ui/src/pages/Review/index.tsx +++ b/ui/src/pages/Review/index.tsx @@ -95,7 +95,7 @@ const Index: FC = () => { const editor = unreviewed_info?.user_info; const editTime = unreviewed_info?.create_at; if (type === 'question') { - itemLink = pathFactory.questionLanding(info?.object_id, info?.title); + itemLink = pathFactory.questionLanding(info?.object_id, info?.url_title); itemTitle = info?.title; editBadge = t('question_edit'); editSummary ||= t('edit_question'); @@ -103,7 +103,7 @@ const Index: FC = () => { itemLink = pathFactory.answerLanding({ // @ts-ignore questionId: unreviewed_info.content.question_id, - questionTitle: info?.title, + slugTitle: info?.url_title, answerId: unreviewed_info.object_id, }); itemTitle = info?.title; diff --git a/ui/src/pages/Search/components/SearchItem/index.tsx b/ui/src/pages/Search/components/SearchItem/index.tsx index 91e0d364..2bd8738a 100644 --- a/ui/src/pages/Search/components/SearchItem/index.tsx +++ b/ui/src/pages/Search/components/SearchItem/index.tsx @@ -15,11 +15,14 @@ const Index: FC = ({ data }) => { if (!data?.object_type) { return null; } - let itemUrl = pathFactory.questionLanding(data.object.id, data.object.title); + let itemUrl = pathFactory.questionLanding( + data.object.id, + data.object.url_title, + ); if (data.object_type === 'answer' && data.object.question_id) { itemUrl = pathFactory.answerLanding({ questionId: data.object.question_id, - questionTitle: data.object.title, + slugTitle: data.object.url_title, answerId: data.object.id, }); } diff --git a/ui/src/pages/Timeline/index.tsx b/ui/src/pages/Timeline/index.tsx index 40f593a2..84ca9b0f 100644 --- a/ui/src/pages/Timeline/index.tsx +++ b/ui/src/pages/Timeline/index.tsx @@ -48,7 +48,7 @@ const Index: FC = () => { if (timelineData?.object_info.object_type === 'question') { linkUrl = pathFactory.questionLanding( timelineData?.object_info.question_id, - timelineData?.object_info.title, + timelineData?.object_info.url_title, ); pageTitle = `${t('title_for_question')} ${timelineData?.object_info.title}`; } @@ -56,7 +56,7 @@ const Index: FC = () => { if (timelineData?.object_info.object_type === 'answer') { linkUrl = pathFactory.answerLanding({ questionId: timelineData?.object_info.question_id, - questionTitle: timelineData?.object_info.title, + slugTitle: timelineData?.object_info.url_title, answerId: timelineData?.object_info.answer_id, }); pageTitle = `${t('title_for_answer', { diff --git a/ui/src/pages/Users/Personal/components/Answers/index.tsx b/ui/src/pages/Users/Personal/components/Answers/index.tsx index 2f7077b4..1a37535e 100644 --- a/ui/src/pages/Users/Personal/components/Answers/index.tsx +++ b/ui/src/pages/Users/Personal/components/Answers/index.tsx @@ -23,7 +23,7 @@ const Index: FC = ({ visible, data }) => {
diff --git a/ui/src/pages/Users/Personal/components/Comments/index.tsx b/ui/src/pages/Users/Personal/components/Comments/index.tsx index 6115c8b4..7422db7f 100644 --- a/ui/src/pages/Users/Personal/components/Comments/index.tsx +++ b/ui/src/pages/Users/Personal/components/Comments/index.tsx @@ -22,10 +22,10 @@ const Index: FC = ({ visible, data }) => { className="text-break" href={ item.object_type === 'question' - ? pathFactory.questionLanding(item.object_id, item.title) + ? pathFactory.questionLanding(item.object_id, item.url_title) : pathFactory.answerLanding({ questionId: item.question_id, - questionTitle: item.title, + slugTitle: item.url_title, answerId: item.object_id, }) }> diff --git a/ui/src/pages/Users/Personal/components/DefaultList/index.tsx b/ui/src/pages/Users/Personal/components/DefaultList/index.tsx index 1781e790..485935e2 100644 --- a/ui/src/pages/Users/Personal/components/DefaultList/index.tsx +++ b/ui/src/pages/Users/Personal/components/DefaultList/index.tsx @@ -29,7 +29,7 @@ const Index: FC = ({ visible, tabName, data }) => { className="text-break" href={pathFactory.questionLanding( tabName === 'questions' ? item.question_id : item.id, - item.title, + item.url_title, )}> {item.title} {tabName === 'questions' && item.status === 'closed' diff --git a/ui/src/pages/Users/Personal/components/Reputation/index.tsx b/ui/src/pages/Users/Personal/components/Reputation/index.tsx index c034713e..104b3f8c 100644 --- a/ui/src/pages/Users/Personal/components/Reputation/index.tsx +++ b/ui/src/pages/Users/Personal/components/Reputation/index.tsx @@ -33,10 +33,13 @@ const Index: FC = ({ visible, data }) => { className="text-break" href={ item.object_type === 'question' - ? pathFactory.questionLanding(item.object_id, item.title) + ? pathFactory.questionLanding( + item.object_id, + item.url_title, + ) : pathFactory.answerLanding({ questionId: item.question_id, - questionTitle: item.title, + slugTitle: item.url_title, answerId: item.object_id, }) }> diff --git a/ui/src/pages/Users/Personal/components/TopList/index.tsx b/ui/src/pages/Users/Personal/components/TopList/index.tsx index f7655875..23dd6470 100644 --- a/ui/src/pages/Users/Personal/components/TopList/index.tsx +++ b/ui/src/pages/Users/Personal/components/TopList/index.tsx @@ -23,10 +23,13 @@ const Index: FC = ({ data, type }) => { type === 'answer' ? pathFactory.answerLanding({ questionId: item.question_id, - questionTitle: item.question_info?.title, + slugTitle: item.question_info?.url_title, answerId: item.answer_id, }) - : pathFactory.questionLanding(item.question_id, item.title) + : pathFactory.questionLanding( + item.question_id, + item.url_title, + ) }> {type === 'answer' ? item.question_info.title : item.title} diff --git a/ui/src/pages/Users/Personal/components/Votes/index.tsx b/ui/src/pages/Users/Personal/components/Votes/index.tsx index 71d3bcf3..5cf369dd 100644 --- a/ui/src/pages/Users/Personal/components/Votes/index.tsx +++ b/ui/src/pages/Users/Personal/components/Votes/index.tsx @@ -29,10 +29,13 @@ const Index: FC = ({ visible, data }) => { className="text-break" href={ item.object_type === 'question' - ? pathFactory.questionLanding(item.question_id, item.title) + ? pathFactory.questionLanding( + item.question_id, + item.url_title, + ) : pathFactory.answerLanding({ questionId: item.question_id, - questionTitle: item.title, + slugTitle: item.url_title, answerId: item.answer_id, }) }> diff --git a/ui/src/router/pathFactory.ts b/ui/src/router/pathFactory.ts index 335b6d34..2330710d 100644 --- a/ui/src/router/pathFactory.ts +++ b/ui/src/router/pathFactory.ts @@ -1,6 +1,5 @@ import urlcat from 'urlcat'; -import Pattern from '@/common/pattern'; import { seoSettingStore } from '@/stores'; const tagLanding = (slugName: string) => { @@ -20,30 +19,25 @@ const tagInfo = (slugName: string) => { const tagEdit = (tagId: string) => { return urlcat('/tags/:tagId/edit', { tagId }); }; -const questionLanding = (questionId: string, title: string = '') => { +const questionLanding = (questionId: string, slugTitle: string = '') => { const { seo } = seoSettingStore.getState(); - if (seo.permalink === 1) { - title = title.toLowerCase(); - title = title.trim().replace(/\s+/g, '-'); - title = title.replace(Pattern.emoji, ''); - if (title) { - return urlcat('/questions/:questionId/:slugPermalink', { - questionId, - slugPermalink: title, - }); - } + if (seo.permalink === 1 && slugTitle) { + return urlcat('/questions/:questionId/:slugPermalink', { + questionId, + slugPermalink: slugTitle, + }); } return urlcat('/questions/:questionId', { questionId }); }; const answerLanding = (params: { questionId: string; - questionTitle?: string; + slugTitle?: string; answerId: string; }) => { const questionLandingUrl = questionLanding( params.questionId, - params.questionTitle, + params.slugTitle, ); return urlcat(`${questionLandingUrl}/:answerId`, { answerId: params.answerId,