diff --git a/.eslintignore b/.eslintignore
index 20fdcbf38..b980bf2d1 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -2,4 +2,5 @@
.gitignore
*.json
*.lock
-*.hbs
\ No newline at end of file
+*.hbs
+*.svg
\ No newline at end of file
diff --git a/public/icons/static/shape/image.svg b/public/icons/static/shape/image.svg
new file mode 100644
index 000000000..403eed857
--- /dev/null
+++ b/public/icons/static/shape/image.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/icons/static/shape/video.svg b/public/icons/static/shape/video.svg
new file mode 100644
index 000000000..5e2a58fb6
--- /dev/null
+++ b/public/icons/static/shape/video.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/components/AvatarsRow/MoreItem.js b/src/components/AvatarsRow/MoreItem.tsx
similarity index 66%
rename from src/components/AvatarsRow/MoreItem.js
rename to src/components/AvatarsRow/MoreItem.tsx
index 883ca9dbc..58b9110f4 100644
--- a/src/components/AvatarsRow/MoreItem.js
+++ b/src/components/AvatarsRow/MoreItem.tsx
@@ -1,8 +1,10 @@
-import React, { useCallback } from 'react'
+import React from 'react'
import { prettyNum } from '@/utils'
import Tooltip from '@/components/Tooltip'
+import type { TProps as TAvatarsProps } from './index'
+
import {
Wrapper,
NumbersMore,
@@ -12,13 +14,19 @@ import {
Focus,
} from './styles/more_item'
-const MoreItem = ({ users, size, total, onTotalSelect, showTotalNumber }) => {
- const handleClick = useCallback(() => {
- onTotalSelect({ users, total })
- }, [onTotalSelect, total, users])
+type TProps = Pick<
+ TAvatarsProps,
+ 'size' | 'total' | 'showTotalNumber' | 'onTotalSelect'
+>
+const MoreItem: React.FC = ({
+ size,
+ total,
+ onTotalSelect,
+ showTotalNumber,
+}) => {
return (
-
+ onTotalSelect()}>
{
)
}
- duration={0}
>
{showTotalNumber ? (
-
+
...
) : (
diff --git a/src/components/AvatarsRow/index.js b/src/components/AvatarsRow/index.tsx
similarity index 58%
rename from src/components/AvatarsRow/index.js
rename to src/components/AvatarsRow/index.tsx
index 1c4879ca1..3130597b0 100755
--- a/src/components/AvatarsRow/index.js
+++ b/src/components/AvatarsRow/index.tsx
@@ -4,16 +4,17 @@
*
*/
-import React, { useCallback } from 'react'
-import T from 'prop-types'
-import { compose, not, isNil, filter, reverse, slice } from 'ramda'
+import React from 'react'
+import { compose, not, isNil, filter, reverse as reverseFn, slice } from 'ramda'
import { trackWindowScroll } from 'react-lazy-load-image-component'
+import type { TUser } from '@/spec'
import { AVATARS_LIST_LENGTH } from '@/config'
import { SIZE } from '@/constant'
-import { buildLog, o2s, s2o } from '@/utils'
+import { buildLog } from '@/utils'
import Tooltip from '@/components/Tooltip'
+import type { TAvatarSize } from './spec'
import MoreItem from './MoreItem'
@@ -45,41 +46,46 @@ const getUniqueArray = (arr, comp) => {
return unique
}
-const AvatarsRow = ({
+export type TProps = {
+ users?: TUser[]
+ size?: TAvatarSize
+ total: number
+ limit: number
+ showTotalNumber?: boolean
+ reverse?: boolean
+ scrollPosition?: any
+
+ onUserSelect: (user: TUser) => void
+ onTotalSelect: () => void
+}
+
+const AvatarsRow: React.FC = ({
+ size = SIZE.SMALL,
total,
- users,
- size,
- limit,
- onUserSelect,
- onTotalSelect,
- showTotalNumber,
- reverse: isReverse,
- scrollPosition,
+ users = [],
+ limit = AVATARS_LIST_LENGTH.POSTS,
+ onUserSelect = log,
+ onTotalSelect = log,
+ showTotalNumber = false,
+ reverse = true,
+ // see https://github.com/Aljullu/react-lazy-load-image-component/issues/42
+ scrollPosition = null,
}) => {
- const handleUserSelect = useCallback(
- (e) => {
- const user = s2o(e.target.dataset.user)
- onUserSelect(user)
- },
- [onUserSelect],
- )
-
if (users.length === 0) {
return
}
users = filter(validUser, getUniqueArray(users, 'id'))
- const sortedUsers = isReverse ? users : reverse(users)
+ const sortedUsers = reverse ? users : reverseFn(users)
return (
-
+
{total <= 1 ? (
) : (
@@ -91,18 +97,18 @@ const AvatarsRow = ({
content={user.nickname}
duration={0}
delay={300}
- contentHeight={getAvatarSize(size)}
+ contentHeight={getAvatarSize(size, 'number') as string}
+ noPadding
>
onUserSelect(user)}
scrollPosition={scrollPosition}
fallback={
}
@@ -114,35 +120,4 @@ const AvatarsRow = ({
)
}
-AvatarsRow.propTypes = {
- users: T.arrayOf(
- T.shape({
- id: T.string,
- avatar: T.string,
- nickname: T.string,
- extra_id: T.string,
- }),
- ),
- size: T.oneOf([SIZE.SMALL, SIZE.MEDIUM]),
- total: T.number.isRequired,
- limit: T.number,
- onUserSelect: T.func,
- onTotalSelect: T.func,
- showTotalNumber: T.bool,
- reverse: T.bool,
- scrollPosition: T.any,
-}
-
-AvatarsRow.defaultProps = {
- size: SIZE.SMALL,
- users: [],
- limit: AVATARS_LIST_LENGTH.POSTS,
- onUserSelect: log,
- onTotalSelect: log,
- showTotalNumber: false,
- reverse: true,
- // see https://github.com/Aljullu/react-lazy-load-image-component/issues/42
- scrollPosition: null,
-}
-
export default trackWindowScroll(AvatarsRow)
diff --git a/src/components/AvatarsRow/spec.ts b/src/components/AvatarsRow/spec.ts
new file mode 100644
index 000000000..f8349bbf2
--- /dev/null
+++ b/src/components/AvatarsRow/spec.ts
@@ -0,0 +1,3 @@
+import type { TSIZE_SM } from '@/spec'
+
+export type TAvatarSize = TSIZE_SM
diff --git a/src/components/AvatarsRow/styles/index.ts b/src/components/AvatarsRow/styles/index.ts
index fc1615bee..c9df23140 100755
--- a/src/components/AvatarsRow/styles/index.ts
+++ b/src/components/AvatarsRow/styles/index.ts
@@ -5,6 +5,7 @@ import { theme, css } from '@/utils'
import ImgFallback from '@/components/ImgFallback'
import { getLiSize, getAvatarSize, getUlMarginRight } from './metric'
+import type { TAvatarSize } from '../spec'
export const Wrapper = styled.ul<{ total: number }>`
${css.flex('align-center')};
@@ -15,7 +16,7 @@ export const Wrapper = styled.ul<{ total: number }>`
margin-right: ${({ total }) => getUlMarginRight(total)};
`
// height: 49px;
-type TBaseAvatarItem = { size: string; noHoverMargin: string }
+type TBaseAvatarItem = { size: TAvatarSize; noHoverMargin: boolean }
const BaseAvatarItem = styled.li`
margin: 0px 0px 0px 0px;
padding: 0px 0px 0px 0px;
@@ -45,7 +46,8 @@ export const AvatarsItem = styled(BaseAvatarItem)`
export const TotalOneOffset = styled.span`
margin-right: 10px;
`
-export const AvatarsImg = styled(Img)<{ size: string }>`
+type TAvatarsImg = { size: string; onClick: () => void; scrollPosition: any }
+export const AvatarsImg = styled(Img)`
border: 2px solid;
border-color: ${theme('thread.commentsUserBorder')};
border-radius: 100px 100px 100px 100px;
@@ -60,7 +62,7 @@ export const AvatarsImg = styled(Img)<{ size: string }>`
text-align: center;
`
-type TAvatarsMore = { size: string; total: number }
+type TAvatarsMore = { size: TAvatarSize; total: number }
export const AvatarsMore = styled.span`
${css.flex('align-both')};
font-size: 14px;
diff --git a/src/components/AvatarsRow/styles/metric.ts b/src/components/AvatarsRow/styles/metric.ts
index e2150fe61..5883d011a 100644
--- a/src/components/AvatarsRow/styles/metric.ts
+++ b/src/components/AvatarsRow/styles/metric.ts
@@ -1,9 +1,11 @@
import { SIZE } from '@/constant'
+import type { TAvatarSize } from '../spec'
+
/**
* NOTE: Li size should always smaller than the avatar size
*/
-export const getLiSize = (size: string): string => {
+export const getLiSize = (size: TAvatarSize): string => {
switch (size) {
case SIZE.SMALL: {
return '15px'
diff --git a/src/components/DigestSentence/index.js b/src/components/DigestSentence/index.js
deleted file mode 100755
index 4d1d7d9b3..000000000
--- a/src/components/DigestSentence/index.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *
- * DigestSentence
- *
- */
-
-import React from 'react'
-import T from 'prop-types'
-
-import { ICON } from '@/config'
-import { buildLog } from '@/utils'
-
-import { Wrapper, PreviewWrapper, PreviewText, PreviewIcon } from './styles'
-
-/* eslint-disable-next-line */
-const log = buildLog('c:DigestSentence:index')
-
-const DigestSentence = ({
- testid,
- children,
- onPreview,
- top,
- bottom,
- left,
- right,
-}) => {
- return (
-
- {children}
-
- 预览
-
-
-
- )
-}
-
-DigestSentence.propTypes = {
- testid: T.string,
- children: T.oneOfType([T.string, T.node]),
- onPreview: T.func,
- top: T.number,
- bottom: T.number,
- left: T.number,
- right: T.number,
-}
-
-DigestSentence.defaultProps = {
- testid: 'digest-sentence',
- children: '可能是最性感的开发者社区,来为你心爱的作品建立...',
- onPreview: log,
- top: 0,
- bottom: 0,
- left: 0,
- right: 0,
-}
-
-export default React.memo(DigestSentence)
diff --git a/src/components/DigestSentence/index.tsx b/src/components/DigestSentence/index.tsx
new file mode 100755
index 000000000..08e71196a
--- /dev/null
+++ b/src/components/DigestSentence/index.tsx
@@ -0,0 +1,73 @@
+/*
+ *
+ * DigestSentence
+ *
+ */
+
+import React from 'react'
+
+import { ICON } from '@/config'
+import { buildLog } from '@/utils'
+
+import { Space } from '@/components/Common'
+
+import {
+ Wrapper,
+ MediaHintWrapper,
+ HintIcon,
+ HintText,
+ PreviewWrapper,
+ PreviewText,
+ PreviewIcon,
+} from './styles'
+
+/* eslint-disable-next-line */
+const log = buildLog('c:DigestSentence:index')
+
+type TProps = {
+ testid?: string
+ children: React.ReactNode
+ onPreview: () => void
+ top?: number
+ bottom?: number
+ left?: number
+ right?: number
+}
+
+const DigestSentence: React.FC = ({
+ testid = 'digest-sentence',
+ children = '可能是最性感的开发者社区,来为你心爱的作品建立...',
+ onPreview = log,
+ top = 0,
+ bottom = 0,
+ left = 0,
+ right = 0,
+}) => {
+ return (
+
+ {children}
+
+
+
+ 3
+
+
+
+ 1
+
+
+ 预览
+
+
+
+ )
+}
+
+export default React.memo(DigestSentence)
diff --git a/src/components/DigestSentence/styles/index.ts b/src/components/DigestSentence/styles/index.ts
index 31f5f3170..a8d928af1 100755
--- a/src/components/DigestSentence/styles/index.ts
+++ b/src/components/DigestSentence/styles/index.ts
@@ -22,6 +22,27 @@ export const Wrapper = styled.div.attrs(({ testid }: TTestable) => ({
transition: color 0.2s;
`
+export const MediaHintWrapper = styled.div`
+ position: relative;
+ margin-left: 5px;
+ display: inline-flex;
+`
+export const HintIcon = styled(Img)`
+ position: absolute;
+ top: 1px;
+ left: 0;
+ fill: ${theme('thread.articleDigest')};
+ ${css.size(14)};
+ margin-right: 3px;
+`
+export const HintText = styled.div`
+ color: ${theme('thread.articleTitle')};
+ font-size: 11px;
+ height: 12px;
+ margin-right: 5px;
+ padding-left: 17px;
+`
+
export const PreviewWrapper = styled.div`
display: inline-flex;
opacity: 0;
diff --git a/src/components/PostItem/DigestView/DesktopView/ActiveBadge.tsx b/src/components/PostItem/DigestView/DesktopView/ActiveBadge.tsx
new file mode 100644
index 000000000..b9a5f93bb
--- /dev/null
+++ b/src/components/PostItem/DigestView/DesktopView/ActiveBadge.tsx
@@ -0,0 +1,41 @@
+import React from 'react'
+
+import type { TPost } from '@/spec'
+import { ICON } from '@/config'
+
+import Tooltip from '@/components/Tooltip'
+
+import {
+ Wrapper,
+ PopContent,
+ PopContentDate,
+ ItemInner,
+ Icon,
+} from '../../styles/digest_view/active_badge'
+
+type TProps = {
+ item: TPost
+}
+
+const ActiveBadge: React.FC = ({ item }) => {
+ return (
+ 0}>
+
+ 最后回复
2020-03-11
+
+ }
+ placement="bottom"
+ noPadding
+ >
+
+
+ 4天前
+
+
+
+ )
+}
+
+export default ActiveBadge
diff --git a/src/components/PostItem/DigestView/DesktopView/Body.js b/src/components/PostItem/DigestView/DesktopView/Body.tsx
similarity index 73%
rename from src/components/PostItem/DigestView/DesktopView/Body.js
rename to src/components/PostItem/DigestView/DesktopView/Body.tsx
index 725e3ce7b..8499c48f6 100644
--- a/src/components/PostItem/DigestView/DesktopView/Body.js
+++ b/src/components/PostItem/DigestView/DesktopView/Body.tsx
@@ -1,13 +1,15 @@
import React from 'react'
import TimeAgo from 'timeago-react'
+import type { TPost } from '@/spec'
import { ICON } from '@/config'
import { cutRest } from '@/utils'
-import Tooltip from '@/components/Tooltip'
import { SpaceGrow } from '@/components/Common'
import DigestSentence from '@/components/DigestSentence'
+import ActiveBadge from './ActiveBadge'
+
import {
Wrapper,
Dot,
@@ -17,11 +19,14 @@ import {
AuthorName,
ItemWrapper,
ViewsIcon,
- ActiveItemWrapper,
- ActiveIcon,
} from '../../styles/digest_view/body'
-const Body = ({ item, onPreview }) => {
+type TProps = {
+ item: TPost
+ onPreview?: (obj: TPost) => void
+}
+
+const Body: React.FC = ({ item, onPreview }) => {
return (
@@ -39,12 +44,7 @@ const Body = ({ item, onPreview }) => {
- 0}>
- 最后回复} placement="bottom">
-
-
- 4天前
-
+
onPreview(item)}>
diff --git a/src/components/PostItem/DigestView/DesktopView/Header.js b/src/components/PostItem/DigestView/DesktopView/Header.tsx
similarity index 85%
rename from src/components/PostItem/DigestView/DesktopView/Header.js
rename to src/components/PostItem/DigestView/DesktopView/Header.tsx
index 75ebef315..d50407a29 100644
--- a/src/components/PostItem/DigestView/DesktopView/Header.js
+++ b/src/components/PostItem/DigestView/DesktopView/Header.tsx
@@ -1,6 +1,7 @@
import React from 'react'
import Link from 'next/link'
+import type { TPost, TUser } from '@/spec'
import { ROUTE } from '@/constant'
import { ICON_CMD } from '@/config'
import { parseDomain } from '@/utils'
@@ -17,7 +18,12 @@ import {
TagListWrapper,
} from '../../styles/digest_view/header'
-const Header = ({ item, onUserSelect }) => {
+type TProps = {
+ item: TPost
+ onUserSelect?: (obj: TUser) => void
+}
+
+const Header: React.FC = ({ item, onUserSelect }) => {
return (
diff --git a/src/components/PostItem/DigestView/DesktopView/index.js b/src/components/PostItem/DigestView/DesktopView/index.tsx
similarity index 66%
rename from src/components/PostItem/DigestView/DesktopView/index.js
rename to src/components/PostItem/DigestView/DesktopView/index.tsx
index 4d87d5bdc..f088c29fd 100644
--- a/src/components/PostItem/DigestView/DesktopView/index.js
+++ b/src/components/PostItem/DigestView/DesktopView/index.tsx
@@ -1,5 +1,6 @@
import React from 'react'
+import type { TPost, TUser, TAccount } from '@/spec'
import { ICON_BASE } from '@/config'
import TheAvatar from '@/components/TheAvatar'
@@ -9,10 +10,19 @@ import Body from './Body'
import { Avatar, Main } from '../../styles/digest_view/index'
-const DigestView = ({
+type TProps = {
+ active?: TPost | null
+ entry: TPost
+ cover: 'avatar' | 'source'
+
+ onPreview?: (obj: TPost) => void
+ onUserSelect?: (obj: TUser) => void
+ onAuthorSelect?: (obj: TAccount) => void
+}
+
+const DigestView: React.FC = ({
entry,
cover,
- community,
onPreview,
onUserSelect,
onAuthorSelect,
@@ -27,11 +37,7 @@ const DigestView = ({
/>
)}
-
+
diff --git a/src/components/PostItem/DigestView/MobileView/Body.js b/src/components/PostItem/DigestView/MobileView/Body.tsx
similarity index 77%
rename from src/components/PostItem/DigestView/MobileView/Body.js
rename to src/components/PostItem/DigestView/MobileView/Body.tsx
index 1c903b2c7..d20665e60 100644
--- a/src/components/PostItem/DigestView/MobileView/Body.js
+++ b/src/components/PostItem/DigestView/MobileView/Body.tsx
@@ -1,5 +1,6 @@
import React from 'react'
+import type { TPost } from '@/spec'
import { ICON_CMD } from '@/config'
import { parseDomain } from '@/utils'
@@ -10,7 +11,12 @@ import {
Title,
} from '../../styles/mobile_view/body'
-const Body = ({ item, onPreview }) => {
+type TProps = {
+ item: TPost
+ onPreview?: (obj: TPost) => void
+}
+
+const Body: React.FC = ({ item, onPreview }) => {
return (
onPreview(item)}>
{item.title}
diff --git a/src/components/PostItem/DigestView/MobileView/Footer.js b/src/components/PostItem/DigestView/MobileView/Footer.tsx
similarity index 86%
rename from src/components/PostItem/DigestView/MobileView/Footer.js
rename to src/components/PostItem/DigestView/MobileView/Footer.tsx
index 182632d70..29bd501f2 100644
--- a/src/components/PostItem/DigestView/MobileView/Footer.js
+++ b/src/components/PostItem/DigestView/MobileView/Footer.tsx
@@ -1,5 +1,6 @@
import React from 'react'
+import type { TPost } from '@/spec'
import { cutRest } from '@/utils'
import { ICON_CMD } from '@/config'
@@ -14,7 +15,11 @@ import {
BodyDigest,
} from '../../styles/mobile_view/footer'
-const Footer = ({ item }) => {
+type TProps = {
+ item: TPost
+}
+
+const Footer: React.FC = ({ item }) => {
return (
diff --git a/src/components/PostItem/DigestView/MobileView/Header.js b/src/components/PostItem/DigestView/MobileView/Header.tsx
similarity index 84%
rename from src/components/PostItem/DigestView/MobileView/Header.js
rename to src/components/PostItem/DigestView/MobileView/Header.tsx
index bffe73693..b02bcb56f 100644
--- a/src/components/PostItem/DigestView/MobileView/Header.js
+++ b/src/components/PostItem/DigestView/MobileView/Header.tsx
@@ -1,6 +1,7 @@
import React from 'react'
import TimeAgo from 'timeago-react'
+import type { TPost, TAccount } from '@/spec'
import { ICON_BASE } from '@/config'
import InlineTags from '@/components/InlineTags'
@@ -16,7 +17,13 @@ import {
TagListWrapper,
} from '../../styles/mobile_view/header'
-const Header = ({ cover, item, onAuthorSelect }) => {
+type TProps = {
+ item: TPost
+ cover: 'avatar' | 'source'
+ onAuthorSelect?: (obj: TAccount) => void
+}
+
+const Header: React.FC = ({ cover, item, onAuthorSelect }) => {
return (
diff --git a/src/components/PostItem/DigestView/MobileView/index.js b/src/components/PostItem/DigestView/MobileView/index.tsx
similarity index 57%
rename from src/components/PostItem/DigestView/MobileView/index.js
rename to src/components/PostItem/DigestView/MobileView/index.tsx
index c163387f2..5a8886818 100644
--- a/src/components/PostItem/DigestView/MobileView/index.js
+++ b/src/components/PostItem/DigestView/MobileView/index.tsx
@@ -1,12 +1,28 @@
import React from 'react'
+import type { TPost, TAccount } from '@/spec'
+
import Header from './Header'
import Body from './Body'
import Footer from './Footer'
import { Wrapper } from '../../styles/mobile_view/index'
-const MobileView = ({ entry, cover, onPreview, onAuthorSelect }) => {
+type TProps = {
+ entry: TPost
+ cover: 'avatar' | 'source'
+ community: string
+
+ onPreview?: (obj: TPost) => void
+ onAuthorSelect?: (obj: TAccount) => void
+}
+
+const MobileView: React.FC = ({
+ entry,
+ cover,
+ onPreview,
+ onAuthorSelect,
+}) => {
return (
diff --git a/src/components/PostItem/ListView.js b/src/components/PostItem/ListView.tsx
similarity index 89%
rename from src/components/PostItem/ListView.js
rename to src/components/PostItem/ListView.tsx
index 2d49124ca..339e9a276 100755
--- a/src/components/PostItem/ListView.js
+++ b/src/components/PostItem/ListView.tsx
@@ -1,9 +1,10 @@
import React from 'react'
import TimeAgo from 'timeago-react'
+import type { TPost } from '@/spec'
import { ICON_CMD } from '@/config'
-
import { cutRest, parseDomain } from '@/utils'
+
import InlineTags from '@/components/InlineTags'
import {
@@ -21,7 +22,12 @@ import {
CommentNum,
} from './styles/list_view'
-const ListView = ({ entry, onPreview }) => (
+type TProps = {
+ entry: TPost
+ onPreview?: (obj: TPost) => void
+}
+
+const ListView: React.FC = ({ entry, onPreview }) => (
diff --git a/src/components/PostItem/index.js b/src/components/PostItem/index.tsx
similarity index 52%
rename from src/components/PostItem/index.js
rename to src/components/PostItem/index.tsx
index c38dc5c59..9cd00a856 100755
--- a/src/components/PostItem/index.js
+++ b/src/components/PostItem/index.tsx
@@ -5,12 +5,13 @@
*/
import React from 'react'
-import T from 'prop-types'
+import type { TPost, TUser, TAccount } from '@/spec'
import { HCN, C11N } from '@/constant'
import { buildLog } from '@/utils'
import ArticleItemPrefixLabel from '@/components/ArticleItemPrefixLabel'
+
import DigestView from './DigestView/index'
import ListView from './ListView'
@@ -19,15 +20,35 @@ import { Wrapper } from './styles'
/* eslint-disable-next-line */
const log = buildLog('c:PostItem:index')
-const PostItem = ({
+type TProps = {
+ active?: TPost | null
+ entry: TPost
+ cover: 'avatar' | 'source'
+ community: string
+ accountInfo: TAccount
+
+ onPreview?: (obj: TPost) => void
+ onUserSelect?: (obj: TUser) => void
+ onAuthorSelect?: (obj: TAccount) => void
+}
+
+const PostItem: React.FC = ({
entry,
- cover,
- community,
- active,
- onPreview,
- onUserSelect,
- onAuthorSelect,
- accountInfo,
+ onPreview = log,
+ onUserSelect = log,
+ onAuthorSelect = log,
+ active = null,
+ cover = 'avatar',
+ community = HCN,
+ accountInfo = {
+ isLogin: false,
+ customization: {
+ contentsLayout: C11N.DIGEST,
+ contentDivider: false,
+ markViewed: true,
+ displayDensity: '20',
+ },
+ },
}) => {
// log('customization --> ', customization)
const {
@@ -52,63 +73,10 @@ const PostItem = ({
onAuthorSelect={onAuthorSelect}
/>
) : (
-
+
)}
)
}
-PostItem.propTypes = {
- active: T.object,
- entry: T.shape({
- title: T.string,
- digest: T.string,
- views: T.number,
-
- author: T.shape({
- nickname: T.string,
- avatar: T.string,
- }),
- }).isRequired,
- cover: T.oneOf(['avatar', 'source']),
- community: T.string,
-
- accountInfo: T.shape({
- isLogin: T.bool,
- customization: T.shape({
- contentsLayout: T.oneOf([C11N.DIGEST, C11N.LIST]),
- markViewed: T.bool,
- contentDivider: T.bool,
- displayDensity: T.oneOf(['20', '25', '30']),
- }),
- }),
- onPreview: T.func,
- onUserSelect: T.func,
- onAuthorSelect: T.func,
-}
-
-PostItem.defaultProps = {
- onPreview: log,
- onUserSelect: log,
- onAuthorSelect: log,
- active: {},
- cover: 'avatar',
- community: HCN,
- accountInfo: {
- isLogin: false,
- customization: T.shape({
- contentsLayout: C11N.DIGEST,
- contentDivider: false,
- markViewed: true,
- displayDensity: '20',
- }),
- },
-}
-
export default React.memo(PostItem)
diff --git a/src/components/PostItem/styles/digest_view/active_badge.ts b/src/components/PostItem/styles/digest_view/active_badge.ts
new file mode 100644
index 000000000..0b57c8ef6
--- /dev/null
+++ b/src/components/PostItem/styles/digest_view/active_badge.ts
@@ -0,0 +1,41 @@
+import styled from 'styled-components'
+
+import { theme, css } from '@/utils'
+import Img from '@/Img'
+
+import { Main } from './index'
+
+export const Wrapper = styled.div<{ hasComments: boolean }>`
+ ${css.flex('align-center')};
+ display: ${({ hasComments }) => (hasComments ? 'flex' : 'none')};
+ position: absolute;
+ top: 3px;
+ right: 0;
+ color: ${theme('thread.articleDigest')};
+ margin-right: 6px;
+ margin-top: 8px;
+ opacity: 0.8;
+
+ ${Main}:hover & {
+ opacity: 1;
+ }
+ transition: opacity 0.2s;
+`
+export const ItemInner = styled.div`
+ ${css.flex('align-center')};
+`
+export const PopContent = styled.div`
+ ${css.flexColumn('align-end')};
+ width: 100%;
+ min-width: 85px;
+ font-size: 12px;
+`
+export const PopContentDate = styled.div`
+ margin-top: 6px;
+`
+export const Icon = styled(Img)`
+ fill: ${theme('thread.articleDigest')};
+ ${css.size(12)};
+ opacity: 0.6;
+ margin-right: 3px;
+`
diff --git a/src/components/PostItem/styles/digest_view/body.ts b/src/components/PostItem/styles/digest_view/body.ts
index a8a068189..6c6070b62 100644
--- a/src/components/PostItem/styles/digest_view/body.ts
+++ b/src/components/PostItem/styles/digest_view/body.ts
@@ -43,25 +43,3 @@ export const ViewsIcon = styled(Img)`
opacity: 0.6;
margin-right: 3px;
`
-
-export const ActiveItemWrapper = styled.div<{ hasComments: string }>`
- position: absolute;
- top: ${({ hasComments }) => (hasComments ? '5px' : '-24px')};
- right: 0;
- ${css.flex('align-center')};
- color: ${theme('thread.articleDigest')};
- margin-right: 6px;
- margin-top: 8px;
- opacity: 0;
-
- ${Main}:hover & {
- opacity: 1;
- }
- transition: opacity 0.2s;
-`
-export const ActiveIcon = styled(Img)`
- fill: ${theme('thread.articleDigest')};
- ${css.size(12)};
- opacity: 0.6;
- margin-right: 3px;
-`
diff --git a/src/components/PostItem/styles/index.ts b/src/components/PostItem/styles/index.ts
index 3e993c3b3..5a3ddbf44 100755
--- a/src/components/PostItem/styles/index.ts
+++ b/src/components/PostItem/styles/index.ts
@@ -1,16 +1,18 @@
import styled from 'styled-components'
-import type { TActive, TUser } from '@/spec'
+import type { TPost, TAccount } from '@/spec'
import { theme, css } from '@/utils'
import { getOpacity } from './metrics'
-type IPostItemUI = TActive & { accountInfo: TUser } & {
- entry: any
+type TWrapper = {
+ entry: TPost
+ active?: TPost | null
divider: boolean
+ accountInfo: TAccount
}
-export const Wrapper = styled.article`
+export const Wrapper = styled.article`
${css.flex()};
position: relative;
opacity: ${({ entry, active, accountInfo }) =>
diff --git a/src/components/PostItem/styles/metrics.ts b/src/components/PostItem/styles/metrics.ts
index a48cdd26a..b232f212c 100644
--- a/src/components/PostItem/styles/metrics.ts
+++ b/src/components/PostItem/styles/metrics.ts
@@ -1,12 +1,18 @@
-export const getOpacity = (entry, active, accountInfo): number => {
+import type { TPost, TAccount } from '@/spec'
+
+export const getOpacity = (
+ entry: TPost,
+ active: TPost | null,
+ accountInfo: TAccount,
+): number => {
const {
isLogin,
customization: { markViewed },
} = accountInfo
const { viewerHasViewed } = entry
- if (active.id) {
- return entry.id !== active.id ? 0.6 : 1
+ if (active?.id) {
+ return entry.id !== active?.id ? 0.6 : 1
}
if (isLogin && markViewed && viewerHasViewed) {
return 0.85
diff --git a/src/containers/unit/Comments/Comment/Header.tsx b/src/containers/unit/Comments/Comment/Header.tsx
index 16aeee7e6..2ba030ebb 100755
--- a/src/containers/unit/Comments/Comment/Header.tsx
+++ b/src/containers/unit/Comments/Comment/Header.tsx
@@ -24,7 +24,7 @@ const getAuthors = (comment) => {
/* eslint-disable no-return-assign */
const replies = forEach((reply) => {
/* @ts-ignore */
- return (reply.author.extra_id = reply.id)
+ return (reply.author.extraId = reply.id)
}, clone(comment.replies))
/* eslint-enable */
diff --git a/src/spec/account.ts b/src/spec/account.ts
index b8562f7f0..0006da1d8 100644
--- a/src/spec/account.ts
+++ b/src/spec/account.ts
@@ -1,14 +1,20 @@
export type TUser = {
- id: string
+ id?: string
login?: string
nickname?: string
name?: string
- avatar: string
+ avatar?: string
+ // TODO: figure it out
+ extraId?: string
}
export type TAccount = TUser & {
customization?: {
- theme: string
- bannerLayout: string
+ theme?: string
+ bannerLayout?: string
+ contentsLayout?: string // oneOf([C11N.DIGEST, C11N.LIST])
+ markViewed?: boolean
+ contentDivider?: boolean
+ displayDensity?: string // oneOf(['20', '25', '30'])
}
isLogin?: boolean
isValidSession?: boolean
diff --git a/src/spec/article.ts b/src/spec/article.ts
index ff67b3c48..faf614f80 100644
--- a/src/spec/article.ts
+++ b/src/spec/article.ts
@@ -1,11 +1,12 @@
-import type { TCommunity } from './index'
+import type { TCommunity, TTag } from './index'
import type { TUser } from './account'
export type TArticle = {
- id: string
- title: string
- body: string
- author: {
+ id?: string
+ title?: string
+ body?: string
+ views?: number
+ author?: {
id: string
login: string
nickname: string
@@ -14,7 +15,15 @@ export type TArticle = {
origialCommunity?: TCommunity
commentsParticipators?: TUser
insertedAt?: string
- // ...
+ viewerHasViewed?: boolean
+ commentsCount?: number
+ tags?: TTag[]
+}
+
+export type TPost = TArticle & {
+ digest?: string
+ linkAddr?: string
+ linkIcon?: string
}
export type TJob = {
diff --git a/src/spec/index.ts b/src/spec/index.ts
index 1e6435622..303c52208 100644
--- a/src/spec/index.ts
+++ b/src/spec/index.ts
@@ -35,6 +35,7 @@ export type { TGQLError } from './graphql'
export type {
TArticle,
+ TPost,
TJob,
TPagedJobs,
TComment,
diff --git a/src/spec/size.ts b/src/spec/size.ts
index 94802a021..67afb11d4 100644
--- a/src/spec/size.ts
+++ b/src/spec/size.ts
@@ -7,6 +7,6 @@ export type TSIZE_M = 'medium'
export type TSIZE_L = 'large'
export type TSIZE_TS = TSIZE_T | TSIZE_S
-export type TSIZE_SM = TSIZE_T | TSIZE_M
+export type TSIZE_SM = TSIZE_S | TSIZE_M
export type TSIZE_TSM = TSIZE_T | TSIZE_S | TSIZE_M
export type TSIZE_SML = TSIZE_S | TSIZE_M | TSIZE_L