about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/view/com/posts/FeedItem.tsx69
-rw-r--r--src/view/com/util/PostEmbeds.tsx31
-rw-r--r--src/view/com/util/PostMeta.tsx16
-rw-r--r--src/view/com/util/UserInfoText.tsx13
-rw-r--r--src/view/com/util/text/RichText.tsx21
-rw-r--r--src/view/lib/ThemeContext.tsx7
-rw-r--r--src/view/lib/hooks/usePalette.ts4
-rw-r--r--src/view/lib/styles.ts13
-rw-r--r--src/view/lib/themes.ts41
9 files changed, 133 insertions, 82 deletions
diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx
index f456fbab8..6cd374d8c 100644
--- a/src/view/com/posts/FeedItem.tsx
+++ b/src/view/com/posts/FeedItem.tsx
@@ -16,8 +16,10 @@ import {PostEmbeds} from '../util/PostEmbeds'
 import {RichText} from '../util/text/RichText'
 import * as Toast from '../util/Toast'
 import {UserAvatar} from '../util/UserAvatar'
-import {s, colors} from '../../lib/styles'
+import {s, colors, lh} from '../../lib/styles'
 import {useStores} from '../../../state'
+import {useTheme} from '../../lib/ThemeContext'
+import {usePalette} from '../../lib/hooks/usePalette'
 
 export const FeedItem = observer(function ({
   item,
@@ -27,6 +29,8 @@ export const FeedItem = observer(function ({
   showReplyLine?: boolean
 }) {
   const store = useStores()
+  const theme = useTheme()
+  const pal = usePalette('default')
   const [deleted, setDeleted] = useState(false)
   const record = item.post.record as unknown as AppBskyFeedPost.Record
   const itemHref = useMemo(() => {
@@ -96,6 +100,8 @@ export const FeedItem = observer(function ({
   const isNoTop = isChild && !item._isThreadChild
   const outerStyles = [
     styles.outer,
+    pal.view,
+    {borderTopColor: pal.colors.border},
     isSmallTop ? styles.outerSmallTop : undefined,
     isNoTop ? styles.outerNoTop : undefined,
     item._isThreadParent ? styles.outerNoBottom : undefined,
@@ -106,10 +112,21 @@ export const FeedItem = observer(function ({
         <FeedItem item={item.replyParent} showReplyLine />
       ) : undefined}
       <Link style={outerStyles} href={itemHref} title={itemTitle} noFeedback>
-        {item._isThreadChild && <View style={[styles.topReplyLine]} />}
+        {item._isThreadChild && (
+          <View
+            style={[
+              styles.topReplyLine,
+              {borderLeftColor: pal.colors.replyLine},
+            ]}
+          />
+        )}
         {(showReplyLine || item._isThreadParent) && (
           <View
-            style={[styles.bottomReplyLine, isNoTop ? {top: 64} : undefined]}
+            style={[
+              styles.bottomReplyLine,
+              {borderLeftColor: pal.colors.replyLine},
+              isNoTop ? {top: 64} : undefined,
+            ]}
           />
         )}
         {item.reasonRepost && (
@@ -120,7 +137,7 @@ export const FeedItem = observer(function ({
               item.reasonRepost.by.displayName || item.reasonRepost.by.handle
             }>
             <FontAwesomeIcon icon="retweet" style={styles.includeReasonIcon} />
-            <Text style={[s.gray4, s.bold, s.f13]}>
+            <Text type="overline2" style={{color: pal.colors.actionLabel}}>
               Reposted by{' '}
               {item.reasonRepost.by.displayName || item.reasonRepost.by.handle}
             </Text>
@@ -137,7 +154,7 @@ export const FeedItem = observer(function ({
               icon="arrow-trend-up"
               style={styles.includeReasonIcon}
             />
-            <Text style={[s.gray4, s.bold, s.f13]}>
+            <Text type="overline2" style={{color: pal.colors.actionLabel}}>
               Trending with{' '}
               {item.reasonTrend.by.displayName || item.reasonTrend.by.handle}
             </Text>
@@ -171,13 +188,16 @@ export const FeedItem = observer(function ({
                 <FontAwesomeIcon
                   icon="reply"
                   size={9}
-                  style={[s.gray4, s.mr5]}
+                  style={[{color: pal.colors.text}, s.mr5]}
                 />
-                <Text style={[s.gray4, s.f12, s.mr2]}>Reply to</Text>
+                <Text type="caption" style={[pal.textLight, s.mr2]}>
+                  Reply to
+                </Text>
                 <Link href={replyHref} title="Parent post">
                   <UserInfoText
+                    type="caption"
                     did={replyAuthorDid}
-                    style={[s.f12, s.gray5]}
+                    style={[pal.textLight]}
                     prefix="@"
                   />
                 </Link>
@@ -186,9 +206,9 @@ export const FeedItem = observer(function ({
             {record.text ? (
               <View style={styles.postTextContainer}>
                 <RichText
+                  type="body1"
                   text={record.text}
                   entities={record.entities}
-                  style={styles.postText}
                 />
               </View>
             ) : (
@@ -210,7 +230,7 @@ export const FeedItem = observer(function ({
       </Link>
       {item._isThreadChildElided ? (
         <Link
-          style={styles.viewFullThread}
+          style={[pal.view, styles.viewFullThread]}
           href={itemHref}
           title={itemTitle}
           noFeedback>
@@ -221,15 +241,17 @@ export const FeedItem = observer(function ({
                 y1="0"
                 x2="2"
                 y2="5"
-                stroke={colors.gray2}
+                stroke={pal.colors.replyLine}
                 strokeWidth="2"
               />
-              <Circle x="2" y="10" r="1.5" fill={colors.gray3} />
-              <Circle x="2" y="16" r="1.5" fill={colors.gray3} />
-              <Circle x="2" y="22" r="1.5" fill={colors.gray3} />
+              <Circle x="2" y="10" r="1.5" fill={pal.colors.replyLineDot} />
+              <Circle x="2" y="16" r="1.5" fill={pal.colors.replyLineDot} />
+              <Circle x="2" y="22" r="1.5" fill={pal.colors.replyLineDot} />
             </Svg>
           </View>
-          <Text style={styles.viewFullThreadText}>View full thread</Text>
+          <Text style={[pal.link, theme.typography.body2]}>
+            View full thread
+          </Text>
         </Link>
       ) : undefined}
     </>
@@ -239,15 +261,11 @@ export const FeedItem = observer(function ({
 const styles = StyleSheet.create({
   outer: {
     borderTopWidth: 1,
-    borderTopColor: colors.gray2,
-    backgroundColor: colors.white,
     padding: 10,
   },
   outerNoTop: {
     borderTopWidth: 0,
     paddingTop: 0,
-    borderTopLeftRadius: 0,
-    borderTopRightRadius: 0,
   },
   outerSmallTop: {
     borderTopWidth: 0,
@@ -262,7 +280,6 @@ const styles = StyleSheet.create({
     top: 0,
     height: 6,
     borderLeftWidth: 2,
-    borderLeftColor: colors.gray2,
   },
   bottomReplyLine: {
     position: 'absolute',
@@ -270,7 +287,6 @@ const styles = StyleSheet.create({
     top: 72,
     bottom: 0,
     borderLeftWidth: 2,
-    borderLeftColor: colors.gray2,
   },
   includeReason: {
     flexDirection: 'row',
@@ -296,17 +312,10 @@ const styles = StyleSheet.create({
     flexWrap: 'wrap',
     paddingBottom: 8,
   },
-  postText: {
-    fontFamily: 'System',
-    fontSize: 16,
-    lineHeight: 20.8, // 1.3 of 16px
-    color: colors.black,
-  },
   postEmbeds: {
     marginBottom: 10,
   },
   viewFullThread: {
-    backgroundColor: colors.white,
     paddingTop: 12,
     paddingBottom: 2,
     paddingLeft: 70,
@@ -316,8 +325,4 @@ const styles = StyleSheet.create({
     left: 33,
     top: 0,
   },
-  viewFullThreadText: {
-    color: colors.blue3,
-    fontSize: 16,
-  },
 })
diff --git a/src/view/com/util/PostEmbeds.tsx b/src/view/com/util/PostEmbeds.tsx
index 839110a21..ce93ac612 100644
--- a/src/view/com/util/PostEmbeds.tsx
+++ b/src/view/com/util/PostEmbeds.tsx
@@ -7,6 +7,8 @@ import {colors} from '../../lib/styles'
 import {AutoSizedImage} from './images/AutoSizedImage'
 import {ImagesLightbox} from '../../../state/models/shell-ui'
 import {useStores} from '../../../state'
+import {useTheme} from '../../lib/ThemeContext'
+import {usePalette} from '../../lib/hooks/usePalette'
 
 type Embed =
   | AppBskyEmbedImages.Presented
@@ -20,6 +22,8 @@ export function PostEmbeds({
   embed?: Embed
   style?: StyleProp<ViewStyle>
 }) {
+  const theme = useTheme()
+  const pal = usePalette('default')
   const store = useStores()
   if (embed?.$type === 'app.bsky.embed.images#presented') {
     const imgEmbed = embed as AppBskyEmbedImages.Presented
@@ -90,18 +94,24 @@ export function PostEmbeds({
     const externalEmbed = embed as AppBskyEmbedExternal.Presented
     const link = externalEmbed.external
     return (
-      <Link style={[styles.extOuter, style]} href={link.uri} noFeedback>
+      <Link
+        style={[styles.extOuter, pal.view, pal.border, style]}
+        href={link.uri}
+        noFeedback>
         {link.thumb ? (
           <AutoSizedImage style={style} uri={link.thumb} />
         ) : undefined}
-        <Text numberOfLines={1} style={styles.extTitle}>
+        <Text type="h5" numberOfLines={1} style={pal.text}>
           {link.title || link.uri}
         </Text>
-        <Text numberOfLines={1} style={styles.extUrl}>
+        <Text type="body2" numberOfLines={1} style={pal.textLight}>
           {link.uri}
         </Text>
         {link.description ? (
-          <Text numberOfLines={2} style={styles.extDescription}>
+          <Text
+            type="body1"
+            numberOfLines={2}
+            style={[pal.text, styles.extDescription]}>
             {link.description}
           </Text>
         ) : undefined}
@@ -140,23 +150,10 @@ const styles = StyleSheet.create({
   },
 
   extOuter: {
-    borderWidth: 1,
-    borderColor: colors.gray2,
     borderRadius: 8,
     padding: 10,
   },
-  extImage: {},
-  extTitle: {
-    fontSize: 16,
-    fontWeight: 'bold',
-    color: colors.black,
-  },
   extDescription: {
     marginTop: 4,
-    fontSize: 15,
-    color: colors.black,
-  },
-  extUrl: {
-    color: colors.gray4,
   },
 })
diff --git a/src/view/com/util/PostMeta.tsx b/src/view/com/util/PostMeta.tsx
index a9ffd688d..4dcd74353 100644
--- a/src/view/com/util/PostMeta.tsx
+++ b/src/view/com/util/PostMeta.tsx
@@ -6,6 +6,8 @@ import {Text} from './text/Text'
 import {PostDropdownBtn} from './forms/DropdownButton'
 import {s} from '../../lib/styles'
 import {ago} from '../../../lib/strings'
+import {useTheme} from '../../lib/ThemeContext'
+import {usePalette} from '../../lib/hooks/usePalette'
 
 interface PostMetaOpts {
   itemHref: string
@@ -20,6 +22,8 @@ interface PostMetaOpts {
 }
 
 export function PostMeta(opts: PostMetaOpts) {
+  const theme = useTheme()
+  const pal = usePalette('default')
   let displayName = opts.authorDisplayName || opts.authorHandle
   let handle = opts.authorHandle
 
@@ -44,16 +48,16 @@ export function PostMeta(opts: PostMetaOpts) {
         style={styles.metaItem}
         href={opts.authorHref}
         title={opts.authorHandle}>
-        <Text style={[s.f17, s.bold, s.black]} numberOfLines={1}>
+        <Text style={[pal.text, theme.typography.h5]} numberOfLines={1}>
           {displayName}
           {handle ? (
-            <Text style={[s.f15, s.gray5, s.normal, s.black]}>
+            <Text style={[pal.textLight, theme.typography.h6]}>
               &nbsp;{handle}
             </Text>
           ) : undefined}
         </Text>
       </Link>
-      <Text style={[styles.metaItem, s.f15, s.gray5]}>
+      <Text style={[styles.metaItem, pal.textLight, theme.typography.h6]}>
         &middot; {ago(opts.timestamp)}
       </Text>
       <View style={s.flex1} />
@@ -64,7 +68,11 @@ export function PostMeta(opts: PostMetaOpts) {
         isAuthor={opts.isAuthor}
         onCopyPostText={opts.onCopyPostText}
         onDeletePost={opts.onDeletePost}>
-        <FontAwesomeIcon icon="ellipsis-h" size={14} style={[s.mt2, s.mr5]} />
+        <FontAwesomeIcon
+          icon="ellipsis-h"
+          size={14}
+          style={[s.mt2, s.mr5, pal.text]}
+        />
       </PostDropdownBtn>
     </View>
   )
diff --git a/src/view/com/util/UserInfoText.tsx b/src/view/com/util/UserInfoText.tsx
index f5ed07d63..38d6d3d38 100644
--- a/src/view/com/util/UserInfoText.tsx
+++ b/src/view/com/util/UserInfoText.tsx
@@ -5,8 +5,10 @@ import {Link} from './Link'
 import {Text} from './text/Text'
 import {LoadingPlaceholder} from './LoadingPlaceholder'
 import {useStores} from '../../../state'
+import {TypographyVariant} from '../../lib/ThemeContext'
 
 export function UserInfoText({
+  type = 'body1',
   did,
   attr,
   loading,
@@ -15,6 +17,7 @@ export function UserInfoText({
   style,
   asLink,
 }: {
+  type?: TypographyVariant
   did: string
   attr?: keyof GetProfile.OutputSchema
   loading?: string
@@ -52,9 +55,15 @@ export function UserInfoText({
 
   let inner
   if (didFail) {
-    inner = <Text style={style}>{failed}</Text>
+    inner = (
+      <Text type={type} style={style}>
+        {failed}
+      </Text>
+    )
   } else if (profile) {
-    inner = <Text style={style}>{`${prefix || ''}${profile[attr]}`}</Text>
+    inner = (
+      <Text type={type} style={style}>{`${prefix || ''}${profile[attr]}`}</Text>
+    )
   } else {
     inner = (
       <LoadingPlaceholder
diff --git a/src/view/com/util/text/RichText.tsx b/src/view/com/util/text/RichText.tsx
index c9ed4b58e..830294d3a 100644
--- a/src/view/com/util/text/RichText.tsx
+++ b/src/view/com/util/text/RichText.tsx
@@ -2,9 +2,9 @@ import React from 'react'
 import {TextStyle, StyleProp} from 'react-native'
 import {TextLink} from '../Link'
 import {Text} from './Text'
-import {s} from '../../../lib/styles'
+import {lh} from '../../../lib/styles'
 import {toShortUrl} from '../../../../lib/strings'
-import {TypographyVariant} from '../../../lib/ThemeContext'
+import {useTheme, TypographyVariant} from '../../../lib/ThemeContext'
 import {usePalette} from '../../../lib/hooks/usePalette'
 
 type TextSlice = {start: number; end: number}
@@ -21,22 +21,24 @@ export function RichText({
   style,
   numberOfLines,
 }: {
-  type: TypographyVariant
+  type?: TypographyVariant
   text: string
   entities?: Entity[]
   style?: StyleProp<TextStyle>
   numberOfLines?: number
 }) {
+  const theme = useTheme()
   const pal = usePalette('default')
+  const lineHeightStyle = lh(theme, 'body1', 1.2)
   if (!entities?.length) {
     if (/^\p{Extended_Pictographic}+$/u.test(text) && text.length <= 5) {
       style = {
         fontSize: 26,
         lineHeight: 30,
       }
-      return <Text style={style}>{text}</Text>
+      return <Text style={[style, pal.text]}>{text}</Text>
     }
-    return <Text style={style}>{text}</Text>
+    return <Text style={[style, pal.text, lineHeightStyle]}>{text}</Text>
   }
   if (!style) style = []
   else if (!Array.isArray(style)) style = [style]
@@ -55,7 +57,7 @@ export function RichText({
             type={type}
             text={segment.text}
             href={`/profile/${segment.entity.value}`}
-            style={[style, pal.link]}
+            style={[style, lineHeightStyle, pal.link]}
           />,
         )
       } else if (segment.entity.type === 'link') {
@@ -65,7 +67,7 @@ export function RichText({
             type={type}
             text={toShortUrl(segment.text)}
             href={segment.entity.value}
-            style={[style, pal.link]}
+            style={[style, lineHeightStyle, pal.link]}
           />,
         )
       }
@@ -73,7 +75,10 @@ export function RichText({
     key++
   }
   return (
-    <Text type={type} style={[pal.text, style]} numberOfLines={numberOfLines}>
+    <Text
+      type={type}
+      style={[style, pal.text, lineHeightStyle]}
+      numberOfLines={numberOfLines}>
       {els}
     </Text>
   )
diff --git a/src/view/lib/ThemeContext.tsx b/src/view/lib/ThemeContext.tsx
index 57f758c53..f51983cb5 100644
--- a/src/view/lib/ThemeContext.tsx
+++ b/src/view/lib/ThemeContext.tsx
@@ -11,7 +11,6 @@ export type PaletteColorName =
   | 'inverted'
   | 'error'
 export type PaletteColor = {
-  isLowContrast: boolean
   background: string
   backgroundLight: string
   text: string
@@ -20,6 +19,7 @@ export type PaletteColor = {
   link: string
   border: string
   icon: string
+  [k: string]: string
 }
 export type Palette = Record<PaletteColorName, PaletteColor>
 
@@ -31,13 +31,16 @@ export type TypographyVariant =
   | 'h2'
   | 'h3'
   | 'h4'
+  | 'h5'
+  | 'h6'
   | 'subtitle1'
   | 'subtitle2'
   | 'body1'
   | 'body2'
   | 'button'
   | 'caption'
-  | 'overline'
+  | 'overline1'
+  | 'overline2'
 export type Typography = Record<TypographyVariant, TextStyle>
 
 export interface Theme {
diff --git a/src/view/lib/hooks/usePalette.ts b/src/view/lib/hooks/usePalette.ts
index e9af4ae16..698b7fba4 100644
--- a/src/view/lib/hooks/usePalette.ts
+++ b/src/view/lib/hooks/usePalette.ts
@@ -23,19 +23,15 @@ export function usePalette(color: PaletteColorName): UsePaletteValue {
     },
     text: {
       color: palette.text,
-      fontWeight: palette.isLowContrast ? '500' : undefined,
     },
     textLight: {
       color: palette.textLight,
-      fontWeight: palette.isLowContrast ? '500' : undefined,
     },
     textInverted: {
       color: palette.textInverted,
-      fontWeight: palette.isLowContrast ? '500' : undefined,
     },
     link: {
       color: palette.link,
-      fontWeight: palette.isLowContrast ? '500' : undefined,
     },
   }
 }
diff --git a/src/view/lib/styles.ts b/src/view/lib/styles.ts
index 26d33f6cb..8933a8d8e 100644
--- a/src/view/lib/styles.ts
+++ b/src/view/lib/styles.ts
@@ -1,4 +1,5 @@
-import {StyleSheet} from 'react-native'
+import {StyleSheet, TextStyle} from 'react-native'
+import {Theme, TypographyVariant} from './ThemeContext'
 
 // 1 is lightest, 2 is light, 3 is mid, 4 is dark, 5 is darkest
 export const colors = {
@@ -191,3 +192,13 @@ export const s = StyleSheet.create({
   green4: {color: colors.green4},
   green5: {color: colors.green5},
 })
+
+export function lh(
+  theme: Theme,
+  type: TypographyVariant,
+  height: number,
+): TextStyle {
+  return {
+    lineHeight: (theme.typography[type].lineHeight || 16) * height,
+  }
+}
diff --git a/src/view/lib/themes.ts b/src/view/lib/themes.ts
index 722c79df0..1dedd049e 100644
--- a/src/view/lib/themes.ts
+++ b/src/view/lib/themes.ts
@@ -5,18 +5,21 @@ export const defaultTheme: Theme = {
   colorScheme: 'light',
   palette: {
     default: {
-      isLowContrast: false,
       background: colors.white,
       backgroundLight: colors.gray2,
       text: colors.black,
       textLight: colors.gray5,
       textInverted: colors.white,
       link: colors.blue3,
-      border: colors.gray3,
+      border: colors.gray2,
       icon: colors.gray2,
+
+      // non-standard
+      actionLabel: colors.gray4,
+      replyLine: colors.gray2,
+      replyLineDot: colors.gray3,
     },
     primary: {
-      isLowContrast: true,
       background: colors.blue3,
       backgroundLight: colors.blue2,
       text: colors.white,
@@ -27,7 +30,6 @@ export const defaultTheme: Theme = {
       icon: colors.blue4,
     },
     secondary: {
-      isLowContrast: true,
       background: colors.green3,
       backgroundLight: colors.green2,
       text: colors.white,
@@ -38,7 +40,6 @@ export const defaultTheme: Theme = {
       icon: colors.green4,
     },
     inverted: {
-      isLowContrast: true,
       background: colors.black,
       backgroundLight: colors.gray6,
       text: colors.white,
@@ -49,7 +50,6 @@ export const defaultTheme: Theme = {
       icon: colors.gray5,
     },
     error: {
-      isLowContrast: true,
       background: colors.red3,
       backgroundLight: colors.red2,
       text: colors.white,
@@ -90,6 +90,16 @@ export const defaultTheme: Theme = {
       fontSize: 20,
       letterSpacing: 0.15,
     },
+    h5: {
+      fontWeight: 'bold',
+      fontSize: 17,
+      letterSpacing: 0.15,
+    },
+    h6: {
+      fontWeight: '400',
+      fontSize: 15,
+      letterSpacing: 0.15,
+    },
     subtitle1: {
       fontSize: 16,
       letterSpacing: 0.15,
@@ -116,11 +126,15 @@ export const defaultTheme: Theme = {
       fontSize: 12,
       letterSpacing: 0.4,
     },
-    overline: {
+    overline1: {
       fontSize: 10,
       letterSpacing: 1.5,
       textTransform: 'uppercase',
     },
+    overline2: {
+      fontSize: 14,
+      fontWeight: '600',
+    },
   },
 }
 
@@ -130,15 +144,19 @@ export const darkTheme: Theme = {
   palette: {
     ...defaultTheme.palette,
     default: {
-      isLowContrast: true,
-      background: colors.black,
+      background: colors.gray8,
       backgroundLight: colors.gray6,
       text: colors.white,
       textLight: colors.gray3,
       textInverted: colors.black,
-      link: colors.blue2,
-      border: colors.gray3,
+      link: colors.blue3,
+      border: colors.gray6,
       icon: colors.gray5,
+
+      // non-standard
+      actionLabel: colors.gray3,
+      replyLine: colors.gray5,
+      replyLineDot: colors.gray6,
     },
     primary: {
       ...defaultTheme.palette.primary,
@@ -149,7 +167,6 @@ export const darkTheme: Theme = {
       textInverted: colors.green2,
     },
     inverted: {
-      isLowContrast: false,
       background: colors.white,
       backgroundLight: colors.gray2,
       text: colors.black,