From 668bca49408e6c3208cf303953913fb39ef90fe4 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Tue, 17 May 2022 22:56:51 +0800 Subject: [PATCH 01/22] chore(bg-editor): basic setup --- .../editor/CustomBgEditor/PicGroup.tsx | 33 ++++++++++ .../editor/CustomBgEditor/index.tsx | 65 +++++++++++++++++++ src/containers/editor/CustomBgEditor/logic.ts | 28 ++++++++ .../editor/CustomBgEditor/schema.ts | 23 +++++++ src/containers/editor/CustomBgEditor/store.ts | 31 +++++++++ .../editor/CustomBgEditor/styles/index.ts | 21 ++++++ .../editor/CustomBgEditor/styles/pic_group.ts | 53 +++++++++++++++ .../editor/CustomBgEditor/tests/index.test.js | 10 +++ .../editor/CustomBgEditor/tests/store.test.js | 10 +++ .../tool/Drawer/Content/renderContent.tsx | 4 ++ src/containers/tool/Drawer/dynamics.tsx | 8 +++ src/containers/tool/Drawer/store.ts | 5 +- src/stores/RootStore/index.ts | 2 + src/stores/index.ts | 1 + src/widgets/PostItem/DesktopView/Header.tsx | 5 +- utils/constant/type.ts | 3 + utils/helper.ts | 4 ++ 17 files changed, 302 insertions(+), 4 deletions(-) create mode 100644 src/containers/editor/CustomBgEditor/PicGroup.tsx create mode 100644 src/containers/editor/CustomBgEditor/index.tsx create mode 100644 src/containers/editor/CustomBgEditor/logic.ts create mode 100644 src/containers/editor/CustomBgEditor/schema.ts create mode 100644 src/containers/editor/CustomBgEditor/store.ts create mode 100644 src/containers/editor/CustomBgEditor/styles/index.ts create mode 100644 src/containers/editor/CustomBgEditor/styles/pic_group.ts create mode 100644 src/containers/editor/CustomBgEditor/tests/index.test.js create mode 100644 src/containers/editor/CustomBgEditor/tests/store.test.js diff --git a/src/containers/editor/CustomBgEditor/PicGroup.tsx b/src/containers/editor/CustomBgEditor/PicGroup.tsx new file mode 100644 index 000000000..f49cb2307 --- /dev/null +++ b/src/containers/editor/CustomBgEditor/PicGroup.tsx @@ -0,0 +1,33 @@ +import { FC, memo } from 'react' + +import { + Wrapper, + Block, + Image, + ActiveSign, + CheckIcon, +} from './styles/pic_group' + +const PicGroup: FC = () => { + return ( + + + + + + + + + + + + + + + + + + ) +} + +export default memo(PicGroup) diff --git a/src/containers/editor/CustomBgEditor/index.tsx b/src/containers/editor/CustomBgEditor/index.tsx new file mode 100644 index 000000000..2c960f5ad --- /dev/null +++ b/src/containers/editor/CustomBgEditor/index.tsx @@ -0,0 +1,65 @@ +/* * + * CustomBgEditor + * + */ + +import { FC } from 'react' + +// import { buildLog } from '@/utils/logger' +import { bond } from '@/utils/mobx' +import { VIEW } from '@/constant' +import { Tabs } from '@/widgets/Switcher' + +import type { TStore } from './store' +import { Wrapper, Content, Title } from './styles' +import PicGroup from './PicGroup' +import { useInit } from './logic' /* eslint-disable-next-line */ + +const TAB_OPTIONS = [ + { + title: '内置背景', + raw: 'buildin', + localIcon: 'settings', + }, + { + title: '自定义图片', + raw: 'custom', + localIcon: 'settings', + }, +] + +type TProps = { + customBgEditor?: TStore + testid?: string +} + +const CustomBgEditorContainer: FC = ({ + customBgEditor: store, + testid = 'custom-bg-editor', +}) => { + useInit(store) + + return ( + + 背景设置 +
+ +
+ +
图案
+ + +
+
纯色
+
...
+
+
+ ) +} + +export default bond(CustomBgEditorContainer, 'customBgEditor') as FC diff --git a/src/containers/editor/CustomBgEditor/logic.ts b/src/containers/editor/CustomBgEditor/logic.ts new file mode 100644 index 000000000..0c9b23eda --- /dev/null +++ b/src/containers/editor/CustomBgEditor/logic.ts @@ -0,0 +1,28 @@ +import { useEffect } from 'react' +// import { } from 'ramda' + +import { buildLog } from '@/utils/logger' + +// import S from './schma' +import type { TStore } from './store' + +let store: TStore | undefined + +/* eslint-disable-next-line */ +const log = buildLog('L:CustomBgEditor') + +export const someMethod = (): void => { + // +} + +// ############################### +// init & uninit handlers +// ############################### + +export const useInit = (_store: TStore): void => { + useEffect(() => { + store = _store + log('useInit: ', store) + // return () => store.reset() + }, [_store]) +} diff --git a/src/containers/editor/CustomBgEditor/schema.ts b/src/containers/editor/CustomBgEditor/schema.ts new file mode 100644 index 000000000..fb2a9f07a --- /dev/null +++ b/src/containers/editor/CustomBgEditor/schema.ts @@ -0,0 +1,23 @@ +import { gql } from '@urql/core' + +const simpleMutation = gql` + mutation ($id: ID!) { + post(id: $id) { + id + } + } +` +const simpleQuery = gql` + query ($filter: filter!) { + post(id: $id) { + id + } + } +` + +const schema = { + simpleMutation, + simpleQuery, +} + +export default schema diff --git a/src/containers/editor/CustomBgEditor/store.ts b/src/containers/editor/CustomBgEditor/store.ts new file mode 100644 index 000000000..773e896da --- /dev/null +++ b/src/containers/editor/CustomBgEditor/store.ts @@ -0,0 +1,31 @@ +/* + * CustomBgEditor store + */ + +import { types as T, getParent, Instance } from 'mobx-state-tree' +// import {} from 'ramda' + +import type { TCommunity, TRootStore } from '@/spec' +import { buildLog } from '@/utils/logger' +import { markStates, toJS } from '@/utils/mobx' + +/* eslint-disable-next-line */ +const log = buildLog('S:CustomBgEditor') + +const CustomBgEditor = T.model('CustomBgEditor', {}) + .views((self) => ({ + get curCommunity(): TCommunity { + const root = getParent(self) as TRootStore + + return toJS(root.viewing.community) + }, + })) + .actions((self) => ({ + mark(sobj: Record): void { + markStates(sobj, self) + }, + })) + +export type TStore = Instance + +export default CustomBgEditor diff --git a/src/containers/editor/CustomBgEditor/styles/index.ts b/src/containers/editor/CustomBgEditor/styles/index.ts new file mode 100644 index 000000000..fa5abb06a --- /dev/null +++ b/src/containers/editor/CustomBgEditor/styles/index.ts @@ -0,0 +1,21 @@ +import styled from 'styled-components' + +import type { TTestable } from '@/spec' +import { theme } from '@/utils/css' + +export const Wrapper = styled.div.attrs(({ testid }: TTestable) => ({ + 'data-test-id': testid, +}))` + padding: 30px; +` +export const Title = styled.div` + font-size: 17px; + color: ${theme('thread.articleTitle')}; + font-weight: bold; + margin-bottom: 16px; + margin-left: 2px; +` +export const Content = styled.div` + margin-top: 20px; + padding: 0 2px; +` diff --git a/src/containers/editor/CustomBgEditor/styles/pic_group.ts b/src/containers/editor/CustomBgEditor/styles/pic_group.ts new file mode 100644 index 000000000..62f6d47d5 --- /dev/null +++ b/src/containers/editor/CustomBgEditor/styles/pic_group.ts @@ -0,0 +1,53 @@ +import styled from 'styled-components' + +import type { TActive } from '@/spec' +import Img from '@/Img' +import css, { theme } from '@/utils/css' +import CheckedSVG from '@/icons/Checked' + +export const Wrapper = styled.div` + ${css.flex()}; + width: calc(100% + 30px); + flex-wrap: wrap; + margin-top: 10px; +` +export const Block = styled.div` + position: relative; + width: 168px; + height: 130px; + margin-right: 16px; + margin-bottom: 10px; + border-radius: 4px; + overflow: hidden; + border: 2px solid; + border-color: ${({ $active }) => + $active ? theme('thread.articleTitle') : 'transparent'}; + + &:hover { + border-color: ${theme('thread.articleTitle')}; + cursor: pointer; + } + + transition: border-color 0.1s linear; +` +export const Image = styled(Img)` + width: 100%; + object-fit: cover; +` +export const ActiveSign = styled.div` + ${css.size(25)}; + background: ${theme('border')}; + position: absolute; + top: 0; + right: 0; + border-top-right-radius: 4px; + border-bottom-left-radius: 15px; + z-index: 3; +` +export const CheckIcon = styled(CheckedSVG)` + fill: ${theme('thread.articleTitle')}; + ${css.size(18)}; + position: absolute; + top: 3px; + left: 6px; +` diff --git a/src/containers/editor/CustomBgEditor/tests/index.test.js b/src/containers/editor/CustomBgEditor/tests/index.test.js new file mode 100644 index 000000000..975b36e01 --- /dev/null +++ b/src/containers/editor/CustomBgEditor/tests/index.test.js @@ -0,0 +1,10 @@ +// import React from 'react' +// import { shallow } from 'enzyme' + +// import CustomBgEditor from '../index' + +describe('TODO ', () => { + it('Expect to have unit tests specified', () => { + expect(true).toEqual(true) + }) +}) diff --git a/src/containers/editor/CustomBgEditor/tests/store.test.js b/src/containers/editor/CustomBgEditor/tests/store.test.js new file mode 100644 index 000000000..e9718ad33 --- /dev/null +++ b/src/containers/editor/CustomBgEditor/tests/store.test.js @@ -0,0 +1,10 @@ +/* + * CustomBgEditor store test + * + */ + +// import CustomBgEditor from '../index' + +it('TODO: store test CustomBgEditor', () => { + expect(1 + 1).toBe(2) +}) diff --git a/src/containers/tool/Drawer/Content/renderContent.tsx b/src/containers/tool/Drawer/Content/renderContent.tsx index e63c7915b..d1bd71ce5 100644 --- a/src/containers/tool/Drawer/Content/renderContent.tsx +++ b/src/containers/tool/Drawer/Content/renderContent.tsx @@ -9,6 +9,7 @@ import { MailsViewer, // editors AccountEditor, + CustomBgEditor, // utils C11NSettingPanel, // userlister @@ -39,6 +40,9 @@ const renderContent = ( // @ts-ignore return + case TYPE.DRAWER.CUSTOM_BG_EDITOR: + return + case TYPE.DRAWER.MODELINE_MENU: // @ts-ignore return diff --git a/src/containers/tool/Drawer/dynamics.tsx b/src/containers/tool/Drawer/dynamics.tsx index 5ee9ea852..d27d34e0f 100755 --- a/src/containers/tool/Drawer/dynamics.tsx +++ b/src/containers/tool/Drawer/dynamics.tsx @@ -83,3 +83,11 @@ export const C11NSettingPanel = dynamic( ssr: false, }, ) + +export const CustomBgEditor = dynamic( + () => import('@/containers/editor/CustomBgEditor'), + { + loading: () => , + ssr: false, + }, +) diff --git a/src/containers/tool/Drawer/store.ts b/src/containers/tool/Drawer/store.ts index 50e748703..8466344a0 100755 --- a/src/containers/tool/Drawer/store.ts +++ b/src/containers/tool/Drawer/store.ts @@ -54,8 +54,10 @@ const DrawerStore = T.model('DrawerStore', { TYPE.DRAWER.MAILS_VIEW, // TYPE.DRAWER.C11N_SETTINGS, + TYPE.DRAWER.CUSTOM_BG_EDITOR, TYPE.DRAWER.MODELINE_MENU, TYPE.DRAWER.USER_LISTER, + ...ARTICLE_THREAD_CURD_TYPES, ]), ), @@ -184,7 +186,8 @@ const DrawerStore = T.model('DrawerStore', { if ( type !== TYPE.DRAWER.ACCOUNT_EDIT && - type !== TYPE.DRAWER.C11N_SETTINGS + type !== TYPE.DRAWER.C11N_SETTINGS && + type !== TYPE.DRAWER.CUSTOM_BG_EDITOR ) { slf.markPreviewURLIfNeed(data) } diff --git a/src/stores/RootStore/index.ts b/src/stores/RootStore/index.ts index ad803a665..e1ded4c80 100755 --- a/src/stores/RootStore/index.ts +++ b/src/stores/RootStore/index.ts @@ -69,6 +69,7 @@ import { CoolGuideContentStore, // GEN: IMPORT SUBSTORE + CustomBgEditorStore, HelpThreadStore, AboutThreadStore, ChangelogThreadStore, @@ -171,6 +172,7 @@ const rootStore = T.model({ coolGuideContent: T.optional(CoolGuideContentStore, {}), // GEN: PLUG SUBSTORE TO ROOTSTORE + customBgEditor: T.optional(CustomBgEditorStore, {}), helpThread: T.optional(HelpThreadStore, {}), aboutThread: T.optional(AboutThreadStore, {}), changelogThread: T.optional(ChangelogThreadStore, {}), diff --git a/src/stores/index.ts b/src/stores/index.ts index e724513a1..de018b662 100755 --- a/src/stores/index.ts +++ b/src/stores/index.ts @@ -78,6 +78,7 @@ export { default as CommunityEditorStore } from '@/containers/editor/CommunityEd export { default as WorksEditorStore } from '@/containers/editor/WorksEditor/store' // GEN: EXPORT CONTAINERS STORE HERE +export { default as CustomBgEditorStore } from '@/containers/editor/CustomBgEditor/store' export { default as HelpThreadStore } from '@/containers/thread/HelpThread/store' export { default as AboutThreadStore } from '@/containers/thread/AboutThread/store' export { default as ChangelogThreadStore } from '@/containers/thread/ChangelogThread/store' diff --git a/src/widgets/PostItem/DesktopView/Header.tsx b/src/widgets/PostItem/DesktopView/Header.tsx index 30de8fdcd..81bbd4402 100644 --- a/src/widgets/PostItem/DesktopView/Header.tsx +++ b/src/widgets/PostItem/DesktopView/Header.tsx @@ -2,9 +2,8 @@ import { FC } from 'react' import dynamic from 'next/dynamic' import type { TPost } from '@/spec' -import { EVENT } from '@/constant' -import { send, c11nSettings } from '@/utils/helper' +import { callCustomBgEditor } from '@/utils/helper' import AvatarsGroup from '@/widgets/AvatarsGroup' // import TagsList from '@/widgets/TagsList' @@ -33,7 +32,7 @@ const Header: FC = ({ item }) => { {/* send(EVENT.PREVIEW_ARTICLE, { article: item })}> */} - <Title onClick={() => c11nSettings()}>{item.title} + callCustomBgEditor()}>{item.title} {/* @ts-ignore */} diff --git a/utils/constant/type.ts b/utils/constant/type.ts index de9d10e3a..63f6045dc 100755 --- a/utils/constant/type.ts +++ b/utils/constant/type.ts @@ -47,6 +47,9 @@ const TYPE = { // c11n settings C11N_SETTINGS: 'C11N_SETTINGS', + // custom background editor + CUSTOM_BG_EDITOR: 'CUSTOM_BG_EDITOR', + // user lister USER_LISTER: 'USER_LISTER', diff --git a/utils/helper.ts b/utils/helper.ts index 6ab4466b2..27aaf4de4 100755 --- a/utils/helper.ts +++ b/utils/helper.ts @@ -262,6 +262,10 @@ export const c11nSettings = (): void => { send(EVENT.DRAWER.OPEN, { type: TYPE.DRAWER.C11N_SETTINGS }) } +export const callCustomBgEditor = (): void => { + send(EVENT.DRAWER.OPEN, { type: TYPE.DRAWER.CUSTOM_BG_EDITOR }) +} + export const upvoteOnArticleList = ( article: TArticle, viewerHasUpvoted: boolean, From 094f553539fc0bad3d80b84335d30e79574ff464 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Wed, 18 May 2022 11:01:27 +0800 Subject: [PATCH 02/22] chore(bg-editor): rename to WallpaperEditor --- .../editor/CustomBgEditor/tests/store.test.js | 10 ---------- .../{CustomBgEditor => WallpaperEditor}/PicGroup.tsx | 0 .../{CustomBgEditor => WallpaperEditor}/index.tsx | 12 ++++++------ .../{CustomBgEditor => WallpaperEditor}/logic.ts | 2 +- .../{CustomBgEditor => WallpaperEditor}/schema.ts | 0 .../{CustomBgEditor => WallpaperEditor}/store.ts | 10 +++++----- .../styles/index.ts | 0 .../styles/pic_group.ts | 4 ++-- .../tests/index.test.js | 4 ++-- .../editor/WallpaperEditor/tests/store.test.js | 10 ++++++++++ src/containers/tool/Drawer/Content/renderContent.tsx | 4 ++-- src/containers/tool/Drawer/dynamics.tsx | 4 ++-- src/stores/RootStore/index.ts | 4 ++-- src/stores/index.ts | 2 +- src/widgets/PostItem/DesktopView/Header.tsx | 4 ++-- utils/helper.ts | 2 +- 16 files changed, 36 insertions(+), 36 deletions(-) delete mode 100644 src/containers/editor/CustomBgEditor/tests/store.test.js rename src/containers/editor/{CustomBgEditor => WallpaperEditor}/PicGroup.tsx (100%) rename src/containers/editor/{CustomBgEditor => WallpaperEditor}/index.tsx (82%) rename src/containers/editor/{CustomBgEditor => WallpaperEditor}/logic.ts (92%) rename src/containers/editor/{CustomBgEditor => WallpaperEditor}/schema.ts (100%) rename src/containers/editor/{CustomBgEditor => WallpaperEditor}/store.ts (72%) rename src/containers/editor/{CustomBgEditor => WallpaperEditor}/styles/index.ts (100%) rename src/containers/editor/{CustomBgEditor => WallpaperEditor}/styles/pic_group.ts (96%) rename src/containers/editor/{CustomBgEditor => WallpaperEditor}/tests/index.test.js (64%) create mode 100644 src/containers/editor/WallpaperEditor/tests/store.test.js diff --git a/src/containers/editor/CustomBgEditor/tests/store.test.js b/src/containers/editor/CustomBgEditor/tests/store.test.js deleted file mode 100644 index e9718ad33..000000000 --- a/src/containers/editor/CustomBgEditor/tests/store.test.js +++ /dev/null @@ -1,10 +0,0 @@ -/* - * CustomBgEditor store test - * - */ - -// import CustomBgEditor from '../index' - -it('TODO: store test CustomBgEditor', () => { - expect(1 + 1).toBe(2) -}) diff --git a/src/containers/editor/CustomBgEditor/PicGroup.tsx b/src/containers/editor/WallpaperEditor/PicGroup.tsx similarity index 100% rename from src/containers/editor/CustomBgEditor/PicGroup.tsx rename to src/containers/editor/WallpaperEditor/PicGroup.tsx diff --git a/src/containers/editor/CustomBgEditor/index.tsx b/src/containers/editor/WallpaperEditor/index.tsx similarity index 82% rename from src/containers/editor/CustomBgEditor/index.tsx rename to src/containers/editor/WallpaperEditor/index.tsx index 2c960f5ad..1605b6b7e 100644 --- a/src/containers/editor/CustomBgEditor/index.tsx +++ b/src/containers/editor/WallpaperEditor/index.tsx @@ -1,5 +1,5 @@ /* * - * CustomBgEditor + * WallpaperEditor * */ @@ -29,13 +29,13 @@ const TAB_OPTIONS = [ ] type TProps = { - customBgEditor?: TStore + wallpaperEditor?: TStore testid?: string } -const CustomBgEditorContainer: FC = ({ - customBgEditor: store, - testid = 'custom-bg-editor', +const WallpaperEditorContainer: FC = ({ + wallpaperEditor: store, + testid = 'wallpaper-editor', }) => { useInit(store) @@ -62,4 +62,4 @@ const CustomBgEditorContainer: FC = ({ ) } -export default bond(CustomBgEditorContainer, 'customBgEditor') as FC +export default bond(WallpaperEditorContainer, 'wallpaperEditor') as FC diff --git a/src/containers/editor/CustomBgEditor/logic.ts b/src/containers/editor/WallpaperEditor/logic.ts similarity index 92% rename from src/containers/editor/CustomBgEditor/logic.ts rename to src/containers/editor/WallpaperEditor/logic.ts index 0c9b23eda..3942d6fc8 100644 --- a/src/containers/editor/CustomBgEditor/logic.ts +++ b/src/containers/editor/WallpaperEditor/logic.ts @@ -9,7 +9,7 @@ import type { TStore } from './store' let store: TStore | undefined /* eslint-disable-next-line */ -const log = buildLog('L:CustomBgEditor') +const log = buildLog('L:WallpaperEditor') export const someMethod = (): void => { // diff --git a/src/containers/editor/CustomBgEditor/schema.ts b/src/containers/editor/WallpaperEditor/schema.ts similarity index 100% rename from src/containers/editor/CustomBgEditor/schema.ts rename to src/containers/editor/WallpaperEditor/schema.ts diff --git a/src/containers/editor/CustomBgEditor/store.ts b/src/containers/editor/WallpaperEditor/store.ts similarity index 72% rename from src/containers/editor/CustomBgEditor/store.ts rename to src/containers/editor/WallpaperEditor/store.ts index 773e896da..fd51ead75 100644 --- a/src/containers/editor/CustomBgEditor/store.ts +++ b/src/containers/editor/WallpaperEditor/store.ts @@ -1,5 +1,5 @@ /* - * CustomBgEditor store + * WallpaperEditor store */ import { types as T, getParent, Instance } from 'mobx-state-tree' @@ -10,9 +10,9 @@ import { buildLog } from '@/utils/logger' import { markStates, toJS } from '@/utils/mobx' /* eslint-disable-next-line */ -const log = buildLog('S:CustomBgEditor') +const log = buildLog('S:WallpaperEditor') -const CustomBgEditor = T.model('CustomBgEditor', {}) +const WallpaperEditor = T.model('WallpaperEditor', {}) .views((self) => ({ get curCommunity(): TCommunity { const root = getParent(self) as TRootStore @@ -26,6 +26,6 @@ const CustomBgEditor = T.model('CustomBgEditor', {}) }, })) -export type TStore = Instance +export type TStore = Instance -export default CustomBgEditor +export default WallpaperEditor diff --git a/src/containers/editor/CustomBgEditor/styles/index.ts b/src/containers/editor/WallpaperEditor/styles/index.ts similarity index 100% rename from src/containers/editor/CustomBgEditor/styles/index.ts rename to src/containers/editor/WallpaperEditor/styles/index.ts diff --git a/src/containers/editor/CustomBgEditor/styles/pic_group.ts b/src/containers/editor/WallpaperEditor/styles/pic_group.ts similarity index 96% rename from src/containers/editor/CustomBgEditor/styles/pic_group.ts rename to src/containers/editor/WallpaperEditor/styles/pic_group.ts index 62f6d47d5..e1a4126a3 100644 --- a/src/containers/editor/CustomBgEditor/styles/pic_group.ts +++ b/src/containers/editor/WallpaperEditor/styles/pic_group.ts @@ -41,13 +41,13 @@ export const ActiveSign = styled.div` top: 0; right: 0; border-top-right-radius: 4px; - border-bottom-left-radius: 15px; + border-bottom-left-radius: 30px; z-index: 3; ` export const CheckIcon = styled(CheckedSVG)` fill: ${theme('thread.articleTitle')}; ${css.size(18)}; position: absolute; - top: 3px; + top: 2px; left: 6px; ` diff --git a/src/containers/editor/CustomBgEditor/tests/index.test.js b/src/containers/editor/WallpaperEditor/tests/index.test.js similarity index 64% rename from src/containers/editor/CustomBgEditor/tests/index.test.js rename to src/containers/editor/WallpaperEditor/tests/index.test.js index 975b36e01..986e8a0bd 100644 --- a/src/containers/editor/CustomBgEditor/tests/index.test.js +++ b/src/containers/editor/WallpaperEditor/tests/index.test.js @@ -1,9 +1,9 @@ // import React from 'react' // import { shallow } from 'enzyme' -// import CustomBgEditor from '../index' +// import WallpaperEditor from '../index' -describe('TODO ', () => { +describe('TODO ', () => { it('Expect to have unit tests specified', () => { expect(true).toEqual(true) }) diff --git a/src/containers/editor/WallpaperEditor/tests/store.test.js b/src/containers/editor/WallpaperEditor/tests/store.test.js new file mode 100644 index 000000000..57a4856fa --- /dev/null +++ b/src/containers/editor/WallpaperEditor/tests/store.test.js @@ -0,0 +1,10 @@ +/* + * WallpaperEditor store test + * + */ + +// import WallpaperEditor from '../index' + +it('TODO: store test WallpaperEditor', () => { + expect(1 + 1).toBe(2) +}) diff --git a/src/containers/tool/Drawer/Content/renderContent.tsx b/src/containers/tool/Drawer/Content/renderContent.tsx index d1bd71ce5..c28282672 100644 --- a/src/containers/tool/Drawer/Content/renderContent.tsx +++ b/src/containers/tool/Drawer/Content/renderContent.tsx @@ -9,7 +9,7 @@ import { MailsViewer, // editors AccountEditor, - CustomBgEditor, + WallpaperEditor, // utils C11NSettingPanel, // userlister @@ -41,7 +41,7 @@ const renderContent = ( return case TYPE.DRAWER.CUSTOM_BG_EDITOR: - return + return case TYPE.DRAWER.MODELINE_MENU: // @ts-ignore diff --git a/src/containers/tool/Drawer/dynamics.tsx b/src/containers/tool/Drawer/dynamics.tsx index d27d34e0f..16ba9387f 100755 --- a/src/containers/tool/Drawer/dynamics.tsx +++ b/src/containers/tool/Drawer/dynamics.tsx @@ -84,8 +84,8 @@ export const C11NSettingPanel = dynamic( }, ) -export const CustomBgEditor = dynamic( - () => import('@/containers/editor/CustomBgEditor'), +export const WallpaperEditor = dynamic( + () => import('@/containers/editor/WallpaperEditor'), { loading: () => , ssr: false, diff --git a/src/stores/RootStore/index.ts b/src/stores/RootStore/index.ts index e1ded4c80..de54c32ac 100755 --- a/src/stores/RootStore/index.ts +++ b/src/stores/RootStore/index.ts @@ -69,7 +69,7 @@ import { CoolGuideContentStore, // GEN: IMPORT SUBSTORE - CustomBgEditorStore, + WallpaperEditorStore, HelpThreadStore, AboutThreadStore, ChangelogThreadStore, @@ -172,7 +172,7 @@ const rootStore = T.model({ coolGuideContent: T.optional(CoolGuideContentStore, {}), // GEN: PLUG SUBSTORE TO ROOTSTORE - customBgEditor: T.optional(CustomBgEditorStore, {}), + wallpaperEditor: T.optional(WallpaperEditorStore, {}), helpThread: T.optional(HelpThreadStore, {}), aboutThread: T.optional(AboutThreadStore, {}), changelogThread: T.optional(ChangelogThreadStore, {}), diff --git a/src/stores/index.ts b/src/stores/index.ts index de018b662..52e180b90 100755 --- a/src/stores/index.ts +++ b/src/stores/index.ts @@ -78,7 +78,7 @@ export { default as CommunityEditorStore } from '@/containers/editor/CommunityEd export { default as WorksEditorStore } from '@/containers/editor/WorksEditor/store' // GEN: EXPORT CONTAINERS STORE HERE -export { default as CustomBgEditorStore } from '@/containers/editor/CustomBgEditor/store' +export { default as WallpaperEditorStore } from '@/containers/editor/WallpaperEditor/store' export { default as HelpThreadStore } from '@/containers/thread/HelpThread/store' export { default as AboutThreadStore } from '@/containers/thread/AboutThread/store' export { default as ChangelogThreadStore } from '@/containers/thread/ChangelogThread/store' diff --git a/src/widgets/PostItem/DesktopView/Header.tsx b/src/widgets/PostItem/DesktopView/Header.tsx index 81bbd4402..f88835a82 100644 --- a/src/widgets/PostItem/DesktopView/Header.tsx +++ b/src/widgets/PostItem/DesktopView/Header.tsx @@ -3,7 +3,7 @@ import dynamic from 'next/dynamic' import type { TPost } from '@/spec' -import { callCustomBgEditor } from '@/utils/helper' +import { callWallpaperEditor } from '@/utils/helper' import AvatarsGroup from '@/widgets/AvatarsGroup' // import TagsList from '@/widgets/TagsList' @@ -32,7 +32,7 @@ const Header: FC = ({ item }) => { {/* send(EVENT.PREVIEW_ARTICLE, { article: item })}> */} - <Title onClick={() => callCustomBgEditor()}>{item.title} + callWallpaperEditor()}>{item.title} {/* @ts-ignore */} diff --git a/utils/helper.ts b/utils/helper.ts index 27aaf4de4..99dbc044e 100755 --- a/utils/helper.ts +++ b/utils/helper.ts @@ -262,7 +262,7 @@ export const c11nSettings = (): void => { send(EVENT.DRAWER.OPEN, { type: TYPE.DRAWER.C11N_SETTINGS }) } -export const callCustomBgEditor = (): void => { +export const callWallpaperEditor = (): void => { send(EVENT.DRAWER.OPEN, { type: TYPE.DRAWER.CUSTOM_BG_EDITOR }) } From 11d70b3b5d968ceae23079c10cc0912c6434a2ec Mon Sep 17 00:00:00 2001 From: mydearxym Date: Wed, 18 May 2022 11:10:57 +0800 Subject: [PATCH 03/22] chore(bg-editor): rename to WallpaperEditor more --- .../layout/GlobalLayout/{CustomBg.tsx => Wallpaper.tsx} | 2 +- src/containers/layout/GlobalLayout/index.tsx | 4 ++-- .../layout/GlobalLayout/styles/{custom_bg.ts => wallpaper.ts} | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename src/containers/layout/GlobalLayout/{CustomBg.tsx => Wallpaper.tsx} (97%) rename src/containers/layout/GlobalLayout/styles/{custom_bg.ts => wallpaper.ts} (100%) diff --git a/src/containers/layout/GlobalLayout/CustomBg.tsx b/src/containers/layout/GlobalLayout/Wallpaper.tsx similarity index 97% rename from src/containers/layout/GlobalLayout/CustomBg.tsx rename to src/containers/layout/GlobalLayout/Wallpaper.tsx index 1a8399955..b8acdca39 100644 --- a/src/containers/layout/GlobalLayout/CustomBg.tsx +++ b/src/containers/layout/GlobalLayout/Wallpaper.tsx @@ -1,7 +1,7 @@ import { FC, memo } from 'react' import { isString } from '@/utils/validator' -import { Wrapper } from './styles/custom_bg' +import { Wrapper } from './styles/wallpaper' type TBackgroundEffect = | { diff --git a/src/containers/layout/GlobalLayout/index.tsx b/src/containers/layout/GlobalLayout/index.tsx index d59c27ba7..ff40dc1ad 100755 --- a/src/containers/layout/GlobalLayout/index.tsx +++ b/src/containers/layout/GlobalLayout/index.tsx @@ -24,7 +24,7 @@ import Header from '@/widgets/Header' import type { TStore } from './store' import SEO from './SEO' -import CustomBg from './CustomBg' +import Wallpaper from './Wallpaper' import { CustomScroller, Footer, ModeLine } from './dynamic' @@ -60,7 +60,7 @@ const GlobalLayoutContainer: FC = ({ return ( - + diff --git a/src/containers/layout/GlobalLayout/styles/custom_bg.ts b/src/containers/layout/GlobalLayout/styles/wallpaper.ts similarity index 100% rename from src/containers/layout/GlobalLayout/styles/custom_bg.ts rename to src/containers/layout/GlobalLayout/styles/wallpaper.ts From 5fc015474eebf47b4e534cb38d6769e0b3b3cb88 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Wed, 18 May 2022 22:13:19 +0800 Subject: [PATCH 04/22] refactor(wallpaper-editor): extract images to constant --- public/bg/Squares.png | Bin 18159 -> 0 bytes .../{bg/Waihou.png => wallpaper/bubbles.png} | Bin .../cartoon.jpeg} | Bin public/{bg/tg-co2.jpeg => wallpaper/co2.jpeg} | Bin public/{bg/tg-code.jpg => wallpaper/code.jpg} | Bin .../{bg/Taieri.png => wallpaper/curves.png} | Bin .../{bg/tg-earth.jpg => wallpaper/earth.jpg} | Bin public/{bg/tg-elec.jpg => wallpaper/elec.jpg} | Bin .../{bg/Fishes.jpeg => wallpaper/fishes.jpeg} | Bin .../istanbul.jpeg} | Bin .../Limones.jpeg => wallpaper/limones.jpeg} | Bin .../{bg/Mataura.png => wallpaper/mataura.png} | Bin .../newspaper.jpeg} | Bin public/wallpaper/patterns/1.png | Bin 0 -> 65132 bytes .../CyBeRGaTa.jpeg => wallpaper/rainbow.jpeg} | Bin public/{bg => wallpaper}/space.svg | 0 public/{bg => wallpaper}/tg-green.jpg | Bin .../editor/WallpaperEditor/PicGroup.tsx | 21 ++++- .../editor/WallpaperEditor/index.tsx | 9 +- .../WallpaperEditor/styles/pic_group.ts | 15 ++-- .../layout/GlobalLayout/Wallpaper.tsx | 84 +++--------------- utils/constant/index.ts | 2 + utils/constant/wallpaper.ts | 59 ++++++++++++ 23 files changed, 105 insertions(+), 85 deletions(-) delete mode 100644 public/bg/Squares.png rename public/{bg/Waihou.png => wallpaper/bubbles.png} (100%) rename public/{bg/tg-cartoon.jpeg => wallpaper/cartoon.jpeg} (100%) rename public/{bg/tg-co2.jpeg => wallpaper/co2.jpeg} (100%) rename public/{bg/tg-code.jpg => wallpaper/code.jpg} (100%) rename public/{bg/Taieri.png => wallpaper/curves.png} (100%) rename public/{bg/tg-earth.jpg => wallpaper/earth.jpg} (100%) rename public/{bg/tg-elec.jpg => wallpaper/elec.jpg} (100%) rename public/{bg/Fishes.jpeg => wallpaper/fishes.jpeg} (100%) rename public/{bg/tg-istanbul.jpeg => wallpaper/istanbul.jpeg} (100%) rename public/{bg/Limones.jpeg => wallpaper/limones.jpeg} (100%) rename public/{bg/Mataura.png => wallpaper/mataura.png} (100%) rename public/{bg/Antiquitarian.jpeg => wallpaper/newspaper.jpeg} (100%) create mode 100644 public/wallpaper/patterns/1.png rename public/{bg/CyBeRGaTa.jpeg => wallpaper/rainbow.jpeg} (100%) rename public/{bg => wallpaper}/space.svg (100%) rename public/{bg => wallpaper}/tg-green.jpg (100%) create mode 100644 utils/constant/wallpaper.ts diff --git a/public/bg/Squares.png b/public/bg/Squares.png deleted file mode 100644 index 260d904ff64db9a2f97f9652946f416a9dcc2095..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18159 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 Ok-w>YBjuXG^Zy5N%<+%_ diff --git a/public/bg/Waihou.png b/public/wallpaper/bubbles.png similarity index 100% rename from public/bg/Waihou.png rename to public/wallpaper/bubbles.png diff --git a/public/bg/tg-cartoon.jpeg b/public/wallpaper/cartoon.jpeg similarity index 100% rename from public/bg/tg-cartoon.jpeg rename to public/wallpaper/cartoon.jpeg diff --git a/public/bg/tg-co2.jpeg b/public/wallpaper/co2.jpeg similarity index 100% rename from public/bg/tg-co2.jpeg rename to public/wallpaper/co2.jpeg diff --git a/public/bg/tg-code.jpg b/public/wallpaper/code.jpg similarity index 100% rename from public/bg/tg-code.jpg rename to public/wallpaper/code.jpg diff --git a/public/bg/Taieri.png b/public/wallpaper/curves.png similarity index 100% rename from public/bg/Taieri.png rename to public/wallpaper/curves.png diff --git a/public/bg/tg-earth.jpg b/public/wallpaper/earth.jpg similarity index 100% rename from public/bg/tg-earth.jpg rename to public/wallpaper/earth.jpg diff --git a/public/bg/tg-elec.jpg b/public/wallpaper/elec.jpg similarity index 100% rename from public/bg/tg-elec.jpg rename to public/wallpaper/elec.jpg diff --git a/public/bg/Fishes.jpeg b/public/wallpaper/fishes.jpeg similarity index 100% rename from public/bg/Fishes.jpeg rename to public/wallpaper/fishes.jpeg diff --git a/public/bg/tg-istanbul.jpeg b/public/wallpaper/istanbul.jpeg similarity index 100% rename from public/bg/tg-istanbul.jpeg rename to public/wallpaper/istanbul.jpeg diff --git a/public/bg/Limones.jpeg b/public/wallpaper/limones.jpeg similarity index 100% rename from public/bg/Limones.jpeg rename to public/wallpaper/limones.jpeg diff --git a/public/bg/Mataura.png b/public/wallpaper/mataura.png similarity index 100% rename from public/bg/Mataura.png rename to public/wallpaper/mataura.png diff --git a/public/bg/Antiquitarian.jpeg b/public/wallpaper/newspaper.jpeg similarity index 100% rename from public/bg/Antiquitarian.jpeg rename to public/wallpaper/newspaper.jpeg diff --git a/public/wallpaper/patterns/1.png b/public/wallpaper/patterns/1.png new file mode 100644 index 0000000000000000000000000000000000000000..38895e677563b33ebe988dfd7e250eae6e217bca GIT binary patch literal 65132 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 B1up;q literal 0 HcmV?d00001 diff --git a/public/bg/CyBeRGaTa.jpeg b/public/wallpaper/rainbow.jpeg similarity index 100% rename from public/bg/CyBeRGaTa.jpeg rename to public/wallpaper/rainbow.jpeg diff --git a/public/bg/space.svg b/public/wallpaper/space.svg similarity index 100% rename from public/bg/space.svg rename to public/wallpaper/space.svg diff --git a/public/bg/tg-green.jpg b/public/wallpaper/tg-green.jpg similarity index 100% rename from public/bg/tg-green.jpg rename to public/wallpaper/tg-green.jpg diff --git a/src/containers/editor/WallpaperEditor/PicGroup.tsx b/src/containers/editor/WallpaperEditor/PicGroup.tsx index f49cb2307..da2cda1da 100644 --- a/src/containers/editor/WallpaperEditor/PicGroup.tsx +++ b/src/containers/editor/WallpaperEditor/PicGroup.tsx @@ -1,4 +1,5 @@ import { FC, memo } from 'react' +import { WALLPAPER } from '@/constant' import { Wrapper, @@ -15,16 +16,28 @@ const PicGroup: FC = () => { - + - + - + - + + + + + + + + + + ) diff --git a/src/containers/editor/WallpaperEditor/index.tsx b/src/containers/editor/WallpaperEditor/index.tsx index 1605b6b7e..b85c4709d 100644 --- a/src/containers/editor/WallpaperEditor/index.tsx +++ b/src/containers/editor/WallpaperEditor/index.tsx @@ -55,8 +55,13 @@ const WallpaperEditorContainer: FC = ({
-
纯色
-
...
+
渐变
+
各种圆形渐变选项
+
parttern 叠加选项
+ +
+
其它
+
图片模糊
) diff --git a/src/containers/editor/WallpaperEditor/styles/pic_group.ts b/src/containers/editor/WallpaperEditor/styles/pic_group.ts index e1a4126a3..710b3726d 100644 --- a/src/containers/editor/WallpaperEditor/styles/pic_group.ts +++ b/src/containers/editor/WallpaperEditor/styles/pic_group.ts @@ -14,7 +14,7 @@ export const Wrapper = styled.div` export const Block = styled.div` position: relative; width: 168px; - height: 130px; + height: 110px; margin-right: 16px; margin-bottom: 10px; border-radius: 4px; @@ -30,23 +30,26 @@ export const Block = styled.div` transition: border-color 0.1s linear; ` -export const Image = styled(Img)` +export const Image = styled(Img)<{ bgColor?: string }>` width: 100%; object-fit: cover; + background-color: ${({ bgColor }) => bgColor || 'transparent'}; ` export const ActiveSign = styled.div` - ${css.size(25)}; + ${css.size(24)}; background: ${theme('border')}; position: absolute; - top: 0; - right: 0; + top: -1px; + right: -1px; border-top-right-radius: 4px; border-bottom-left-radius: 30px; z-index: 3; + border: 1px solid; + border-color: ${theme('thread.articleTitle')}; ` export const CheckIcon = styled(CheckedSVG)` fill: ${theme('thread.articleTitle')}; - ${css.size(18)}; + ${css.size(16)}; position: absolute; top: 2px; left: 6px; diff --git a/src/containers/layout/GlobalLayout/Wallpaper.tsx b/src/containers/layout/GlobalLayout/Wallpaper.tsx index b8acdca39..2761f4afa 100644 --- a/src/containers/layout/GlobalLayout/Wallpaper.tsx +++ b/src/containers/layout/GlobalLayout/Wallpaper.tsx @@ -1,81 +1,19 @@ import { FC, memo } from 'react' +import { WALLPAPER } from '@/constant' import { isString } from '@/utils/validator' import { Wrapper } from './styles/wallpaper' -type TBackgroundEffect = - | { - bgImage: string - bgColor?: string - bgSize?: 'contain' | 'cover' | 'auto' - } - | string +// type TBackgroundEffect = +// | { +// bgImage: string +// bgColor?: string +// bgSize?: 'contain' | 'cover' | 'auto' +// } +// | string -const ComstomBg: FC = () => { - const effects = { - // linear colors - b: ` - background: #2c3e50; /* fallback for old browsers */ - background: -webkit-linear-gradient(to right, #2c3e50, #fd746c); /* Chrome 10-25, Safari 5.1-6 */ - background: linear-gradient(to right, #2c3e50, #fd746c); - `, - - // custom-images - e: { - bgImage: '/bg/Waihou.png', - }, - f: { - bgImage: '/bg/Limones.jpeg', - }, - g: { - bgImage: '/bg/Mataura.png', - bgSize: 'cover', - }, - j: { - bgImage: '/bg/Taieri.png', - bgColor: '#050139', // backgroundBg or fallback - }, - k: { - bgImage: '/bg/Squares.png', - }, - m: { - bgImage: '/bg/Antiquitarian.jpeg', - }, - l: { - bgImage: '/bg/CyBeRGaTa.jpeg', - }, - o: { - bgImage: '/bg/Fishes.jpeg', - }, - x: { - bgImage: '/bg/space.svg', - bgColor: '#002630', // backgroundBg - }, - tg: { - bgImage: '/bg/tg-green.jpg', - bgSize: 'auto', - }, - tg2: { - bgImage: '/bg/tg-earth.jpg', - }, - tg3: { - bgImage: '/bg/tg-code.jpg', - }, - tg4: { - bgImage: '/bg/tg-elec.jpg', - }, - tg5: { - bgImage: '/bg/tg-co2.jpeg', - }, - tg6: { - bgImage: '/bg/tg-cartoon.jpeg', - }, - tg7: { - bgImage: '/bg/tg-istanbul.jpeg', - }, - } - - const effect = effects.tg6 +const Wallpaper: FC = () => { + const effect = WALLPAPER.green // for linear/solid background colors if (isString(effect)) { @@ -99,4 +37,4 @@ const ComstomBg: FC = () => { ) } -export default memo(ComstomBg) +export default memo(Wallpaper) diff --git a/utils/constant/index.ts b/utils/constant/index.ts index 2cf0149f4..7fe9b9c1c 100755 --- a/utils/constant/index.ts +++ b/utils/constant/index.ts @@ -35,6 +35,8 @@ export { COMMUNITY_MAP_ALIAS } from './alias' export { AS_STATE, AS_TYPE } from './article_state' export { default as DEFAULT_TOAST_OPTIONS } from './toast' + +export { default as WALLPAPER } from './wallpaper' /* some svg icon are sensitive to fill color */ /* some community svg need fill color, like city etc.. */ export const NON_FILL_COMMUNITY = ['javascript'] diff --git a/utils/constant/wallpaper.ts b/utils/constant/wallpaper.ts new file mode 100644 index 000000000..8d73471e0 --- /dev/null +++ b/utils/constant/wallpaper.ts @@ -0,0 +1,59 @@ +const DIR = '/wallpaper' + +const WALLPAPER = { + // parttens + bubbles: { + bgImage: `${DIR}/bubbles.png`, + }, + limones: { + bgImage: `${DIR}/limones.jpeg`, + }, + mataura: { + bgImage: `${DIR}/mataura.png`, + bgSize: 'cover', + }, + curves: { + bgImage: `${DIR}/curves.png`, + bgColor: '#050139', // backgroundBg or fallback + }, + newspaper: { + bgImage: `${DIR}/newspaper.jpeg`, + }, + rainbow: { + bgImage: `${DIR}/rainbow.jpeg`, + }, + fishes: { + bgImage: `${DIR}/fishes.jpeg`, + }, + // space: { + // bgImage: `${DIR}/space.svg`, + // bgColor: '#002630', + // }, + earth: { + bgImage: `${DIR}/earth.jpg`, + }, + code: { + bgImage: `${DIR}/code.jpg`, + }, + elec: { + bgImage: `${DIR}/elec.jpg`, + }, + co2: { + bgImage: `${DIR}/co2.jpeg`, + }, + cartoon: { + bgImage: `${DIR}/cartoon.jpeg`, + }, + istanbul: { + bgImage: `${DIR}/istanbul.jpeg`, + }, + + // linear gradian + // background: #2c3e50; /* fallback for old browsers */ + // background: -webkit-linear-gradient(#C6D183, #72B58C); /* Chrome 10-25, Safari 5.1-6 */ + green: ` + background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #C6D183, #72B58C); + `, +} + +export default WALLPAPER From c708be8419b966d9b01cdda32ee6382aa25ca719 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Thu, 19 May 2022 22:07:45 +0800 Subject: [PATCH 05/22] refactor(wallpaper-editor): basic selector ux --- .../editor/WallpaperEditor/GradientGroup.tsx | 46 +++++++++++ .../editor/WallpaperEditor/PicGroup.tsx | 53 ++++++------ .../editor/WallpaperEditor/index.tsx | 82 +++++++++++++------ .../editor/WallpaperEditor/logic.ts | 4 +- .../editor/WallpaperEditor/store.ts | 4 +- .../WallpaperEditor/styles/gradient_group.ts | 58 +++++++++++++ .../editor/WallpaperEditor/styles/index.ts | 37 +++++++-- .../WallpaperEditor/styles/pic_group.ts | 3 +- .../layout/GlobalLayout/Wallpaper.tsx | 2 +- .../tool/Drawer/Content/DesktopView.tsx | 31 ++++--- utils/constant/index.ts | 2 +- utils/constant/wallpaper.ts | 66 ++++++++++----- 12 files changed, 287 insertions(+), 101 deletions(-) create mode 100644 src/containers/editor/WallpaperEditor/GradientGroup.tsx create mode 100644 src/containers/editor/WallpaperEditor/styles/gradient_group.ts diff --git a/src/containers/editor/WallpaperEditor/GradientGroup.tsx b/src/containers/editor/WallpaperEditor/GradientGroup.tsx new file mode 100644 index 000000000..55316341a --- /dev/null +++ b/src/containers/editor/WallpaperEditor/GradientGroup.tsx @@ -0,0 +1,46 @@ +import { FC, memo } from 'react' +import { keys } from 'ramda' +import { GRADIENT_WALLPAPER } from '@/constant' + +import { + Wrapper, + Block, + // Image, + // ActiveSign, + // CheckIcon, +} from './styles/gradient_group' + +import { setCurrent } from './logic' + +type TProps = { + current: string +} + +const PicGroup: FC = ({ current }) => { + const gradientKeys = keys(GRADIENT_WALLPAPER) + + return ( + + {gradientKeys.map((name) => ( + + {/* {name === current && ( + + + + )} */} + {/* setCurrent(name)} + /> */} + + ))} + + ) +} + +export default memo(PicGroup) diff --git a/src/containers/editor/WallpaperEditor/PicGroup.tsx b/src/containers/editor/WallpaperEditor/PicGroup.tsx index da2cda1da..287c3a9d9 100644 --- a/src/containers/editor/WallpaperEditor/PicGroup.tsx +++ b/src/containers/editor/WallpaperEditor/PicGroup.tsx @@ -1,5 +1,6 @@ import { FC, memo } from 'react' -import { WALLPAPER } from '@/constant' +import { keys } from 'ramda' +import { PATTERN_WALLPAPER } from '@/constant' import { Wrapper, @@ -9,36 +10,30 @@ import { CheckIcon, } from './styles/pic_group' -const PicGroup: FC = () => { +import { setCurrent } from './logic' + +type TProps = { + current: string +} + +const PicGroup: FC = ({ current }) => { + const patternKeys = keys(PATTERN_WALLPAPER) + return ( - - - - - - - - - - - - - - - - - - - - - - - - + {patternKeys.map((name) => ( + + {name === current && ( + + + + )} + setCurrent(name)} + /> + + ))} ) } diff --git a/src/containers/editor/WallpaperEditor/index.tsx b/src/containers/editor/WallpaperEditor/index.tsx index b85c4709d..9f9967aca 100644 --- a/src/containers/editor/WallpaperEditor/index.tsx +++ b/src/containers/editor/WallpaperEditor/index.tsx @@ -7,22 +7,37 @@ import { FC } from 'react' // import { buildLog } from '@/utils/logger' import { bond } from '@/utils/mobx' -import { VIEW } from '@/constant' +import { VIEW, DRAWER_SCROLLER } from '@/constant' + import { Tabs } from '@/widgets/Switcher' +import CustomScroller from '@/widgets/CustomScroller' +import Button from '@/widgets/Buttons/Button' import type { TStore } from './store' -import { Wrapper, Content, Title } from './styles' + import PicGroup from './PicGroup' +import GradientGroup from './GradientGroup' + +import { + Wrapper, + Banner, + BannerTitle, + Content, + Title, + SubTitle, + Footer, +} from './styles' + import { useInit } from './logic' /* eslint-disable-next-line */ const TAB_OPTIONS = [ { - title: '内置背景', + title: '内置壁纸', raw: 'buildin', localIcon: 'settings', }, { - title: '自定义图片', + title: '上传壁纸', raw: 'custom', localIcon: 'settings', }, @@ -38,31 +53,48 @@ const WallpaperEditorContainer: FC = ({ testid = 'wallpaper-editor', }) => { useInit(store) + const { current } = store return ( - 背景设置 -
- -
- -
图案
- - -
-
渐变
-
各种圆形渐变选项
-
parttern 叠加选项
+ + 壁纸设置 +
+ +
+
-
-
其它
-
图片模糊
-
+ + + 图案: + +
+ 纯色渐变: + +
+
+
叠加花纹
+
模糊效果
+
+
+
+ + +
) } diff --git a/src/containers/editor/WallpaperEditor/logic.ts b/src/containers/editor/WallpaperEditor/logic.ts index 3942d6fc8..28d4e03c4 100644 --- a/src/containers/editor/WallpaperEditor/logic.ts +++ b/src/containers/editor/WallpaperEditor/logic.ts @@ -11,8 +11,8 @@ let store: TStore | undefined /* eslint-disable-next-line */ const log = buildLog('L:WallpaperEditor') -export const someMethod = (): void => { - // +export const setCurrent = (current: string): void => { + store.mark({ current }) } // ############################### diff --git a/src/containers/editor/WallpaperEditor/store.ts b/src/containers/editor/WallpaperEditor/store.ts index fd51ead75..8a43e0e03 100644 --- a/src/containers/editor/WallpaperEditor/store.ts +++ b/src/containers/editor/WallpaperEditor/store.ts @@ -12,7 +12,9 @@ import { markStates, toJS } from '@/utils/mobx' /* eslint-disable-next-line */ const log = buildLog('S:WallpaperEditor') -const WallpaperEditor = T.model('WallpaperEditor', {}) +const WallpaperEditor = T.model('WallpaperEditor', { + current: T.optional(T.string, 'green'), +}) .views((self) => ({ get curCommunity(): TCommunity { const root = getParent(self) as TRootStore diff --git a/src/containers/editor/WallpaperEditor/styles/gradient_group.ts b/src/containers/editor/WallpaperEditor/styles/gradient_group.ts new file mode 100644 index 000000000..433c48a27 --- /dev/null +++ b/src/containers/editor/WallpaperEditor/styles/gradient_group.ts @@ -0,0 +1,58 @@ +import styled from 'styled-components' + +import type { TActive } from '@/spec' +import Img from '@/Img' +import css, { theme } from '@/utils/css' +import CheckedSVG from '@/icons/Checked' + +export const Wrapper = styled.div` + ${css.flex()}; + width: calc(100% + 30px); + flex-wrap: wrap; + margin-top: 10px; + margin-left: 1px; +` + +type TBlock = { + bg: string +} & TActive + +export const Block = styled.div` + position: relative; + ${css.circle(32)}; + margin-right: 18px; + margin-bottom: 10px; + ${({ bg }) => bg || 'transparent'}; + background-size: 200px; + + &:hover { + border-color: ${theme('thread.articleTitle')}; + cursor: pointer; + } + + transition: border-color 0.1s linear; +` +export const Image = styled(Img)<{ bgColor?: string }>` + width: 100%; + object-fit: cover; + background-color: ${({ bgColor }) => bgColor || 'transparent'}; +` +export const ActiveSign = styled.div` + ${css.size(24)}; + background: ${theme('border')}; + position: absolute; + top: -1px; + right: -1px; + border-top-right-radius: 4px; + border-bottom-left-radius: 30px; + z-index: 3; + border: 1px solid; + border-color: ${theme('thread.articleTitle')}; +` +export const CheckIcon = styled(CheckedSVG)` + fill: ${theme('thread.articleTitle')}; + ${css.size(16)}; + position: absolute; + top: 2px; + left: 6px; +` diff --git a/src/containers/editor/WallpaperEditor/styles/index.ts b/src/containers/editor/WallpaperEditor/styles/index.ts index fa5abb06a..64d4db9f4 100644 --- a/src/containers/editor/WallpaperEditor/styles/index.ts +++ b/src/containers/editor/WallpaperEditor/styles/index.ts @@ -1,21 +1,48 @@ import styled from 'styled-components' import type { TTestable } from '@/spec' -import { theme } from '@/utils/css' +import css, { theme } from '@/utils/css' export const Wrapper = styled.div.attrs(({ testid }: TTestable) => ({ 'data-test-id': testid, }))` - padding: 30px; + position: relative; + height: 100%; ` -export const Title = styled.div` +export const Banner = styled.div` + padding: 20px 30px; +` +export const BannerTitle = styled.div` font-size: 17px; color: ${theme('thread.articleTitle')}; font-weight: bold; margin-bottom: 16px; margin-left: 2px; ` +export const Title = styled.div` + font-size: 14px; + color: ${theme('thread.articleDigest')}; + font-weight: bold; + margin-bottom: 16px; + margin-left: 2px; +` +export const SubTitle = styled.div` + font-size: 14px; + color: ${theme('thread.articleDigest')}; + margin-bottom: 16px; + margin-left: 2px; +` + export const Content = styled.div` - margin-top: 20px; - padding: 0 2px; + padding: 0 30px; + height: 100%; + overflow-y: scroll; +` +export const Footer = styled.div` + ${css.flex('align-center', 'justify-between')}; + width: 100%; + padding: 0 30px; + position: absolute; + bottom: 18px; + left: 0; ` diff --git a/src/containers/editor/WallpaperEditor/styles/pic_group.ts b/src/containers/editor/WallpaperEditor/styles/pic_group.ts index 710b3726d..992dfdaf6 100644 --- a/src/containers/editor/WallpaperEditor/styles/pic_group.ts +++ b/src/containers/editor/WallpaperEditor/styles/pic_group.ts @@ -30,10 +30,9 @@ export const Block = styled.div` transition: border-color 0.1s linear; ` -export const Image = styled(Img)<{ bgColor?: string }>` +export const Image = styled(Img)` width: 100%; object-fit: cover; - background-color: ${({ bgColor }) => bgColor || 'transparent'}; ` export const ActiveSign = styled.div` ${css.size(24)}; diff --git a/src/containers/layout/GlobalLayout/Wallpaper.tsx b/src/containers/layout/GlobalLayout/Wallpaper.tsx index 2761f4afa..a77f75150 100644 --- a/src/containers/layout/GlobalLayout/Wallpaper.tsx +++ b/src/containers/layout/GlobalLayout/Wallpaper.tsx @@ -13,7 +13,7 @@ import { Wrapper } from './styles/wallpaper' // | string const Wallpaper: FC = () => { - const effect = WALLPAPER.green + const effect = WALLPAPER.pink // for linear/solid background colors if (isString(effect)) { diff --git a/src/containers/tool/Drawer/Content/DesktopView.tsx b/src/containers/tool/Drawer/Content/DesktopView.tsx index c5659b1c7..ce577a6da 100644 --- a/src/containers/tool/Drawer/Content/DesktopView.tsx +++ b/src/containers/tool/Drawer/Content/DesktopView.tsx @@ -5,6 +5,7 @@ import CustomScroller from '@/widgets/CustomScroller' import renderContent from './renderContent' import { Wrapper } from '../styles/content' +import { isViewerMode } from '../styles/metrics' type TProps = { visible: boolean @@ -26,19 +27,23 @@ const Content: FC = ({ visible, type, attUser, userListerType }) => { } }, [visible, ref]) - return ( - - - {renderContent(type, attUser, userListerType)} - - - ) + if (isViewerMode(type)) { + return ( + + + {renderContent(type, attUser, userListerType)} + + + ) + } + + return {renderContent(type, attUser, userListerType)} } export default memo(Content) diff --git a/utils/constant/index.ts b/utils/constant/index.ts index 7fe9b9c1c..5c472603f 100755 --- a/utils/constant/index.ts +++ b/utils/constant/index.ts @@ -36,7 +36,7 @@ export { AS_STATE, AS_TYPE } from './article_state' export { default as DEFAULT_TOAST_OPTIONS } from './toast' -export { default as WALLPAPER } from './wallpaper' +export { PATTERN_WALLPAPER, GRADIENT_WALLPAPER, WALLPAPER } from './wallpaper' /* some svg icon are sensitive to fill color */ /* some community svg need fill color, like city etc.. */ export const NON_FILL_COMMUNITY = ['javascript'] diff --git a/utils/constant/wallpaper.ts b/utils/constant/wallpaper.ts index 8d73471e0..dec2792b2 100644 --- a/utils/constant/wallpaper.ts +++ b/utils/constant/wallpaper.ts @@ -1,10 +1,9 @@ const DIR = '/wallpaper' -const WALLPAPER = { - // parttens - bubbles: { - bgImage: `${DIR}/bubbles.png`, - }, +export const PATTERN_WALLPAPER = { + // bubbles: { + // bgImage: `${DIR}/bubbles.png`, + // }, limones: { bgImage: `${DIR}/limones.jpeg`, }, @@ -12,19 +11,19 @@ const WALLPAPER = { bgImage: `${DIR}/mataura.png`, bgSize: 'cover', }, - curves: { - bgImage: `${DIR}/curves.png`, - bgColor: '#050139', // backgroundBg or fallback - }, - newspaper: { - bgImage: `${DIR}/newspaper.jpeg`, - }, + // curves: { + // bgImage: `${DIR}/curves.png`, + // bgColor: '#050139', // backgroundBg or fallback + // }, + // newspaper: { + // bgImage: `${DIR}/newspaper.jpeg`, + // }, rainbow: { bgImage: `${DIR}/rainbow.jpeg`, }, - fishes: { - bgImage: `${DIR}/fishes.jpeg`, - }, + // fishes: { + // bgImage: `${DIR}/fishes.jpeg`, + // }, // space: { // bgImage: `${DIR}/space.svg`, // bgColor: '#002630', @@ -35,25 +34,48 @@ const WALLPAPER = { code: { bgImage: `${DIR}/code.jpg`, }, - elec: { - bgImage: `${DIR}/elec.jpg`, - }, + // elec: { + // bgImage: `${DIR}/elec.jpg`, + // }, co2: { bgImage: `${DIR}/co2.jpeg`, }, cartoon: { bgImage: `${DIR}/cartoon.jpeg`, }, - istanbul: { - bgImage: `${DIR}/istanbul.jpeg`, - }, + // istanbul: { + // bgImage: `${DIR}/istanbul.jpeg`, + // }, +} +export const GRADIENT_WALLPAPER = { // linear gradian // background: #2c3e50; /* fallback for old browsers */ // background: -webkit-linear-gradient(#C6D183, #72B58C); /* Chrome 10-25, Safari 5.1-6 */ green: ` background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #C6D183, #72B58C); `, + purple: ` + background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #BBA4C9, #8390CD); + `, + yellow: ` + background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #F7CE7E, #E17D43); + `, + cyan: ` + background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #6EC0C2, #222937); + `, + red: ` + background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #E76B66, #6E3837); + `, + blue: ` + background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #85AADA, #274AA1); + `, + pink: ` + background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #D6C4BA, #C5BADB); + `, } -export default WALLPAPER +export const WALLPAPER = { + ...PATTERN_WALLPAPER, + ...GRADIENT_WALLPAPER, +} From 29da1a7092dab2680b1df37232d98662222a6064 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Fri, 20 May 2022 09:35:38 +0800 Subject: [PATCH 06/22] refactor(wallpaper-utils): extract helper & fmt --- .../editor/WallpaperEditor/GradientGroup.tsx | 6 +- .../WallpaperEditor/styles/gradient_group.ts | 4 +- .../layout/GlobalLayout/Wallpaper.tsx | 32 ++------- utils/constant/wallpaper.ts | 62 +++++++++++------ utils/wallpaper.ts | 69 +++++++++++++++++++ 5 files changed, 121 insertions(+), 52 deletions(-) create mode 100644 utils/wallpaper.ts diff --git a/src/containers/editor/WallpaperEditor/GradientGroup.tsx b/src/containers/editor/WallpaperEditor/GradientGroup.tsx index 55316341a..57b04a6ae 100644 --- a/src/containers/editor/WallpaperEditor/GradientGroup.tsx +++ b/src/containers/editor/WallpaperEditor/GradientGroup.tsx @@ -1,6 +1,8 @@ import { FC, memo } from 'react' import { keys } from 'ramda' + import { GRADIENT_WALLPAPER } from '@/constant' +import { parseWallpaperByName } from '@/utils/wallpaper' import { Wrapper, @@ -10,7 +12,7 @@ import { // CheckIcon, } from './styles/gradient_group' -import { setCurrent } from './logic' +// import { setCurrent } from './logic' type TProps = { current: string @@ -25,7 +27,7 @@ const PicGroup: FC = ({ current }) => { {/* {name === current && ( diff --git a/src/containers/editor/WallpaperEditor/styles/gradient_group.ts b/src/containers/editor/WallpaperEditor/styles/gradient_group.ts index 433c48a27..dcdf00952 100644 --- a/src/containers/editor/WallpaperEditor/styles/gradient_group.ts +++ b/src/containers/editor/WallpaperEditor/styles/gradient_group.ts @@ -14,7 +14,7 @@ export const Wrapper = styled.div` ` type TBlock = { - bg: string + background: string } & TActive export const Block = styled.div` @@ -22,7 +22,7 @@ export const Block = styled.div` ${css.circle(32)}; margin-right: 18px; margin-bottom: 10px; - ${({ bg }) => bg || 'transparent'}; + background: ${({ background }) => background || 'transparent'}; background-size: 200px; &:hover { diff --git a/src/containers/layout/GlobalLayout/Wallpaper.tsx b/src/containers/layout/GlobalLayout/Wallpaper.tsx index a77f75150..a75ab4c1a 100644 --- a/src/containers/layout/GlobalLayout/Wallpaper.tsx +++ b/src/containers/layout/GlobalLayout/Wallpaper.tsx @@ -1,40 +1,18 @@ import { FC, memo } from 'react' import { WALLPAPER } from '@/constant' -import { isString } from '@/utils/validator' -import { Wrapper } from './styles/wallpaper' +import { parseWallpaper } from '@/utils/wallpaper' -// type TBackgroundEffect = -// | { -// bgImage: string -// bgColor?: string -// bgSize?: 'contain' | 'cover' | 'auto' -// } -// | string +import { Wrapper } from './styles/wallpaper' const Wallpaper: FC = () => { - const effect = WALLPAPER.pink - - // for linear/solid background colors - if (isString(effect)) { - // @ts-ignore - return - } - - // @ts-ignore - const { bgImage, bgColor = '', bgSize = 'contain' } = effect + const wallpaper = WALLPAPER.rainbow + const { background, effect } = parseWallpaper(wallpaper) // for custom image/svg // for use style object not passing props // @link see https://github.com/styled-components/styled-components/issues/3315#issuecomment-885977691 - return ( - - ) + return } export default memo(Wallpaper) diff --git a/utils/constant/wallpaper.ts b/utils/constant/wallpaper.ts index dec2792b2..87cb39cb8 100644 --- a/utils/constant/wallpaper.ts +++ b/utils/constant/wallpaper.ts @@ -48,31 +48,51 @@ export const PATTERN_WALLPAPER = { // }, } +// demo: ` +// background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #C6D183, #72B58C); +// `, + +const DEFAULT_GRADIENT_EFFECT = { + hasPattern: false, + hasBlur: false, + direction: 'to bottom', +} + export const GRADIENT_WALLPAPER = { // linear gradian // background: #2c3e50; /* fallback for old browsers */ // background: -webkit-linear-gradient(#C6D183, #72B58C); /* Chrome 10-25, Safari 5.1-6 */ - green: ` - background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #C6D183, #72B58C); - `, - purple: ` - background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #BBA4C9, #8390CD); - `, - yellow: ` - background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #F7CE7E, #E17D43); - `, - cyan: ` - background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #6EC0C2, #222937); - `, - red: ` - background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #E76B66, #6E3837); - `, - blue: ` - background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #85AADA, #274AA1); - `, - pink: ` - background: url(${DIR}/patterns/1.png) repeat, linear-gradient(to bottom, #D6C4BA, #C5BADB); - `, + + green: { + colors: ['#C6D183', '#72B58C'], + ...DEFAULT_GRADIENT_EFFECT, + hasPattern: true, + }, + purple: { + colors: ['#BBA4C9', '#8390CD'], + ...DEFAULT_GRADIENT_EFFECT, + }, + yellow: { + colors: ['#F7CE7E', '#E17D43'], + ...DEFAULT_GRADIENT_EFFECT, + }, + cyan: { + colors: ['#6EC0C2', '#222937'], + ...DEFAULT_GRADIENT_EFFECT, + }, + red: { + colors: ['#E76B66', '#6E3837'], + ...DEFAULT_GRADIENT_EFFECT, + }, + blue: { + colors: ['#85AADA', '#274AA1'], + ...DEFAULT_GRADIENT_EFFECT, + }, + pink: { + colors: ['#D6C4BA', '#C5BADB'], + ...DEFAULT_GRADIENT_EFFECT, + hasBlur: true, + }, } export const WALLPAPER = { diff --git a/utils/wallpaper.ts b/utils/wallpaper.ts new file mode 100644 index 000000000..0918990ba --- /dev/null +++ b/utils/wallpaper.ts @@ -0,0 +1,69 @@ +import { WALLPAPER } from '@/constant' + +type TWallpaperFmt = { + effect: string + background: string +} + +type TWallpaperGradient = { + colors?: string[] + hasPattern?: boolean + hasBlur?: boolean + direction?: string +} + +type TWallpaperPic = { + bgImage?: string + bgColor?: string + bgSize?: 'contain' | 'cover' | 'auto' + // for ts check + colors?: string[] +} + +type TWallpaper = TWallpaperGradient | TWallpaperPic + +/** + * parse wallpaper both for gradient and picture background + */ +export const parseWallpaperByName = (name: string): TWallpaperFmt => { + return parseWallpaper(WALLPAPER[name]) +} + +/** + * parse wallpaper both for gradient and picture background + */ +export const parseWallpaper = (wallpaper: TWallpaper): TWallpaperFmt => { + return wallpaper.colors + ? gotGradientBackground(wallpaper) + : getPicBackground(wallpaper) +} + +const gotGradientBackground = (gradient: TWallpaperGradient): TWallpaperFmt => { + const DIR = '/wallpaper' + const { direction, hasPattern, hasBlur } = gradient + let background = `linear-gradient(${direction}, ${gradient.colors.join(',')})` + + const patternPic = `${DIR}/patterns/1.png` + background = hasPattern + ? `url(${patternPic}) repeat, ${background}` + : background + + const effect = hasBlur ? 'filter: blur(3px)' : '' + + return { + effect, + background, + } +} + +const getPicBackground = (pic: TWallpaperPic): TWallpaperFmt => { + const { bgImage, bgColor = '', bgSize = 'contain' } = pic + const background = `url(${bgImage})` + + const effect = `background-color: ${bgColor}; background-size: ${bgSize}` + + return { + effect, + background, + } +} From f9757b82d24e0ac5af8bbfa1d48c1f3583e5e84f Mon Sep 17 00:00:00 2001 From: mydearxym Date: Fri, 20 May 2022 13:27:25 +0800 Subject: [PATCH 07/22] refactor(wallpaper-utils): switch ux/logic --- .../editor/WallpaperEditor/GradientGroup.tsx | 25 +++--------- .../WallpaperEditor/styles/gradient_group.ts | 40 ++++++++----------- .../editor/WallpaperEditor/styles/index.ts | 1 + .../layout/GlobalLayout/Wallpaper.tsx | 8 ++-- src/containers/layout/GlobalLayout/index.tsx | 4 +- src/containers/layout/GlobalLayout/store.ts | 4 ++ utils/wallpaper.ts | 18 +++++---- 7 files changed, 44 insertions(+), 56 deletions(-) diff --git a/src/containers/editor/WallpaperEditor/GradientGroup.tsx b/src/containers/editor/WallpaperEditor/GradientGroup.tsx index 57b04a6ae..f400e4d31 100644 --- a/src/containers/editor/WallpaperEditor/GradientGroup.tsx +++ b/src/containers/editor/WallpaperEditor/GradientGroup.tsx @@ -2,17 +2,11 @@ import { FC, memo } from 'react' import { keys } from 'ramda' import { GRADIENT_WALLPAPER } from '@/constant' -import { parseWallpaperByName } from '@/utils/wallpaper' +import { parseWallpaper } from '@/utils/wallpaper' -import { - Wrapper, - Block, - // Image, - // ActiveSign, - // CheckIcon, -} from './styles/gradient_group' +import { Wrapper, Block, ColorBall } from './styles/gradient_group' -// import { setCurrent } from './logic' +import { setCurrent } from './logic' type TProps = { current: string @@ -27,18 +21,9 @@ const PicGroup: FC = ({ current }) => { setCurrent(name)} > - {/* {name === current && ( - - - - )} */} - {/* setCurrent(name)} - /> */} + ))} diff --git a/src/containers/editor/WallpaperEditor/styles/gradient_group.ts b/src/containers/editor/WallpaperEditor/styles/gradient_group.ts index dcdf00952..d32ee2439 100644 --- a/src/containers/editor/WallpaperEditor/styles/gradient_group.ts +++ b/src/containers/editor/WallpaperEditor/styles/gradient_group.ts @@ -1,9 +1,7 @@ import styled from 'styled-components' import type { TActive } from '@/spec' -import Img from '@/Img' import css, { theme } from '@/utils/css' -import CheckedSVG from '@/icons/Checked' export const Wrapper = styled.div` ${css.flex()}; @@ -13,29 +11,30 @@ export const Wrapper = styled.div` margin-left: 1px; ` -type TBlock = { - background: string -} & TActive - -export const Block = styled.div` - position: relative; - ${css.circle(32)}; - margin-right: 18px; +export const Block = styled.div` + /* ${css.circle(35)}; */ + ${css.flex('align-both')}; + border-radius: 100%; + /* position: relative; */ + border: 2px solid; + border-color: ${({ $active }) => + $active ? theme('thread.articleDigest') : 'transparent'}; + /* padding: ${({ $active }) => ($active ? '3px' : '2px')}; */ + padding: 3px; + margin-right: 12px; margin-bottom: 10px; - background: ${({ background }) => background || 'transparent'}; - background-size: 200px; &:hover { border-color: ${theme('thread.articleTitle')}; cursor: pointer; } - transition: border-color 0.1s linear; + transition: border-color 0.2s linear; ` -export const Image = styled(Img)<{ bgColor?: string }>` - width: 100%; - object-fit: cover; - background-color: ${({ bgColor }) => bgColor || 'transparent'}; +export const ColorBall = styled.div<{ background: string }>` + ${css.circle(30)}; + background: ${({ background }) => background || 'transparent'}; + background-size: 200px; ` export const ActiveSign = styled.div` ${css.size(24)}; @@ -49,10 +48,3 @@ export const ActiveSign = styled.div` border: 1px solid; border-color: ${theme('thread.articleTitle')}; ` -export const CheckIcon = styled(CheckedSVG)` - fill: ${theme('thread.articleTitle')}; - ${css.size(16)}; - position: absolute; - top: 2px; - left: 6px; -` diff --git a/src/containers/editor/WallpaperEditor/styles/index.ts b/src/containers/editor/WallpaperEditor/styles/index.ts index 64d4db9f4..59a157dce 100644 --- a/src/containers/editor/WallpaperEditor/styles/index.ts +++ b/src/containers/editor/WallpaperEditor/styles/index.ts @@ -37,6 +37,7 @@ export const Content = styled.div` padding: 0 30px; height: 100%; overflow-y: scroll; + overflow-x: hidden; ` export const Footer = styled.div` ${css.flex('align-center', 'justify-between')}; diff --git a/src/containers/layout/GlobalLayout/Wallpaper.tsx b/src/containers/layout/GlobalLayout/Wallpaper.tsx index a75ab4c1a..eb72629b7 100644 --- a/src/containers/layout/GlobalLayout/Wallpaper.tsx +++ b/src/containers/layout/GlobalLayout/Wallpaper.tsx @@ -1,12 +1,14 @@ import { FC, memo } from 'react' -import { WALLPAPER } from '@/constant' import { parseWallpaper } from '@/utils/wallpaper' import { Wrapper } from './styles/wallpaper' -const Wallpaper: FC = () => { - const wallpaper = WALLPAPER.rainbow +type TProps = { + wallpaper: string +} + +const Wallpaper: FC = ({ wallpaper }) => { const { background, effect } = parseWallpaper(wallpaper) // for custom image/svg diff --git a/src/containers/layout/GlobalLayout/index.tsx b/src/containers/layout/GlobalLayout/index.tsx index ff40dc1ad..3f36235c0 100755 --- a/src/containers/layout/GlobalLayout/index.tsx +++ b/src/containers/layout/GlobalLayout/index.tsx @@ -56,11 +56,11 @@ const GlobalLayoutContainer: FC = ({ // load debug graph useInit(store, { isMobile }) - const { accountInfo, sidebarPin, curCommunity } = store + const { accountInfo, sidebarPin, curCommunity, wallpaper } = store return ( - + diff --git a/src/containers/layout/GlobalLayout/store.ts b/src/containers/layout/GlobalLayout/store.ts index 852f3ffbd..1a3ac5d6d 100755 --- a/src/containers/layout/GlobalLayout/store.ts +++ b/src/containers/layout/GlobalLayout/store.ts @@ -41,6 +41,10 @@ const GlobalLayout = T.model('GlobalLayoutStore', { const root = getParent(self) as TRootStore return root.sidebar.pin }, + get wallpaper(): string { + const root = getParent(self) as TRootStore + return root.wallpaperEditor.current + }, })) .actions((self) => ({ toast(type, options): void { diff --git a/utils/wallpaper.ts b/utils/wallpaper.ts index 0918990ba..abf45a948 100644 --- a/utils/wallpaper.ts +++ b/utils/wallpaper.ts @@ -25,20 +25,24 @@ type TWallpaper = TWallpaperGradient | TWallpaperPic /** * parse wallpaper both for gradient and picture background */ -export const parseWallpaperByName = (name: string): TWallpaperFmt => { - return parseWallpaper(WALLPAPER[name]) +export const parseWallpaper = (name: string): TWallpaperFmt => { + return _parseWallpaper(WALLPAPER[name]) } +export const holder = 1 + /** * parse wallpaper both for gradient and picture background */ -export const parseWallpaper = (wallpaper: TWallpaper): TWallpaperFmt => { +const _parseWallpaper = (wallpaper: TWallpaper): TWallpaperFmt => { return wallpaper.colors - ? gotGradientBackground(wallpaper) - : getPicBackground(wallpaper) + ? _parseGradientBackground(wallpaper) + : _parsePicBackground(wallpaper) } -const gotGradientBackground = (gradient: TWallpaperGradient): TWallpaperFmt => { +const _parseGradientBackground = ( + gradient: TWallpaperGradient, +): TWallpaperFmt => { const DIR = '/wallpaper' const { direction, hasPattern, hasBlur } = gradient let background = `linear-gradient(${direction}, ${gradient.colors.join(',')})` @@ -56,7 +60,7 @@ const gotGradientBackground = (gradient: TWallpaperGradient): TWallpaperFmt => { } } -const getPicBackground = (pic: TWallpaperPic): TWallpaperFmt => { +const _parsePicBackground = (pic: TWallpaperPic): TWallpaperFmt => { const { bgImage, bgColor = '', bgSize = 'contain' } = pic const background = `url(${bgImage})` From 26cd758be4026903cfed056dbd9539cb54f004f6 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Fri, 20 May 2022 13:31:37 +0800 Subject: [PATCH 08/22] refactor(wallpaper-utils): renaming functions --- .../editor/WallpaperEditor/GradientGroup.tsx | 10 +++++----- .../editor/WallpaperEditor/PicGroup.tsx | 12 ++++++------ src/containers/editor/WallpaperEditor/index.tsx | 16 ++++------------ src/containers/editor/WallpaperEditor/logic.ts | 4 ++-- src/containers/editor/WallpaperEditor/store.ts | 2 +- src/containers/layout/GlobalLayout/store.ts | 2 +- 6 files changed, 19 insertions(+), 27 deletions(-) diff --git a/src/containers/editor/WallpaperEditor/GradientGroup.tsx b/src/containers/editor/WallpaperEditor/GradientGroup.tsx index f400e4d31..aba61d7ee 100644 --- a/src/containers/editor/WallpaperEditor/GradientGroup.tsx +++ b/src/containers/editor/WallpaperEditor/GradientGroup.tsx @@ -6,13 +6,13 @@ import { parseWallpaper } from '@/utils/wallpaper' import { Wrapper, Block, ColorBall } from './styles/gradient_group' -import { setCurrent } from './logic' +import { setWallpaper } from './logic' type TProps = { - current: string + wallpaper: string } -const PicGroup: FC = ({ current }) => { +const PicGroup: FC = ({ wallpaper }) => { const gradientKeys = keys(GRADIENT_WALLPAPER) return ( @@ -20,8 +20,8 @@ const PicGroup: FC = ({ current }) => { {gradientKeys.map((name) => ( setCurrent(name)} + $active={name === wallpaper} + onClick={() => setWallpaper(name)} > diff --git a/src/containers/editor/WallpaperEditor/PicGroup.tsx b/src/containers/editor/WallpaperEditor/PicGroup.tsx index 287c3a9d9..9061262e3 100644 --- a/src/containers/editor/WallpaperEditor/PicGroup.tsx +++ b/src/containers/editor/WallpaperEditor/PicGroup.tsx @@ -10,27 +10,27 @@ import { CheckIcon, } from './styles/pic_group' -import { setCurrent } from './logic' +import { setWallpaper } from './logic' type TProps = { - current: string + wallpaper: string } -const PicGroup: FC = ({ current }) => { +const PicGroup: FC = ({ wallpaper }) => { const patternKeys = keys(PATTERN_WALLPAPER) return ( {patternKeys.map((name) => ( - - {name === current && ( + + {name === wallpaper && ( )} setCurrent(name)} + onClick={() => setWallpaper(name)} /> ))} diff --git a/src/containers/editor/WallpaperEditor/index.tsx b/src/containers/editor/WallpaperEditor/index.tsx index 9f9967aca..3d0dd7924 100644 --- a/src/containers/editor/WallpaperEditor/index.tsx +++ b/src/containers/editor/WallpaperEditor/index.tsx @@ -18,15 +18,7 @@ import type { TStore } from './store' import PicGroup from './PicGroup' import GradientGroup from './GradientGroup' -import { - Wrapper, - Banner, - BannerTitle, - Content, - Title, - SubTitle, - Footer, -} from './styles' +import { Wrapper, Banner, BannerTitle, Content, Title, Footer } from './styles' import { useInit } from './logic' /* eslint-disable-next-line */ @@ -53,7 +45,7 @@ const WallpaperEditorContainer: FC = ({ testid = 'wallpaper-editor', }) => { useInit(store) - const { current } = store + const { wallpaper } = store return ( @@ -79,10 +71,10 @@ const WallpaperEditorContainer: FC = ({ > 图案: - +
纯色渐变: - +

叠加花纹
diff --git a/src/containers/editor/WallpaperEditor/logic.ts b/src/containers/editor/WallpaperEditor/logic.ts index 28d4e03c4..dafbdc4bd 100644 --- a/src/containers/editor/WallpaperEditor/logic.ts +++ b/src/containers/editor/WallpaperEditor/logic.ts @@ -11,8 +11,8 @@ let store: TStore | undefined /* eslint-disable-next-line */ const log = buildLog('L:WallpaperEditor') -export const setCurrent = (current: string): void => { - store.mark({ current }) +export const setWallpaper = (wallpaper: string): void => { + store.mark({ wallpaper }) } // ############################### diff --git a/src/containers/editor/WallpaperEditor/store.ts b/src/containers/editor/WallpaperEditor/store.ts index 8a43e0e03..299c4866f 100644 --- a/src/containers/editor/WallpaperEditor/store.ts +++ b/src/containers/editor/WallpaperEditor/store.ts @@ -13,7 +13,7 @@ import { markStates, toJS } from '@/utils/mobx' const log = buildLog('S:WallpaperEditor') const WallpaperEditor = T.model('WallpaperEditor', { - current: T.optional(T.string, 'green'), + wallpaper: T.optional(T.string, 'green'), }) .views((self) => ({ get curCommunity(): TCommunity { diff --git a/src/containers/layout/GlobalLayout/store.ts b/src/containers/layout/GlobalLayout/store.ts index 1a3ac5d6d..f114f7328 100755 --- a/src/containers/layout/GlobalLayout/store.ts +++ b/src/containers/layout/GlobalLayout/store.ts @@ -43,7 +43,7 @@ const GlobalLayout = T.model('GlobalLayoutStore', { }, get wallpaper(): string { const root = getParent(self) as TRootStore - return root.wallpaperEditor.current + return root.wallpaperEditor.wallpaper }, })) .actions((self) => ({ From 960ca8efdd97864268307c1e8950ca216f0cc14b Mon Sep 17 00:00:00 2001 From: mydearxym Date: Fri, 20 May 2022 16:42:42 +0800 Subject: [PATCH 09/22] fix(wallpaper-utils): background-size not working --- utils/constant/wallpaper.ts | 6 +++--- utils/wallpaper.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/utils/constant/wallpaper.ts b/utils/constant/wallpaper.ts index 87cb39cb8..eae96e069 100644 --- a/utils/constant/wallpaper.ts +++ b/utils/constant/wallpaper.ts @@ -15,9 +15,9 @@ export const PATTERN_WALLPAPER = { // bgImage: `${DIR}/curves.png`, // bgColor: '#050139', // backgroundBg or fallback // }, - // newspaper: { - // bgImage: `${DIR}/newspaper.jpeg`, - // }, + newspaper: { + bgImage: `${DIR}/newspaper.jpeg`, + }, rainbow: { bgImage: `${DIR}/rainbow.jpeg`, }, diff --git a/utils/wallpaper.ts b/utils/wallpaper.ts index abf45a948..be3fd9b58 100644 --- a/utils/wallpaper.ts +++ b/utils/wallpaper.ts @@ -64,7 +64,7 @@ const _parsePicBackground = (pic: TWallpaperPic): TWallpaperFmt => { const { bgImage, bgColor = '', bgSize = 'contain' } = pic const background = `url(${bgImage})` - const effect = `background-color: ${bgColor}; background-size: ${bgSize}` + const effect = `background-color: ${bgColor}; background-size: ${bgSize} !important;` return { effect, From 0f2a162c0444583c795afe17de3407c2e379ce04 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Fri, 20 May 2022 18:52:22 +0800 Subject: [PATCH 10/22] refactor(wallpaper): re-org by move data source to store --- .../editor/WallpaperEditor/GradientGroup.tsx | 7 +++-- .../editor/WallpaperEditor/index.tsx | 7 +++-- .../editor/WallpaperEditor/store.ts | 12 +++++++- src/spec/index.ts | 7 +++++ src/spec/wallpaper.d.ts | 21 ++++++++++++++ utils/constant/wallpaper.ts | 4 ++- utils/wallpaper.ts | 28 ++++--------------- 7 files changed, 57 insertions(+), 29 deletions(-) create mode 100644 src/spec/wallpaper.d.ts diff --git a/src/containers/editor/WallpaperEditor/GradientGroup.tsx b/src/containers/editor/WallpaperEditor/GradientGroup.tsx index aba61d7ee..74d0673ee 100644 --- a/src/containers/editor/WallpaperEditor/GradientGroup.tsx +++ b/src/containers/editor/WallpaperEditor/GradientGroup.tsx @@ -1,7 +1,7 @@ import { FC, memo } from 'react' import { keys } from 'ramda' -import { GRADIENT_WALLPAPER } from '@/constant' +import type { TWallpaper } from '@/spec' import { parseWallpaper } from '@/utils/wallpaper' import { Wrapper, Block, ColorBall } from './styles/gradient_group' @@ -10,10 +10,11 @@ import { setWallpaper } from './logic' type TProps = { wallpaper: string + gradientWallpapers: Record } -const PicGroup: FC = ({ wallpaper }) => { - const gradientKeys = keys(GRADIENT_WALLPAPER) +const PicGroup: FC = ({ wallpaper, gradientWallpapers }) => { + const gradientKeys = keys(gradientWallpapers) return ( diff --git a/src/containers/editor/WallpaperEditor/index.tsx b/src/containers/editor/WallpaperEditor/index.tsx index 3d0dd7924..ead6d2a06 100644 --- a/src/containers/editor/WallpaperEditor/index.tsx +++ b/src/containers/editor/WallpaperEditor/index.tsx @@ -45,7 +45,7 @@ const WallpaperEditorContainer: FC = ({ testid = 'wallpaper-editor', }) => { useInit(store) - const { wallpaper } = store + const { wallpaper, gradientWallpapers } = store return ( @@ -74,7 +74,10 @@ const WallpaperEditorContainer: FC = ({
纯色渐变: - +

叠加花纹
diff --git a/src/containers/editor/WallpaperEditor/store.ts b/src/containers/editor/WallpaperEditor/store.ts index 299c4866f..3bf3aae6c 100644 --- a/src/containers/editor/WallpaperEditor/store.ts +++ b/src/containers/editor/WallpaperEditor/store.ts @@ -5,7 +5,8 @@ import { types as T, getParent, Instance } from 'mobx-state-tree' // import {} from 'ramda' -import type { TCommunity, TRootStore } from '@/spec' +import { WALLPAPER, GRADIENT_WALLPAPER } from '@/constant' +import type { TCommunity, TRootStore, TWallpaper } from '@/spec' import { buildLog } from '@/utils/logger' import { markStates, toJS } from '@/utils/mobx' @@ -14,6 +15,11 @@ const log = buildLog('S:WallpaperEditor') const WallpaperEditor = T.model('WallpaperEditor', { wallpaper: T.optional(T.string, 'green'), + + // for gradient colors + hasPattern: T.optional(T.boolean, false), + hasBlur: T.optional(T.boolean, false), + direction: T.optional(T.string, 'to bottom'), }) .views((self) => ({ get curCommunity(): TCommunity { @@ -21,6 +27,10 @@ const WallpaperEditor = T.model('WallpaperEditor', { return toJS(root.viewing.community) }, + + get gradientWallpapers(): Record { + return GRADIENT_WALLPAPER + }, })) .actions((self) => ({ mark(sobj: Record): void { diff --git a/src/spec/index.ts b/src/spec/index.ts index ccadf74ae..8354b1d14 100644 --- a/src/spec/index.ts +++ b/src/spec/index.ts @@ -131,6 +131,13 @@ export type { TAccountStore, TViewingStore } from './store' export type { TEmotion, TEmotionType } from './emotion' +export type { + TWallpaperPic, + TWallpaperGradient, + TWallpaperFmt, + TWallpaper, +} from './wallpaper' + export type TRoute = { communityPath?: string threadPath?: string diff --git a/src/spec/wallpaper.d.ts b/src/spec/wallpaper.d.ts new file mode 100644 index 000000000..388b2b881 --- /dev/null +++ b/src/spec/wallpaper.d.ts @@ -0,0 +1,21 @@ +export type TWallpaperFmt = { + effect: string + background: string +} + +export type TWallpaperGradient = { + colors?: string[] + hasPattern?: boolean + hasBlur?: boolean + direction?: string +} + +export type TWallpaperPic = { + bgImage?: string + bgColor?: string + bgSize?: 'contain' | 'cover' | 'auto' + // for ts check + colors?: string[] +} + +export type TWallpaper = TWallpaperGradient | TWallpaperPic diff --git a/utils/constant/wallpaper.ts b/utils/constant/wallpaper.ts index eae96e069..4e5f5c2f9 100644 --- a/utils/constant/wallpaper.ts +++ b/utils/constant/wallpaper.ts @@ -1,3 +1,5 @@ +import type { TWallpaper } from '@/spec' + const DIR = '/wallpaper' export const PATTERN_WALLPAPER = { @@ -93,7 +95,7 @@ export const GRADIENT_WALLPAPER = { ...DEFAULT_GRADIENT_EFFECT, hasBlur: true, }, -} +} as Record export const WALLPAPER = { ...PATTERN_WALLPAPER, diff --git a/utils/wallpaper.ts b/utils/wallpaper.ts index be3fd9b58..56809e3f3 100644 --- a/utils/wallpaper.ts +++ b/utils/wallpaper.ts @@ -1,26 +1,10 @@ import { WALLPAPER } from '@/constant' - -type TWallpaperFmt = { - effect: string - background: string -} - -type TWallpaperGradient = { - colors?: string[] - hasPattern?: boolean - hasBlur?: boolean - direction?: string -} - -type TWallpaperPic = { - bgImage?: string - bgColor?: string - bgSize?: 'contain' | 'cover' | 'auto' - // for ts check - colors?: string[] -} - -type TWallpaper = TWallpaperGradient | TWallpaperPic +import type { + TWallpaperFmt, + TWallpaperGradient, + TWallpaperPic, + TWallpaper, +} from '@/spec' /** * parse wallpaper both for gradient and picture background From 1e8f99c875caac67d822876197b773078a4ac9d7 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Fri, 20 May 2022 19:46:11 +0800 Subject: [PATCH 11/22] refactor(wallpaper): wip --- .../editor/WallpaperEditor/GradientGroup.tsx | 6 ++-- .../editor/WallpaperEditor/PicGroup.tsx | 10 ++++--- .../editor/WallpaperEditor/index.tsx | 9 ++++-- .../editor/WallpaperEditor/store.ts | 29 ++++++++++++++++--- .../WallpaperEditor/styles/gradient_group.ts | 5 +--- .../layout/GlobalLayout/Wallpaper.tsx | 8 +++-- src/containers/layout/GlobalLayout/index.tsx | 4 +-- src/containers/layout/GlobalLayout/store.ts | 12 +++++++- src/spec/wallpaper.d.ts | 6 ++-- utils/wallpaper.ts | 7 ++++- 10 files changed, 69 insertions(+), 27 deletions(-) diff --git a/src/containers/editor/WallpaperEditor/GradientGroup.tsx b/src/containers/editor/WallpaperEditor/GradientGroup.tsx index 74d0673ee..809c25dfa 100644 --- a/src/containers/editor/WallpaperEditor/GradientGroup.tsx +++ b/src/containers/editor/WallpaperEditor/GradientGroup.tsx @@ -2,7 +2,7 @@ import { FC, memo } from 'react' import { keys } from 'ramda' import type { TWallpaper } from '@/spec' -import { parseWallpaper } from '@/utils/wallpaper' +import { parseWallpaper2 } from '@/utils/wallpaper' import { Wrapper, Block, ColorBall } from './styles/gradient_group' @@ -24,7 +24,9 @@ const PicGroup: FC = ({ wallpaper, gradientWallpapers }) => { $active={name === wallpaper} onClick={() => setWallpaper(name)} > - +
))}
diff --git a/src/containers/editor/WallpaperEditor/PicGroup.tsx b/src/containers/editor/WallpaperEditor/PicGroup.tsx index 9061262e3..edc88748f 100644 --- a/src/containers/editor/WallpaperEditor/PicGroup.tsx +++ b/src/containers/editor/WallpaperEditor/PicGroup.tsx @@ -1,6 +1,7 @@ import { FC, memo } from 'react' import { keys } from 'ramda' -import { PATTERN_WALLPAPER } from '@/constant' + +import type { TWallpaper } from '@/spec' import { Wrapper, @@ -14,10 +15,11 @@ import { setWallpaper } from './logic' type TProps = { wallpaper: string + patternWallpapers: Record } -const PicGroup: FC = ({ wallpaper }) => { - const patternKeys = keys(PATTERN_WALLPAPER) +const PicGroup: FC = ({ wallpaper, patternWallpapers }) => { + const patternKeys = keys(patternWallpapers) return ( @@ -29,7 +31,7 @@ const PicGroup: FC = ({ wallpaper }) => {
)} setWallpaper(name)} />
diff --git a/src/containers/editor/WallpaperEditor/index.tsx b/src/containers/editor/WallpaperEditor/index.tsx index ead6d2a06..2415143e2 100644 --- a/src/containers/editor/WallpaperEditor/index.tsx +++ b/src/containers/editor/WallpaperEditor/index.tsx @@ -45,7 +45,9 @@ const WallpaperEditorContainer: FC = ({ testid = 'wallpaper-editor', }) => { useInit(store) - const { wallpaper, gradientWallpapers } = store + const { wallpaper, gradientWallpapers, patternWallpapers } = store + + console.log('>> gradientWallpapers---> ', gradientWallpapers) return ( @@ -71,7 +73,10 @@ const WallpaperEditorContainer: FC = ({ > 图案: - +
纯色渐变: { + return PATTERN_WALLPAPER + }, + get gradientWallpapers(): Record { - return GRADIENT_WALLPAPER + const slf = self as TStore + const wallpapers = clone(GRADIENT_WALLPAPER) + const paperKeys = keys(GRADIENT_WALLPAPER) + + forEach((key) => { + wallpapers[key].hasPattern = slf.hasPattern + }, paperKeys) + + return wallpapers + }, + + get wallpapers(): Record { + const slf = self as TStore + + return { + ...slf.gradientWallpapers, + ...slf.patternWallpapers, + } }, })) .actions((self) => ({ diff --git a/src/containers/editor/WallpaperEditor/styles/gradient_group.ts b/src/containers/editor/WallpaperEditor/styles/gradient_group.ts index d32ee2439..55ab2e482 100644 --- a/src/containers/editor/WallpaperEditor/styles/gradient_group.ts +++ b/src/containers/editor/WallpaperEditor/styles/gradient_group.ts @@ -10,16 +10,13 @@ export const Wrapper = styled.div` margin-top: 10px; margin-left: 1px; ` - export const Block = styled.div` - /* ${css.circle(35)}; */ ${css.flex('align-both')}; border-radius: 100%; /* position: relative; */ - border: 2px solid; + border: 1.5px solid; border-color: ${({ $active }) => $active ? theme('thread.articleDigest') : 'transparent'}; - /* padding: ${({ $active }) => ($active ? '3px' : '2px')}; */ padding: 3px; margin-right: 12px; margin-bottom: 10px; diff --git a/src/containers/layout/GlobalLayout/Wallpaper.tsx b/src/containers/layout/GlobalLayout/Wallpaper.tsx index eb72629b7..13fc51bd5 100644 --- a/src/containers/layout/GlobalLayout/Wallpaper.tsx +++ b/src/containers/layout/GlobalLayout/Wallpaper.tsx @@ -1,15 +1,17 @@ import { FC, memo } from 'react' -import { parseWallpaper } from '@/utils/wallpaper' +import type { TWallpaper } from '@/spec' +import { parseWallpaper2 } from '@/utils/wallpaper' import { Wrapper } from './styles/wallpaper' type TProps = { wallpaper: string + wallpapers: Record } -const Wallpaper: FC = ({ wallpaper }) => { - const { background, effect } = parseWallpaper(wallpaper) +const Wallpaper: FC = ({ wallpaper, wallpapers }) => { + const { background, effect } = parseWallpaper2(wallpapers, wallpaper) // for custom image/svg // for use style object not passing props diff --git a/src/containers/layout/GlobalLayout/index.tsx b/src/containers/layout/GlobalLayout/index.tsx index 3f36235c0..85342bd6d 100755 --- a/src/containers/layout/GlobalLayout/index.tsx +++ b/src/containers/layout/GlobalLayout/index.tsx @@ -56,11 +56,11 @@ const GlobalLayoutContainer: FC = ({ // load debug graph useInit(store, { isMobile }) - const { accountInfo, sidebarPin, curCommunity, wallpaper } = store + const { accountInfo, sidebarPin, curCommunity, wallpaper, wallpapers } = store return ( - + diff --git a/src/containers/layout/GlobalLayout/store.ts b/src/containers/layout/GlobalLayout/store.ts index f114f7328..b6cd07097 100755 --- a/src/containers/layout/GlobalLayout/store.ts +++ b/src/containers/layout/GlobalLayout/store.ts @@ -5,7 +5,13 @@ import { types as T, getParent, Instance } from 'mobx-state-tree' -import type { TRootStore, TAccount, TC11N, TCommunity } from '@/spec' +import type { + TRootStore, + TAccount, + TC11N, + TCommunity, + TWallpaper, +} from '@/spec' import { markStates, toJS } from '@/utils/mobx' const Platform = T.model('Platform', { @@ -45,6 +51,10 @@ const GlobalLayout = T.model('GlobalLayoutStore', { const root = getParent(self) as TRootStore return root.wallpaperEditor.wallpaper }, + get wallpapers(): Record { + const root = getParent(self) as TRootStore + return root.wallpaperEditor.wallpapers + }, })) .actions((self) => ({ toast(type, options): void { diff --git a/src/spec/wallpaper.d.ts b/src/spec/wallpaper.d.ts index 388b2b881..27bf475cf 100644 --- a/src/spec/wallpaper.d.ts +++ b/src/spec/wallpaper.d.ts @@ -13,9 +13,7 @@ export type TWallpaperGradient = { export type TWallpaperPic = { bgImage?: string bgColor?: string - bgSize?: 'contain' | 'cover' | 'auto' - // for ts check - colors?: string[] + bgSize?: string // 'contain' | 'cover' | 'auto' } -export type TWallpaper = TWallpaperGradient | TWallpaperPic +export type TWallpaper = TWallpaperGradient & TWallpaperPic diff --git a/utils/wallpaper.ts b/utils/wallpaper.ts index 56809e3f3..5323773aa 100644 --- a/utils/wallpaper.ts +++ b/utils/wallpaper.ts @@ -13,7 +13,12 @@ export const parseWallpaper = (name: string): TWallpaperFmt => { return _parseWallpaper(WALLPAPER[name]) } -export const holder = 1 +export const parseWallpaper2 = ( + wallpapers: Record, + name: string, +): TWallpaperFmt => { + return _parseWallpaper(wallpapers[name]) +} /** * parse wallpaper both for gradient and picture background From 9e77dede0ffd00bae546258129c9e60c915d772c Mon Sep 17 00:00:00 2001 From: mydearxym Date: Fri, 20 May 2022 20:17:59 +0800 Subject: [PATCH 12/22] feat(wallpaper): add toggle pattern effect --- .../editor/WallpaperEditor/index.tsx | 41 +++++++++++++------ .../editor/WallpaperEditor/logic.ts | 7 ++++ .../WallpaperEditor/styles/gradient_group.ts | 2 +- .../editor/WallpaperEditor/styles/index.ts | 15 ++++++- src/widgets/Checker/styles/index.ts | 10 +++-- 5 files changed, 57 insertions(+), 18 deletions(-) diff --git a/src/containers/editor/WallpaperEditor/index.tsx b/src/containers/editor/WallpaperEditor/index.tsx index 2415143e2..8d65e8f61 100644 --- a/src/containers/editor/WallpaperEditor/index.tsx +++ b/src/containers/editor/WallpaperEditor/index.tsx @@ -9,6 +9,8 @@ import { FC } from 'react' import { bond } from '@/utils/mobx' import { VIEW, DRAWER_SCROLLER } from '@/constant' +import { Br } from '@/widgets/Common' +import Checker from '@/widgets/Checker' import { Tabs } from '@/widgets/Switcher' import CustomScroller from '@/widgets/CustomScroller' import Button from '@/widgets/Buttons/Button' @@ -18,9 +20,18 @@ import type { TStore } from './store' import PicGroup from './PicGroup' import GradientGroup from './GradientGroup' -import { Wrapper, Banner, BannerTitle, Content, Title, Footer } from './styles' +import { + Wrapper, + Banner, + BannerTitle, + Content, + Title, + SettingWrapper, + Footer, + ConfirmBtn, +} from './styles' -import { useInit } from './logic' /* eslint-disable-next-line */ +import { useInit, togglePattern } from './logic' const TAB_OPTIONS = [ { @@ -45,9 +56,8 @@ const WallpaperEditorContainer: FC = ({ testid = 'wallpaper-editor', }) => { useInit(store) - const { wallpaper, gradientWallpapers, patternWallpapers } = store - - console.log('>> gradientWallpapers---> ', gradientWallpapers) + const { wallpaper, gradientWallpapers, patternWallpapers, hasPattern } = store + console.log('bbb hasPattern -> ', hasPattern) return ( @@ -67,7 +77,7 @@ const WallpaperEditorContainer: FC = ({ instanceKey={DRAWER_SCROLLER} direction="vertical" height="calc(100vh - 226px)" - barSize="medium" + barSize="small" showShadow={false} autoHide={false} > @@ -77,23 +87,30 @@ const WallpaperEditorContainer: FC = ({ wallpaper={wallpaper} patternWallpapers={patternWallpapers} /> -
+
纯色渐变: -
-
-
叠加花纹
-
模糊效果
+
+ 附加效果: + +
+ + 叠加花纹 + +
+ 模糊效果 +
+
- + 确定
) diff --git a/src/containers/editor/WallpaperEditor/logic.ts b/src/containers/editor/WallpaperEditor/logic.ts index dafbdc4bd..04d1c6330 100644 --- a/src/containers/editor/WallpaperEditor/logic.ts +++ b/src/containers/editor/WallpaperEditor/logic.ts @@ -15,6 +15,13 @@ export const setWallpaper = (wallpaper: string): void => { store.mark({ wallpaper }) } +/** + * toggle pattern mark only for gradient backgrounds + */ +export const togglePattern = (hasPattern: boolean): void => { + store.mark({ hasPattern }) +} + // ############################### // init & uninit handlers // ############################### diff --git a/src/containers/editor/WallpaperEditor/styles/gradient_group.ts b/src/containers/editor/WallpaperEditor/styles/gradient_group.ts index 55ab2e482..4363bacb2 100644 --- a/src/containers/editor/WallpaperEditor/styles/gradient_group.ts +++ b/src/containers/editor/WallpaperEditor/styles/gradient_group.ts @@ -14,7 +14,7 @@ export const Block = styled.div` ${css.flex('align-both')}; border-radius: 100%; /* position: relative; */ - border: 1.5px solid; + border: 1px solid; border-color: ${({ $active }) => $active ? theme('thread.articleDigest') : 'transparent'}; padding: 3px; diff --git a/src/containers/editor/WallpaperEditor/styles/index.ts b/src/containers/editor/WallpaperEditor/styles/index.ts index 59a157dce..5630c4da4 100644 --- a/src/containers/editor/WallpaperEditor/styles/index.ts +++ b/src/containers/editor/WallpaperEditor/styles/index.ts @@ -3,6 +3,8 @@ import styled from 'styled-components' import type { TTestable } from '@/spec' import css, { theme } from '@/utils/css' +import Button from '@/widgets/Buttons/Button' + export const Wrapper = styled.div.attrs(({ testid }: TTestable) => ({ 'data-test-id': testid, }))` @@ -39,11 +41,22 @@ export const Content = styled.div` overflow-y: scroll; overflow-x: hidden; ` +export const SettingWrapper = styled.div` + margin-left: 3px; +` export const Footer = styled.div` ${css.flex('align-center', 'justify-between')}; width: 100%; padding: 0 30px; position: absolute; - bottom: 18px; + bottom: 0; left: 0; + border-top: 1px solid; + border-top-color: ${theme('border')}; + height: 65px; +` +export const ConfirmBtn = styled(Button)` + padding-left: 12px; + padding-right: 12px; + height: 28px; ` diff --git a/src/widgets/Checker/styles/index.ts b/src/widgets/Checker/styles/index.ts index fdddaaa6b..4e12fecd7 100755 --- a/src/widgets/Checker/styles/index.ts +++ b/src/widgets/Checker/styles/index.ts @@ -22,21 +22,23 @@ export const Wrapper = styled.div` ` export const IconWrapper = styled.div` position: relative; - background: ${({ checked }) => (checked ? '#0d3d4e' : '#0b2631')}; + background: ${({ checked }) => + checked ? theme('thread.articleDigest') : 'transparent'}; width: ${({ size }) => getIconSize(size)}; height: ${({ size }) => getIconSize(size)}; ${css.flex('align-both')}; border: ${({ disabled }) => (!disabled ? '1px solid' : 'none')}; - border-color: ${({ checked }) => (checked ? '#246b8c' : '#1c5975')}; + border-color: ${({ checked }) => + checked ? theme('thread.articleTitle') : theme('thread.articleDigest')}; border-radius: ${({ size }) => getBorderRadius(size)}; transition: all 0.2s; ` export const CheckIcon = styled(CheckedSVG)` position: absolute; - fill: #327faf; + fill: ${({ checked }) => (checked ? 'white' : 'none')}; display: ${({ checked }) => (checked ? 'block' : 'none')}; width: ${({ size }) => getIconSize(size)}; height: ${({ size }) => getIconSize(size)}; @@ -48,7 +50,7 @@ export const ChildWrapper = styled.div` color: ${({ checked }) => checked ? theme('thread.articleTitle') : theme('thread.articleDigest')}; font-size: ${({ size }) => getFontSize(size)}; - margin-left: 6px; + margin-left: 8px; cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')}; &:hover { From 98f82e25b6106421e7212e9cf6d946015f60130f Mon Sep 17 00:00:00 2001 From: mydearxym Date: Fri, 20 May 2022 22:06:21 +0800 Subject: [PATCH 13/22] feat(wallpaper): add toggle blur & condition checker --- .../editor/WallpaperEditor/GradientGroup.tsx | 8 ++--- .../editor/WallpaperEditor/PicGroup.tsx | 4 +-- .../editor/WallpaperEditor/index.tsx | 33 +++++++++++++------ .../editor/WallpaperEditor/logic.ts | 4 +++ .../editor/WallpaperEditor/store.ts | 30 +++++++++++++++-- .../layout/GlobalLayout/Wallpaper.tsx | 4 +-- src/spec/index.ts | 1 + src/spec/wallpaper.d.ts | 5 ++- utils/constant/index.ts | 7 +++- utils/constant/wallpaper.ts | 8 ++++- utils/wallpaper.ts | 26 ++++++++++----- 11 files changed, 97 insertions(+), 33 deletions(-) diff --git a/src/containers/editor/WallpaperEditor/GradientGroup.tsx b/src/containers/editor/WallpaperEditor/GradientGroup.tsx index 809c25dfa..343c74806 100644 --- a/src/containers/editor/WallpaperEditor/GradientGroup.tsx +++ b/src/containers/editor/WallpaperEditor/GradientGroup.tsx @@ -1,8 +1,8 @@ import { FC, memo } from 'react' import { keys } from 'ramda' -import type { TWallpaper } from '@/spec' -import { parseWallpaper2 } from '@/utils/wallpaper' +import type { TWallpaperGradient } from '@/spec' +import { parseWallpaper } from '@/utils/wallpaper' import { Wrapper, Block, ColorBall } from './styles/gradient_group' @@ -10,7 +10,7 @@ import { setWallpaper } from './logic' type TProps = { wallpaper: string - gradientWallpapers: Record + gradientWallpapers: Record } const PicGroup: FC = ({ wallpaper, gradientWallpapers }) => { @@ -25,7 +25,7 @@ const PicGroup: FC = ({ wallpaper, gradientWallpapers }) => { onClick={() => setWallpaper(name)} > ))} diff --git a/src/containers/editor/WallpaperEditor/PicGroup.tsx b/src/containers/editor/WallpaperEditor/PicGroup.tsx index edc88748f..fffa467a9 100644 --- a/src/containers/editor/WallpaperEditor/PicGroup.tsx +++ b/src/containers/editor/WallpaperEditor/PicGroup.tsx @@ -1,7 +1,7 @@ import { FC, memo } from 'react' import { keys } from 'ramda' -import type { TWallpaper } from '@/spec' +import type { TWallpaperPic } from '@/spec' import { Wrapper, @@ -15,7 +15,7 @@ import { setWallpaper } from './logic' type TProps = { wallpaper: string - patternWallpapers: Record + patternWallpapers: Record } const PicGroup: FC = ({ wallpaper, patternWallpapers }) => { diff --git a/src/containers/editor/WallpaperEditor/index.tsx b/src/containers/editor/WallpaperEditor/index.tsx index 8d65e8f61..1a61081bb 100644 --- a/src/containers/editor/WallpaperEditor/index.tsx +++ b/src/containers/editor/WallpaperEditor/index.tsx @@ -3,11 +3,11 @@ * */ -import { FC } from 'react' +import { FC, Fragment } from 'react' // import { buildLog } from '@/utils/logger' import { bond } from '@/utils/mobx' -import { VIEW, DRAWER_SCROLLER } from '@/constant' +import { VIEW, DRAWER_SCROLLER, WALLPAPER_TYPE } from '@/constant' import { Br } from '@/widgets/Common' import Checker from '@/widgets/Checker' @@ -31,7 +31,7 @@ import { ConfirmBtn, } from './styles' -import { useInit, togglePattern } from './logic' +import { useInit, togglePattern, toggleBlur } from './logic' const TAB_OPTIONS = [ { @@ -56,8 +56,14 @@ const WallpaperEditorContainer: FC = ({ testid = 'wallpaper-editor', }) => { useInit(store) - const { wallpaper, gradientWallpapers, patternWallpapers, hasPattern } = store - console.log('bbb hasPattern -> ', hasPattern) + const { + wallpaper, + wallpaperType, + gradientWallpapers, + patternWallpapers, + hasPattern, + hasBlur, + } = store return ( @@ -96,12 +102,19 @@ const WallpaperEditorContainer: FC = ({
附加效果: -
- - 叠加花纹 - + {wallpaperType === WALLPAPER_TYPE.GRADIENT && ( + +
+ + 叠加印纹 + +
+ )} +
- 模糊效果 + + 模糊效果 +
diff --git a/src/containers/editor/WallpaperEditor/logic.ts b/src/containers/editor/WallpaperEditor/logic.ts index 04d1c6330..555e63410 100644 --- a/src/containers/editor/WallpaperEditor/logic.ts +++ b/src/containers/editor/WallpaperEditor/logic.ts @@ -22,6 +22,10 @@ export const togglePattern = (hasPattern: boolean): void => { store.mark({ hasPattern }) } +export const toggleBlur = (hasBlur: boolean): void => { + store.mark({ hasBlur }) +} + // ############################### // init & uninit handlers // ############################### diff --git a/src/containers/editor/WallpaperEditor/store.ts b/src/containers/editor/WallpaperEditor/store.ts index b1a690163..259d4ebd0 100644 --- a/src/containers/editor/WallpaperEditor/store.ts +++ b/src/containers/editor/WallpaperEditor/store.ts @@ -6,9 +6,17 @@ import { types as T, getParent, Instance } from 'mobx-state-tree' import { keys, clone, forEach } from 'ramda' import { GRADIENT_WALLPAPER, PATTERN_WALLPAPER } from '@/constant' -import type { TCommunity, TRootStore, TWallpaper } from '@/spec' +import type { + TCommunity, + TRootStore, + TWallpaper, + TWallpaperType, + TWallpaperGradient, + TWallpaperPic, +} from '@/spec' import { buildLog } from '@/utils/logger' import { markStates, toJS } from '@/utils/mobx' +import { getWallpaperType } from '@/utils/wallpaper' /* eslint-disable-next-line */ const log = buildLog('S:WallpaperEditor') @@ -29,7 +37,16 @@ const WallpaperEditor = T.model('WallpaperEditor', { }, get patternWallpapers(): Record { - return PATTERN_WALLPAPER + const slf = self as TStore + const wallpapers = clone(PATTERN_WALLPAPER) + const paperKeys = keys(PATTERN_WALLPAPER) + + forEach((key) => { + const wallpaperObj = wallpapers[key] as TWallpaperPic + wallpaperObj.hasBlur = slf.hasBlur + }, paperKeys) + + return wallpapers }, get gradientWallpapers(): Record { @@ -38,7 +55,10 @@ const WallpaperEditor = T.model('WallpaperEditor', { const paperKeys = keys(GRADIENT_WALLPAPER) forEach((key) => { - wallpapers[key].hasPattern = slf.hasPattern + const wallpaperObj = wallpapers[key] as TWallpaperGradient + + wallpaperObj.hasPattern = slf.hasPattern + wallpaperObj.hasBlur = slf.hasBlur }, paperKeys) return wallpapers @@ -52,6 +72,10 @@ const WallpaperEditor = T.model('WallpaperEditor', { ...slf.patternWallpapers, } }, + get wallpaperType(): TWallpaperType { + const slf = self as TStore + return getWallpaperType(slf.wallpaper) + }, })) .actions((self) => ({ mark(sobj: Record): void { diff --git a/src/containers/layout/GlobalLayout/Wallpaper.tsx b/src/containers/layout/GlobalLayout/Wallpaper.tsx index 13fc51bd5..32b1969cd 100644 --- a/src/containers/layout/GlobalLayout/Wallpaper.tsx +++ b/src/containers/layout/GlobalLayout/Wallpaper.tsx @@ -1,7 +1,7 @@ import { FC, memo } from 'react' import type { TWallpaper } from '@/spec' -import { parseWallpaper2 } from '@/utils/wallpaper' +import { parseWallpaper } from '@/utils/wallpaper' import { Wrapper } from './styles/wallpaper' @@ -11,7 +11,7 @@ type TProps = { } const Wallpaper: FC = ({ wallpaper, wallpapers }) => { - const { background, effect } = parseWallpaper2(wallpapers, wallpaper) + const { background, effect } = parseWallpaper(wallpapers, wallpaper) // for custom image/svg // for use style object not passing props diff --git a/src/spec/index.ts b/src/spec/index.ts index 8354b1d14..af0ae31c4 100644 --- a/src/spec/index.ts +++ b/src/spec/index.ts @@ -136,6 +136,7 @@ export type { TWallpaperGradient, TWallpaperFmt, TWallpaper, + TWallpaperType, } from './wallpaper' export type TRoute = { diff --git a/src/spec/wallpaper.d.ts b/src/spec/wallpaper.d.ts index 27bf475cf..ded65d34b 100644 --- a/src/spec/wallpaper.d.ts +++ b/src/spec/wallpaper.d.ts @@ -14,6 +14,9 @@ export type TWallpaperPic = { bgImage?: string bgColor?: string bgSize?: string // 'contain' | 'cover' | 'auto' + hasBlur?: boolean } -export type TWallpaper = TWallpaperGradient & TWallpaperPic +export type TWallpaper = TWallpaperGradient | TWallpaperPic + +export type TWallpaperType = 'pattern' | 'gradient' | 'custom' diff --git a/utils/constant/index.ts b/utils/constant/index.ts index 5c472603f..e94ae04e6 100755 --- a/utils/constant/index.ts +++ b/utils/constant/index.ts @@ -36,7 +36,12 @@ export { AS_STATE, AS_TYPE } from './article_state' export { default as DEFAULT_TOAST_OPTIONS } from './toast' -export { PATTERN_WALLPAPER, GRADIENT_WALLPAPER, WALLPAPER } from './wallpaper' +export { + PATTERN_WALLPAPER, + GRADIENT_WALLPAPER, + WALLPAPER, + WALLPAPER_TYPE, +} from './wallpaper' /* some svg icon are sensitive to fill color */ /* some community svg need fill color, like city etc.. */ export const NON_FILL_COMMUNITY = ['javascript'] diff --git a/utils/constant/wallpaper.ts b/utils/constant/wallpaper.ts index 4e5f5c2f9..e437693fe 100644 --- a/utils/constant/wallpaper.ts +++ b/utils/constant/wallpaper.ts @@ -1,7 +1,13 @@ -import type { TWallpaper } from '@/spec' +import type { TWallpaper, TWallpaperType } from '@/spec' const DIR = '/wallpaper' +export const WALLPAPER_TYPE = { + PATTERN: 'pattern', + GRADIENT: 'gradient', + CUSTOM: 'custom', +} as Record, TWallpaperType> + export const PATTERN_WALLPAPER = { // bubbles: { // bgImage: `${DIR}/bubbles.png`, diff --git a/utils/wallpaper.ts b/utils/wallpaper.ts index 5323773aa..a3c5e9036 100644 --- a/utils/wallpaper.ts +++ b/utils/wallpaper.ts @@ -1,30 +1,37 @@ -import { WALLPAPER } from '@/constant' +import { keys, includes } from 'ramda' +import { PATTERN_WALLPAPER, WALLPAPER_TYPE } from '@/constant' + import type { TWallpaperFmt, TWallpaperGradient, TWallpaperPic, TWallpaper, + TWallpaperType, } from '@/spec' /** * parse wallpaper both for gradient and picture background */ -export const parseWallpaper = (name: string): TWallpaperFmt => { - return _parseWallpaper(WALLPAPER[name]) -} - -export const parseWallpaper2 = ( +export const parseWallpaper = ( wallpapers: Record, name: string, ): TWallpaperFmt => { return _parseWallpaper(wallpapers[name]) } +export const getWallpaperType = (name: string): TWallpaperType => { + if (includes(name, keys(PATTERN_WALLPAPER))) { + return WALLPAPER_TYPE.PATTERN + } + return WALLPAPER_TYPE.GRADIENT +} + /** * parse wallpaper both for gradient and picture background */ const _parseWallpaper = (wallpaper: TWallpaper): TWallpaperFmt => { - return wallpaper.colors + // @ts-ignore + return wallpaper?.colors ? _parseGradientBackground(wallpaper) : _parsePicBackground(wallpaper) } @@ -50,10 +57,11 @@ const _parseGradientBackground = ( } const _parsePicBackground = (pic: TWallpaperPic): TWallpaperFmt => { - const { bgImage, bgColor = '', bgSize = 'contain' } = pic + const { bgImage, bgColor = '', bgSize = 'contain', hasBlur } = pic const background = `url(${bgImage})` - const effect = `background-color: ${bgColor}; background-size: ${bgSize} !important;` + const blur = hasBlur ? 'filter: blur(3px)' : '' + const effect = `background-color: ${bgColor}; background-size: ${bgSize} !important; ${blur}` return { effect, From c2248359b1e88cbc473c22b40ebaadc63a5282ef Mon Sep 17 00:00:00 2001 From: mydearxym Date: Fri, 20 May 2022 22:31:23 +0800 Subject: [PATCH 14/22] refactor(wallpaper): adjust select effect & button slim --- .../editor/WallpaperEditor/GradientGroup.tsx | 1 + .../editor/WallpaperEditor/index.tsx | 4 +++- .../WallpaperEditor/styles/gradient_group.ts | 22 ++++++++++++++----- .../editor/WallpaperEditor/styles/index.ts | 2 -- src/widgets/Buttons/styles/button.ts | 2 ++ 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/containers/editor/WallpaperEditor/GradientGroup.tsx b/src/containers/editor/WallpaperEditor/GradientGroup.tsx index 343c74806..3b9963578 100644 --- a/src/containers/editor/WallpaperEditor/GradientGroup.tsx +++ b/src/containers/editor/WallpaperEditor/GradientGroup.tsx @@ -25,6 +25,7 @@ const PicGroup: FC = ({ wallpaper, gradientWallpapers }) => { onClick={() => setWallpaper(name)} > diff --git a/src/containers/editor/WallpaperEditor/index.tsx b/src/containers/editor/WallpaperEditor/index.tsx index 1a61081bb..5115877fc 100644 --- a/src/containers/editor/WallpaperEditor/index.tsx +++ b/src/containers/editor/WallpaperEditor/index.tsx @@ -123,7 +123,9 @@ const WallpaperEditorContainer: FC = ({ - 确定 + + 确定 +
) diff --git a/src/containers/editor/WallpaperEditor/styles/gradient_group.ts b/src/containers/editor/WallpaperEditor/styles/gradient_group.ts index 4363bacb2..b02ea205a 100644 --- a/src/containers/editor/WallpaperEditor/styles/gradient_group.ts +++ b/src/containers/editor/WallpaperEditor/styles/gradient_group.ts @@ -1,7 +1,7 @@ import styled from 'styled-components' import type { TActive } from '@/spec' -import css, { theme } from '@/utils/css' +import css, { animate, theme } from '@/utils/css' export const Wrapper = styled.div` ${css.flex()}; @@ -16,22 +16,34 @@ export const Block = styled.div` /* position: relative; */ border: 1px solid; border-color: ${({ $active }) => - $active ? theme('thread.articleDigest') : 'transparent'}; + $active ? theme('thread.articleTitle') : 'transparent'}; padding: 3px; - margin-right: 12px; + background: ${({ $active }) => ($active ? theme('border') : 'transparent')}; + + margin-right: ${({ $active }) => ($active ? '13px' : '12px')}; margin-bottom: 10px; &:hover { border-color: ${theme('thread.articleTitle')}; + background: ${theme('border')}; cursor: pointer; } - transition: border-color 0.2s linear; + transition: all 0.1s linear; ` -export const ColorBall = styled.div<{ background: string }>` +type TColorBall = { background: string } & TActive +export const ColorBall = styled.div` ${css.circle(30)}; + ${({ $active }) => ($active ? css.circle(28) : css.circle(30))}; + background: ${({ background }) => background || 'transparent'}; background-size: 200px; + + &:active { + animation: ${animate.breath} 2s linear; + } + + transition: all 0.1s linear; ` export const ActiveSign = styled.div` ${css.size(24)}; diff --git a/src/containers/editor/WallpaperEditor/styles/index.ts b/src/containers/editor/WallpaperEditor/styles/index.ts index 5630c4da4..cc9388b20 100644 --- a/src/containers/editor/WallpaperEditor/styles/index.ts +++ b/src/containers/editor/WallpaperEditor/styles/index.ts @@ -56,7 +56,5 @@ export const Footer = styled.div` height: 65px; ` export const ConfirmBtn = styled(Button)` - padding-left: 12px; - padding-right: 12px; height: 28px; ` diff --git a/src/widgets/Buttons/styles/button.ts b/src/widgets/Buttons/styles/button.ts index e672d1024..999c3afe7 100644 --- a/src/widgets/Buttons/styles/button.ts +++ b/src/widgets/Buttons/styles/button.ts @@ -17,6 +17,8 @@ export const Wrapper = styled.button` ${css.flex('align-both')}; -webkit-appearance: button; outline: none; + // otherwise the slim effect will appear outside + overflow: hidden; line-height: 1.5; text-align: center; From 1976a81f2da6833624a8125c7c784060cac368d1 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Fri, 20 May 2022 22:45:15 +0800 Subject: [PATCH 15/22] refactor(wallpaper): adjust block select effect --- .../editor/WallpaperEditor/GradientGroup.tsx | 19 ++++++++++--------- .../WallpaperEditor/styles/gradient_group.ts | 13 ++++++------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/containers/editor/WallpaperEditor/GradientGroup.tsx b/src/containers/editor/WallpaperEditor/GradientGroup.tsx index 3b9963578..a16dc6de5 100644 --- a/src/containers/editor/WallpaperEditor/GradientGroup.tsx +++ b/src/containers/editor/WallpaperEditor/GradientGroup.tsx @@ -4,7 +4,7 @@ import { keys } from 'ramda' import type { TWallpaperGradient } from '@/spec' import { parseWallpaper } from '@/utils/wallpaper' -import { Wrapper, Block, ColorBall } from './styles/gradient_group' +import { Wrapper, Block, BallWrapper, ColorBall } from './styles/gradient_group' import { setWallpaper } from './logic' @@ -19,15 +19,16 @@ const PicGroup: FC = ({ wallpaper, gradientWallpapers }) => { return ( {gradientKeys.map((name) => ( - setWallpaper(name)} - > - + + onClick={() => setWallpaper(name)} + > + + ))} diff --git a/src/containers/editor/WallpaperEditor/styles/gradient_group.ts b/src/containers/editor/WallpaperEditor/styles/gradient_group.ts index b02ea205a..980a6047b 100644 --- a/src/containers/editor/WallpaperEditor/styles/gradient_group.ts +++ b/src/containers/editor/WallpaperEditor/styles/gradient_group.ts @@ -8,23 +8,22 @@ export const Wrapper = styled.div` width: calc(100% + 30px); flex-wrap: wrap; margin-top: 10px; - margin-left: 1px; ` -export const Block = styled.div` +export const Block = styled.div` + margin-right: 12px; +` +export const BallWrapper = styled.div` + ${css.size(36)}; ${css.flex('align-both')}; border-radius: 100%; - /* position: relative; */ - border: 1px solid; + border: 1.5px solid; border-color: ${({ $active }) => $active ? theme('thread.articleTitle') : 'transparent'}; padding: 3px; background: ${({ $active }) => ($active ? theme('border') : 'transparent')}; - - margin-right: ${({ $active }) => ($active ? '13px' : '12px')}; margin-bottom: 10px; &:hover { - border-color: ${theme('thread.articleTitle')}; background: ${theme('border')}; cursor: pointer; } From 5b128c18c2969fad95c995209de613bfb6519398 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Sat, 21 May 2022 09:46:32 +0800 Subject: [PATCH 16/22] refactor(wallpaper-editor): add some light animation --- src/containers/editor/WallpaperEditor/styles/pic_group.ts | 4 +++- src/containers/layout/GlobalLayout/styles/wallpaper.ts | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/containers/editor/WallpaperEditor/styles/pic_group.ts b/src/containers/editor/WallpaperEditor/styles/pic_group.ts index 992dfdaf6..33f141291 100644 --- a/src/containers/editor/WallpaperEditor/styles/pic_group.ts +++ b/src/containers/editor/WallpaperEditor/styles/pic_group.ts @@ -22,13 +22,15 @@ export const Block = styled.div` border: 2px solid; border-color: ${({ $active }) => $active ? theme('thread.articleTitle') : 'transparent'}; + opacity: ${({ $active }) => ($active ? 1 : 0.85)}; &:hover { border-color: ${theme('thread.articleTitle')}; cursor: pointer; + opacity: 0.85; } - transition: border-color 0.1s linear; + transition: all 0.2s linear; ` export const Image = styled(Img)` width: 100%; diff --git a/src/containers/layout/GlobalLayout/styles/wallpaper.ts b/src/containers/layout/GlobalLayout/styles/wallpaper.ts index bb898bcf8..4a1e69e12 100644 --- a/src/containers/layout/GlobalLayout/styles/wallpaper.ts +++ b/src/containers/layout/GlobalLayout/styles/wallpaper.ts @@ -10,6 +10,7 @@ export const Wrapper = styled.div<{ effect: string }>` /* see https://www.zhangxinxu.com/wordpress/2015/11/css3-will-change-improve-paint/ */ will-change: transform; ${({ effect }) => effect || ''}; + transition: all 0.25s; ` export const holder = 1 From e2b34840f8f0e6a3553b1fe9d1e1ad03e7fa5a09 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Sat, 21 May 2022 10:48:18 +0800 Subject: [PATCH 17/22] refactor(wallpaper-editor): re-org modules into tab unit --- .../{ => BuildIn}/GradientGroup.tsx | 11 +- .../PatternGroup.tsx} | 10 +- .../editor/WallpaperEditor/BuildIn/index.tsx | 69 ++++++++++++ .../editor/WallpaperEditor/Custom/index.tsx | 13 +++ .../editor/WallpaperEditor/Footer.tsx | 19 ++++ .../editor/WallpaperEditor/constant.ts | 17 +++ .../editor/WallpaperEditor/index.tsx | 106 ++++-------------- .../editor/WallpaperEditor/logic.ts | 7 +- .../editor/WallpaperEditor/spec.d.ts | 12 ++ .../editor/WallpaperEditor/store.ts | 23 +++- .../styles/{ => build_in}/gradient_group.ts | 0 .../WallpaperEditor/styles/build_in/index.ts | 21 ++++ .../pattern_group.ts} | 0 .../WallpaperEditor/styles/custom/index.ts | 9 ++ .../editor/WallpaperEditor/styles/footer.ts | 20 ++++ .../editor/WallpaperEditor/styles/index.ts | 37 +----- utils/constant/wallpaper.ts | 2 +- 17 files changed, 243 insertions(+), 133 deletions(-) rename src/containers/editor/WallpaperEditor/{ => BuildIn}/GradientGroup.tsx (80%) rename src/containers/editor/WallpaperEditor/{PicGroup.tsx => BuildIn/PatternGroup.tsx} (73%) create mode 100644 src/containers/editor/WallpaperEditor/BuildIn/index.tsx create mode 100644 src/containers/editor/WallpaperEditor/Custom/index.tsx create mode 100644 src/containers/editor/WallpaperEditor/Footer.tsx create mode 100644 src/containers/editor/WallpaperEditor/constant.ts create mode 100644 src/containers/editor/WallpaperEditor/spec.d.ts rename src/containers/editor/WallpaperEditor/styles/{ => build_in}/gradient_group.ts (100%) create mode 100644 src/containers/editor/WallpaperEditor/styles/build_in/index.ts rename src/containers/editor/WallpaperEditor/styles/{pic_group.ts => build_in/pattern_group.ts} (100%) create mode 100644 src/containers/editor/WallpaperEditor/styles/custom/index.ts create mode 100644 src/containers/editor/WallpaperEditor/styles/footer.ts diff --git a/src/containers/editor/WallpaperEditor/GradientGroup.tsx b/src/containers/editor/WallpaperEditor/BuildIn/GradientGroup.tsx similarity index 80% rename from src/containers/editor/WallpaperEditor/GradientGroup.tsx rename to src/containers/editor/WallpaperEditor/BuildIn/GradientGroup.tsx index a16dc6de5..51a9d5e91 100644 --- a/src/containers/editor/WallpaperEditor/GradientGroup.tsx +++ b/src/containers/editor/WallpaperEditor/BuildIn/GradientGroup.tsx @@ -4,9 +4,14 @@ import { keys } from 'ramda' import type { TWallpaperGradient } from '@/spec' import { parseWallpaper } from '@/utils/wallpaper' -import { Wrapper, Block, BallWrapper, ColorBall } from './styles/gradient_group' +import { + Wrapper, + Block, + BallWrapper, + ColorBall, +} from '../styles/build_in/gradient_group' -import { setWallpaper } from './logic' +import { changeWallpaper } from '../logic' type TProps = { wallpaper: string @@ -22,7 +27,7 @@ const PicGroup: FC = ({ wallpaper, gradientWallpapers }) => { setWallpaper(name)} + onClick={() => changeWallpaper(name)} > } -const PicGroup: FC = ({ wallpaper, patternWallpapers }) => { +const PatternGroup: FC = ({ wallpaper, patternWallpapers }) => { const patternKeys = keys(patternWallpapers) return ( @@ -32,7 +32,7 @@ const PicGroup: FC = ({ wallpaper, patternWallpapers }) => { )} setWallpaper(name)} + onClick={() => changeWallpaper(name)} /> ))} @@ -40,4 +40,4 @@ const PicGroup: FC = ({ wallpaper, patternWallpapers }) => { ) } -export default memo(PicGroup) +export default memo(PatternGroup) diff --git a/src/containers/editor/WallpaperEditor/BuildIn/index.tsx b/src/containers/editor/WallpaperEditor/BuildIn/index.tsx new file mode 100644 index 000000000..318233541 --- /dev/null +++ b/src/containers/editor/WallpaperEditor/BuildIn/index.tsx @@ -0,0 +1,69 @@ +/* * + * WallpaperEditor + * + */ + +import { FC, Fragment } from 'react' + +import { WALLPAPER_TYPE } from '@/constant' + +import { Br } from '@/widgets/Common' +import Checker from '@/widgets/Checker' + +import PatternGroup from './PatternGroup' +import GradientGroup from './GradientGroup' + +import type { TWallpaperData } from '../spec' +import { Wrapper, Title, SettingWrapper } from '../styles/build_in' +import { togglePattern, toggleBlur } from '../logic' + +type TProps = { + wallpaperData: TWallpaperData +} + +const BuildIn: FC = ({ wallpaperData }) => { + const { + wallpaper, + wallpaperType, + gradientWallpapers, + patternWallpapers, + hasPattern, + hasBlur, + } = wallpaperData + + return ( + + 图案: + +
+ 纯色渐变: + +
+ 附加效果: + + {wallpaperType === WALLPAPER_TYPE.GRADIENT && ( + +
+ + 叠加印纹 + +
+ )} + +
+ + 模糊效果 + +
+
+
+ ) +} + +export default BuildIn diff --git a/src/containers/editor/WallpaperEditor/Custom/index.tsx b/src/containers/editor/WallpaperEditor/Custom/index.tsx new file mode 100644 index 000000000..72b6cf108 --- /dev/null +++ b/src/containers/editor/WallpaperEditor/Custom/index.tsx @@ -0,0 +1,13 @@ +import { FC, memo } from 'react' + +import { Wrapper } from '../styles/custom' + +const Custom: FC = () => { + return ( + +
Custom
+
+ ) +} + +export default memo(Custom) diff --git a/src/containers/editor/WallpaperEditor/Footer.tsx b/src/containers/editor/WallpaperEditor/Footer.tsx new file mode 100644 index 000000000..dec884555 --- /dev/null +++ b/src/containers/editor/WallpaperEditor/Footer.tsx @@ -0,0 +1,19 @@ +import { FC, memo } from 'react' + +import Button from '@/widgets/Buttons/Button' +import { Wrapper, ConfirmBtn } from './styles/footer' + +const Footer: FC = () => { + return ( + + + + 确定 + + + ) +} + +export default memo(Footer) diff --git a/src/containers/editor/WallpaperEditor/constant.ts b/src/containers/editor/WallpaperEditor/constant.ts new file mode 100644 index 000000000..6b5149838 --- /dev/null +++ b/src/containers/editor/WallpaperEditor/constant.ts @@ -0,0 +1,17 @@ +import type { TTab } from './spec' + +export const TAB = { + BUILDIN: 'buildin', + CUSTOM: 'custom', +} as Record, TTab> + +export const TAB_OPTIONS = [ + { + title: '内置壁纸', + raw: TAB.BUILDIN, + }, + { + title: '上传壁纸', + raw: TAB.CUSTOM, + }, +] diff --git a/src/containers/editor/WallpaperEditor/index.tsx b/src/containers/editor/WallpaperEditor/index.tsx index 5115877fc..0162ce4d7 100644 --- a/src/containers/editor/WallpaperEditor/index.tsx +++ b/src/containers/editor/WallpaperEditor/index.tsx @@ -3,48 +3,23 @@ * */ -import { FC, Fragment } from 'react' +import { FC } from 'react' -// import { buildLog } from '@/utils/logger' import { bond } from '@/utils/mobx' -import { VIEW, DRAWER_SCROLLER, WALLPAPER_TYPE } from '@/constant' +import { VIEW, DRAWER_SCROLLER } from '@/constant' -import { Br } from '@/widgets/Common' -import Checker from '@/widgets/Checker' import { Tabs } from '@/widgets/Switcher' import CustomScroller from '@/widgets/CustomScroller' -import Button from '@/widgets/Buttons/Button' import type { TStore } from './store' +import { TAB, TAB_OPTIONS } from './constant' -import PicGroup from './PicGroup' -import GradientGroup from './GradientGroup' +import BuildIn from './BuildIn' +import Custom from './Custom' +import Footer from './Footer' -import { - Wrapper, - Banner, - BannerTitle, - Content, - Title, - SettingWrapper, - Footer, - ConfirmBtn, -} from './styles' - -import { useInit, togglePattern, toggleBlur } from './logic' - -const TAB_OPTIONS = [ - { - title: '内置壁纸', - raw: 'buildin', - localIcon: 'settings', - }, - { - title: '上传壁纸', - raw: 'custom', - localIcon: 'settings', - }, -] +import { Wrapper, Banner, Title, Content } from './styles' +import { useInit, changeTab } from './logic' type TProps = { wallpaperEditor?: TStore @@ -56,27 +31,18 @@ const WallpaperEditorContainer: FC = ({ testid = 'wallpaper-editor', }) => { useInit(store) - const { - wallpaper, - wallpaperType, - gradientWallpapers, - patternWallpapers, - hasPattern, - hasBlur, - } = store + const { tab, wallpaperData } = store return ( - 壁纸设置 -
- -
+ 壁纸设置 +
= ({ autoHide={false} > - 图案: - -
- 纯色渐变: - -
- 附加效果: - - {wallpaperType === WALLPAPER_TYPE.GRADIENT && ( - -
- - 叠加印纹 - -
- )} - -
- - 模糊效果 - -
-
+ {tab === TAB.BUILDIN && } + {tab === TAB.CUSTOM && }
-
- - - 确定 - -
+