Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

ALF log screen (#8845)

authored by

Samuel Newman and committed by
GitHub
3810b29f 9d77b361

+129 -117
+1 -1
src/Navigation.tsx
··· 55 55 import {FeedsScreen} from '#/view/screens/Feeds' 56 56 import {HomeScreen} from '#/view/screens/Home' 57 57 import {ListsScreen} from '#/view/screens/Lists' 58 - import {LogScreen} from '#/view/screens/Log' 59 58 import {ModerationBlockedAccounts} from '#/view/screens/ModerationBlockedAccounts' 60 59 import {ModerationModlistsScreen} from '#/view/screens/ModerationModlists' 61 60 import {ModerationMutedAccounts} from '#/view/screens/ModerationMutedAccounts' ··· 74 73 import {createNativeStackNavigatorWithAuth} from '#/view/shell/createNativeStackNavigatorWithAuth' 75 74 import {SharedPreferencesTesterScreen} from '#/screens/E2E/SharedPreferencesTesterScreen' 76 75 import HashtagScreen from '#/screens/Hashtag' 76 + import {LogScreen} from '#/screens/Log' 77 77 import {MessagesScreen} from '#/screens/Messages/ChatList' 78 78 import {MessagesConversationScreen} from '#/screens/Messages/Conversation' 79 79 import {MessagesInboxScreen} from '#/screens/Messages/Inbox'
+128
src/screens/Log.tsx
··· 1 + import {useCallback, useState} from 'react' 2 + import {LayoutAnimation, View} from 'react-native' 3 + import {Pressable} from 'react-native' 4 + import {msg, Trans} from '@lingui/macro' 5 + import {useLingui} from '@lingui/react' 6 + import {useFocusEffect} from '@react-navigation/native' 7 + 8 + import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo' 9 + import { 10 + type CommonNavigatorParams, 11 + type NativeStackScreenProps, 12 + } from '#/lib/routes/types' 13 + import {getEntries} from '#/logger/logDump' 14 + import {useTickEveryMinute} from '#/state/shell' 15 + import {useSetMinimalShellMode} from '#/state/shell' 16 + import {atoms as a, useTheme} from '#/alf' 17 + import { 18 + ChevronBottom_Stroke2_Corner0_Rounded as ChevronBottomIcon, 19 + ChevronTop_Stroke2_Corner0_Rounded as ChevronTopIcon, 20 + } from '#/components/icons/Chevron' 21 + import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfoIcon} from '#/components/icons/CircleInfo' 22 + import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning' 23 + import * as Layout from '#/components/Layout' 24 + import {Text} from '#/components/Typography' 25 + 26 + export function LogScreen({}: NativeStackScreenProps< 27 + CommonNavigatorParams, 28 + 'Log' 29 + >) { 30 + const t = useTheme() 31 + const {_} = useLingui() 32 + const setMinimalShellMode = useSetMinimalShellMode() 33 + const [expanded, setExpanded] = useState<string[]>([]) 34 + const timeAgo = useGetTimeAgo() 35 + const tick = useTickEveryMinute() 36 + 37 + useFocusEffect( 38 + useCallback(() => { 39 + setMinimalShellMode(false) 40 + }, [setMinimalShellMode]), 41 + ) 42 + 43 + const toggler = (id: string) => () => { 44 + LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut) 45 + if (expanded.includes(id)) { 46 + setExpanded(expanded.filter(v => v !== id)) 47 + } else { 48 + setExpanded([...expanded, id]) 49 + } 50 + } 51 + 52 + return ( 53 + <Layout.Screen> 54 + <Layout.Header.Outer> 55 + <Layout.Header.BackButton /> 56 + <Layout.Header.Content> 57 + <Layout.Header.TitleText> 58 + <Trans>System log</Trans> 59 + </Layout.Header.TitleText> 60 + </Layout.Header.Content> 61 + <Layout.Header.Slot /> 62 + </Layout.Header.Outer> 63 + <Layout.Content> 64 + {getEntries() 65 + .slice(0) 66 + .map(entry => { 67 + return ( 68 + <View key={`entry-${entry.id}`}> 69 + <Pressable 70 + style={[ 71 + a.flex_row, 72 + a.align_center, 73 + a.py_md, 74 + a.px_sm, 75 + a.border_b, 76 + t.atoms.border_contrast_low, 77 + t.atoms.bg, 78 + a.gap_sm, 79 + ]} 80 + onPress={toggler(entry.id)} 81 + accessibilityLabel={_(msg`View debug entry`)} 82 + accessibilityHint={_( 83 + msg`Opens additional details for a debug entry`, 84 + )}> 85 + {entry.level === 'warn' || entry.level === 'error' ? ( 86 + <WarningIcon size="sm" fill={t.palette.negative_500} /> 87 + ) : ( 88 + <CircleInfoIcon size="sm" /> 89 + )} 90 + <Text style={[a.flex_1]}>{String(entry.message)}</Text> 91 + {entry.metadata && 92 + Object.keys(entry.metadata).length > 0 && 93 + (expanded.includes(entry.id) ? ( 94 + <ChevronTopIcon 95 + size="sm" 96 + style={[t.atoms.text_contrast_low]} 97 + /> 98 + ) : ( 99 + <ChevronBottomIcon 100 + size="sm" 101 + style={[t.atoms.text_contrast_low]} 102 + /> 103 + ))} 104 + <Text style={[{minWidth: 40}, t.atoms.text_contrast_medium]}> 105 + {timeAgo(entry.timestamp, tick)} 106 + </Text> 107 + </Pressable> 108 + {expanded.includes(entry.id) && ( 109 + <View 110 + style={[ 111 + t.atoms.bg_contrast_25, 112 + a.rounded_xs, 113 + a.p_sm, 114 + a.border_b, 115 + t.atoms.border_contrast_low, 116 + ]}> 117 + <View style={[a.px_sm, a.py_xs]}> 118 + <Text>{JSON.stringify(entry.metadata, null, 2)}</Text> 119 + </View> 120 + </View> 121 + )} 122 + </View> 123 + ) 124 + })} 125 + </Layout.Content> 126 + </Layout.Screen> 127 + ) 128 + }
-116
src/view/screens/Log.tsx
··· 1 - import React from 'react' 2 - import {StyleSheet, TouchableOpacity, View} from 'react-native' 3 - import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 4 - import {msg} from '@lingui/macro' 5 - import {useLingui} from '@lingui/react' 6 - import {useFocusEffect} from '@react-navigation/native' 7 - 8 - import {usePalette} from '#/lib/hooks/usePalette' 9 - import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo' 10 - import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types' 11 - import {s} from '#/lib/styles' 12 - import {getEntries} from '#/logger/logDump' 13 - import {useTickEveryMinute} from '#/state/shell' 14 - import {useSetMinimalShellMode} from '#/state/shell' 15 - import {Text} from '#/view/com/util/text/Text' 16 - import {ViewHeader} from '#/view/com/util/ViewHeader' 17 - import {ScrollView} from '#/view/com/util/Views' 18 - import * as Layout from '#/components/Layout' 19 - 20 - export function LogScreen({}: NativeStackScreenProps< 21 - CommonNavigatorParams, 22 - 'Log' 23 - >) { 24 - const pal = usePalette('default') 25 - const {_} = useLingui() 26 - const setMinimalShellMode = useSetMinimalShellMode() 27 - const [expanded, setExpanded] = React.useState<string[]>([]) 28 - const timeAgo = useGetTimeAgo() 29 - const tick = useTickEveryMinute() 30 - 31 - useFocusEffect( 32 - React.useCallback(() => { 33 - setMinimalShellMode(false) 34 - }, [setMinimalShellMode]), 35 - ) 36 - 37 - const toggler = (id: string) => () => { 38 - if (expanded.includes(id)) { 39 - setExpanded(expanded.filter(v => v !== id)) 40 - } else { 41 - setExpanded([...expanded, id]) 42 - } 43 - } 44 - 45 - return ( 46 - <Layout.Screen> 47 - <ViewHeader title="Log" /> 48 - <ScrollView style={s.flex1}> 49 - {getEntries() 50 - .slice(0) 51 - .map(entry => { 52 - return ( 53 - <View key={`entry-${entry.id}`}> 54 - <TouchableOpacity 55 - style={[styles.entry, pal.border, pal.view]} 56 - onPress={toggler(entry.id)} 57 - accessibilityLabel={_(msg`View debug entry`)} 58 - accessibilityHint={_( 59 - msg`Opens additional details for a debug entry`, 60 - )}> 61 - {entry.level === 'debug' ? ( 62 - <FontAwesomeIcon icon="info" /> 63 - ) : ( 64 - <FontAwesomeIcon icon="exclamation" style={s.red3} /> 65 - )} 66 - <Text type="sm" style={[styles.summary, pal.text]}> 67 - {String(entry.message)} 68 - </Text> 69 - {entry.metadata && Object.keys(entry.metadata).length ? ( 70 - <FontAwesomeIcon 71 - icon={ 72 - expanded.includes(entry.id) ? 'angle-up' : 'angle-down' 73 - } 74 - style={s.mr5} 75 - /> 76 - ) : undefined} 77 - <Text type="sm" style={[styles.ts, pal.textLight]}> 78 - {timeAgo(entry.timestamp, tick)} 79 - </Text> 80 - </TouchableOpacity> 81 - {expanded.includes(entry.id) ? ( 82 - <View style={[pal.view, s.pl10, s.pr10, s.pb10]}> 83 - <View style={[pal.btn, styles.details]}> 84 - <Text type="mono" style={pal.text}> 85 - {JSON.stringify(entry.metadata, null, 2)} 86 - </Text> 87 - </View> 88 - </View> 89 - ) : undefined} 90 - </View> 91 - ) 92 - })} 93 - <View style={s.footerSpacer} /> 94 - </ScrollView> 95 - </Layout.Screen> 96 - ) 97 - } 98 - 99 - const styles = StyleSheet.create({ 100 - entry: { 101 - flexDirection: 'row', 102 - borderTopWidth: 1, 103 - paddingVertical: 10, 104 - paddingHorizontal: 6, 105 - }, 106 - summary: { 107 - flex: 1, 108 - }, 109 - ts: { 110 - width: 40, 111 - }, 112 - details: { 113 - paddingVertical: 10, 114 - paddingHorizontal: 6, 115 - }, 116 - })