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/PostLikedBy.tsx139
-rw-r--r--src/view/com/post-thread/PostRepostedBy.tsx141
-rw-r--r--src/view/com/post-thread/PostThreadItem.tsx22
3 files changed, 300 insertions, 2 deletions
diff --git a/src/view/com/post-thread/PostLikedBy.tsx b/src/view/com/post-thread/PostLikedBy.tsx
new file mode 100644
index 000000000..678e069f6
--- /dev/null
+++ b/src/view/com/post-thread/PostLikedBy.tsx
@@ -0,0 +1,139 @@
+import React, {useState, useEffect} from 'react'
+import {observer} from 'mobx-react-lite'
+import {
+  ActivityIndicator,
+  FlatList,
+  Image,
+  StyleSheet,
+  Text,
+  TouchableOpacity,
+  View,
+} from 'react-native'
+import {OnNavigateContent} from '../../routes/types'
+import {
+  LikedByViewModel,
+  LikedByViewItemModel,
+} from '../../../state/models/liked-by-view'
+import {useStores} from '../../../state'
+import {s} from '../../lib/styles'
+import {AVIS} from '../../lib/assets'
+
+export const PostLikedBy = observer(function PostLikedBy({
+  uri,
+  onNavigateContent,
+}: {
+  uri: string
+  onNavigateContent: OnNavigateContent
+}) {
+  const store = useStores()
+  const [view, setView] = useState<LikedByViewModel | undefined>()
+
+  useEffect(() => {
+    if (view?.params.uri === uri) {
+      console.log('Liked by doing nothing')
+      return // no change needed? or trigger refresh?
+    }
+    console.log('Fetching Liked by', uri)
+    const newView = new LikedByViewModel(store, {uri})
+    setView(newView)
+    newView.setup().catch(err => console.error('Failed to fetch liked by', err))
+  }, [uri, view?.params.uri, store])
+
+  // loading
+  // =
+  if (
+    !view ||
+    (view.isLoading && !view.isRefreshing) ||
+    view.params.uri !== uri
+  ) {
+    return (
+      <View>
+        <ActivityIndicator />
+      </View>
+    )
+  }
+
+  // error
+  // =
+  if (view.hasError) {
+    return (
+      <View>
+        <Text>{view.error}</Text>
+      </View>
+    )
+  }
+
+  // loaded
+  // =
+  const renderItem = ({item}: {item: LikedByViewItemModel}) => (
+    <LikedByItem item={item} onNavigateContent={onNavigateContent} />
+  )
+  return (
+    <View>
+      <FlatList
+        data={view.likedBy}
+        keyExtractor={item => item._reactKey}
+        renderItem={renderItem}
+      />
+    </View>
+  )
+})
+
+const LikedByItem = ({
+  item,
+  onNavigateContent,
+}: {
+  item: LikedByViewItemModel
+  onNavigateContent: OnNavigateContent
+}) => {
+  const onPressOuter = () => {
+    onNavigateContent('Profile', {
+      name: item.name,
+    })
+  }
+  return (
+    <TouchableOpacity style={styles.outer} onPress={onPressOuter}>
+      <View style={styles.layout}>
+        <View style={styles.layoutAvi}>
+          <Image
+            style={styles.avi}
+            source={AVIS[item.name] || AVIS['alice.com']}
+          />
+        </View>
+        <View style={styles.layoutContent}>
+          <Text style={[s.f15, s.bold]}>{item.displayName}</Text>
+          <Text style={[s.f14, s.gray]}>@{item.name}</Text>
+        </View>
+      </View>
+    </TouchableOpacity>
+  )
+}
+
+const styles = StyleSheet.create({
+  outer: {
+    borderTopWidth: 1,
+    borderTopColor: '#e8e8e8',
+    backgroundColor: '#fff',
+  },
+  layout: {
+    flexDirection: 'row',
+  },
+  layoutAvi: {
+    width: 60,
+    paddingLeft: 10,
+    paddingTop: 10,
+    paddingBottom: 10,
+  },
+  avi: {
+    width: 40,
+    height: 40,
+    borderRadius: 30,
+    resizeMode: 'cover',
+  },
+  layoutContent: {
+    flex: 1,
+    paddingRight: 10,
+    paddingTop: 10,
+    paddingBottom: 10,
+  },
+})
diff --git a/src/view/com/post-thread/PostRepostedBy.tsx b/src/view/com/post-thread/PostRepostedBy.tsx
new file mode 100644
index 000000000..98c24ef86
--- /dev/null
+++ b/src/view/com/post-thread/PostRepostedBy.tsx
@@ -0,0 +1,141 @@
+import React, {useState, useEffect} from 'react'
+import {observer} from 'mobx-react-lite'
+import {
+  ActivityIndicator,
+  FlatList,
+  Image,
+  StyleSheet,
+  Text,
+  TouchableOpacity,
+  View,
+} from 'react-native'
+import {OnNavigateContent} from '../../routes/types'
+import {
+  RepostedByViewModel,
+  RepostedByViewItemModel,
+} from '../../../state/models/reposted-by-view'
+import {useStores} from '../../../state'
+import {s} from '../../lib/styles'
+import {AVIS} from '../../lib/assets'
+
+export const PostRepostedBy = observer(function PostRepostedBy({
+  uri,
+  onNavigateContent,
+}: {
+  uri: string
+  onNavigateContent: OnNavigateContent
+}) {
+  const store = useStores()
+  const [view, setView] = useState<RepostedByViewModel | undefined>()
+
+  useEffect(() => {
+    if (view?.params.uri === uri) {
+      console.log('Reposted by doing nothing')
+      return // no change needed? or trigger refresh?
+    }
+    console.log('Fetching Reposted by', uri)
+    const newView = new RepostedByViewModel(store, {uri})
+    setView(newView)
+    newView
+      .setup()
+      .catch(err => console.error('Failed to fetch reposted by', err))
+  }, [uri, view?.params.uri, store])
+
+  // loading
+  // =
+  if (
+    !view ||
+    (view.isLoading && !view.isRefreshing) ||
+    view.params.uri !== uri
+  ) {
+    return (
+      <View>
+        <ActivityIndicator />
+      </View>
+    )
+  }
+
+  // error
+  // =
+  if (view.hasError) {
+    return (
+      <View>
+        <Text>{view.error}</Text>
+      </View>
+    )
+  }
+
+  // loaded
+  // =
+  const renderItem = ({item}: {item: RepostedByViewItemModel}) => (
+    <RepostedByItem item={item} onNavigateContent={onNavigateContent} />
+  )
+  return (
+    <View>
+      <FlatList
+        data={view.repostedBy}
+        keyExtractor={item => item._reactKey}
+        renderItem={renderItem}
+      />
+    </View>
+  )
+})
+
+const RepostedByItem = ({
+  item,
+  onNavigateContent,
+}: {
+  item: RepostedByViewItemModel
+  onNavigateContent: OnNavigateContent
+}) => {
+  const onPressOuter = () => {
+    onNavigateContent('Profile', {
+      name: item.name,
+    })
+  }
+  return (
+    <TouchableOpacity style={styles.outer} onPress={onPressOuter}>
+      <View style={styles.layout}>
+        <View style={styles.layoutAvi}>
+          <Image
+            style={styles.avi}
+            source={AVIS[item.name] || AVIS['alice.com']}
+          />
+        </View>
+        <View style={styles.layoutContent}>
+          <Text style={[s.f15, s.bold]}>{item.displayName}</Text>
+          <Text style={[s.f14, s.gray]}>@{item.name}</Text>
+        </View>
+      </View>
+    </TouchableOpacity>
+  )
+}
+
+const styles = StyleSheet.create({
+  outer: {
+    borderTopWidth: 1,
+    borderTopColor: '#e8e8e8',
+    backgroundColor: '#fff',
+  },
+  layout: {
+    flexDirection: 'row',
+  },
+  layoutAvi: {
+    width: 60,
+    paddingLeft: 10,
+    paddingTop: 10,
+    paddingBottom: 10,
+  },
+  avi: {
+    width: 40,
+    height: 40,
+    borderRadius: 30,
+    resizeMode: 'cover',
+  },
+  layoutContent: {
+    flex: 1,
+    paddingRight: 10,
+    paddingTop: 10,
+    paddingBottom: 10,
+  },
+})
diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx
index 896eab89f..7263c61b3 100644
--- a/src/view/com/post-thread/PostThreadItem.tsx
+++ b/src/view/com/post-thread/PostThreadItem.tsx
@@ -40,6 +40,20 @@ export const PostThreadItem = observer(function PostThreadItem({
       name: item.author.name,
     })
   }
+  const onPressLikes = () => {
+    const urip = new AdxUri(item.uri)
+    onNavigateContent('PostLikedBy', {
+      name: item.author.name,
+      recordKey: urip.recordKey,
+    })
+  }
+  const onPressReposts = () => {
+    const urip = new AdxUri(item.uri)
+    onNavigateContent('PostRepostedBy', {
+      name: item.author.name,
+      recordKey: urip.recordKey,
+    })
+  }
   const onPressToggleRepost = () => {
     item
       .toggleRepost()
@@ -91,7 +105,9 @@ export const PostThreadItem = observer(function PostThreadItem({
           {item._isHighlightedPost && hasEngagement ? (
             <View style={styles.expandedInfo}>
               {item.repostCount ? (
-                <Text style={[styles.expandedInfoItem, s.gray, s.semiBold]}>
+                <Text
+                  style={[styles.expandedInfoItem, s.gray, s.semiBold]}
+                  onPress={onPressReposts}>
                   <Text style={[s.bold, s.black]}>{item.repostCount}</Text>{' '}
                   {pluralize(item.repostCount, 'repost')}
                 </Text>
@@ -99,7 +115,9 @@ export const PostThreadItem = observer(function PostThreadItem({
                 <></>
               )}
               {item.likeCount ? (
-                <Text style={[styles.expandedInfoItem, s.gray, s.semiBold]}>
+                <Text
+                  style={[styles.expandedInfoItem, s.gray, s.semiBold]}
+                  onPress={onPressLikes}>
                   <Text style={[s.bold, s.black]}>{item.likeCount}</Text>{' '}
                   {pluralize(item.likeCount, 'like')}
                 </Text>