about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2023-02-22 23:37:14 -0600
committerPaul Frazee <pfrazee@gmail.com>2023-02-22 23:37:14 -0600
commitc5f28376c86478b4c55d9f0910d8d0cb4a1feb06 (patch)
tree515ba2f63955c484a0aa3ba3238187e52d76d94e
parent9bfffadd88df5ce524f0516c23b2426f463106ae (diff)
downloadvoidsky-c5f28376c86478b4c55d9f0910d8d0cb4a1feb06.tar.zst
Rework web shell ui
-rw-r--r--src/lib/hooks/useColorSchemeStyle.ts6
-rw-r--r--src/lib/icons.tsx26
-rw-r--r--src/view/com/discover/LiteSuggestedFollows.tsx21
-rw-r--r--src/view/shell/web/DesktopLeftColumn.tsx201
-rw-r--r--src/view/shell/web/DesktopRightColumn.tsx43
5 files changed, 191 insertions, 106 deletions
diff --git a/src/lib/hooks/useColorSchemeStyle.ts b/src/lib/hooks/useColorSchemeStyle.ts
new file mode 100644
index 000000000..61e3d7cc9
--- /dev/null
+++ b/src/lib/hooks/useColorSchemeStyle.ts
@@ -0,0 +1,6 @@
+import {useColorScheme} from 'react-native'
+
+export function useColorSchemeStyle(lightStyle: any, darkStyle: any) {
+  const colorScheme = useColorScheme()
+  return colorScheme === 'dark' ? darkStyle : lightStyle
+}
diff --git a/src/lib/icons.tsx b/src/lib/icons.tsx
index f400c3f72..931e3c721 100644
--- a/src/lib/icons.tsx
+++ b/src/lib/icons.tsx
@@ -527,3 +527,29 @@ export function RectTallIcon({
     </Svg>
   )
 }
+export function ComposeIcon({
+  style,
+  size,
+  strokeWidth = 1.5,
+}: {
+  style?: StyleProp<TextStyle>
+  size?: string | number
+  strokeWidth?: number
+}) {
+  return (
+    <Svg
+      fill="none"
+      viewBox="0 0 24 24"
+      strokeWidth={strokeWidth}
+      stroke="currentColor"
+      width={size || 24}
+      height={size || 24}
+      style={style}>
+      <Path
+        strokeLinecap="round"
+        strokeLinejoin="round"
+        d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10"
+      />
+    </Svg>
+  )
+}
diff --git a/src/view/com/discover/LiteSuggestedFollows.tsx b/src/view/com/discover/LiteSuggestedFollows.tsx
index 5314e691c..d9620f387 100644
--- a/src/view/com/discover/LiteSuggestedFollows.tsx
+++ b/src/view/com/discover/LiteSuggestedFollows.tsx
@@ -5,7 +5,6 @@ import {
   TouchableOpacity,
   View,
 } from 'react-native'
-import LinearGradient from 'react-native-linear-gradient'
 import {observer} from 'mobx-react-lite'
 import _omit from 'lodash.omit'
 import {Link} from '../util/Link'
@@ -99,6 +98,7 @@ const User = ({
   onPressUnfollow: (item: SuggestedActor) => void
 }) => {
   const pal = usePalette('default')
+  const palInverted = usePalette('inverted')
   return (
     <View style={[styles.actor]}>
       <View style={styles.actorMeta}>
@@ -121,23 +121,19 @@ const User = ({
         <View style={styles.actorBtn}>
           {follow ? (
             <TouchableOpacity onPress={() => onPressUnfollow(item)}>
-              <View style={[styles.btn, styles.secondaryBtn, pal.btn]}>
+              <View style={[styles.btn, pal.btn]}>
                 <Text type="button" style={pal.text}>
                   Unfollow
                 </Text>
               </View>
             </TouchableOpacity>
           ) : (
-            <TouchableOpacity onPress={() => onPressFollow(item)}>
-              <LinearGradient
-                colors={[gradients.blueLight.start, gradients.blueLight.end]}
-                start={{x: 0, y: 0}}
-                end={{x: 1, y: 1}}
-                style={[styles.btn, styles.gradientBtn]}>
-                <Text type="sm-medium" style={s.white}>
-                  Follow
-                </Text>
-              </LinearGradient>
+            <TouchableOpacity
+              onPress={() => onPressFollow(item)}
+              style={[styles.btn, palInverted.view]}>
+              <Text type="sm-medium" style={palInverted.text}>
+                Follow
+              </Text>
             </TouchableOpacity>
           )}
         </View>
@@ -187,6 +183,7 @@ const styles = StyleSheet.create({
     alignItems: 'center',
     justifyContent: 'center',
     paddingVertical: 7,
+    paddingHorizontal: 14,
     borderRadius: 50,
     marginLeft: 6,
   },
diff --git a/src/view/shell/web/DesktopLeftColumn.tsx b/src/view/shell/web/DesktopLeftColumn.tsx
index d5fe45e80..819bcba6d 100644
--- a/src/view/shell/web/DesktopLeftColumn.tsx
+++ b/src/view/shell/web/DesktopLeftColumn.tsx
@@ -1,13 +1,13 @@
 import React from 'react'
 import {Pressable, StyleSheet, TouchableOpacity, View} from 'react-native'
 import {observer} from 'mobx-react-lite'
-import LinearGradient from 'react-native-linear-gradient'
 import {Link} from '../../com/util/Link'
 import {Text} from '../../com/util/text/Text'
 import {UserAvatar} from '../../com/util/UserAvatar'
-import {s, colors, gradients} from 'lib/styles'
+import {colors} from 'lib/styles'
 import {useStores} from 'state/index'
 import {usePalette} from 'lib/hooks/usePalette'
+import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle'
 import {
   HomeIcon,
   HomeIconSolid,
@@ -15,6 +15,7 @@ import {
   BellIconSolid,
   MagnifyingGlassIcon,
   CogIcon,
+  ComposeIcon,
 } from 'lib/icons'
 
 interface NavItemProps {
@@ -28,15 +29,18 @@ interface NavItemProps {
 export const NavItem = observer(
   ({label, count, href, icon, iconFilled, isProfile}: NavItemProps) => {
     const store = useStores()
-    const pal = usePalette('default')
+    const hoverBg = useColorSchemeStyle(
+      styles.navItemHoverBgLight,
+      styles.navItemHoverBgDark,
+    )
     const isCurrent = store.nav.tab.current.url === href
     return (
       <Pressable
         style={state => [
           // @ts-ignore Pressable state differs for RNW -prf
-          state.hovered && {backgroundColor: pal.colors.backgroundLight},
+          state.hovered && hoverBg,
         ]}>
-        <Link style={styles.navItem} href={href}>
+        <Link style={[styles.navItem, isCurrent && hoverBg]} href={href}>
           <View
             style={[
               styles.navItemIconWrapper,
@@ -50,8 +54,7 @@ export const NavItem = observer(
             )}
           </View>
           <Text
-            type={isCurrent ? 'xl-bold' : 'xl'}
-            style={styles.navItemLabel}
+            type={isCurrent || isProfile ? 'xl' : 'xl-thin'}
             numberOfLines={1}>
             {label}
           </Text>
@@ -63,6 +66,14 @@ export const NavItem = observer(
 
 export const DesktopLeftColumn = observer(() => {
   const store = useStores()
+  const containerBg = useColorSchemeStyle(
+    styles.containerBgLight,
+    styles.containerBgDark,
+  )
+  const hoverBg = useColorSchemeStyle(
+    styles.navItemHoverBgLight,
+    styles.navItemHoverBgDark,
+  )
   const pal = usePalette('default')
   const onPressCompose = () => store.shell.openComposer({})
   const avi = (
@@ -70,81 +81,152 @@ export const DesktopLeftColumn = observer(() => {
       handle={store.me.handle}
       displayName={store.me.displayName}
       avatar={store.me.avatar}
-      size={40}
+      size={30}
     />
   )
   return (
-    <View style={[styles.container, pal.border]}>
-      <NavItem
-        isProfile
-        href={`/profile/${store.me.handle}`}
-        label={store.me.displayName || store.me.handle}
-        icon={avi}
-        iconFilled={avi}
-      />
-      <NavItem
-        href="/"
-        label="Home"
-        icon={<HomeIcon />}
-        iconFilled={<HomeIconSolid />}
-      />
-      <NavItem
-        href="/search"
-        label="Search"
-        icon={<MagnifyingGlassIcon />}
-        iconFilled={<MagnifyingGlassIcon strokeWidth={4} />}
-      />
-      <NavItem
-        href="/notifications"
-        label="Notifications"
-        count={store.me.notifications.unreadCount}
-        icon={<BellIcon />}
-        iconFilled={<BellIconSolid />}
-      />
-      <NavItem
-        href="/settings"
-        label="Settings"
-        icon={<CogIcon strokeWidth={1.5} />}
-        iconFilled={<CogIcon strokeWidth={2} />}
-      />
-      <TouchableOpacity onPress={onPressCompose}>
-        <LinearGradient
-          colors={[gradients.blueLight.start, gradients.blueLight.end]}
-          start={{x: 0, y: 0}}
-          end={{x: 1, y: 1}}
-          style={styles.composeBtn}>
-          <Text type="xl-medium" style={[s.white, s.textCenter]}>
-            New Post
+    <View style={[styles.container, containerBg, pal.border]}>
+      <View style={styles.main}>
+        <Link style={styles.logo} href="/">
+          <Text type="title-xl">Bluesky</Text>
+        </Link>
+        <Link href="/search" style={[pal.view, pal.borderDark, styles.search]}>
+          <MagnifyingGlassIcon
+            size={18}
+            style={[pal.textLight, styles.searchIconWrapper]}
+          />
+          <Text type="md-thin" style={pal.textLight}>
+            Search
           </Text>
-        </LinearGradient>
-      </TouchableOpacity>
+        </Link>
+        <NavItem
+          href="/"
+          label="Home"
+          icon={<HomeIcon size={21} />}
+          iconFilled={<HomeIconSolid size={21} />}
+        />
+        <NavItem
+          href="/search"
+          label="Explore"
+          icon={<MagnifyingGlassIcon size={21} />}
+          iconFilled={<MagnifyingGlassIcon strokeWidth={3} size={21} />}
+        />
+        <NavItem
+          href="/notifications"
+          label="Notifications"
+          count={store.me.notifications.unreadCount}
+          icon={<BellIcon size={21} />}
+          iconFilled={<BellIconSolid size={21} />}
+        />
+        <NavItem
+          href="/settings"
+          label="Settings"
+          icon={<CogIcon strokeWidth={2} size={21} />}
+          iconFilled={<CogIcon strokeWidth={2.5} size={21} />}
+        />
+        <View style={[pal.border, styles.separator]} />
+        <Pressable
+          style={state => [
+            // @ts-ignore Pressable state differs for RNW -prf
+            state.hovered && hoverBg,
+          ]}>
+          <TouchableOpacity style={styles.navItem} onPress={onPressCompose}>
+            <View style={styles.navItemIconWrapper}>
+              <ComposeIcon size={21} />
+            </View>
+            <Text type="xl-thin">New Post</Text>
+          </TouchableOpacity>
+        </Pressable>
+      </View>
+      <View style={[styles.footer, pal.borderDark]}>
+        <NavItem
+          isProfile
+          href={`/profile/${store.me.handle}`}
+          label={store.me.displayName || store.me.handle}
+          icon={avi}
+          iconFilled={avi}
+        />
+      </View>
     </View>
   )
 })
 
 const styles = StyleSheet.create({
+  containerBgLight: {
+    backgroundColor: '#f9f9fd',
+  },
+  containerBgDark: {
+    backgroundColor: '#f9f9fd', // TODO
+  },
+
   container: {
     position: 'absolute',
-    left: 'calc(50vw - 530px)',
-    width: '230px',
-    height: '100%',
+    left: 0,
+    width: '300px',
+    height: '100vh',
     borderRightWidth: 1,
     paddingTop: 5,
   },
+  main: {
+    flex: 1,
+    paddingHorizontal: 16,
+  },
+  footer: {
+    borderTopWidth: 1,
+    paddingHorizontal: 16,
+    paddingVertical: 8,
+  },
+  separator: {
+    borderTopWidth: 1,
+    marginVertical: 12,
+    marginHorizontal: 8,
+  },
+
+  logo: {
+    paddingTop: 6,
+    paddingBottom: 12,
+  },
+
+  search: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    borderRadius: 8,
+    paddingVertical: 8,
+    paddingHorizontal: 6,
+    marginBottom: 10,
+    borderWidth: 1,
+  },
+  searchIconWrapper: {
+    flexDirection: 'row',
+    width: 30,
+    justifyContent: 'center',
+    marginRight: 6,
+  },
+
   navItem: {
-    paddingVertical: 10,
-    paddingHorizontal: 10,
+    paddingVertical: 8,
+    paddingHorizontal: 6,
+    marginBottom: 2,
     flexDirection: 'row',
     alignItems: 'center',
+    borderRadius: 6,
+  },
+  navItemHoverBgLight: {
+    backgroundColor: '#ebebf0',
+    borderRadius: 6,
+  },
+  navItemHoverBgDark: {
+    backgroundColor: colors.gray2, // TODO
+    borderRadius: 6,
   },
   navItemIconWrapper: {
     flexDirection: 'row',
     width: 30,
     justifyContent: 'center',
-    marginRight: 5,
+    marginRight: 8,
   },
   navItemProfile: {
-    width: 40,
+    width: 30,
     marginRight: 10,
   },
   navItemCount: {
@@ -158,9 +240,6 @@ const styles = StyleSheet.create({
     paddingHorizontal: 4,
     borderRadius: 6,
   },
-  navItemLabel: {
-    fontSize: 19,
-  },
   composeBtn: {
     marginTop: 20,
     marginBottom: 10,
diff --git a/src/view/shell/web/DesktopRightColumn.tsx b/src/view/shell/web/DesktopRightColumn.tsx
index 22acac382..b051e6094 100644
--- a/src/view/shell/web/DesktopRightColumn.tsx
+++ b/src/view/shell/web/DesktopRightColumn.tsx
@@ -1,25 +1,15 @@
 import React from 'react'
-import {View, StyleSheet} from 'react-native'
-import {Link} from '../../com/util/Link'
+import {StyleSheet, View} from 'react-native'
 import {Text} from '../../com/util/text/Text'
-import {usePalette} from 'lib/hooks/usePalette'
-import {MagnifyingGlassIcon} from 'lib/icons'
 import {LiteSuggestedFollows} from '../../com/discover/LiteSuggestedFollows'
 import {s} from 'lib/styles'
+import {useStores} from 'state/index'
 
 export const DesktopRightColumn: React.FC = () => {
-  const pal = usePalette('default')
+  const store = useStores()
   return (
-    <View style={[styles.container, pal.border]}>
-      <Link href="/search" style={[pal.btn, styles.searchContainer]}>
-        <View style={styles.searchIcon}>
-          <MagnifyingGlassIcon style={pal.textLight} />
-        </View>
-        <Text type="lg" style={pal.textLight}>
-          Search
-        </Text>
-      </Link>
-      <Text type="xl-bold" style={s.mb10}>
+    <View style={styles.container}>
+      <Text type="lg-bold" style={s.mb10}>
         Suggested Follows
       </Text>
       <LiteSuggestedFollows />
@@ -30,23 +20,10 @@ export const DesktopRightColumn: React.FC = () => {
 const styles = StyleSheet.create({
   container: {
     position: 'absolute',
-    right: 'calc(50vw - 650px)',
-    width: '350px',
-    height: '100%',
-    borderLeftWidth: 1,
-    overscrollBehavior: 'auto',
-    paddingLeft: 30,
-    paddingTop: 10,
-  },
-  searchContainer: {
-    flexDirection: 'row',
-    alignItems: 'center',
-    paddingHorizontal: 14,
-    paddingVertical: 10,
-    borderRadius: 20,
-    marginBottom: 20,
-  },
-  searchIcon: {
-    marginRight: 5,
+    right: 0,
+    width: '400px',
+    paddingHorizontal: 16,
+    paddingRight: 32,
+    paddingTop: 20,
   },
 })