From 2d2a72502fcb991913f7e9d89863dacd513693f4 Mon Sep 17 00:00:00 2001 From: shixuewen Date: Fri, 15 Mar 2024 16:14:11 +0800 Subject: [PATCH] feat: organize mobile header menu --- .../components/common/button/ColorButton.tsx | 3 +- apps/u3/src/components/explore/HomeLayout.tsx | 26 +- .../components/layout/ListRoutelLayout.tsx | 34 --- apps/u3/src/components/layout/LoginButton.tsx | 130 ---------- apps/u3/src/components/layout/Nav.tsx | 229 ------------------ .../layout/mobile/MobileMainNav.tsx | 16 +- .../components/social/AddPostMobileBtn.tsx | 4 +- .../community/CommunityMobileHeader.tsx | 2 + .../container/explore/ExploreMobileHeader.tsx | 33 ++- .../container/message/MessageMobileHeader.tsx | 10 +- apps/u3/src/route/nav.tsx | 128 ---------- apps/u3/src/route/svgs/bell.svg | 3 - apps/u3/src/route/svgs/bookmark.svg | 10 - apps/u3/src/route/svgs/compass.svg | 4 - apps/u3/src/route/svgs/dapp.svg | 4 - apps/u3/src/route/svgs/heart.svg | 3 - apps/u3/src/route/svgs/home.svg | 5 - apps/u3/src/route/svgs/image.svg | 3 - apps/u3/src/route/svgs/line-chart-up.svg | 3 - apps/u3/src/route/svgs/news.svg | 11 - apps/u3/src/route/svgs/social.svg | 10 - apps/u3/src/route/svgs/user-circle.svg | 3 - apps/u3/src/route/svgs/wallet.svg | 3 - 23 files changed, 54 insertions(+), 623 deletions(-) delete mode 100644 apps/u3/src/components/layout/ListRoutelLayout.tsx delete mode 100644 apps/u3/src/components/layout/LoginButton.tsx delete mode 100644 apps/u3/src/components/layout/Nav.tsx delete mode 100644 apps/u3/src/route/nav.tsx delete mode 100644 apps/u3/src/route/svgs/bell.svg delete mode 100644 apps/u3/src/route/svgs/bookmark.svg delete mode 100644 apps/u3/src/route/svgs/compass.svg delete mode 100644 apps/u3/src/route/svgs/dapp.svg delete mode 100644 apps/u3/src/route/svgs/heart.svg delete mode 100644 apps/u3/src/route/svgs/home.svg delete mode 100644 apps/u3/src/route/svgs/image.svg delete mode 100644 apps/u3/src/route/svgs/line-chart-up.svg delete mode 100644 apps/u3/src/route/svgs/news.svg delete mode 100644 apps/u3/src/route/svgs/social.svg delete mode 100644 apps/u3/src/route/svgs/user-circle.svg delete mode 100644 apps/u3/src/route/svgs/wallet.svg diff --git a/apps/u3/src/components/common/button/ColorButton.tsx b/apps/u3/src/components/common/button/ColorButton.tsx index 7ddfc98c..48ed7018 100644 --- a/apps/u3/src/components/common/button/ColorButton.tsx +++ b/apps/u3/src/components/common/button/ColorButton.tsx @@ -9,7 +9,8 @@ export default function ColorButton({ return ( - )} - - ); -} - -export function LogoutButton({ - onlyIcon, - ...otherProps -}: StyledComponentPropsWithRef<'button'> & { - onlyIcon?: boolean; -}) { - return ( - - ); -} - -const LoginButtonWrapper = styled.div` - width: 100%; - box-sizing: border-box; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 10px; -`; -const Button = styled(ButtonPrimaryLine)<{ onlyIcon?: boolean }>` - width: 100%; - box-sizing: border-box; - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - padding: 12px; - gap: 10px; - isolation: isolate; - transition: all 0.3s ease-out; - ${({ onlyIcon }) => - onlyIcon && - ` - padding: 0; - border: none; - `} -`; -const LoginUser = styled(Button)<{ onlyIcon?: boolean }>` - gap: 4px !important; - padding: 8px 10px !important; - [data-us3r-component='UserAvatar'] { - width: 16px !important; - height: 16px !important; - } - [data-us3r-component='UserName'] { - flex: 1 !important; - text-align: left !important; - font-size: 16px !important; - font-weight: 500 !important; - line-height: 17px !important; - - color: #fff !important; - overflow: hidden !important; - text-overflow: ellipsis !important; - white-space: nowrap !important; - } - ${({ onlyIcon }) => - onlyIcon && - ` - padding: 0px !important; - [data-us3r-component='UserAvatar'] { - width: 40px !important; - height: 40px !important; - } - [data-us3r-component="UserName"] { - flex: 0 !important; - width: 0 !important; - } - `} -`; -const LogoutIconButton = styled.img` - width: 24px; - height: 24px; -`; - -const NoLoginText = styled.span` - font-weight: 500; - font-size: 16px; - color: #ffffff; -`; diff --git a/apps/u3/src/components/layout/Nav.tsx b/apps/u3/src/components/layout/Nav.tsx deleted file mode 100644 index f13ff9b4..00000000 --- a/apps/u3/src/components/layout/Nav.tsx +++ /dev/null @@ -1,229 +0,0 @@ -/* - * @Author: shixuewen friendlysxw@163.com - * @Date: 2022-11-30 18:17:08 - * @LastEditors: bufan bufan@hotmail.com - * @LastEditTime: 2023-10-30 14:54:49 - * @Description: file description - */ -import { ComponentPropsWithRef, useCallback, useRef, useState } from 'react'; -import { useNavigate } from 'react-router-dom'; -import styled from 'styled-components'; -import { isMobile } from 'react-device-detect'; -import useLogin from '../../hooks/shared/useLogin'; -import { CustomNavObject, navs } from '../../route/nav'; -import useRoute from '../../route/useRoute'; -import { cn } from '@/lib/utils'; - -type Props = { - onlyIcon?: boolean; -}; - -export default function Nav({ onlyIcon }: Props) { - const { isLogin, isAdmin } = useLogin(); - const navigate = useNavigate(); - const { firstRouteMeta } = useRoute(); - const [openGroupKeys, setOpenGroupKeys] = useState>([]); - const handleGroupClick = useCallback( - (key: string) => { - if (openGroupKeys.includes(key)) { - setOpenGroupKeys([...openGroupKeys.filter((item) => item !== key)]); - } else { - setOpenGroupKeys([...openGroupKeys, key]); - } - }, - [openGroupKeys, setOpenGroupKeys] - ); - const navItemIsActive = useCallback( - (nav: CustomNavObject) => nav.activeRouteKeys.includes(firstRouteMeta.key), - [firstRouteMeta] - ); - - const groupChidrenInnerEls = useRef(new WeakMap()); - const navItemTextInnerEls = useRef(new WeakMap()); - const renderNavItemText = useCallback( - (nav: CustomNavObject) => { - if (navItemTextInnerEls.current.has(nav)) { - const innerEl = navItemTextInnerEls.current.get(nav); - innerEl.parentElement.style.width = onlyIcon - ? '0px' - : `${innerEl.scrollWidth}px`; - } - return ( - - { - if (el) { - navItemTextInnerEls.current.set(nav, el); - } - }} - > - {nav.name} - - - ); - }, - [onlyIcon] - ); - const renderNavItem = useCallback( - (nav: CustomNavObject) => { - const isActive = navItemIsActive(nav); - return ( - navigate(nav.route.path)} - > - {nav.icon} - {!isMobile && renderNavItemText(nav)} - - ); - }, - [navItemIsActive, onlyIcon] - ); - return ( - - {navs.map((item) => { - if (item?.component) { - return item.component; - } - // feed submit 特殊处理 - if (item.key === 'feed-submit') { - // 未登录不显示 - if (!isLogin) return null; - // 如果不是admin只显示submit content - if (!isAdmin) { - return renderNavItem(item); - } - } - if (item.children) { - const groupIsOpen = openGroupKeys.includes(item.key); - const childrenHasActive = !!item.children.find((nav) => - navItemIsActive(nav) - ); - const groupIsActive = onlyIcon - ? childrenHasActive - : groupIsOpen - ? false - : childrenHasActive; - - if (groupChidrenInnerEls.current.has(item)) { - const innerEl = groupChidrenInnerEls.current.get(item); - innerEl.parentElement.style.height = - onlyIcon || !groupIsOpen ? '0px' : `${innerEl.offsetHeight}px`; - } - return ( - - handleGroupClick(item.key)} - > - - {item.icon} - - {!isMobile && renderNavItemText(item)} - - - { - if (el) { - groupChidrenInnerEls.current.set(item, el); - } - }} - > - {item.children.map((nav) => renderNavItem(nav))} - - - - ); - } - return renderNavItem(item); - })} - - ); -} -export const NavWrapper = styled.div` - width: 100%; - display: flex; - flex-direction: column; - gap: 10px; - transition: all 0.3s ease-out; -`; -export const PcNavItem = styled.div<{ isActive?: boolean; disabled?: boolean }>` - overflow: hidden; - height: 40px; - font-weight: 400; - font-size: 16px; - line-height: 19px; - text-transform: capitalize; - padding: 10px; - border-radius: 10px; - box-sizing: border-box; - display: flex; - align-items: center; - gap: 10px; - cursor: pointer; - background: ${(props) => (props?.isActive ? '#14171A' : 'none')}; - color: ${(props) => (props?.isActive ? '#fff' : '#718096')}; - &:hover { - ${(props) => - !props?.isActive && - ` - background: #14171a; - opacity: 0.8; - `}; - } - transition: all 0.3s ease-out; - ${(props) => - props?.disabled && - ` - opacity: 0.5; - cursor: not-allowed; - `}; -`; -export function NavItemIconBox({ - isActive, - className, - children, - ...props -}: ComponentPropsWithRef<'div'> & { isActive?: boolean }) { - return ( -
- {children} -
- ); -} -export const NavItemIconInner = styled.div<{ isActive?: boolean }>` - width: 100%; - height: 100%; - svg { - width: 100%; - height: 100%; - path { - stroke: ${({ isActive }) => (isActive ? `#fff` : '#718096')}; - transition: all 0.3s ease-out; - } - } -`; -export const PcNavItemTextBox = styled.div` - overflow: hidden; - transition: all 0.5s ease-out; -`; -export const PcNavItemTextInner = styled.div` - white-space: nowrap; -`; -const PcNavGroupBox = styled.div` - max-height: 100vh; - transition: height 1s; -`; -const GroupChildrenBox = styled.div` - overflow: hidden; - transition: all 0.5s ease-out; -`; -const GroupChildrenInner = styled.div``; diff --git a/apps/u3/src/components/layout/mobile/MobileMainNav.tsx b/apps/u3/src/components/layout/mobile/MobileMainNav.tsx index 5664bef6..7671a7da 100644 --- a/apps/u3/src/components/layout/mobile/MobileMainNav.tsx +++ b/apps/u3/src/components/layout/mobile/MobileMainNav.tsx @@ -16,14 +16,12 @@ import NotificationIcon from '../nav-icons/NotificationIcon'; import MessageIcon from '../nav-icons/MessageIcon'; import ExploreIcon from '../nav-icons/ExploreIcon'; import FavIcon from '../nav-icons/FavIcon'; -import useLogin from '@/hooks/shared/useLogin'; export default function MobileMainNav({ className, ...props }: ComponentPropsWithRef<'div'>) { const { firstRouteMeta, lastRouteMeta } = useRoute(); - const { isLogin } = useLogin(); const firstRouteKey = firstRouteMeta?.key; const lastRouteKey = lastRouteMeta?.key; @@ -52,22 +50,22 @@ export default function MobileMainNav({ )} {...props} > - - - Communities - Explore - - - Message + + + Communities Notification + + + Message + Favorites diff --git a/apps/u3/src/components/social/AddPostMobileBtn.tsx b/apps/u3/src/components/social/AddPostMobileBtn.tsx index 7d5bc0e4..7a42ce50 100644 --- a/apps/u3/src/components/social/AddPostMobileBtn.tsx +++ b/apps/u3/src/components/social/AddPostMobileBtn.tsx @@ -9,7 +9,7 @@ export default function AddPostMobileBtn() { return ( <> { if (!isLogin) { login(); @@ -18,7 +18,7 @@ export default function AddPostMobileBtn() { setOpen(true); }} > - Post + +
+
diff --git a/apps/u3/src/container/explore/ExploreMobileHeader.tsx b/apps/u3/src/container/explore/ExploreMobileHeader.tsx index 9c67772e..246ef07b 100644 --- a/apps/u3/src/container/explore/ExploreMobileHeader.tsx +++ b/apps/u3/src/container/explore/ExploreMobileHeader.tsx @@ -13,18 +13,18 @@ import { MobileHeaderWrapper, } from '@/components/layout/mobile/MobileHeaderCommon'; import SearchIconBtn from '@/components/layout/SearchIconBtn'; -import ColorButton from '@/components/common/button/ColorButton'; +import LoginButtonV2Mobile from '@/components/layout/LoginButtonV2Mobile'; export default function ExploreMobileHeader( props: ComponentPropsWithRef<'div'> ) { - const navigate = useNavigate(); const { pathname } = useLocation(); const isHomePath = pathname === '/'; const isCommunitiesPath = pathname.startsWith('/communities'); const isPosterGalleryPath = pathname === '/poster-gallery'; const isCasterDailyPath = pathname === '/caster-daily'; const isPostsPath = pathname.startsWith('/social'); + const isPostDetailPath = pathname.startsWith('/social/post-detail'); return ( @@ -32,21 +32,10 @@ export default function ExploreMobileHeader( if (isHomePath) { return ( <> -
navigate('/')} - > - Explore -
+
Explore
- { - navigate('/caster-daily'); - }} - > - Mint - +
); @@ -54,9 +43,13 @@ export default function ExploreMobileHeader( if (isCommunitiesPath) { return ( <> - +
+ Communities +
+ {/* */}
+
); @@ -70,11 +63,15 @@ export default function ExploreMobileHeader( if (isPostsPath) { return ( <> - +
- +
+ ); } diff --git a/apps/u3/src/container/message/MessageMobileHeader.tsx b/apps/u3/src/container/message/MessageMobileHeader.tsx index d67e50b5..2ec95131 100644 --- a/apps/u3/src/container/message/MessageMobileHeader.tsx +++ b/apps/u3/src/container/message/MessageMobileHeader.tsx @@ -12,6 +12,8 @@ import { } from '@/components/layout/mobile/MobileHeaderCommon'; import { MessageRoute, useXmtpClient } from '@/contexts/message/XmtpClientCtx'; import ProfileInfoHeadless from '@/components/profile/info/ProfileInfoHeadless'; +import LoginButtonV2Mobile from '@/components/layout/LoginButtonV2Mobile'; +import SearchIconBtn from '@/components/layout/SearchIconBtn'; export default function MessageMobileHeader( props: ComponentPropsWithRef<'div'> @@ -44,8 +46,12 @@ export default function MessageMobileHeader( } return ( <> - -
+
Messages
+ {/* */} +
+ + +
); })()} diff --git a/apps/u3/src/route/nav.tsx b/apps/u3/src/route/nav.tsx deleted file mode 100644 index 4cdedccc..00000000 --- a/apps/u3/src/route/nav.tsx +++ /dev/null @@ -1,128 +0,0 @@ -/* - * @Author: shixuewen friendlysxw@163.com - * @Date: 2022-12-12 13:59:01 - * @LastEditors: bufan bufan@hotmail.com - * @LastEditTime: 2023-12-15 09:18:03 - * @Description: file description - */ -import React, { ReactNode } from 'react'; -import { isMobile } from 'react-device-detect'; -import { ReactComponent as CompassSvg } from './svgs/compass.svg'; -import { ReactComponent as NewsSvg } from './svgs/news.svg'; -import { ReactComponent as SocialSvg } from './svgs/social.svg'; -import { ReactComponent as DappSvg } from './svgs/dapp.svg'; -import { ReactComponent as BookmarkSvg } from './svgs/bookmark.svg'; -import { ReactComponent as BellSvg } from './svgs/bell.svg'; - -import { CutomRouteObject, getRoute, RouteKey } from './routes'; -// import NotificationButton from '@/components/notification/NotificationNavBtn'; -// import MobileNotificationNavBtn from '@/components/notification/MobileNotificationNavBtn'; - -export type CustomNavObject = { - name: string; - activeRouteKeys: RouteKey[]; // 指定哪些路由key下,该nav被激活(可用来高亮显示,有子菜单展开子菜单等...) - icon?: ReactNode; - children?: CustomNavObject[]; - key?: string; - route?: CutomRouteObject; - component?: JSX.Element; -}; -const navMap = { - explore: { - name: 'Explore', - activeRouteKeys: [RouteKey.home], - icon: React.createElement(CompassSvg), - route: getRoute(RouteKey.home), - }, - news: { - name: 'Apps', - activeRouteKeys: [ - RouteKey.newsLayout, - RouteKey.links, - RouteKey.link, - RouteKey.contents, - RouteKey.content, - RouteKey.contentCreate, - RouteKey.events, - RouteKey.event, - RouteKey.eventCreate, - RouteKey.eventEdit, - ], - icon: React.createElement(NewsSvg), - route: getRoute(RouteKey.newsLayout), - }, - social: { - name: 'Social', - activeRouteKeys: [ - RouteKey.social, - RouteKey.socialLayout, - RouteKey.socialPostDetailFcast, - RouteKey.socialPostDetailLens, - ], - icon: React.createElement(SocialSvg), - route: getRoute(RouteKey.socialLayout), - }, - // notifications: { - // name: 'notifications', - // activeRouteKeys: [RouteKey.notification], - // component: isMobile ? ( - // - // ) : ( - // - // ), - // }, - apps: { - name: 'Apps', - activeRouteKeys: [RouteKey.dappStore, RouteKey.dapp], - icon: React.createElement(DappSvg), - route: getRoute(RouteKey.dappStore), - }, - save: { - name: 'Save', - activeRouteKeys: [RouteKey.fav], - icon: React.createElement(BookmarkSvg), - route: getRoute(RouteKey.fav), - }, -}; -export const navs: CustomNavObject[] = [ - ...(isMobile - ? [ - navMap.explore, - navMap.social, - navMap.news, - // navMap.notifications, - navMap.apps, - navMap.save, - ] - : [ - navMap.explore, - navMap.news, - navMap.social, - // navMap.notifications, - navMap.save, - ]), - // { - // name: 'profile', - // activeRouteKeys: [RouteKey.profile], - // icon: React.createElement(UserCircleSvg), - // route: getRoute(RouteKey.profile), - // }, - // { - // name: 'activity', - // activeRouteKeys: [RouteKey.activity], - // icon: React.createElement(LineChartUpSvg), - // route: getRoute(RouteKey.activity), - // }, - // { - // name: 'asset', - // activeRouteKeys: [RouteKey.asset], - // icon: React.createElement(WalletSvg), - // route: getRoute(RouteKey.asset), - // }, - // { - // name: 'gallery', - // activeRouteKeys: [RouteKey.gallery], - // icon: React.createElement(ImageSvg), - // route: getRoute(RouteKey.gallery), - // }, -]; diff --git a/apps/u3/src/route/svgs/bell.svg b/apps/u3/src/route/svgs/bell.svg deleted file mode 100644 index 6cb6d187..00000000 --- a/apps/u3/src/route/svgs/bell.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/apps/u3/src/route/svgs/bookmark.svg b/apps/u3/src/route/svgs/bookmark.svg deleted file mode 100644 index c13c84fe..00000000 --- a/apps/u3/src/route/svgs/bookmark.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/apps/u3/src/route/svgs/compass.svg b/apps/u3/src/route/svgs/compass.svg deleted file mode 100644 index 0374b6ba..00000000 --- a/apps/u3/src/route/svgs/compass.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/apps/u3/src/route/svgs/dapp.svg b/apps/u3/src/route/svgs/dapp.svg deleted file mode 100644 index 8055aea0..00000000 --- a/apps/u3/src/route/svgs/dapp.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/apps/u3/src/route/svgs/heart.svg b/apps/u3/src/route/svgs/heart.svg deleted file mode 100644 index d8f7c25f..00000000 --- a/apps/u3/src/route/svgs/heart.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/apps/u3/src/route/svgs/home.svg b/apps/u3/src/route/svgs/home.svg deleted file mode 100644 index e91de6d8..00000000 --- a/apps/u3/src/route/svgs/home.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - diff --git a/apps/u3/src/route/svgs/image.svg b/apps/u3/src/route/svgs/image.svg deleted file mode 100644 index 2e4c7052..00000000 --- a/apps/u3/src/route/svgs/image.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/apps/u3/src/route/svgs/line-chart-up.svg b/apps/u3/src/route/svgs/line-chart-up.svg deleted file mode 100644 index 73c59cc3..00000000 --- a/apps/u3/src/route/svgs/line-chart-up.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/apps/u3/src/route/svgs/news.svg b/apps/u3/src/route/svgs/news.svg deleted file mode 100644 index 51e3ba7c..00000000 --- a/apps/u3/src/route/svgs/news.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/apps/u3/src/route/svgs/social.svg b/apps/u3/src/route/svgs/social.svg deleted file mode 100644 index a59bb800..00000000 --- a/apps/u3/src/route/svgs/social.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/apps/u3/src/route/svgs/user-circle.svg b/apps/u3/src/route/svgs/user-circle.svg deleted file mode 100644 index 2d9354ff..00000000 --- a/apps/u3/src/route/svgs/user-circle.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/apps/u3/src/route/svgs/wallet.svg b/apps/u3/src/route/svgs/wallet.svg deleted file mode 100644 index 8f98fece..00000000 --- a/apps/u3/src/route/svgs/wallet.svg +++ /dev/null @@ -1,3 +0,0 @@ - - -