about summary refs log tree commit diff
path: root/src/view
diff options
context:
space:
mode:
Diffstat (limited to 'src/view')
-rw-r--r--src/view/com/notifications/FeedItem.tsx33
-rw-r--r--src/view/com/post-thread/PostThreadItem.tsx68
-rw-r--r--src/view/com/post-thread/PostVotedBy.tsx (renamed from src/view/com/post-thread/PostLikedBy.tsx)42
-rw-r--r--src/view/com/post/Post.tsx20
-rw-r--r--src/view/com/posts/FeedItem.tsx20
-rw-r--r--src/view/com/util/PostCtrls.tsx30
-rw-r--r--src/view/com/util/UserInfoText.tsx2
-rw-r--r--src/view/routes.ts12
-rw-r--r--src/view/screens/PostDownvotedBy.tsx26
-rw-r--r--src/view/screens/PostUpvotedBy.tsx (renamed from src/view/screens/PostLikedBy.tsx)10
10 files changed, 181 insertions, 82 deletions
diff --git a/src/view/com/notifications/FeedItem.tsx b/src/view/com/notifications/FeedItem.tsx
index 45bad95fc..c67e6b966 100644
--- a/src/view/com/notifications/FeedItem.tsx
+++ b/src/view/com/notifications/FeedItem.tsx
@@ -6,6 +6,7 @@ import {FontAwesomeIcon, Props} from '@fortawesome/react-native-fontawesome'
 import {NotificationsViewItemModel} from '../../../state/models/notifications-view'
 import {s, colors} from '../../lib/styles'
 import {ago, pluralize} from '../../lib/strings'
+import {UpIconSolid} from '../../lib/icons'
 import {UserAvatar} from '../util/UserAvatar'
 import {PostText} from '../post/PostText'
 import {Post} from '../post/Post'
@@ -19,7 +20,7 @@ export const FeedItem = observer(function FeedItem({
   item: NotificationsViewItemModel
 }) {
   const itemHref = useMemo(() => {
-    if (item.isLike || item.isRepost) {
+    if (item.isUpvote || item.isRepost) {
       const urip = new AtUri(item.subjectUri)
       return `/profile/${urip.host}/post/${urip.rkey}`
     } else if (item.isFollow) {
@@ -31,7 +32,7 @@ export const FeedItem = observer(function FeedItem({
     return ''
   }, [item])
   const itemTitle = useMemo(() => {
-    if (item.isLike || item.isRepost) {
+    if (item.isUpvote || item.isRepost) {
       return 'Post'
     } else if (item.isFollow) {
       return item.author.handle
@@ -55,16 +56,16 @@ export const FeedItem = observer(function FeedItem({
   }
 
   let action = ''
-  let icon: Props['icon']
+  let icon: Props['icon'] | 'UpIconSolid'
   let iconStyle: Props['style'] = []
-  if (item.isLike) {
-    action = 'liked your post'
-    icon = ['fas', 'heart']
-    iconStyle = [s.blue3]
+  if (item.isUpvote) {
+    action = 'upvoted your post'
+    icon = 'UpIconSolid'
+    iconStyle = [s.red3, {position: 'relative', top: -4}]
   } else if (item.isRepost) {
     action = 'reposted your post'
     icon = 'retweet'
-    iconStyle = [s.blue3]
+    iconStyle = [s.green3]
   } else if (item.isReply) {
     action = 'replied to your post'
     icon = ['far', 'comment']
@@ -100,11 +101,15 @@ export const FeedItem = observer(function FeedItem({
       title={itemTitle}>
       <View style={styles.layout}>
         <View style={styles.layoutIcon}>
-          <FontAwesomeIcon
-            icon={icon}
-            size={22}
-            style={[styles.icon, ...iconStyle]}
-          />
+          {icon === 'UpIconSolid' ? (
+            <UpIconSolid size={26} style={[styles.icon, ...iconStyle]} />
+          ) : (
+            <FontAwesomeIcon
+              icon={icon}
+              size={22}
+              style={[styles.icon, ...iconStyle]}
+            />
+          )}
         </View>
         <View style={styles.layoutContent}>
           <View style={styles.avis}>
@@ -150,7 +155,7 @@ export const FeedItem = observer(function FeedItem({
               {ago(item.indexedAt)}
             </Text>
           </View>
-          {item.isLike || item.isRepost ? (
+          {item.isUpvote || item.isRepost ? (
             <PostText uri={item.subjectUri} style={[s.gray5]} />
           ) : (
             <></>
diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx
index 17f37cb2e..a4b628101 100644
--- a/src/view/com/post-thread/PostThreadItem.tsx
+++ b/src/view/com/post-thread/PostThreadItem.tsx
@@ -28,7 +28,8 @@ export const PostThreadItem = observer(function PostThreadItem({
 }) {
   const store = useStores()
   const record = item.record as unknown as PostType.Record
-  const hasEngagement = item.likeCount || item.repostCount
+  const hasEngagement =
+    item.upvoteCount || item.downvoteCount || item.repostCount
 
   const itemHref = useMemo(() => {
     const urip = new AtUri(item.uri)
@@ -37,11 +38,16 @@ export const PostThreadItem = observer(function PostThreadItem({
   const itemTitle = `Post by ${item.author.handle}`
   const authorHref = `/profile/${item.author.handle}`
   const authorTitle = item.author.handle
-  const likesHref = useMemo(() => {
+  const upvotesHref = useMemo(() => {
     const urip = new AtUri(item.uri)
-    return `/profile/${item.author.handle}/post/${urip.rkey}/liked-by`
+    return `/profile/${item.author.handle}/post/${urip.rkey}/upvoted-by`
   }, [item.uri, item.author.handle])
-  const likesTitle = 'Likes on this post'
+  const upvotesTitle = 'Upvotes on this post'
+  const downvotesHref = useMemo(() => {
+    const urip = new AtUri(item.uri)
+    return `/profile/${item.author.handle}/post/${urip.rkey}/downvoted-by`
+  }, [item.uri, item.author.handle])
+  const downvotesTitle = 'Downvotes on this post'
   const repostsHref = useMemo(() => {
     const urip = new AtUri(item.uri)
     return `/profile/${item.author.handle}/post/${urip.rkey}/reposted-by`
@@ -59,10 +65,15 @@ export const PostThreadItem = observer(function PostThreadItem({
       .toggleRepost()
       .catch(e => console.error('Failed to toggle repost', record, e))
   }
-  const onPressToggleLike = () => {
+  const onPressToggleUpvote = () => {
+    item
+      .toggleUpvote()
+      .catch(e => console.error('Failed to toggle upvote', record, e))
+  }
+  const onPressToggleDownvote = () => {
     item
-      .toggleLike()
-      .catch(e => console.error('Failed to toggle like', record, e))
+      .toggleDownvote()
+      .catch(e => console.error('Failed to toggle downvote', record, e))
   }
 
   if (item._isHighlightedPost) {
@@ -135,16 +146,31 @@ export const PostThreadItem = observer(function PostThreadItem({
               ) : (
                 <></>
               )}
-              {item.likeCount ? (
+              {item.upvoteCount ? (
+                <Link
+                  style={styles.expandedInfoItem}
+                  href={upvotesHref}
+                  title={upvotesTitle}>
+                  <Text style={[s.gray5, s.semiBold, s.f16]}>
+                    <Text style={[s.bold, s.black, s.f16]}>
+                      {item.upvoteCount}
+                    </Text>{' '}
+                    {pluralize(item.upvoteCount, 'upvote')}
+                  </Text>
+                </Link>
+              ) : (
+                <></>
+              )}
+              {item.downvoteCount ? (
                 <Link
                   style={styles.expandedInfoItem}
-                  href={likesHref}
-                  title={likesTitle}>
+                  href={downvotesHref}
+                  title={downvotesTitle}>
                   <Text style={[s.gray5, s.semiBold, s.f16]}>
                     <Text style={[s.bold, s.black, s.f16]}>
-                      {item.likeCount}
+                      {item.downvoteCount}
                     </Text>{' '}
-                    {pluralize(item.likeCount, 'like')}
+                    {pluralize(item.downvoteCount, 'downvote')}
                   </Text>
                 </Link>
               ) : (
@@ -158,12 +184,15 @@ export const PostThreadItem = observer(function PostThreadItem({
             <PostCtrls
               replyCount={item.replyCount}
               repostCount={item.repostCount}
-              likeCount={item.likeCount}
+              upvoteCount={item.upvoteCount}
+              downvoteCount={item.downvoteCount}
               isReposted={!!item.myState.repost}
-              isLiked={!!item.myState.like}
+              isUpvoted={!!item.myState.upvote}
+              isDownvoted={!!item.myState.downvote}
               onPressReply={onPressReply}
               onPressToggleRepost={onPressToggleRepost}
-              onPressToggleLike={onPressToggleLike}
+              onPressToggleUpvote={onPressToggleUpvote}
+              onPressToggleDownvote={onPressToggleDownvote}
             />
           </View>
         </View>
@@ -260,12 +289,15 @@ export const PostThreadItem = observer(function PostThreadItem({
             <PostCtrls
               replyCount={item.replyCount}
               repostCount={item.repostCount}
-              likeCount={item.likeCount}
+              upvoteCount={item.upvoteCount}
+              downvoteCount={item.downvoteCount}
               isReposted={!!item.myState.repost}
-              isLiked={!!item.myState.like}
+              isUpvoted={!!item.myState.upvote}
+              isDownvoted={!!item.myState.downvote}
               onPressReply={onPressReply}
               onPressToggleRepost={onPressToggleRepost}
-              onPressToggleLike={onPressToggleLike}
+              onPressToggleUpvote={onPressToggleUpvote}
+              onPressToggleDownvote={onPressToggleDownvote}
             />
           </View>
         </View>
diff --git a/src/view/com/post-thread/PostLikedBy.tsx b/src/view/com/post-thread/PostVotedBy.tsx
index 87829955e..f5b01f0db 100644
--- a/src/view/com/post-thread/PostLikedBy.tsx
+++ b/src/view/com/post-thread/PostVotedBy.tsx
@@ -2,27 +2,33 @@ import React, {useState, useEffect} from 'react'
 import {observer} from 'mobx-react-lite'
 import {ActivityIndicator, FlatList, StyleSheet, Text, View} from 'react-native'
 import {
-  LikedByViewModel,
-  LikedByViewItemModel,
-} from '../../../state/models/liked-by-view'
+  VotesViewModel,
+  VotesViewItemModel,
+} from '../../../state/models/votes-view'
 import {Link} from '../util/Link'
 import {UserAvatar} from '../util/UserAvatar'
 import {useStores} from '../../../state'
 import {s, colors} from '../../lib/styles'
 
-export const PostLikedBy = observer(function PostLikedBy({uri}: {uri: string}) {
+export const PostVotedBy = observer(function PostVotedBy({
+  uri,
+  direction,
+}: {
+  uri: string
+  direction: 'up' | 'down'
+}) {
   const store = useStores()
-  const [view, setView] = useState<LikedByViewModel | undefined>()
+  const [view, setView] = useState<VotesViewModel | undefined>()
 
   useEffect(() => {
     if (view?.params.uri === uri) {
-      console.log('Liked by doing nothing')
+      console.log('Voted by doing nothing')
       return // no change needed? or trigger refresh?
     }
-    console.log('Fetching Liked by', uri)
-    const newView = new LikedByViewModel(store, {uri})
+    console.log('Fetching voted by', uri)
+    const newView = new VotesViewModel(store, {uri, direction})
     setView(newView)
-    newView.setup().catch(err => console.error('Failed to fetch liked by', err))
+    newView.setup().catch(err => console.error('Failed to fetch voted by', err))
   }, [uri, view?.params.uri, store])
 
   // loading
@@ -51,13 +57,13 @@ export const PostLikedBy = observer(function PostLikedBy({uri}: {uri: string}) {
 
   // loaded
   // =
-  const renderItem = ({item}: {item: LikedByViewItemModel}) => (
+  const renderItem = ({item}: {item: VotesViewItemModel}) => (
     <LikedByItem item={item} />
   )
   return (
     <View>
       <FlatList
-        data={view.likedBy}
+        data={view.votes}
         keyExtractor={item => item._reactKey}
         renderItem={renderItem}
       />
@@ -65,23 +71,23 @@ export const PostLikedBy = observer(function PostLikedBy({uri}: {uri: string}) {
   )
 })
 
-const LikedByItem = ({item}: {item: LikedByViewItemModel}) => {
+const LikedByItem = ({item}: {item: VotesViewItemModel}) => {
   return (
     <Link
       style={styles.outer}
-      href={`/profile/${item.handle}`}
-      title={item.handle}>
+      href={`/profile/${item.actor.handle}`}
+      title={item.actor.handle}>
       <View style={styles.layout}>
         <View style={styles.layoutAvi}>
           <UserAvatar
             size={40}
-            displayName={item.displayName}
-            handle={item.handle}
+            displayName={item.actor.displayName}
+            handle={item.actor.handle}
           />
         </View>
         <View style={styles.layoutContent}>
-          <Text style={[s.f15, s.bold]}>{item.displayName}</Text>
-          <Text style={[s.f14, s.gray5]}>@{item.handle}</Text>
+          <Text style={[s.f15, s.bold]}>{item.actor.displayName}</Text>
+          <Text style={[s.f14, s.gray5]}>@{item.actor.handle}</Text>
         </View>
       </View>
     </Link>
diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx
index 37d25a7b1..4a1e67b63 100644
--- a/src/view/com/post/Post.tsx
+++ b/src/view/com/post/Post.tsx
@@ -78,10 +78,15 @@ export const Post = observer(function Post({uri}: {uri: string}) {
       .toggleRepost()
       .catch(e => console.error('Failed to toggle repost', record, e))
   }
-  const onPressToggleLike = () => {
+  const onPressToggleUpvote = () => {
     item
-      .toggleLike()
-      .catch(e => console.error('Failed to toggle like', record, e))
+      .toggleUpvote()
+      .catch(e => console.error('Failed to toggle upvote', record, e))
+  }
+  const onPressToggleDownvote = () => {
+    item
+      .toggleDownvote()
+      .catch(e => console.error('Failed to toggle downvote', record, e))
   }
 
   return (
@@ -129,12 +134,15 @@ export const Post = observer(function Post({uri}: {uri: string}) {
           <PostCtrls
             replyCount={item.replyCount}
             repostCount={item.repostCount}
-            likeCount={item.likeCount}
+            upvoteCount={item.upvoteCount}
+            downvoteCount={item.downvoteCount}
             isReposted={!!item.myState.repost}
-            isLiked={!!item.myState.like}
+            isUpvoted={!!item.myState.upvote}
+            isDownvoted={!!item.myState.downvote}
             onPressReply={onPressReply}
             onPressToggleRepost={onPressToggleRepost}
-            onPressToggleLike={onPressToggleLike}
+            onPressToggleUpvote={onPressToggleUpvote}
+            onPressToggleDownvote={onPressToggleDownvote}
           />
         </View>
       </View>
diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx
index feaa78550..73593166c 100644
--- a/src/view/com/posts/FeedItem.tsx
+++ b/src/view/com/posts/FeedItem.tsx
@@ -48,10 +48,15 @@ export const FeedItem = observer(function FeedItem({
       .toggleRepost()
       .catch(e => console.error('Failed to toggle repost', record, e))
   }
-  const onPressToggleLike = () => {
+  const onPressToggleUpvote = () => {
     item
-      .toggleLike()
-      .catch(e => console.error('Failed to toggle like', record, e))
+      .toggleUpvote()
+      .catch(e => console.error('Failed to toggle upvote', record, e))
+  }
+  const onPressToggleDownvote = () => {
+    item
+      .toggleDownvote()
+      .catch(e => console.error('Failed to toggle downvote', record, e))
   }
   const onPressShare = (uri: string) => {
     store.shell.openModal(new SharePostModel(uri))
@@ -129,12 +134,15 @@ export const FeedItem = observer(function FeedItem({
           <PostCtrls
             replyCount={item.replyCount}
             repostCount={item.repostCount}
-            likeCount={item.likeCount}
+            upvoteCount={item.upvoteCount}
+            downvoteCount={item.downvoteCount}
             isReposted={!!item.myState.repost}
-            isLiked={!!item.myState.like}
+            isUpvoted={!!item.myState.upvote}
+            isDownvoted={!!item.myState.downvote}
             onPressReply={onPressReply}
             onPressToggleRepost={onPressToggleRepost}
-            onPressToggleLike={onPressToggleLike}
+            onPressToggleUpvote={onPressToggleUpvote}
+            onPressToggleDownvote={onPressToggleDownvote}
           />
         </View>
       </View>
diff --git a/src/view/com/util/PostCtrls.tsx b/src/view/com/util/PostCtrls.tsx
index 3dd77eb30..707030ea2 100644
--- a/src/view/com/util/PostCtrls.tsx
+++ b/src/view/com/util/PostCtrls.tsx
@@ -7,12 +7,15 @@ import {s, colors} from '../../lib/styles'
 interface PostCtrlsOpts {
   replyCount: number
   repostCount: number
-  likeCount: number
+  upvoteCount: number
+  downvoteCount: number
   isReposted: boolean
-  isLiked: boolean
+  isUpvoted: boolean
+  isDownvoted: boolean
   onPressReply: () => void
   onPressToggleRepost: () => void
-  onPressToggleLike: () => void
+  onPressToggleUpvote: () => void
+  onPressToggleDownvote: () => void
 }
 
 export function PostCtrls(opts: PostCtrlsOpts) {
@@ -36,22 +39,27 @@ export function PostCtrls(opts: PostCtrlsOpts) {
           {opts.repostCount}
         </Text>
       </TouchableOpacity>
-      <TouchableOpacity style={styles.ctrl} onPress={opts.onPressToggleLike}>
-        {opts.isLiked ? (
+      <TouchableOpacity style={styles.ctrl} onPress={opts.onPressToggleUpvote}>
+        {opts.isUpvoted ? (
           <UpIconSolid style={styles.ctrlIconUpvoted} size={18} />
         ) : (
           <UpIcon style={styles.ctrlIcon} size={18} />
         )}
-        <Text style={opts.isLiked ? [s.bold, s.blue3, s.f13] : s.f13}>
-          {opts.likeCount}
+        <Text style={opts.isUpvoted ? [s.bold, s.red3, s.f13] : s.f13}>
+          {opts.upvoteCount}
         </Text>
       </TouchableOpacity>
-      <TouchableOpacity style={styles.ctrl} onPress={opts.onPressToggleLike}>
-        {opts.isLiked ? (
+      <TouchableOpacity
+        style={styles.ctrl}
+        onPress={opts.onPressToggleDownvote}>
+        {opts.isDownvoted ? (
           <DownIconSolid style={styles.ctrlIconDownvoted} size={18} />
         ) : (
           <DownIcon style={styles.ctrlIcon} size={18} />
         )}
+        <Text style={opts.isDownvoted ? [s.bold, s.blue3, s.f13] : s.f13}>
+          {opts.downvoteCount}
+        </Text>
       </TouchableOpacity>
     </View>
   )
@@ -78,10 +86,10 @@ const styles = StyleSheet.create({
   },
   ctrlIconUpvoted: {
     marginRight: 5,
-    color: colors.blue3,
+    color: colors.red3,
   },
   ctrlIconDownvoted: {
     marginRight: 5,
-    color: colors.red3,
+    color: colors.blue3,
   },
 })
diff --git a/src/view/com/util/UserInfoText.tsx b/src/view/com/util/UserInfoText.tsx
index 411891863..77fb59886 100644
--- a/src/view/com/util/UserInfoText.tsx
+++ b/src/view/com/util/UserInfoText.tsx
@@ -31,7 +31,7 @@ export function UserInfoText({
   useEffect(() => {
     let aborted = false
     // TODO use caching to reduce loads
-    store.api.app.bsky.actor.getProfile({user: did}).then(
+    store.api.app.bsky.actor.getProfile({actor: did}).then(
       v => {
         if (aborted) return
         setProfile(v.data)
diff --git a/src/view/routes.ts b/src/view/routes.ts
index d458813ec..a72afe592 100644
--- a/src/view/routes.ts
+++ b/src/view/routes.ts
@@ -7,7 +7,8 @@ import {Search} from './screens/Search'
 import {Notifications} from './screens/Notifications'
 import {NotFound} from './screens/NotFound'
 import {PostThread} from './screens/PostThread'
-import {PostLikedBy} from './screens/PostLikedBy'
+import {PostUpvotedBy} from './screens/PostUpvotedBy'
+import {PostDownvotedBy} from './screens/PostDownvotedBy'
 import {PostRepostedBy} from './screens/PostRepostedBy'
 import {Profile} from './screens/Profile'
 import {ProfileFollowers} from './screens/ProfileFollowers'
@@ -42,9 +43,14 @@ export const routes: Route[] = [
     r('/profile/(?<name>[^/]+)/post/(?<rkey>[^/]+)'),
   ],
   [
-    PostLikedBy,
+    PostUpvotedBy,
     'heart',
-    r('/profile/(?<name>[^/]+)/post/(?<rkey>[^/]+)/liked-by'),
+    r('/profile/(?<name>[^/]+)/post/(?<rkey>[^/]+)/upvoted-by'),
+  ],
+  [
+    PostDownvotedBy,
+    'heart',
+    r('/profile/(?<name>[^/]+)/post/(?<rkey>[^/]+)/downvoted-by'),
   ],
   [
     PostRepostedBy,
diff --git a/src/view/screens/PostDownvotedBy.tsx b/src/view/screens/PostDownvotedBy.tsx
new file mode 100644
index 000000000..a77476834
--- /dev/null
+++ b/src/view/screens/PostDownvotedBy.tsx
@@ -0,0 +1,26 @@
+import React, {useEffect} from 'react'
+import {View} from 'react-native'
+import {ViewHeader} from '../com/util/ViewHeader'
+import {PostVotedBy as PostLikedByComponent} from '../com/post-thread/PostVotedBy'
+import {ScreenParams} from '../routes'
+import {useStores} from '../../state'
+import {makeRecordUri} from '../lib/strings'
+
+export const PostDownvotedBy = ({visible, params}: ScreenParams) => {
+  const store = useStores()
+  const {name, rkey} = params
+  const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
+
+  useEffect(() => {
+    if (visible) {
+      store.nav.setTitle('Downvoted by')
+    }
+  }, [store, visible])
+
+  return (
+    <View>
+      <ViewHeader title="Downvoted by" />
+      <PostLikedByComponent uri={uri} direction="down" />
+    </View>
+  )
+}
diff --git a/src/view/screens/PostLikedBy.tsx b/src/view/screens/PostUpvotedBy.tsx
index 8adc58c89..0bf662def 100644
--- a/src/view/screens/PostLikedBy.tsx
+++ b/src/view/screens/PostUpvotedBy.tsx
@@ -1,26 +1,26 @@
 import React, {useEffect} from 'react'
 import {View} from 'react-native'
 import {ViewHeader} from '../com/util/ViewHeader'
-import {PostLikedBy as PostLikedByComponent} from '../com/post-thread/PostLikedBy'
+import {PostVotedBy as PostLikedByComponent} from '../com/post-thread/PostVotedBy'
 import {ScreenParams} from '../routes'
 import {useStores} from '../../state'
 import {makeRecordUri} from '../lib/strings'
 
-export const PostLikedBy = ({visible, params}: ScreenParams) => {
+export const PostUpvotedBy = ({visible, params}: ScreenParams) => {
   const store = useStores()
   const {name, rkey} = params
   const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
 
   useEffect(() => {
     if (visible) {
-      store.nav.setTitle('Liked by')
+      store.nav.setTitle('Upvoted by')
     }
   }, [store, visible])
 
   return (
     <View>
-      <ViewHeader title="Liked by" />
-      <PostLikedByComponent uri={uri} />
+      <ViewHeader title="Upvoted by" />
+      <PostLikedByComponent uri={uri} direction="up" />
     </View>
   )
 }