about summary refs log tree commit diff
path: root/src/view/com/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/util')
-rw-r--r--src/view/com/util/PostMeta.tsx31
-rw-r--r--src/view/com/util/UserInfoText.tsx6
-rw-r--r--src/view/com/util/UserPreviewLink.tsx3
-rw-r--r--src/view/com/util/post-ctrls/PostCtrls.tsx7
-rw-r--r--src/view/com/util/post-embeds/QuoteEmbed.tsx8
-rw-r--r--src/view/com/util/text/ThemedText.tsx80
6 files changed, 113 insertions, 22 deletions
diff --git a/src/view/com/util/PostMeta.tsx b/src/view/com/util/PostMeta.tsx
index 5df6b3983..2ce499765 100644
--- a/src/view/com/util/PostMeta.tsx
+++ b/src/view/com/util/PostMeta.tsx
@@ -7,13 +7,19 @@ import {usePalette} from 'lib/hooks/usePalette'
 import {UserAvatar} from './UserAvatar'
 import {observer} from 'mobx-react-lite'
 import {sanitizeDisplayName} from 'lib/strings/display-names'
+import {sanitizeHandle} from 'lib/strings/handles'
 import {isAndroid} from 'platform/detection'
 import {TimeElapsed} from './TimeElapsed'
+import {makeProfileLink} from 'lib/routes/links'
 
 interface PostMetaOpts {
-  authorAvatar?: string
-  authorHandle: string
-  authorDisplayName: string | undefined
+  author: {
+    avatar?: string
+    did: string
+    handle: string
+    displayName?: string | undefined
+  }
+  showAvatar?: boolean
   authorHasWarning: boolean
   postHref: string
   timestamp: string
@@ -21,15 +27,15 @@ interface PostMetaOpts {
 
 export const PostMeta = observer(function (opts: PostMetaOpts) {
   const pal = usePalette('default')
-  const displayName = opts.authorDisplayName || opts.authorHandle
-  const handle = opts.authorHandle
+  const displayName = opts.author.displayName || opts.author.handle
+  const handle = opts.author.handle
 
   return (
     <View style={styles.metaOneLine}>
-      {typeof opts.authorAvatar !== 'undefined' && (
+      {opts.showAvatar && typeof opts.author.avatar !== 'undefined' && (
         <View style={styles.avatar}>
           <UserAvatar
-            avatar={opts.authorAvatar}
+            avatar={opts.author.avatar}
             size={16}
             // TODO moderation
           />
@@ -43,17 +49,17 @@ export const PostMeta = observer(function (opts: PostMetaOpts) {
           lineHeight={1.2}
           text={
             <>
-              {sanitizeDisplayName(displayName)}
+              {sanitizeDisplayName(displayName)}&nbsp;
               <Text
                 type="md"
-                style={[pal.textLight]}
                 numberOfLines={1}
-                lineHeight={1.2}>
-                &nbsp;@{handle}
+                lineHeight={1.2}
+                style={pal.textLight}>
+                {sanitizeHandle(handle, '@')}
               </Text>
             </>
           }
-          href={`/profile/${opts.authorHandle}`}
+          href={makeProfileLink(opts.author)}
         />
       </View>
       {!isAndroid && (
@@ -85,6 +91,7 @@ export const PostMeta = observer(function (opts: PostMetaOpts) {
 const styles = StyleSheet.create({
   metaOneLine: {
     flexDirection: 'row',
+    alignItems: 'baseline',
     paddingBottom: 2,
     gap: 4,
   },
diff --git a/src/view/com/util/UserInfoText.tsx b/src/view/com/util/UserInfoText.tsx
index b737b2b1e..695711b2a 100644
--- a/src/view/com/util/UserInfoText.tsx
+++ b/src/view/com/util/UserInfoText.tsx
@@ -7,6 +7,8 @@ import {LoadingPlaceholder} from './LoadingPlaceholder'
 import {useStores} from 'state/index'
 import {TypographyVariant} from 'lib/ThemeContext'
 import {sanitizeDisplayName} from 'lib/strings/display-names'
+import {sanitizeHandle} from 'lib/strings/handles'
+import {makeProfileLink} from 'lib/routes/links'
 
 export function UserInfoText({
   type = 'md',
@@ -68,11 +70,11 @@ export function UserInfoText({
         style={style}
         lineHeight={1.2}
         numberOfLines={1}
-        href={`/profile/${profile.handle}`}
+        href={makeProfileLink(profile)}
         text={`${prefix || ''}${sanitizeDisplayName(
           typeof profile[attr] === 'string' && profile[attr]
             ? (profile[attr] as string)
-            : profile.handle,
+            : sanitizeHandle(profile.handle),
         )}`}
       />
     )
diff --git a/src/view/com/util/UserPreviewLink.tsx b/src/view/com/util/UserPreviewLink.tsx
index ae49301fd..7eedbc2d4 100644
--- a/src/view/com/util/UserPreviewLink.tsx
+++ b/src/view/com/util/UserPreviewLink.tsx
@@ -3,6 +3,7 @@ import {Pressable, StyleProp, ViewStyle} from 'react-native'
 import {useStores} from 'state/index'
 import {Link} from './Link'
 import {isDesktopWeb} from 'platform/detection'
+import {makeProfileLink} from 'lib/routes/links'
 
 interface UserPreviewLinkProps {
   did: string
@@ -17,7 +18,7 @@ export function UserPreviewLink(
   if (isDesktopWeb) {
     return (
       <Link
-        href={`/profile/${props.handle}`}
+        href={makeProfileLink(props)}
         title={props.handle}
         asAnchor
         style={props.style}>
diff --git a/src/view/com/util/post-ctrls/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx
index cd6db408c..c544f6409 100644
--- a/src/view/com/util/post-ctrls/PostCtrls.tsx
+++ b/src/view/com/util/post-ctrls/PostCtrls.tsx
@@ -32,9 +32,10 @@ interface PostCtrlsOpts {
   itemTitle: string
   isAuthor: boolean
   author: {
+    did: string
     handle: string
-    displayName: string
-    avatar: string
+    displayName?: string | undefined
+    avatar?: string | undefined
   }
   text: string
   indexedAt: string
@@ -269,7 +270,7 @@ const styles = StyleSheet.create({
     margin: -5,
   },
   ctrlIconLiked: {
-    color: colors.red3,
+    color: colors.like,
   },
   mt1: {
     marginTop: 1,
diff --git a/src/view/com/util/post-embeds/QuoteEmbed.tsx b/src/view/com/util/post-embeds/QuoteEmbed.tsx
index 3836132d5..4995562ac 100644
--- a/src/view/com/util/post-embeds/QuoteEmbed.tsx
+++ b/src/view/com/util/post-embeds/QuoteEmbed.tsx
@@ -8,6 +8,7 @@ import {Text} from '../text/Text'
 import {usePalette} from 'lib/hooks/usePalette'
 import {ComposerOptsQuote} from 'state/models/ui/shell'
 import {PostEmbeds} from '.'
+import {makeProfileLink} from 'lib/routes/links'
 
 export function QuoteEmbed({
   quote,
@@ -18,7 +19,7 @@ export function QuoteEmbed({
 }) {
   const pal = usePalette('default')
   const itemUrip = new AtUri(quote.uri)
-  const itemHref = `/profile/${quote.author.handle}/post/${itemUrip.rkey}`
+  const itemHref = makeProfileLink(quote.author, 'post', itemUrip.rkey)
   const itemTitle = `Post by ${quote.author.handle}`
   const isEmpty = React.useMemo(
     () => quote.text.trim().length === 0,
@@ -39,9 +40,8 @@ export function QuoteEmbed({
       href={itemHref}
       title={itemTitle}>
       <PostMeta
-        authorAvatar={quote.author.avatar}
-        authorHandle={quote.author.handle}
-        authorDisplayName={quote.author.displayName}
+        author={quote.author}
+        showAvatar
         authorHasWarning={false}
         postHref={itemHref}
         timestamp={quote.indexedAt}
diff --git a/src/view/com/util/text/ThemedText.tsx b/src/view/com/util/text/ThemedText.tsx
new file mode 100644
index 000000000..2844d273c
--- /dev/null
+++ b/src/view/com/util/text/ThemedText.tsx
@@ -0,0 +1,80 @@
+import React from 'react'
+import {CustomTextProps, Text} from './Text'
+import {usePalette} from 'lib/hooks/usePalette'
+import {addStyle} from 'lib/styles'
+
+export type ThemedTextProps = CustomTextProps & {
+  fg?: 'default' | 'light' | 'error' | 'inverted' | 'inverted-light'
+  bg?: 'default' | 'light' | 'error' | 'inverted' | 'inverted-light'
+  border?: 'default' | 'dark' | 'error' | 'inverted' | 'inverted-dark'
+  lineHeight?: number
+}
+
+export function ThemedText({
+  fg,
+  bg,
+  border,
+  style,
+  children,
+  ...props
+}: React.PropsWithChildren<ThemedTextProps>) {
+  const pal = usePalette('default')
+  const palInverted = usePalette('inverted')
+  const palError = usePalette('error')
+  switch (fg) {
+    case 'default':
+      style = addStyle(style, pal.text)
+      break
+    case 'light':
+      style = addStyle(style, pal.textLight)
+      break
+    case 'error':
+      style = addStyle(style, {color: palError.colors.background})
+      break
+    case 'inverted':
+      style = addStyle(style, palInverted.text)
+      break
+    case 'inverted-light':
+      style = addStyle(style, palInverted.textLight)
+      break
+  }
+  switch (bg) {
+    case 'default':
+      style = addStyle(style, pal.view)
+      break
+    case 'light':
+      style = addStyle(style, pal.viewLight)
+      break
+    case 'error':
+      style = addStyle(style, palError.view)
+      break
+    case 'inverted':
+      style = addStyle(style, palInverted.view)
+      break
+    case 'inverted-light':
+      style = addStyle(style, palInverted.viewLight)
+      break
+  }
+  switch (border) {
+    case 'default':
+      style = addStyle(style, pal.border)
+      break
+    case 'dark':
+      style = addStyle(style, pal.borderDark)
+      break
+    case 'error':
+      style = addStyle(style, palError.border)
+      break
+    case 'inverted':
+      style = addStyle(style, palInverted.border)
+      break
+    case 'inverted-dark':
+      style = addStyle(style, palInverted.borderDark)
+      break
+  }
+  return (
+    <Text style={style} {...props}>
+      {children}
+    </Text>
+  )
+}