1
0
mirror of https://github.com/tooot-app/app synced 2025-03-28 01:10:15 +01:00

Use spinkit instead of activityindicator

This commit is contained in:
Zhiyuan Zheng 2020-12-27 00:32:51 +01:00
parent bd5601f8f9
commit e1eade2b43
No known key found for this signature in database
GPG Key ID: 078A93AB607D85E0
10 changed files with 245 additions and 166 deletions

View File

@ -1,4 +0,0 @@
{
"12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true,
"40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true
}

View File

@ -1,8 +1,9 @@
import { Feather } from '@expo/vector-icons'
import React, { useMemo } from 'react'
import { ActivityIndicator, StyleSheet, Text, View } from 'react-native'
import { StyleSheet, Text, View } from 'react-native'
import { Chase } from 'react-native-animated-spinkit'
import { QueryStatus } from 'react-query'
import Button from '@components/Button'
import { Feather } from '@expo/vector-icons'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
@ -17,7 +18,9 @@ const TimelineEmpty: React.FC<Props> = ({ status, refetch }) => {
const children = useMemo(() => {
switch (status) {
case 'loading':
return <ActivityIndicator />
return (
<Chase size={StyleConstants.Font.Size.L} color={theme.secondary} />
)
case 'error':
return (
<>

View File

@ -1,6 +1,7 @@
import { Feather } from '@expo/vector-icons'
import React from 'react'
import { ActivityIndicator, StyleSheet, Text, View } from 'react-native'
import { StyleSheet, Text, View } from 'react-native'
import { Chase } from 'react-native-animated-spinkit'
import { Feather } from '@expo/vector-icons'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
@ -14,7 +15,7 @@ const TimelineEnd: React.FC<Props> = ({ hasNextPage }) => {
return (
<View style={styles.base}>
{hasNextPage ? (
<ActivityIndicator />
<Chase size={StyleConstants.Font.Size.L} color={theme.secondary} />
) : (
<Text style={[styles.text, { color: theme.secondary }]}>
{' '}

View File

@ -1,21 +1,16 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import {
ActivityIndicator,
Pressable,
StyleSheet,
Text,
View
} from 'react-native'
import { Pressable, StyleSheet, Text, View } from 'react-native'
import { Chase } from 'react-native-animated-spinkit'
import { useQuery } from 'react-query'
import client from '@api/client'
import { Feather } from '@expo/vector-icons'
import Emojis from '@components/Timelines/Timeline/Shared/Emojis'
import relativeTime from '@utils/relativeTime'
import { useTheme } from '@utils/styles/ThemeManager'
import { StyleConstants } from '@utils/styles/constants'
import { useQuery } from 'react-query'
import { relationshipFetch } from '@utils/fetches/relationshipFetch'
import client from '@api/client'
import { toast } from '@components/toast'
import openLink from '@root/utils/openLink'
import relativeTime from '@utils/relativeTime'
import { StyleConstants } from '@utils/styles/constants'
import { relationshipFetch } from '@utils/fetches/relationshipFetch'
import { useTheme } from '@utils/styles/ThemeManager'
export interface Props {
notification: Mastodon.Notification
@ -87,7 +82,9 @@ const TimelineHeaderNotification: React.FC<Props> = ({ notification }) => {
switch (status) {
case 'idle':
case 'loading':
return <ActivityIndicator />
return (
<Chase size={StyleConstants.Font.Size.L} color={theme.secondary} />
)
case 'success':
return (
<Pressable onPress={relationshipOnPress}>

View File

@ -162,12 +162,16 @@ const TimelinePoll: React.FC<Props> = ({
<View style={styles.optionSelected}>
<Feather
style={styles.voted}
name={poll.multiple ? 'check-square' : 'check-circle'}
name={
`${poll.own_votes!.includes(index) ? 'check-' : ''}${
poll.multiple ? 'square' : 'circle'
}` as any
}
size={StyleConstants.Font.Size.M}
color={
poll.own_votes!.includes(index)
? theme.primary
: theme.background
: theme.disabled
}
/>
<View style={styles.contentSelected}>
@ -266,7 +270,7 @@ const styles = StyleSheet.create({
flexDirection: 'row'
},
contentSelected: {
flexShrink: 1,
flex: 1,
flexDirection: 'row',
alignItems: 'center',
paddingRight: StyleConstants.Spacing.S

View File

@ -1,25 +1,18 @@
import { MenuRow } from '@components/Menu'
import { useNavigation } from '@react-navigation/native'
import React from 'react'
import { ActivityIndicator, Text } from 'react-native'
import { useQuery } from 'react-query'
import { MenuContainer, MenuRow } from '@components/Menu'
import TimelineEmpty from '@root/components/Timelines/Timeline/Empty'
import { listsFetch } from '@utils/fetches/listsFetch'
import React, { useMemo } from 'react'
import { StyleSheet } from 'react-native'
import { useQuery } from 'react-query'
const ScreenMeLists: React.FC = () => {
const navigation = useNavigation()
const { status, data } = useQuery(['Lists'], listsFetch)
const { status, data, refetch } = useQuery(['Lists'], listsFetch)
let lists
switch (status) {
case 'loading':
lists = <ActivityIndicator />
break
case 'error':
lists = <Text></Text>
break
case 'success':
lists = data?.map((d: Mastodon.List, i: number) => (
const children = useMemo(() => {
if (status === 'success') {
return data?.map((d: Mastodon.List, i: number) => (
<MenuRow
key={i}
iconFront='list'
@ -32,10 +25,19 @@ const ScreenMeLists: React.FC = () => {
}
/>
))
break
}
} else {
return <TimelineEmpty status={status} refetch={refetch} />
}
}, [status])
return <MenuContainer>{lists}</MenuContainer>
return <>{children}</>
}
const styles = StyleSheet.create({
loading: {
flex: 1,
alignItems: 'center'
}
})
export default ScreenMeLists

View File

@ -42,6 +42,8 @@ const AccountHeader: React.FC<Props> = ({
isMounted &&
setRatio(limitHeight ? accountState.headerRatio : height / width)
})
} else {
isMounted && setRatio(1 / 5)
}
}, [account, isMounted])

View File

@ -528,7 +528,6 @@ const Compose: React.FC<Props> = ({ route: { params }, navigation }) => {
const totalTextCount =
(composeState.spoiler.active ? composeState.spoiler.count : 0) +
composeState.text.count
// doesn't work
const rawCount = composeState.text.raw.length
const postButtonText = {

View File

@ -1,40 +1,37 @@
import { forEach, groupBy, sortBy } from 'lodash'
import React, {
Dispatch,
RefObject,
useCallback,
useContext,
useEffect,
useMemo,
useRef
} from 'react'
import {
View,
ActivityIndicator,
FlatList,
Pressable,
ProgressViewIOS,
StyleSheet,
Text,
TextInput,
Image
} from 'react-native'
import { useQuery } from 'react-query'
import Emojis from '@components/Timelines/Timeline/Shared/Emojis'
import { emojisFetch } from '@utils/fetches/emojisFetch'
import { searchFetch } from '@utils/fetches/searchFetch'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import {
ComposeAction,
ComposeState,
ComposeContext
} from '@screens/Shared/Compose'
import ComposeActions from '@screens/Shared/Compose/Actions'
import updateText from './updateText'
import * as Permissions from 'expo-permissions'
import ComposeRootFooter from '@screens/Shared/Compose/Root/Footer'
import ComposeRootHeader from '@screens/Shared/Compose/Root/Header'
import updateText from '@screens/Shared/Compose/updateText'
import { emojisFetch } from '@utils/fetches/emojisFetch'
import { searchFetch } from '@utils/fetches/searchFetch'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import * as Permissions from 'expo-permissions'
import { forEach, groupBy, sortBy } from 'lodash'
import React, {
Dispatch,
useCallback,
useContext,
useEffect,
useMemo
} from 'react'
import {
View,
FlatList,
Pressable,
ProgressViewIOS,
StyleSheet,
Text,
Image
} from 'react-native'
import { Chase } from 'react-native-animated-spinkit'
import { useQuery } from 'react-query'
const ListItem = React.memo(
({
@ -109,6 +106,8 @@ const ListItem = React.memo(
)
const ComposeRoot: React.FC = () => {
const { theme } = useTheme()
const { composeState, composeDispatch } = useContext(ComposeContext)
const { isFetching, isSuccess, data, refetch } = useQuery(
@ -159,7 +158,14 @@ const ComposeRoot: React.FC = () => {
const listEmpty = useMemo(() => {
if (isFetching) {
return <ActivityIndicator />
return (
<View style={styles.loading}>
<Chase
size={StyleConstants.Font.Size.M * 1.25}
color={theme.secondary}
/>
</View>
)
}
}, [isFetching])
@ -242,6 +248,10 @@ const styles = StyleSheet.create({
fontSize: StyleConstants.Font.Size.S,
fontWeight: StyleConstants.Font.Weight.Bold,
marginBottom: StyleConstants.Spacing.XS
},
loading: {
flex: 1,
alignItems: 'center'
}
})

View File

@ -1,6 +1,7 @@
import { Feather } from '@expo/vector-icons'
import { useNavigation } from '@react-navigation/native'
import { HeaderRight } from '@root/components/Header'
import ParseContent from '@root/components/ParseContent'
import Emojis from '@root/components/Timelines/Timeline/Shared/Emojis'
import { searchFetch } from '@root/utils/fetches/searchFetch'
import { StyleConstants } from '@root/utils/styles/constants'
@ -8,8 +9,8 @@ import { useTheme } from '@root/utils/styles/ThemeManager'
import { debounce } from 'lodash'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import {
ActivityIndicator,
Image,
KeyboardAvoidingView,
Pressable,
SectionList,
StyleSheet,
@ -17,6 +18,7 @@ import {
TextInput,
View
} from 'react-native'
import { Chase } from 'react-native-animated-spinkit'
import { SafeAreaView } from 'react-native-safe-area-context'
import { useQuery } from 'react-query'
@ -71,46 +73,52 @@ const ScreenSharedSearch: React.FC = () => {
}, [searchTerm])
const listEmpty = useMemo(
() =>
status === 'loading' ? (
<View style={styles.emptyBase}>
<ActivityIndicator />
</View>
) : (
<View style={styles.emptyBase}>
<Text
style={[
styles.emptyDefault,
styles.emptyFontSize,
{ color: theme.primary }
]}
>
<Text style={styles.emptyFontBold}></Text>
<Text style={styles.emptyFontBold}></Text>
<Text style={styles.emptyFontBold}></Text>
</Text>
<Text style={[styles.emptyAdvanced, { color: theme.primary }]}>
</Text>
<Text style={[styles.emptyAdvanced, { color: theme.primary }]}>
<Text style={{ color: theme.secondary }}>@username@domain</Text>
{' '}
</Text>
<Text style={[styles.emptyAdvanced, { color: theme.primary }]}>
<Text style={{ color: theme.secondary }}>#example</Text>
{' '}
</Text>
<Text style={[styles.emptyAdvanced, { color: theme.primary }]}>
<Text style={{ color: theme.secondary }}>URL</Text>
{' '}
</Text>
<Text style={[styles.emptyAdvanced, { color: theme.primary }]}>
<Text style={{ color: theme.secondary }}>URL</Text>
{' '}
</Text>
</View>
),
() => (
<View style={styles.emptyBase}>
{status === 'loading' ? (
<View style={styles.loading}>
<Chase
size={StyleConstants.Font.Size.M * 1.25}
color={theme.secondary}
/>
</View>
) : (
<>
<Text
style={[
styles.emptyDefault,
styles.emptyFontSize,
{ color: theme.primary }
]}
>
<Text style={styles.emptyFontBold}></Text>
<Text style={styles.emptyFontBold}></Text>
<Text style={styles.emptyFontBold}></Text>
</Text>
<Text style={[styles.emptyAdvanced, { color: theme.primary }]}>
</Text>
<Text style={[styles.emptyAdvanced, { color: theme.primary }]}>
<Text style={{ color: theme.secondary }}>@username@domain</Text>
{' '}
</Text>
<Text style={[styles.emptyAdvanced, { color: theme.primary }]}>
<Text style={{ color: theme.secondary }}>#example</Text>
{' '}
</Text>
<Text style={[styles.emptyAdvanced, { color: theme.primary }]}>
<Text style={{ color: theme.secondary }}>URL</Text>
{' '}
</Text>
<Text style={[styles.emptyAdvanced, { color: theme.primary }]}>
<Text style={{ color: theme.secondary }}>URL</Text>
{' '}
</Text>
</>
)}
</View>
),
[status]
)
const sectionHeader = useCallback(
@ -204,63 +212,115 @@ const ScreenSharedSearch: React.FC = () => {
</Pressable>
)
case 'statuses':
return <Text>{item.id || 'empty'}</Text>
return (
<Pressable
style={[
styles.itemDefault,
styles.itemAccount,
{ borderBottomColor: theme.border }
]}
onPress={() => {
navigation.goBack()
navigation.push('Screen-Shared-Toot', { toot: item })
}}
>
<Image
source={{ uri: item.account.avatar_static }}
style={styles.itemAccountAvatar}
/>
<View>
{item.account.emojis?.length ? (
<Emojis
content={item.account.display_name || item.account.username}
emojis={item.account.emojis}
size={StyleConstants.Font.Size.S}
fontBold={true}
/>
) : (
<Text
style={[styles.nameWithoutEmoji, { color: theme.primary }]}
>
{item.account.display_name || item.account.username}
</Text>
)}
<Text
style={[styles.itemAccountAcct, { color: theme.secondary }]}
>
@{item.account.acct}
</Text>
{item.content && (
<View style={styles.itemStatus}>
<ParseContent
content={item.content}
size='M'
emojis={item.emojis}
numberOfLines={2}
/>
</View>
)}
</View>
</Pressable>
)
default:
return null
}
}, [])
return (
<SafeAreaView style={{ flex: 1 }} edges={['bottom']}>
<View style={styles.searchBar}>
<View
style={[styles.searchField, { borderBottomColor: theme.secondary }]}
>
<Feather
name='search'
color={theme.primary}
size={StyleConstants.Font.Size.M}
style={styles.searchIcon}
/>
<TextInput
style={[
styles.textInput,
{
color: theme.primary
<KeyboardAvoidingView behavior='padding' style={{ flex: 1 }}>
<SafeAreaView style={{ flex: 1 }} edges={['bottom']}>
<View style={styles.searchBar}>
<View
style={[styles.searchField, { borderBottomColor: theme.secondary }]}
>
<Feather
name='search'
color={theme.primary}
size={StyleConstants.Font.Size.M}
style={styles.searchIcon}
/>
<TextInput
style={[
styles.textInput,
{
color: theme.primary
}
]}
autoFocus
onChangeText={onChangeText}
autoCapitalize='none'
autoCorrect={false}
clearButtonMode='never'
keyboardType='web-search'
onSubmitEditing={({ nativeEvent: { text } }) =>
setSearchTerm(text)
}
]}
autoFocus
onChangeText={onChangeText}
autoCapitalize='none'
autoCorrect={false}
clearButtonMode='never'
keyboardType='web-search'
onSubmitEditing={({ nativeEvent: { text } }) => setSearchTerm(text)}
placeholder={'搜索些什么'}
placeholderTextColor={theme.secondary}
returnKeyType='go'
/>
placeholder={'搜索些什么'}
placeholderTextColor={theme.secondary}
returnKeyType='go'
/>
</View>
<View style={styles.searchCancel}>
<HeaderRight
type='text'
content='取消'
onPress={() => navigation.goBack()}
/>
</View>
</View>
<View style={styles.searchCancel}>
<HeaderRight
type='text'
content='取消'
onPress={() => navigation.goBack()}
/>
</View>
</View>
<SectionList
style={styles.base}
renderItem={listItem}
stickySectionHeadersEnabled
sections={setctionData}
ListEmptyComponent={listEmpty}
keyboardShouldPersistTaps='always'
renderSectionHeader={sectionHeader}
renderSectionFooter={sectionFooter}
keyExtractor={(item, index) => item + index}
/>
</SafeAreaView>
<SectionList
style={styles.base}
renderItem={listItem}
stickySectionHeadersEnabled
sections={setctionData}
ListEmptyComponent={listEmpty}
keyboardShouldPersistTaps='always'
renderSectionHeader={sectionHeader}
renderSectionFooter={sectionFooter}
keyExtractor={(item, index) => item + index}
/>
</SafeAreaView>
</KeyboardAvoidingView>
)
}
@ -303,6 +363,7 @@ const styles = StyleSheet.create({
StyleConstants.Spacing.M +
StyleConstants.Spacing.S
},
loading: { flex: 1, alignItems: 'center' },
emptyFontSize: { fontSize: StyleConstants.Font.Size.S },
emptyFontBold: {
fontWeight: StyleConstants.Font.Weight.Bold
@ -338,6 +399,7 @@ const styles = StyleSheet.create({
alignItems: 'center'
},
itemAccountAvatar: {
alignSelf: 'flex-start',
width: StyleConstants.Avatar.S,
height: StyleConstants.Avatar.S,
borderRadius: 6,
@ -350,6 +412,9 @@ const styles = StyleSheet.create({
itemAccountAcct: { marginTop: StyleConstants.Spacing.XS },
itemHashtag: {
fontSize: StyleConstants.Font.Size.M
},
itemStatus: {
marginTop: StyleConstants.Spacing.S
}
})