about summary refs log tree commit diff
path: root/src/view/com/post-thread
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/post-thread')
-rw-r--r--src/view/com/post-thread/PostThread.tsx90
-rw-r--r--src/view/com/post-thread/PostThreadItem.tsx483
2 files changed, 349 insertions, 224 deletions
diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx
index 51f63dbb3..399e47006 100644
--- a/src/view/com/post-thread/PostThread.tsx
+++ b/src/view/com/post-thread/PostThread.tsx
@@ -20,25 +20,37 @@ import {ComposePrompt} from '../composer/Prompt'
 import {ErrorMessage} from '../util/error/ErrorMessage'
 import {Text} from '../util/text/Text'
 import {s} from 'lib/styles'
-import {isDesktopWeb, isMobileWeb} from 'platform/detection'
+import {isIOS, isDesktopWeb, isMobileWeb} from 'platform/detection'
 import {usePalette} from 'lib/hooks/usePalette'
 import {useSetTitle} from 'lib/hooks/useSetTitle'
 import {useNavigation} from '@react-navigation/native'
 import {NavigationProp} from 'lib/routes/types'
 import {sanitizeDisplayName} from 'lib/strings/display-names'
 
+const MAINTAIN_VISIBLE_CONTENT_POSITION = {minIndexForVisible: 0}
+
+const PARENT_SPINNER = {
+  _reactKey: '__parent_spinner__',
+  _isHighlightedPost: false,
+}
 const REPLY_PROMPT = {_reactKey: '__reply__', _isHighlightedPost: false}
 const DELETED = {_reactKey: '__deleted__', _isHighlightedPost: false}
 const BLOCKED = {_reactKey: '__blocked__', _isHighlightedPost: false}
+const CHILD_SPINNER = {
+  _reactKey: '__child_spinner__',
+  _isHighlightedPost: false,
+}
 const BOTTOM_COMPONENT = {
   _reactKey: '__bottom_component__',
   _isHighlightedPost: false,
 }
 type YieldedItem =
   | PostThreadItemModel
+  | typeof PARENT_SPINNER
   | typeof REPLY_PROMPT
   | typeof DELETED
   | typeof BLOCKED
+  | typeof PARENT_SPINNER
 
 export const PostThread = observer(function PostThread({
   uri,
@@ -51,14 +63,24 @@ export const PostThread = observer(function PostThread({
 }) {
   const pal = usePalette('default')
   const ref = useRef<FlatList>(null)
+  const hasScrolledIntoView = useRef<boolean>(false)
   const [isRefreshing, setIsRefreshing] = React.useState(false)
   const navigation = useNavigation<NavigationProp>()
   const posts = React.useMemo(() => {
     if (view.thread) {
-      return Array.from(flattenThread(view.thread)).concat([BOTTOM_COMPONENT])
+      const arr = Array.from(flattenThread(view.thread))
+      if (view.isLoadingFromCache) {
+        if (view.thread?.postRecord?.reply) {
+          arr.unshift(PARENT_SPINNER)
+        }
+        arr.push(CHILD_SPINNER)
+      } else {
+        arr.push(BOTTOM_COMPONENT)
+      }
+      return arr
     }
     return []
-  }, [view.thread])
+  }, [view.isLoadingFromCache, view.thread])
   useSetTitle(
     view.thread?.postRecord &&
       `${sanitizeDisplayName(
@@ -80,17 +102,37 @@ export const PostThread = observer(function PostThread({
     setIsRefreshing(false)
   }, [view, setIsRefreshing])
 
-  const onLayout = React.useCallback(() => {
+  const onContentSizeChange = React.useCallback(() => {
+    // only run once
+    if (hasScrolledIntoView.current) {
+      return
+    }
+
+    // wait for loading to finish
+    if (
+      !view.hasContent ||
+      (view.isFromCache && view.isLoadingFromCache) ||
+      view.isLoading
+    ) {
+      return
+    }
+
     const index = posts.findIndex(post => post._isHighlightedPost)
     if (index !== -1) {
       ref.current?.scrollToIndex({
         index,
         animated: false,
-        viewOffset: 40,
+        viewPosition: 0,
       })
+      hasScrolledIntoView.current = true
     }
-  }, [posts, ref])
-
+  }, [
+    posts,
+    view.hasContent,
+    view.isFromCache,
+    view.isLoadingFromCache,
+    view.isLoading,
+  ])
   const onScrollToIndexFailed = React.useCallback(
     (info: {
       index: number
@@ -115,7 +157,13 @@ export const PostThread = observer(function PostThread({
 
   const renderItem = React.useCallback(
     ({item}: {item: YieldedItem}) => {
-      if (item === REPLY_PROMPT) {
+      if (item === PARENT_SPINNER) {
+        return (
+          <View style={styles.parentSpinner}>
+            <ActivityIndicator />
+          </View>
+        )
+      } else if (item === REPLY_PROMPT) {
         return <ComposePrompt onPressCompose={onPressReply} />
       } else if (item === DELETED) {
         return (
@@ -150,6 +198,12 @@ export const PostThread = observer(function PostThread({
             ]}
           />
         )
+      } else if (item === CHILD_SPINNER) {
+        return (
+          <View style={styles.childSpinner}>
+            <ActivityIndicator />
+          </View>
+        )
       } else if (item instanceof PostThreadItemModel) {
         return <PostThreadItem item={item} onPostReply={onRefresh} />
       }
@@ -247,6 +301,11 @@ export const PostThread = observer(function PostThread({
       ref={ref}
       data={posts}
       initialNumToRender={posts.length}
+      maintainVisibleContentPosition={
+        isIOS && view.isFromCache
+          ? MAINTAIN_VISIBLE_CONTENT_POSITION
+          : undefined
+      }
       keyExtractor={item => item._reactKey}
       renderItem={renderItem}
       refreshControl={
@@ -257,10 +316,12 @@ export const PostThread = observer(function PostThread({
           titleColor={pal.colors.text}
         />
       }
-      onLayout={onLayout}
+      onContentSizeChange={
+        isIOS && view.isFromCache ? undefined : onContentSizeChange
+      }
       onScrollToIndexFailed={onScrollToIndexFailed}
       style={s.hContentRegion}
-      contentContainerStyle={s.contentContainerExtra}
+      contentContainerStyle={styles.contentContainerExtra}
     />
   )
 })
@@ -307,10 +368,17 @@ const styles = StyleSheet.create({
     paddingHorizontal: 18,
     paddingVertical: 18,
   },
+  parentSpinner: {
+    paddingVertical: 10,
+  },
+  childSpinner: {},
   bottomBorder: {
     borderBottomWidth: 1,
   },
   bottomSpacer: {
-    height: 200,
+    height: 400,
+  },
+  contentContainerExtra: {
+    paddingBottom: 500,
   },
 })
diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx
index edf8d7749..8a56012f0 100644
--- a/src/view/com/post-thread/PostThreadItem.tsx
+++ b/src/view/com/post-thread/PostThreadItem.tsx
@@ -26,15 +26,14 @@ import {PostEmbeds} from '../util/post-embeds'
 import {PostCtrls} from '../util/post-ctrls/PostCtrls'
 import {PostHider} from '../util/moderation/PostHider'
 import {ContentHider} from '../util/moderation/ContentHider'
-import {ImageHider} from '../util/moderation/ImageHider'
+import {PostAlerts} from '../util/moderation/PostAlerts'
 import {PostSandboxWarning} from '../util/PostSandboxWarning'
 import {ErrorMessage} from '../util/error/ErrorMessage'
 import {usePalette} from 'lib/hooks/usePalette'
 import {formatCount} from '../util/numeric/format'
 import {TimeElapsed} from 'view/com/util/TimeElapsed'
 import {makeProfileLink} from 'lib/routes/links'
-
-const PARENT_REPLY_LINE_LENGTH = 8
+import {isDesktopWeb} from 'platform/detection'
 
 export const PostThreadItem = observer(function PostThreadItem({
   item,
@@ -69,8 +68,7 @@ export const PostThreadItem = observer(function PostThreadItem({
   }, [item.post.uri, item.post.author])
   const repostsTitle = 'Reposts of this post'
 
-  const primaryLanguage = store.preferences.contentLanguages[0] || 'en'
-  const translatorUrl = getTranslatorLink(primaryLanguage, record?.text || '')
+  const translatorUrl = getTranslatorLink(record?.text || '')
   const needsTranslation = useMemo(
     () =>
       store.preferences.contentLanguages.length > 0 &&
@@ -159,159 +157,197 @@ export const PostThreadItem = observer(function PostThreadItem({
 
   if (item._isHighlightedPost) {
     return (
-      <PostHider
-        testID={`postThreadItem-by-${item.post.author.handle}`}
-        style={[styles.outer, styles.outerHighlighted, pal.border, pal.view]}
-        moderation={item.moderation.thread}>
-        <PostSandboxWarning />
-        <View style={styles.layout}>
-          <View style={styles.layoutAvi}>
-            <PreviewableUserAvatar
-              size={52}
-              did={item.post.author.did}
-              handle={item.post.author.handle}
-              avatar={item.post.author.avatar}
-              moderation={item.moderation.avatar}
-            />
+      <>
+        {item.rootUri !== item.uri && (
+          <View style={{paddingLeft: 18, flexDirection: 'row', height: 16}}>
+            <View style={{width: 52}}>
+              <View
+                style={[
+                  styles.replyLine,
+                  {
+                    flexGrow: 1,
+                    backgroundColor: pal.colors.replyLine,
+                  },
+                ]}
+              />
+            </View>
           </View>
-          <View style={styles.layoutContent}>
-            <View style={[styles.meta, styles.metaExpandedLine1]}>
-              <View style={[s.flexRow]}>
+        )}
+
+        <Link
+          testID={`postThreadItem-by-${item.post.author.handle}`}
+          style={[styles.outer, styles.outerHighlighted, pal.border, pal.view]}
+          noFeedback
+          accessible={false}>
+          <PostSandboxWarning />
+          <View style={styles.layout}>
+            <View style={[styles.layoutAvi, {paddingBottom: 8}]}>
+              <PreviewableUserAvatar
+                size={52}
+                did={item.post.author.did}
+                handle={item.post.author.handle}
+                avatar={item.post.author.avatar}
+                moderation={item.moderation.avatar}
+              />
+            </View>
+            <View style={styles.layoutContent}>
+              <View style={[styles.meta, styles.metaExpandedLine1]}>
+                <View style={[s.flexRow]}>
+                  <Link
+                    style={styles.metaItem}
+                    href={authorHref}
+                    title={authorTitle}>
+                    <Text
+                      type="xl-bold"
+                      style={[pal.text]}
+                      numberOfLines={1}
+                      lineHeight={1.2}>
+                      {sanitizeDisplayName(
+                        item.post.author.displayName ||
+                          sanitizeHandle(item.post.author.handle),
+                      )}
+                    </Text>
+                  </Link>
+                  <Text type="md" style={[styles.metaItem, pal.textLight]}>
+                    &middot;&nbsp;
+                    <TimeElapsed timestamp={item.post.indexedAt}>
+                      {({timeElapsed}) => <>{timeElapsed}</>}
+                    </TimeElapsed>
+                  </Text>
+                </View>
+              </View>
+              <View style={styles.meta}>
                 <Link
                   style={styles.metaItem}
                   href={authorHref}
                   title={authorTitle}>
-                  <Text
-                    type="xl-bold"
-                    style={[pal.text]}
-                    numberOfLines={1}
-                    lineHeight={1.2}>
-                    {sanitizeDisplayName(
-                      item.post.author.displayName ||
-                        sanitizeHandle(item.post.author.handle),
-                    )}
+                  <Text type="md" style={[pal.textLight]} numberOfLines={1}>
+                    {sanitizeHandle(item.post.author.handle, '@')}
                   </Text>
                 </Link>
-                <Text type="md" style={[styles.metaItem, pal.textLight]}>
-                  &middot;&nbsp;
-                  <TimeElapsed timestamp={item.post.indexedAt}>
-                    {({timeElapsed}) => <>{timeElapsed}</>}
-                  </TimeElapsed>
-                </Text>
-              </View>
-              <View style={s.flex1} />
-              <PostDropdownBtn
-                testID="postDropdownBtn"
-                itemUri={itemUri}
-                itemCid={itemCid}
-                itemHref={itemHref}
-                itemTitle={itemTitle}
-                isAuthor={item.post.author.did === store.me.did}
-                isThreadMuted={item.isThreadMuted}
-                onCopyPostText={onCopyPostText}
-                onOpenTranslate={onOpenTranslate}
-                onToggleThreadMute={onToggleThreadMute}
-                onDeletePost={onDeletePost}
-              />
-            </View>
-            <View style={styles.meta}>
-              <Link
-                style={styles.metaItem}
-                href={authorHref}
-                title={authorTitle}>
-                <Text type="md" style={[pal.textLight]} numberOfLines={1}>
-                  {sanitizeHandle(item.post.author.handle, '@')}
-                </Text>
-              </Link>
-            </View>
-          </View>
-        </View>
-        <View style={[s.pl10, s.pr10, s.pb10]}>
-          <ContentHider moderation={item.moderation.view}>
-            {item.richText?.text ? (
-              <View
-                style={[
-                  styles.postTextContainer,
-                  styles.postTextLargeContainer,
-                ]}>
-                <RichText
-                  type="post-text-lg"
-                  richText={item.richText}
-                  lineHeight={1.3}
-                  style={s.flex1}
-                />
               </View>
-            ) : undefined}
-            <ImageHider moderation={item.moderation.view} style={s.mb10}>
-              <PostEmbeds embed={item.post.embed} style={s.mb10} />
-            </ImageHider>
-          </ContentHider>
-          <ExpandedPostDetails
-            post={item.post}
-            translatorUrl={translatorUrl}
-            needsTranslation={needsTranslation}
-          />
-          {hasEngagement ? (
-            <View style={[styles.expandedInfo, pal.border]}>
-              {item.post.repostCount ? (
-                <Link
-                  style={styles.expandedInfoItem}
-                  href={repostsHref}
-                  title={repostsTitle}>
-                  <Text testID="repostCount" type="lg" style={pal.textLight}>
-                    <Text type="xl-bold" style={pal.text}>
-                      {formatCount(item.post.repostCount)}
-                    </Text>{' '}
-                    {pluralize(item.post.repostCount, 'repost')}
-                  </Text>
-                </Link>
-              ) : (
-                <></>
-              )}
-              {item.post.likeCount ? (
-                <Link
-                  style={styles.expandedInfoItem}
-                  href={likesHref}
-                  title={likesTitle}>
-                  <Text testID="likeCount" type="lg" style={pal.textLight}>
-                    <Text type="xl-bold" style={pal.text}>
-                      {formatCount(item.post.likeCount)}
-                    </Text>{' '}
-                    {pluralize(item.post.likeCount, 'like')}
-                  </Text>
-                </Link>
-              ) : (
-                <></>
-              )}
             </View>
-          ) : (
-            <></>
-          )}
-          <View style={[s.pl10, s.pb5]}>
-            <PostCtrls
-              big
+            <PostDropdownBtn
+              testID="postDropdownBtn"
               itemUri={itemUri}
               itemCid={itemCid}
               itemHref={itemHref}
               itemTitle={itemTitle}
-              author={item.post.author}
-              text={item.richText?.text || record.text}
-              indexedAt={item.post.indexedAt}
               isAuthor={item.post.author.did === store.me.did}
-              isReposted={!!item.post.viewer?.repost}
-              isLiked={!!item.post.viewer?.like}
               isThreadMuted={item.isThreadMuted}
-              onPressReply={onPressReply}
-              onPressToggleRepost={onPressToggleRepost}
-              onPressToggleLike={onPressToggleLike}
               onCopyPostText={onCopyPostText}
               onOpenTranslate={onOpenTranslate}
               onToggleThreadMute={onToggleThreadMute}
               onDeletePost={onDeletePost}
+              style={{
+                paddingVertical: 6,
+                paddingHorizontal: 10,
+                marginLeft: 'auto',
+                width: 40,
+              }}
+            />
+          </View>
+          <View style={[s.pl10, s.pr10, s.pb10]}>
+            <ContentHider
+              moderation={item.moderation.content}
+              ignoreMute
+              style={styles.contentHider}
+              childContainerStyle={styles.contentHiderChild}>
+              <PostAlerts
+                moderation={item.moderation.content}
+                includeMute
+                style={styles.alert}
+              />
+              {item.richText?.text ? (
+                <View
+                  style={[
+                    styles.postTextContainer,
+                    styles.postTextLargeContainer,
+                  ]}>
+                  <RichText
+                    type="post-text-lg"
+                    richText={item.richText}
+                    lineHeight={1.3}
+                    style={s.flex1}
+                  />
+                </View>
+              ) : undefined}
+              {item.post.embed && (
+                <ContentHider moderation={item.moderation.embed} style={s.mb10}>
+                  <PostEmbeds
+                    embed={item.post.embed}
+                    moderation={item.moderation.embed}
+                  />
+                </ContentHider>
+              )}
+            </ContentHider>
+            <ExpandedPostDetails
+              post={item.post}
+              translatorUrl={translatorUrl}
+              needsTranslation={needsTranslation}
             />
+            {hasEngagement ? (
+              <View style={[styles.expandedInfo, pal.border]}>
+                {item.post.repostCount ? (
+                  <Link
+                    style={styles.expandedInfoItem}
+                    href={repostsHref}
+                    title={repostsTitle}>
+                    <Text testID="repostCount" type="lg" style={pal.textLight}>
+                      <Text type="xl-bold" style={pal.text}>
+                        {formatCount(item.post.repostCount)}
+                      </Text>{' '}
+                      {pluralize(item.post.repostCount, 'repost')}
+                    </Text>
+                  </Link>
+                ) : (
+                  <></>
+                )}
+                {item.post.likeCount ? (
+                  <Link
+                    style={styles.expandedInfoItem}
+                    href={likesHref}
+                    title={likesTitle}>
+                    <Text testID="likeCount" type="lg" style={pal.textLight}>
+                      <Text type="xl-bold" style={pal.text}>
+                        {formatCount(item.post.likeCount)}
+                      </Text>{' '}
+                      {pluralize(item.post.likeCount, 'like')}
+                    </Text>
+                  </Link>
+                ) : (
+                  <></>
+                )}
+              </View>
+            ) : (
+              <></>
+            )}
+            <View style={[s.pl10, s.pb5]}>
+              <PostCtrls
+                big
+                itemUri={itemUri}
+                itemCid={itemCid}
+                itemHref={itemHref}
+                itemTitle={itemTitle}
+                author={item.post.author}
+                text={item.richText?.text || record.text}
+                indexedAt={item.post.indexedAt}
+                isAuthor={item.post.author.did === store.me.did}
+                isReposted={!!item.post.viewer?.repost}
+                isLiked={!!item.post.viewer?.like}
+                isThreadMuted={item.isThreadMuted}
+                onPressReply={onPressReply}
+                onPressToggleRepost={onPressToggleRepost}
+                onPressToggleLike={onPressToggleLike}
+                onCopyPostText={onCopyPostText}
+                onOpenTranslate={onOpenTranslate}
+                onToggleThreadMute={onToggleThreadMute}
+                onDeletePost={onDeletePost}
+              />
+            </View>
           </View>
-        </View>
-      </PostHider>
+        </Link>
+      </>
     )
   } else {
     return (
@@ -324,26 +360,36 @@ export const PostThreadItem = observer(function PostThreadItem({
             pal.border,
             pal.view,
             item._showParentReplyLine && styles.noTopBorder,
+            !item._showChildReplyLine && {borderBottomWidth: 1},
           ]}
-          moderation={item.moderation.thread}>
-          {item._showParentReplyLine && (
-            <View
-              style={[
-                styles.parentReplyLine,
-                {borderColor: pal.colors.replyLine},
-              ]}
-            />
-          )}
-          {item._showChildReplyLine && (
-            <View
-              style={[
-                styles.childReplyLine,
-                {borderColor: pal.colors.replyLine},
-              ]}
-            />
-          )}
+          moderation={item.moderation.content}>
           <PostSandboxWarning />
-          <View style={styles.layout}>
+
+          <View
+            style={{flexDirection: 'row', gap: 10, paddingLeft: 8, height: 16}}>
+            <View style={{width: 52}}>
+              {item._showParentReplyLine && (
+                <View
+                  style={[
+                    styles.replyLine,
+                    {
+                      flexGrow: 1,
+                      backgroundColor: pal.colors.replyLine,
+                      marginBottom: 4,
+                    },
+                  ]}
+                />
+              )}
+            </View>
+          </View>
+
+          <View
+            style={[
+              styles.layout,
+              {
+                paddingBottom: item._showChildReplyLine ? 0 : 8,
+              },
+            ]}>
             <View style={styles.layoutAvi}>
               <PreviewableUserAvatar
                 size={52}
@@ -352,7 +398,21 @@ export const PostThreadItem = observer(function PostThreadItem({
                 avatar={item.post.author.avatar}
                 moderation={item.moderation.avatar}
               />
+
+              {item._showChildReplyLine && (
+                <View
+                  style={[
+                    styles.replyLine,
+                    {
+                      flexGrow: 1,
+                      backgroundColor: pal.colors.replyLine,
+                      marginTop: 4,
+                    },
+                  ]}
+                />
+              )}
             </View>
+
             <View style={styles.layoutContent}>
               <PostMeta
                 author={item.post.author}
@@ -360,32 +420,39 @@ export const PostThreadItem = observer(function PostThreadItem({
                 timestamp={item.post.indexedAt}
                 postHref={itemHref}
               />
-              <ContentHider
-                moderation={item.moderation.thread}
-                containerStyle={styles.contentHider}>
-                {item.richText?.text ? (
-                  <View style={styles.postTextContainer}>
-                    <RichText
-                      type="post-text"
-                      richText={item.richText}
-                      style={[pal.text, s.flex1]}
-                      lineHeight={1.3}
-                    />
-                  </View>
-                ) : undefined}
-                <ImageHider style={s.mb10} moderation={item.moderation.thread}>
-                  <PostEmbeds embed={item.post.embed} style={s.mb10} />
-                </ImageHider>
-                {needsTranslation && (
-                  <View style={[pal.borderDark, styles.translateLink]}>
-                    <Link href={translatorUrl} title="Translate">
-                      <Text type="sm" style={pal.link}>
-                        Translate this post
-                      </Text>
-                    </Link>
-                  </View>
-                )}
-              </ContentHider>
+              <PostAlerts
+                moderation={item.moderation.content}
+                style={styles.alert}
+              />
+              {item.richText?.text ? (
+                <View style={styles.postTextContainer}>
+                  <RichText
+                    type="post-text"
+                    richText={item.richText}
+                    style={[pal.text, s.flex1]}
+                    lineHeight={1.3}
+                  />
+                </View>
+              ) : undefined}
+              {item.post.embed && (
+                <ContentHider
+                  style={styles.contentHider}
+                  moderation={item.moderation.embed}>
+                  <PostEmbeds
+                    embed={item.post.embed}
+                    moderation={item.moderation.embed}
+                  />
+                </ContentHider>
+              )}
+              {needsTranslation && (
+                <View style={[pal.borderDark, styles.translateLink]}>
+                  <Link href={translatorUrl} title="Translate">
+                    <Text type="sm" style={pal.link}>
+                      Translate this post
+                    </Text>
+                  </Link>
+                </View>
+              )}
               <PostCtrls
                 itemUri={itemUri}
                 itemCid={itemCid}
@@ -416,7 +483,7 @@ export const PostThreadItem = observer(function PostThreadItem({
           <Link
             style={[
               styles.loadMore,
-              {borderTopColor: pal.colors.border},
+              {borderBottomColor: pal.colors.border},
               pal.view,
             ]}
             href={itemHref}
@@ -466,41 +533,22 @@ const styles = StyleSheet.create({
     paddingLeft: 10,
   },
   outerHighlighted: {
-    paddingTop: 2,
-    paddingLeft: 6,
-    paddingRight: 6,
+    paddingTop: 16,
+    paddingLeft: 10,
+    paddingRight: 10,
   },
   noTopBorder: {
     borderTopWidth: 0,
   },
-  parentReplyLine: {
-    position: 'absolute',
-    left: 44,
-    top: -1 * PARENT_REPLY_LINE_LENGTH + 6,
-    height: PARENT_REPLY_LINE_LENGTH,
-    borderLeftWidth: 2,
-  },
-  childReplyLine: {
-    position: 'absolute',
-    left: 44,
-    top: 65,
-    bottom: 0,
-    borderLeftWidth: 2,
-  },
   layout: {
     flexDirection: 'row',
+    gap: 10,
+    paddingLeft: 8,
   },
-  layoutAvi: {
-    paddingLeft: 10,
-    paddingTop: 10,
-    paddingBottom: 10,
-    marginRight: 10,
-  },
+  layoutAvi: {},
   layoutContent: {
     flex: 1,
     paddingRight: 10,
-    paddingTop: 10,
-    paddingBottom: 10,
   },
   meta: {
     flexDirection: 'row',
@@ -513,7 +561,10 @@ const styles = StyleSheet.create({
   },
   metaItem: {
     paddingRight: 5,
-    maxWidth: 240,
+    maxWidth: isDesktopWeb ? 380 : 220,
+  },
+  alert: {
+    marginBottom: 6,
   },
   postTextContainer: {
     flexDirection: 'row',
@@ -521,7 +572,6 @@ const styles = StyleSheet.create({
     flexWrap: 'wrap',
     paddingBottom: 8,
     paddingRight: 10,
-    minHeight: 36,
   },
   postTextLargeContainer: {
     paddingHorizontal: 0,
@@ -531,7 +581,10 @@ const styles = StyleSheet.create({
     marginBottom: 6,
   },
   contentHider: {
-    marginTop: 4,
+    marginBottom: 6,
+  },
+  contentHiderChild: {
+    marginTop: 6,
   },
   expandedInfo: {
     flexDirection: 'row',
@@ -547,10 +600,14 @@ const styles = StyleSheet.create({
   loadMore: {
     flexDirection: 'row',
     justifyContent: 'space-between',
-    borderTopWidth: 1,
+    borderBottomWidth: 1,
     paddingLeft: 80,
     paddingRight: 20,
-    paddingVertical: 10,
-    marginBottom: 8,
+    paddingVertical: 12,
+  },
+  replyLine: {
+    width: 2,
+    marginLeft: 'auto',
+    marginRight: 'auto',
   },
 })