about summary refs log tree commit diff
path: root/src/view/com/post-thread/PostThread.tsx
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2022-07-20 15:00:37 -0500
committerPaul Frazee <pfrazee@gmail.com>2022-07-20 15:00:37 -0500
commitc712cbbfe27cca5db5d87abd8d7fd3b749492fcc (patch)
tree6ba411c9d9ab7a63b4578071752fdbd9c6a9cec3 /src/view/com/post-thread/PostThread.tsx
parent19c694bc601c2b5d494d635134ffe9ca3fdc7774 (diff)
downloadvoidsky-c712cbbfe27cca5db5d87abd8d7fd3b749492fcc.tar.zst
Add WIP post-thread view
Diffstat (limited to 'src/view/com/post-thread/PostThread.tsx')
-rw-r--r--src/view/com/post-thread/PostThread.tsx88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx
new file mode 100644
index 000000000..bc6642e07
--- /dev/null
+++ b/src/view/com/post-thread/PostThread.tsx
@@ -0,0 +1,88 @@
+import React, {useState, useEffect} from 'react'
+import {observer} from 'mobx-react-lite'
+import {ActivityIndicator, FlatList, Text, View} from 'react-native'
+import {OnNavigateContent} from '../../routes/types'
+import {
+  PostThreadViewModel,
+  PostThreadViewPostModel,
+} from '../../../state/models/post-thread-view'
+import {useStores} from '../../../state'
+import {PostThreadItem} from './PostThreadItem'
+
+export const PostThread = observer(function PostThread({
+  uri,
+  onNavigateContent,
+}: {
+  uri: string
+  onNavigateContent: OnNavigateContent
+}) {
+  const store = useStores()
+  const [view, setView] = useState<PostThreadViewModel | undefined>()
+
+  useEffect(() => {
+    if (view?.params.uri === uri) {
+      console.log('Post thread doing nothing')
+      return // no change needed? or trigger refresh?
+    }
+    console.log('Fetching post thread', uri)
+    const newView = new PostThreadViewModel(store, {uri})
+    setView(newView)
+    newView.setup().catch(err => console.error('Failed to fetch thread', err))
+  }, [uri, view?.params.uri, store])
+
+  // not yet setup
+  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>
+    )
+  }
+
+  // rendering
+  const posts = Array.from(flattenThread(view.thread))
+  const renderItem = ({item}: {item: PostThreadViewPostModel}) => (
+    <PostThreadItem item={item} onNavigateContent={onNavigateContent} />
+  )
+  const onRefresh = () => {
+    view.refresh().catch(err => console.error('Failed to refresh', err))
+  }
+  return (
+    <View>
+      {view.isRefreshing && <ActivityIndicator />}
+      {view.hasContent && (
+        <FlatList
+          data={posts}
+          keyExtractor={item => item._reactKey}
+          renderItem={renderItem}
+          refreshing={view.isRefreshing}
+          onRefresh={onRefresh}
+        />
+      )}
+    </View>
+  )
+})
+
+function* flattenThread(
+  post: PostThreadViewPostModel,
+): Generator<PostThreadViewPostModel, void> {
+  yield post
+  if (post.replies?.length) {
+    for (const reply of post.replies) {
+      yield* flattenThread(reply)
+    }
+  }
+}