about summary refs log tree commit diff
path: root/src/view/screens/Log.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/screens/Log.tsx')
-rw-r--r--src/view/screens/Log.tsx100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/view/screens/Log.tsx b/src/view/screens/Log.tsx
new file mode 100644
index 000000000..56337435f
--- /dev/null
+++ b/src/view/screens/Log.tsx
@@ -0,0 +1,100 @@
+import React, {useEffect} from 'react'
+import {ScrollView, StyleSheet, TouchableOpacity, View} from 'react-native'
+import {observer} from 'mobx-react-lite'
+import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
+import {useStores} from '../../state'
+import {ScreenParams} from '../routes'
+import {s} from '../lib/styles'
+import {ViewHeader} from '../com/util/ViewHeader'
+import {Text} from '../com/util/text/Text'
+import {usePalette} from '../lib/hooks/usePalette'
+import {ago} from '../../lib/strings'
+
+export const Log = observer(function Log({navIdx, visible}: ScreenParams) {
+  const pal = usePalette('default')
+  const store = useStores()
+  const [expanded, setExpanded] = React.useState<string[]>([])
+
+  useEffect(() => {
+    if (!visible) {
+      return
+    }
+    store.shell.setMinimalShellMode(false)
+    store.nav.setTitle(navIdx, 'Log')
+  }, [visible, store])
+
+  const toggler = (id: string) => () => {
+    if (expanded.includes(id)) {
+      setExpanded(expanded.filter(v => v !== id))
+    } else {
+      setExpanded([...expanded, id])
+    }
+  }
+
+  return (
+    <View style={[s.flex1]}>
+      <ViewHeader title="Log" />
+      <ScrollView style={s.flex1}>
+        {store.log.entries
+          .slice(0)
+          .reverse()
+          .map(entry => {
+            return (
+              <View key={`entry-${entry.id}`}>
+                <TouchableOpacity
+                  style={[styles.entry, pal.border, pal.view]}
+                  onPress={toggler(entry.id)}>
+                  {entry.type === 'debug' ? (
+                    <FontAwesomeIcon icon="info" />
+                  ) : (
+                    <FontAwesomeIcon icon="exclamation" style={s.red3} />
+                  )}
+                  <Text type="body2" style={[styles.summary, pal.text]}>
+                    {entry.summary}
+                  </Text>
+                  {!!entry.details ? (
+                    <FontAwesomeIcon
+                      icon={
+                        expanded.includes(entry.id) ? 'angle-up' : 'angle-down'
+                      }
+                      style={s.mr5}
+                    />
+                  ) : undefined}
+                  <Text type="body2" style={[styles.ts, pal.textLight]}>
+                    {entry.ts ? ago(entry.ts) : ''}
+                  </Text>
+                </TouchableOpacity>
+                {expanded.includes(entry.id) ? (
+                  <View style={[pal.btn, styles.details]}>
+                    <Text type="body1" style={pal.text}>
+                      {entry.details}
+                    </Text>
+                  </View>
+                ) : undefined}
+              </View>
+            )
+          })}
+        <View style={{height: 100}} />
+      </ScrollView>
+    </View>
+  )
+})
+
+const styles = StyleSheet.create({
+  entry: {
+    flexDirection: 'row',
+    borderTopWidth: 1,
+    paddingVertical: 10,
+    paddingHorizontal: 6,
+  },
+  summary: {
+    flex: 1,
+  },
+  ts: {
+    width: 40,
+  },
+  details: {
+    paddingVertical: 10,
+    paddingHorizontal: 6,
+  },
+})