diff --git a/src/containers/content/UserContent/logic.ts b/src/containers/content/UserContent/logic.ts index 0e94a6fdb..643b7c04f 100755 --- a/src/containers/content/UserContent/logic.ts +++ b/src/containers/content/UserContent/logic.ts @@ -78,6 +78,14 @@ const loadEditableCommunities = () => { sr71$.query(S.editableCommunities, { login, filter }) } +const loadPublishedWorks = (): void => { + const { viewingUser: user } = store + if (!user.isMaker) return + + const filter = { page: 1, size: 10 } + sr71$.query(S.pagedPublishedWorks, { login: user.login, filter }) +} + const DataSolver = [ { match: asyncRes('follow'), @@ -91,6 +99,13 @@ const DataSolver = [ match: asyncRes('editableCommunities'), action: ({ editableCommunities }) => { store.mark({ pagedEditableCommunities: editableCommunities }) + loadPublishedWorks() + }, + }, + { + match: asyncRes('pagedPublishedWorks'), + action: ({ pagedPublishedWorks }) => { + store.mark({ pagedWorks: pagedPublishedWorks }) }, }, { diff --git a/src/containers/content/UserContent/schema.ts b/src/containers/content/UserContent/schema.ts index 6e9d098d9..a5750bea4 100755 --- a/src/containers/content/UserContent/schema.ts +++ b/src/containers/content/UserContent/schema.ts @@ -36,11 +36,27 @@ const editableCommunities = gql` } ` +const pagedPublishedWorks = ` + query($login: String!, $filter: PagedFilter!) { + pagedPublishedWorks(login: $login, filter: $filter) { + entries { + id + title + cover + desc + homeLink + } + ${F.pagi} + } + } +` + const schema = { follow, undoFollow, user, editableCommunities, + pagedPublishedWorks, } export default schema diff --git a/src/containers/editor/ArticleEditor/index.tsx b/src/containers/editor/ArticleEditor/index.tsx index 7ce3896bc..05f726106 100755 --- a/src/containers/editor/ArticleEditor/index.tsx +++ b/src/containers/editor/ArticleEditor/index.tsx @@ -10,8 +10,9 @@ import { METRIC } from '@/constant' import { buildLog } from '@/utils/logger' import { pluggedIn } from '@/utils/mobx' -import { ArchiveAlert } from '@/widgets/dynamic' +import { ArchiveAlert, IllegalWarning } from '@/widgets/dynamic' +import NoticeBar from '@/widgets/NoticeBar' import CommunityTagSetter from '@/containers/tool/CommunityTagSetter' import RichEditor from '@/containers/editor/RichEditor' import CommunityBadgeSelector from '@/widgets/CommunityBadgeSelector' @@ -53,8 +54,11 @@ const ArticleEditorContainer: FC = ({ texts, thread, editData, + viewingArticle, + allowEdit, } = store + const { meta } = viewingArticle const { title, body } = editData const initEditor = mode === 'publish' || body !== '{}' @@ -70,6 +74,14 @@ const ArticleEditorContainer: FC = ({ /> )} + {!allowEdit && ( + + )} + {isArchived && ( )} @@ -94,6 +106,13 @@ const ArticleEditorContainer: FC = ({
+ + {mode === 'update' && !meta.isLegal && ( + + )}
diff --git a/src/containers/editor/ArticleEditor/schema.ts b/src/containers/editor/ArticleEditor/schema.ts index 1d5697de6..ad01578bf 100755 --- a/src/containers/editor/ArticleEditor/schema.ts +++ b/src/containers/editor/ArticleEditor/schema.ts @@ -176,6 +176,9 @@ const post = gql` copyRight archivedAt isArchived + author { + ${F.author} + } originalCommunity { ${F.community} @@ -187,6 +190,9 @@ const post = gql` meta { thread + isLegal + illegalReason + illegalWords } document { @@ -206,6 +212,10 @@ const job = gql` archivedAt isArchived + author { + ${F.author} + } + originalCommunity { ${F.community} } @@ -216,6 +226,9 @@ const job = gql` meta { thread + isLegal + illegalReason + illegalWords } document { @@ -244,6 +257,9 @@ const radar = gql` meta { thread + isLegal + illegalReason + illegalWords } document { diff --git a/src/containers/editor/ArticleEditor/store.ts b/src/containers/editor/ArticleEditor/store.ts index 78d70bfce..2125da0bc 100755 --- a/src/containers/editor/ArticleEditor/store.ts +++ b/src/containers/editor/ArticleEditor/store.ts @@ -14,6 +14,7 @@ import type { TTag, TArticleThread, TSubmitState, + TAccount, } from '@/spec' import { ARTICLE_THREAD } from '@/constant' @@ -51,10 +52,22 @@ const ArticleEditor = T.model('ArticleEditor', { const root = getParent(self) as TRootStore return root.account.isLogin }, + get accountInfo(): TAccount { + const root = getParent(self) as TRootStore + return root.account.accountInfo + }, get viewingArticle(): TArticle { const root = getParent(self) as TRootStore return toJS(root.viewing.viewingArticle) }, + get allowEdit(): boolean { + const slf = self as TStore + const { mode, accountInfo, viewingArticle } = slf + + return ( + mode === 'update' && accountInfo.login === viewingArticle.author?.login + ) + }, get thread(): TArticleThread { const root = getParent(self) as TRootStore return toJS(root.viewing.viewingThread) @@ -138,7 +151,17 @@ const ArticleEditor = T.model('ArticleEditor', { }, get submitState(): TSubmitState { const slf = self as TStore - return pick(['publishing', 'publishDone', 'isReady', 'isArchived'], slf) + return pick( + [ + 'publishing', + 'publishDone', + 'isReady', + 'isArchived', + 'mode', + 'isArticleAuthor', + ], + slf, + ) }, })) .actions((self) => ({ diff --git a/src/containers/editor/WorksEditor/Content/BasicInfoPart/index.tsx b/src/containers/editor/WorksEditor/Content/BasicInfoPart/index.tsx index 806eba0d7..8cd27c022 100755 --- a/src/containers/editor/WorksEditor/Content/BasicInfoPart/index.tsx +++ b/src/containers/editor/WorksEditor/Content/BasicInfoPart/index.tsx @@ -1,7 +1,7 @@ import { FC, memo } from 'react' import { filter, includes } from 'ramda' -import type { TSelectOption } from '@/spec' +import type { TSelectOption, TUser } from '@/spec' import Checker from '@/widgets/Checker' import Select from '@/widgets/Select' @@ -32,6 +32,10 @@ import { checkerOnChange, addSocial, citiesOnChange, + searchUser, + addTeammate, + removeTeammate, + closeSearchedUsers, } from '../../logic' const cityOptions = [ @@ -53,9 +57,14 @@ const cityOptions = [ type TProps = { inputData: TInputData socialOptions: TSelectOption[] + searchedUsers: TUser[] } -const BasicInfoPart: FC = ({ inputData, socialOptions }) => { +const BasicInfoPart: FC = ({ + inputData, + socialOptions, + searchedUsers, +}) => { const { cover, title, @@ -198,7 +207,16 @@ const BasicInfoPart: FC = ({ inputData, socialOptions }) => {
- +
diff --git a/src/containers/editor/WorksEditor/Content/NamePart.tsx b/src/containers/editor/WorksEditor/Content/NamePart.tsx index f8bbcf3b3..abb772dd4 100755 --- a/src/containers/editor/WorksEditor/Content/NamePart.tsx +++ b/src/containers/editor/WorksEditor/Content/NamePart.tsx @@ -1,8 +1,11 @@ import { FC, memo, useEffect, useRef } from 'react' import { TEditMode } from '@/spec' -import type { TInputData } from '../spec' +import { nilOrEmpty } from '@/utils/validator' + +import PublishRules from './PublishRules' +import type { TInputData } from '../spec' import { Wrapper, Input, Title, Desc } from '../styles/content/name_part' import { inputOnChange } from '../logic' @@ -26,12 +29,13 @@ const NamePart: FC = ({ mode, inputData }) => { return ( {mode === 'publish' ? 发布作品 : 更新作品} - 你(们)的作品名称是 ? + 你(们)的作品名字是 ? inputOnChange(e, 'title')} autoFocus /> + {nilOrEmpty(title) && } ) } diff --git a/src/containers/editor/WorksEditor/Content/PublishRules.tsx b/src/containers/editor/WorksEditor/Content/PublishRules.tsx new file mode 100644 index 000000000..223678547 --- /dev/null +++ b/src/containers/editor/WorksEditor/Content/PublishRules.tsx @@ -0,0 +1,83 @@ +import { FC, memo, useState, Fragment, useCallback } from 'react' +import Link from 'next/link' + +import { ROUTE } from '@/constant' + +import { + Wrapper, + ToggleTitle, + Section, + DoTitle, + DoNotTitle, + Ul, + Li, + Bold, + Strike, + TextLink, +} from '../styles/content/publish_rules' + +const PublishRules: FC = () => { + const [showDetail, setShowDetail] = useState(false) + + const toggleDetail = useCallback(() => { + setShowDetail(!showDetail) + }, [showDetail]) + + return ( + + + {!showDetail ? ( + 发布须知 + ) : ( + 收起 + )} + + {showDetail && ( + +
+ 欢迎发布: +
    +
  • + 各平台能提高开发者 / 设计师 / 产品生产力的软件工具,插件或服务。 +
  • +
  • 你参与编写和设计的库,框架等各种作品。
  • +
  • 字体,图标,UI/UX模板手稿等人机交互类的设计资源或服务。
  • +
  • 各类辅助管理工具或服务。
  • +
  • 品牌,运营,增长,统计等工具或服务。
  • +
  • 硬件产品,物联网,VR, 机器人等类似项目。
  • +
+
+
+ 不适合发布: +
    +
  • + 你没有参与的项目。如果你是个喜欢收集的 Hunter, + + 酷导航 + + 是最合适的地方。 +
  • +
  • + Markdown 类项目, 包括但不限于排行榜, 资料收集, + 面经题库,课程培训等。 +
  • +
  • 聚合类项目,包括但不限于 xx 导航,xx 热榜等。
  • +
  • 后台管理模板,xx 商城系统,xx 手脚架。
  • +
  • + 和开发者(广义上包括 IT 从业者)关系不大的项目。 + 简单来讲,如果你要发布的项目主要目标用户不是 IT + 从业者,那么通常就不适合。 这里是垂直社区, + 不是 APP 应用商店。 +
  • +
  • + 三天或一周时间写的 Demo 项目, 天才例外。 +
  • +
+
+
+ )} +
+ ) +} + +export default memo(PublishRules) diff --git a/src/containers/editor/WorksEditor/Content/index.tsx b/src/containers/editor/WorksEditor/Content/index.tsx index b4ea89c7d..8632fc597 100755 --- a/src/containers/editor/WorksEditor/Content/index.tsx +++ b/src/containers/editor/WorksEditor/Content/index.tsx @@ -1,6 +1,6 @@ import { FC, memo } from 'react' -import { TSelectOption, TTechCommunities, TEditMode } from '@/spec' +import { TSelectOption, TTechCommunities, TEditMode, TUser } from '@/spec' import type { TStep, TInputData } from '../spec' import { STEP } from '../constant' @@ -19,6 +19,7 @@ type TProps = { inputData: TInputData socialOptions: TSelectOption[] techCommunities: TTechCommunities + searchedUsers: TUser[] } const Content: FC = ({ @@ -27,18 +28,18 @@ const Content: FC = ({ inputData, socialOptions, techCommunities, + searchedUsers, }) => { let StepComp = null switch (step) { - case STEP.ZERO: { - StepComp = - break - } - case STEP.ONE: { StepComp = ( - + ) break } @@ -59,7 +60,7 @@ const Content: FC = ({ } default: { - StepComp =
default step
+ StepComp = break } } diff --git a/src/containers/editor/WorksEditor/index.tsx b/src/containers/editor/WorksEditor/index.tsx index dd5bd78a6..0be6778c2 100755 --- a/src/containers/editor/WorksEditor/index.tsx +++ b/src/containers/editor/WorksEditor/index.tsx @@ -14,6 +14,8 @@ import { METRIC } from '@/constant' import { buildLog } from '@/utils/logger' import { pluggedIn } from '@/utils/mobx' +import NoticeBar from '@/widgets/NoticeBar' + import Preview from './Preview' import StepsBar from './StepsBar' import Content from './Content' @@ -46,11 +48,21 @@ const WorksEditorContainer: FC = ({ socialOptions, techCommunities, submitState, + searchedUsersData, + allowEdit, } = store return ( + {!allowEdit && ( + + )} + = ({ inputData={inputData} socialOptions={socialOptions} techCommunities={techCommunities} + searchedUsers={searchedUsersData} /> -