Skip to content
This repository has been archived by the owner on Nov 8, 2022. It is now read-only.

Commit

Permalink
refactor(sidebar): seperate meulist as sort and noral, done beatifully
Browse files Browse the repository at this point in the history
  • Loading branch information
mydearxym committed Aug 25, 2019
1 parent fa7b0e6 commit 87a617f
Show file tree
Hide file tree
Showing 10 changed files with 238 additions and 66 deletions.
20 changes: 18 additions & 2 deletions src/containers/Sidebar/Footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,28 @@ import React from 'react'
// eslint-disable-next-line import/named
import { ICON_CMD } from '@config'

import { Wrapper, InnerWrapper, SettingIcon } from './styles/footer'
import {
Wrapper,
InnerWrapper,
SettingIcon,
OptionWrapper,
OptionItem,
OptionDivider,
} from './styles/footer'

const Footer = ({ pin, showFooterShadow }) => (
import { sortBtnOnClick } from './logic'

const Footer = ({ pin, showFooterShadow, sortOptActive }) => (
<Wrapper pin={pin} dropShadow={showFooterShadow}>
<InnerWrapper pin={pin}>
<SettingIcon src={`${ICON_CMD}/setting.svg`} />
<OptionWrapper pin={pin}>
<OptionItem active={sortOptActive} onClick={() => sortBtnOnClick()}>
排序
</OptionItem>
<OptionDivider />
<OptionItem>分组</OptionItem>
</OptionWrapper>
</InnerWrapper>
</Wrapper>
)
Expand Down
24 changes: 21 additions & 3 deletions src/containers/Sidebar/MenuBar.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import React from 'react'
import R from 'ramda'

// eslint-disable-next-line import/named
import { ICON_CMD } from '@config'
import TrendLine from '@components/TrendLine'
import { uid } from '@utils'

import {
Wrapper,
ActiveBar,
DragIcon,
MenuRow,
MenuItemBar,
MenuItemIcon,
Expand All @@ -16,11 +19,26 @@ import {

import { onCommunitySelect } from './logic'

const MenuBar = ({ pin, item, activeRaw, forceRerender, dropShadow }) => (
const MenuBar = ({
pin,
sortOptActive,
item,
activeRaw,
forceRerender,
dropShadow,
}) => (
<Wrapper onClick={onCommunitySelect.bind(this, item)}>
<ActiveBar pin={pin} active={activeRaw === R.toLower(item.raw)} />
<ActiveBar
pin={pin}
active={!sortOptActive && activeRaw === R.toLower(item.raw)}
/>
<DragIcon src={`${ICON_CMD}/drag.svg`} show={sortOptActive} />
<MenuItemBar dropShadow={dropShadow}>
<MenuRow pin={pin} active={activeRaw === R.toLower(item.raw)}>
<MenuRow
pin={pin}
sortOptActive={sortOptActive}
active={!sortOptActive && activeRaw === R.toLower(item.raw)}
>
<MenuItemIcon
key={uid.gen()}
active={activeRaw === R.toLower(item.raw)}
Expand Down
100 changes: 45 additions & 55 deletions src/containers/Sidebar/MenuList.js
Original file line number Diff line number Diff line change
@@ -1,64 +1,54 @@
import React from 'react'
import R from 'ramda'
import { Waypoint } from 'react-waypoint'
import { SortableContainer, SortableElement } from 'react-sortable-hoc'
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'

import MenuBar from './MenuBar'
import { anchorTop, anchorOffTop, anchorBottom, anchorOffBottom } from './logic'
import { Wrapper, ScrollWrapper } from './styles/menu_list'
import NormalMenuList from './NormalMenuList'
import SortableMenuList from './SortableMenuList'

const SortableMenuBar = SortableElement(
({ pin, item, activeRaw, forceRerender }) => (
<MenuBar
pin={pin}
item={item}
activeRaw={activeRaw}
forceRerender={forceRerender}
/>
)
)
import { Wrapper } from './styles/menu_list'
import { onSortMenuEnd } from './logic'

const MenuList = SortableContainer(
({ items, pin, activeRaw, forceRerender, showHeaderShadow }) => {
const homeCommunities = R.filter(R.propEq('raw', 'home'), items)
const sortableCommunities = R.reject(R.propEq('raw', 'home'), items)
const MenuList = ({
items,
pin,
sortOptActive,
activeRaw,
forceRerender,
showHeaderShadow,
}) => {
const pinedCommunities = R.filter(R.propEq('raw', 'home'), items)
const sortableCommunities = R.reject(R.propEq('raw', 'home'), items)

return (
<Wrapper>
{homeCommunities.map(item => (
<MenuBar
key={item.raw}
pin={pin}
item={item}
activeRaw={activeRaw}
dropShadow={showHeaderShadow}
/>
))}
<OverlayScrollbarsComponent
options={{ scrollbars: { autoHide: 'scroll', autoHideDelay: 200 } }}
className="os-theme-light"
>
<ScrollWrapper>
<React.Fragment>
<Waypoint onEnter={anchorTop} onLeave={anchorOffTop} />
{sortableCommunities.map((item, index) => (
<SortableMenuBar
index={index}
key={item.raw}
pin={pin}
item={item}
activeRaw={activeRaw}
forceRerender={forceRerender}
/>
))}
<Waypoint onEnter={anchorBottom} onLeave={anchorOffBottom} />
</React.Fragment>
</ScrollWrapper>
</OverlayScrollbarsComponent>
</Wrapper>
)
}
)
return (
<Wrapper>
{pinedCommunities.map(item => (
<MenuBar
key={item.raw}
pin={pin}
item={item}
activeRaw={activeRaw}
dropShadow={showHeaderShadow}
/>
))}
{!sortOptActive ? (
<NormalMenuList
communities={sortableCommunities}
pin={pin}
activeRaw={activeRaw}
forceRerender={forceRerender}
/>
) : (
<SortableMenuList
communities={sortableCommunities}
sortOptActive={sortOptActive}
pin={pin}
activeRaw={activeRaw}
forceRerender={forceRerender}
onSortEnd={onSortMenuEnd}
/>
)}
</Wrapper>
)
}

export default MenuList
32 changes: 32 additions & 0 deletions src/containers/Sidebar/NormalMenuList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react'
import { Waypoint } from 'react-waypoint'
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'

import MenuBar from './MenuBar'
import { anchorTop, anchorOffTop, anchorBottom, anchorOffBottom } from './logic'
import { ScrollWrapper } from './styles/menu_list'

const NormalMenuList = ({ communities, pin, activeRaw, forceRerender }) => (
<OverlayScrollbarsComponent
options={{ scrollbars: { autoHide: 'scroll', autoHideDelay: 200 } }}
className="os-theme-light"
>
<ScrollWrapper>
<React.Fragment>
<Waypoint onEnter={anchorTop} onLeave={anchorOffTop} />
{communities.map(item => (
<MenuBar
key={item.raw}
pin={pin}
item={item}
activeRaw={activeRaw}
forceRerender={forceRerender}
/>
))}
<Waypoint onEnter={anchorBottom} onLeave={anchorOffBottom} />
</React.Fragment>
</ScrollWrapper>
</OverlayScrollbarsComponent>
)

export default NormalMenuList
53 changes: 53 additions & 0 deletions src/containers/Sidebar/SortableMenuList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react'
import { Waypoint } from 'react-waypoint'
import { SortableContainer, SortableElement } from 'react-sortable-hoc'
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'

import MenuBar from './MenuBar'
import { anchorTop, anchorOffTop, anchorBottom, anchorOffBottom } from './logic'
import { ScrollWrapper } from './styles/menu_list'

const SortableMenuBar = SortableElement(
({ pin, sortOptActive, item, activeRaw, forceRerender }) => (
<MenuBar
pin={pin}
sortOptActive={sortOptActive}
item={item}
activeRaw={activeRaw}
forceRerender={forceRerender}
/>
)
)

const SortableMenuList = SortableContainer(
({ communities, pin, sortOptActive, activeRaw, forceRerender }) => {
console.log(' sortOptActive --> ', sortOptActive)

return (
<OverlayScrollbarsComponent
options={{ scrollbars: { autoHide: 'scroll', autoHideDelay: 200 } }}
className="os-theme-light"
>
<ScrollWrapper>
<React.Fragment>
<Waypoint onEnter={anchorTop} onLeave={anchorOffTop} />
{communities.map((item, index) => (
<SortableMenuBar
index={index}
key={item.raw}
pin={pin}
sortOptActive={sortOptActive}
item={item}
activeRaw={activeRaw}
forceRerender={forceRerender}
/>
))}
<Waypoint onEnter={anchorBottom} onLeave={anchorOffBottom} />
</React.Fragment>
</ScrollWrapper>
</OverlayScrollbarsComponent>
)
}
)

export default SortableMenuList
8 changes: 7 additions & 1 deletion src/containers/Sidebar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const SidebarContainer = ({ sidebar }) => {
searchCommunityValue,
showHeaderShadow,
showFooterShadow,
sortOptActive,
communitiesData,
forceRerender,
} = sidebar
Expand All @@ -41,13 +42,18 @@ const SidebarContainer = ({ sidebar }) => {
<MenuList
items={communitiesData}
pin={pin}
sortOptActive={sortOptActive}
showHeaderShadow={showHeaderShadow}
forceRerender={forceRerender}
activeRaw={activeRaw}
onSortEnd={onSortMenuEnd}
distance={5}
/>
<Footer pin={pin} showFooterShadow={showFooterShadow} />
<Footer
pin={pin}
showFooterShadow={showFooterShadow}
sortOptActive={sortOptActive}
/>
</Wrapper>
)
}
Expand Down
10 changes: 7 additions & 3 deletions src/containers/Sidebar/logic.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,16 @@ export const onCommunitySelect = community => {
send(EVENT.COMMUNITY_CHANGE)
}

const mapIndexed = R.addIndex(R.map)
export const sortBtnOnClick = () => {
if (!store.sortOptActive) {
store.mark({ pin: true })
}
store.mark({ sortOptActive: !store.sortOptActive })
}

const mapIndexed = R.addIndex(R.map)
export const onSortMenuEnd = ({ oldIndex, newIndex }) => {
const sortedCommunities = arrayMove(store.communitiesData, oldIndex, newIndex)
// TODO: sync to server
setC11N(sortedCommunities)
store.onSortCommunities(sortedCommunities)
}
Expand All @@ -79,7 +84,6 @@ const setC11N = sortedCommunities => {
const { isLogin } = store
if (!isLogin) return store.authWarning()

// TODO: check login
sortedCommunities = R.reject(R.propEq('raw', 'home'), sortedCommunities)
const sidebarCommunitiesIndex = mapIndexed(
(c, index) => ({ community: c.raw, index }),
Expand Down
2 changes: 2 additions & 0 deletions src/containers/Sidebar/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const SidebarStore = t
// add shadow effect to footer when user scroll the communities list
showFooterShadow: t.optional(t.boolean, false),
searchCommunityValue: t.optional(t.string, ''),
// after user click custom sort option in footer
sortOptActive: t.optional(t.boolean, false),

/*
this is a fix for wired svg icon in sidebar
Expand Down
41 changes: 40 additions & 1 deletion src/containers/Sidebar/styles/footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import styled from 'styled-components'
import { theme, cs } from '@utils'
import Img from '@Img'

import { Wrapper as SidebarWrapper } from './index'

export const Wrapper = styled.div`
// margin-bottom: ${({ pin }) => (pin ? '0' : '20px')};
margin-top: -20px;
background: ${theme('sidebar.bg')};
Expand All @@ -19,9 +20,47 @@ export const InnerWrapper = styled.div`
height: 5vh;
color: wheat;
${cs.flex('align-both')};
justify-content: ${({ pin }) => (pin ? 'flex-start' : 'center')};
padding: ${({ pin }) => (pin ? '0 17px' : '')};
${SidebarWrapper}:hover & {
justify-content: flex-start;
padding: 0 17px;
}
`
export const SettingIcon = styled(Img)`
fill: ${theme('sidebar.menuLink')};
width: 16px;
height: 16px;
display: block;
`

export const OptionWrapper = styled.div`
display: ${({ pin }) => (pin ? 'flex' : 'none')};
justify-content: ${({ pin }) => (pin ? 'center' : '')};
width: 100%;
margin-left: -8px;
${SidebarWrapper}:hover & {
display: flex;
justify-content: center;
}
`
export const OptionDivider = styled.div`
border-right: 1px solid;
margin-left: 10px;
margin-right: 10px;
border-right-color: ${theme('sidebar.menuLink')};
opacity: 0.4;
`

export const OptionItem = styled.div`
color: ${({ active }) =>
active ? theme('sidebar.pinActive') : theme('sidebar.menuLink')};
font-weight: ${({ active }) => (active ? 'bold' : 'normal')};
&:hover {
cursor: pointer;
}
`
Loading

0 comments on commit 87a617f

Please sign in to comment.