Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ next-env.d.ts
*.json
*.lock
*.hbs
*.svg
*.svg
*.png
1 change: 1 addition & 0 deletions config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"DEFAULT_USER_AVATAR": "https://cps-oss.oss-cn-shanghai.aliyuncs.com/icons/cmd/alien_user3.svg",
"GRAPHQL_ENDPOINT": "https://api.coderplanets.com/graphiql",
"SITE_URL": "https://coderplanets.com",
"SITE_URL_SHORT": "https://cper.co",
"GITHUB": "https://github.com/coderplanets",
"GITHUB_WEB_ADDR": "https://github.com/coderplanets/coderplanets_web",
"GITHUB_SERVER_ADDR": "https://github.com/coderplanets/coderplanets_server",
Expand Down
1 change: 1 addition & 0 deletions config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const {
DEFAULT_ICON,
DEFAULT_USER_AVATAR,
SITE_URL,
SITE_URL_SHORT,
GITHUB,
GITHUB_WEB_ADDR,
GITHUB_SERVER_ADDR,
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,13 @@
"promise-timeout": "^1.3.0",
"prop-types": "^15.5.10",
"pubsub-js": "^1.9.3",
"qrcode-react": "^0.1.16",
"ramda": "0.26.1",
"react": "17.0.2",
"react-animation": "^1.2.2",
"react-calendar-heatmap": "1.8.1",
"react-content-loader": "3.4.2",
"react-copy-to-clipboard": "^5.0.3",
"react-dom": "17.0.2",
"react-highlight-words": "^0.16.0",
"react-lazy-load-image-component": "1.5.0",
Expand Down
1 change: 1 addition & 0 deletions public/icons/static/article/clipboard.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/icons/static/shape/link.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/static/social/QQ-share.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/icons/static/social/embed-share.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/static/social/facebook-share.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions public/icons/static/social/mail-share.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/static/social/twitter-share.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/static/social/wechat-share.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/static/social/weibo-share.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions src/components/Buttons/CopyButton/Animate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { FC, memo, useEffect, useState } from 'react'

import { ICON } from '@/config'
import { IconButton } from '@/components/Buttons'
import { CopyToClipboard } from 'react-copy-to-clipboard'

import { AnimateOnChange } from 'react-animation'
import { CopyedHintIcon } from '../styles/copy_button'

type TProps = {
value: string
}

const CopyButton: FC<TProps> = ({ value }) => {
const [done, setDone] = useState(false)

useEffect(() => {
if (done) {
setTimeout(() => setDone(false), 2000)
}
}, [done])

return (
<AnimateOnChange
// animationIn="bounceIn"
animationIn="popIn"
animationOut="bounceOut"
durationOut={100}
>
{!done && (
<CopyToClipboard text={value} onCopy={() => setDone(true)}>
<IconButton path="article/clipboard.svg" mRight={5} />
</CopyToClipboard>
)}
{done && <CopyedHintIcon src={`${ICON}/shape/checked.svg`} />}
</AnimateOnChange>
)
}

export default memo(CopyButton)
27 changes: 27 additions & 0 deletions src/components/Buttons/CopyButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { FC, memo } from 'react'
import dynamic from 'next/dynamic'

import IconButton from '../IconButton'
import { Wrapper } from '../styles/copy_button'

const AnimatedCopyButton = dynamic(() => import('./Animate'), {
/* eslint-disable react/display-name */
loading: () => {
return <IconButton path="article/clipboard.svg" mRight={5} />
},
ssr: false,
})

type TProps = {
value: string
}

const CopyButton: FC<TProps> = ({ value }) => {
return (
<Wrapper>
<AnimatedCopyButton value={value} />
</Wrapper>
)
}

export default memo(CopyButton)
1 change: 1 addition & 0 deletions src/components/Buttons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export { default as NotifyButton } from './NotifyButton'
export { default as FollowButton } from './FollowButton'
export { default as YesOrNoButtons } from './YesOrNoButtons'
export { default as IconButton } from './IconButton'
export { default as CopyButton } from './CopyButton'
13 changes: 13 additions & 0 deletions src/components/Buttons/styles/copy_button/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import styled from 'styled-components'

import { css, theme } from '@/utils'
import Img from '@/Img'

export const Wrapper = styled.div`
${css.flex('align-center')};
`
export const CopyedHintIcon = styled(Img)`
fill: ${theme('baseColor.green')};
${css.size(20)};
margin-right: 3px;
`
2 changes: 1 addition & 1 deletion src/components/Input/styles/textarea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const Wrapper = styled(TextareaAutosize).attrs(
color: ${theme('form.text')};
min-height: 56px;
padding: 6px 10px;
background-color: #06303b;
background-color: #0b2631;
border: 1px solid;
border-color: ${theme('editor.border')};
resize: none;
Expand Down
2 changes: 1 addition & 1 deletion src/components/Modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const Modal: FC<TProps> = ({
onClose = log,
mode = 'default',
background = 'default',
offsetTop = '13%',
offsetTop = '20%',
}) => {
const { Portal } = usePortal()
const [visibleOnPage, setVisibleOnPage] = useState(false)
Expand Down
3 changes: 1 addition & 2 deletions src/components/Modal/styles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ export const Wrapper = styled.div<TWrapper>`
max-height: 81vh;
box-shadow: -5px 6px 37px -8px rgba(0, 0, 0, 0.42);
/* border: 1px solid; */
border-left: 2px solid;
border-right: 2px solid;
border-top: 3px solid;
border-color: ${({ mode }) =>
mode === 'default' ? theme('modal.border') : theme('baseColor.red')};
animation: ${animate.zoomIn} 0.2s linear;
Expand Down
6 changes: 6 additions & 0 deletions src/containers/layout/GlobalLayout/dynamic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ export const Doraemon = dynamic(() => import('@/containers/tool/Doraemon'), {
ssr: false,
})

export const Share = dynamic(() => import('@/containers/tool/Share'), {
/* eslint-disable react/display-name */
loading: () => <div />,
ssr: false,
})

export const AbuseReport = dynamic(
() => import('@/containers/tool/AbuseReport'),
{
Expand Down
11 changes: 10 additions & 1 deletion src/containers/layout/GlobalLayout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@ import CustomScroller from '@/components/CustomScroller'

import type { TStore } from './store'
import SEO from './SEO'
import { AbuseReport, Doraemon, ErrorBox, Footer, ErrorPage } from './dynamic'

import {
AbuseReport,
Doraemon,
ErrorBox,
Footer,
ErrorPage,
Share,
} from './dynamic'

import { Wrapper, InnerWrapper, BodyWrapper, ContentWrapper } from './styles'

Expand Down Expand Up @@ -95,6 +103,7 @@ const GlobalLayoutContainer: FC<TProps> = ({
{!noSidebar && bannerLayout !== C11N.HOLY_GRAIL && <Sidebar />}
<AbuseReport />
<Drawer />
<Share />
<Doraemon />
<ErrorBox />
<ContentWrapper
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { FC, memo } from 'react'

import type { TArticle } from '@/spec'
import { shareTo } from '@/utils'

import { IconButton } from '@/components/Buttons'
import Upvote from '@/components/Upvote'
Expand All @@ -25,8 +26,9 @@ const ArticleSticker: FC<TProps> = ({ show, article }) => {
/>
<IconButton
path="article/share-solid.svg"
onClick={() => shareTo()}
size={20}
mLeft={4}
mLeft={5}
mTop={15}
mRight={0}
/>
Expand Down
4 changes: 2 additions & 2 deletions src/containers/tool/ArticleSticker/styles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const Wrapper = styled.div.attrs(({ testid }: TTestable) => ({
}))<TWrapper>`
${css.flexColumn('align-center', 'justify-start')};
${({ metric }) => css.fitStickerWidth(metric)};
min-height: 68vh;
min-height: 60vh;
`
export const InnerWrapper = styled.div`
${css.flexColumn('justify-between')}
Expand Down Expand Up @@ -75,6 +75,6 @@ export const GoTopWrapper = styled.div<TActive>`
${css.flex('align-both')};
opacity: ${({ show }) => (show ? 1 : 0)};
position: absolute;
bottom: -50px;
bottom: -100px;
width: 100%;
`
29 changes: 29 additions & 0 deletions src/containers/tool/Share/IFrameBoard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { FC, memo } from 'react'

import { CopyButton } from '@/components/Buttons'

import {
Wrapper,
Header,
Title,
CodeWrapper,
Inputer,
} from './styles/iframe_board'

const IFrameBoard: FC = () => {
const code =
'<iframe width="560" height="315" src="https://www.youtube.com/embed/5KnkUBBVqis" title="YouTube video player" frameborder="0"></iframe>'
return (
<Wrapper>
<Header>
<Title>嵌入网页</Title>
<CopyButton value={code} />
</Header>
<CodeWrapper>
<Inputer behavior="textarea" value={code} />
</CodeWrapper>
</Wrapper>
)
}

export default memo(IFrameBoard)
43 changes: 43 additions & 0 deletions src/containers/tool/Share/InfoPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { FC, memo } from 'react'

import { SITE_SHARE_TYPE } from './constant'

import LinkBoard from './LinkBoard'
import IFrameBoard from './IFrameBoard'
import WechatBoard from './WechatBoard'

import { Wrapper } from './styles/info_panel'
import type { TLinksData } from './store'

type TProps = {
type: string
linksData: TLinksData
}

const InfoPanel: FC<TProps> = ({ type, linksData }) => {
switch (type) {
case SITE_SHARE_TYPE.EMBED: {
return (
<Wrapper type={type}>
<IFrameBoard />
</Wrapper>
)
}
case SITE_SHARE_TYPE.WECHAT: {
return (
<Wrapper type={type}>
<WechatBoard />
</Wrapper>
)
}
default: {
return (
<Wrapper type={type}>
<LinkBoard linksData={linksData} />
</Wrapper>
)
}
}
}

export default memo(InfoPanel)
59 changes: 59 additions & 0 deletions src/containers/tool/Share/LinkBoard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { FC, memo, Fragment, useState } from 'react'

import { CopyButton } from '@/components/Buttons'
import type { TLinksData } from './store'

import {
Header,
TabWrapper,
TabName,
BoxWrapper,
Inputer,
} from './styles/link_board'

type TProps = {
linksData: TLinksData
}

const LinkBoard: FC<TProps> = ({ linksData }) => {
const [activeTab, setActiveTab] = useState('link')

return (
<Fragment>
<Header>
<TabWrapper>
<TabName
$active={activeTab === 'link'}
onClick={() => setActiveTab('link')}
>
URL
</TabName>
<TabName
$active={activeTab === 'html'}
onClick={() => setActiveTab('html')}
>
HTML
</TabName>
<TabName
$active={activeTab === 'md'}
onClick={() => setActiveTab('md')}
>
MD
</TabName>
<TabName
$active={activeTab === 'orgMode'}
onClick={() => setActiveTab('orgMode')}
>
OrgMode
</TabName>
</TabWrapper>
<CopyButton value={linksData[activeTab]} />
</Header>
<BoxWrapper>
<Inputer value={linksData[activeTab]} />
</BoxWrapper>
</Fragment>
)
}

export default memo(LinkBoard)
Loading