mirror of
https://github.com/tooot-app/app
synced 2025-02-09 00:18:38 +01:00
Using new text component
Need to use global accessibility checks rather than per text component which is not efficient
This commit is contained in:
parent
8caf315894
commit
7c48c61c99
@ -123,7 +123,7 @@ private_lane :build_ios do
|
||||
end
|
||||
|
||||
desc "Build and deploy Android app"
|
||||
private_lane :build_android do
|
||||
lane :build_android do
|
||||
sh("echo #{ENV["ANDROID_KEYSTORE"]} | base64 -d | tee #{File.expand_path('..', Dir.pwd)}/android/tooot.jks >/dev/null", log: false)
|
||||
|
||||
case ENVIRONMENT
|
||||
|
@ -19,7 +19,7 @@
|
||||
"android": "react-native run-android",
|
||||
"iphone": "react-native run-ios",
|
||||
"ipad": "react-native run-ios --simulator 'iPad mini (6th generation)'",
|
||||
"app:build": "bundle exec fastlane build",
|
||||
"app:build": "bundle exec fastlane build_android",
|
||||
"release": "scripts/release.sh",
|
||||
"clean": "react-native-clean-project",
|
||||
"postinstall": "patch-package"
|
||||
|
@ -5,9 +5,10 @@ import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useCallback } from 'react'
|
||||
import { Pressable, StyleSheet, Text, View } from 'react-native'
|
||||
import { Pressable, View } from 'react-native'
|
||||
import analytics from './analytics'
|
||||
import GracefullyImage from './GracefullyImage'
|
||||
import CustomText from './Text'
|
||||
|
||||
export interface Props {
|
||||
account: Mastodon.Account
|
||||
@ -32,50 +33,45 @@ const ComponentAccount: React.FC<Props> = ({
|
||||
return (
|
||||
<Pressable
|
||||
accessibilityRole='button'
|
||||
style={[styles.itemDefault, styles.itemAccount]}
|
||||
style={{
|
||||
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding,
|
||||
paddingVertical: StyleConstants.Spacing.M,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
}}
|
||||
onPress={customOnPress || onPress}
|
||||
>
|
||||
<GracefullyImage
|
||||
uri={{ original: account.avatar, static: account.avatar_static }}
|
||||
style={styles.itemAccountAvatar}
|
||||
style={{
|
||||
alignSelf: 'flex-start',
|
||||
width: StyleConstants.Avatar.S,
|
||||
height: StyleConstants.Avatar.S,
|
||||
borderRadius: 6,
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
}}
|
||||
/>
|
||||
<View>
|
||||
<Text numberOfLines={1}>
|
||||
<CustomText numberOfLines={1}>
|
||||
<ParseEmojis
|
||||
content={account.display_name || account.username}
|
||||
emojis={account.emojis}
|
||||
size='S'
|
||||
fontBold
|
||||
/>
|
||||
</Text>
|
||||
<Text
|
||||
</CustomText>
|
||||
<CustomText
|
||||
numberOfLines={1}
|
||||
style={[styles.itemAccountAcct, { color: colors.secondary }]}
|
||||
style={{
|
||||
marginTop: StyleConstants.Spacing.XS,
|
||||
color: colors.secondary
|
||||
}}
|
||||
>
|
||||
@{account.acct}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
</Pressable>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
itemDefault: {
|
||||
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding,
|
||||
paddingVertical: StyleConstants.Spacing.M
|
||||
},
|
||||
itemAccount: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
itemAccountAvatar: {
|
||||
alignSelf: 'flex-start',
|
||||
width: StyleConstants.Avatar.S,
|
||||
height: StyleConstants.Avatar.S,
|
||||
borderRadius: 6,
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
},
|
||||
itemAccountAcct: { marginTop: StyleConstants.Spacing.XS }
|
||||
})
|
||||
|
||||
export default ComponentAccount
|
||||
|
@ -7,12 +7,11 @@ import {
|
||||
AccessibilityProps,
|
||||
Pressable,
|
||||
StyleProp,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
ViewStyle
|
||||
} from 'react-native'
|
||||
import { Flow } from 'react-native-animated-spinkit'
|
||||
import CustomText from './Text'
|
||||
|
||||
export interface Props {
|
||||
accessibilityLabel?: AccessibilityProps['accessibilityLabel']
|
||||
@ -116,7 +115,7 @@ const Button: React.FC<Props> = ({
|
||||
case 'text':
|
||||
return (
|
||||
<>
|
||||
<Text
|
||||
<CustomText
|
||||
style={{
|
||||
color: mainColor,
|
||||
fontSize:
|
||||
@ -146,8 +145,10 @@ const Button: React.FC<Props> = ({
|
||||
busy: loading
|
||||
}}
|
||||
style={[
|
||||
styles.button,
|
||||
{
|
||||
borderRadius: 100,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderWidth: overlay ? 0 : 1,
|
||||
borderColor: mainColor,
|
||||
backgroundColor: colorBackground,
|
||||
@ -170,12 +171,4 @@ const Button: React.FC<Props> = ({
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
button: {
|
||||
borderRadius: 100,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}
|
||||
})
|
||||
|
||||
export default Button
|
||||
|
@ -1,3 +1,4 @@
|
||||
import CustomText from '@components/Text'
|
||||
import { useAppDispatch } from '@root/store'
|
||||
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
||||
import { countInstanceEmoji } from '@utils/slices/instancesSlice'
|
||||
@ -11,8 +12,6 @@ import {
|
||||
findNodeHandle,
|
||||
Pressable,
|
||||
SectionList,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
} from 'react-native'
|
||||
import FastImage from 'react-native-fast-image'
|
||||
@ -30,7 +29,12 @@ const EmojisList = React.memo(
|
||||
|
||||
const listHeader = useCallback(
|
||||
({ section: { title } }) => (
|
||||
<Text style={[styles.group, { color: colors.secondary }]}>{title}</Text>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{ position: 'absolute', color: colors.secondary }}
|
||||
>
|
||||
{title}
|
||||
</CustomText>
|
||||
),
|
||||
[]
|
||||
)
|
||||
@ -38,7 +42,15 @@ const EmojisList = React.memo(
|
||||
const listItem = useCallback(
|
||||
({ index, item }: { item: Mastodon.Emoji[]; index: number }) => {
|
||||
return (
|
||||
<View key={index} style={styles.emojis}>
|
||||
<View
|
||||
key={index}
|
||||
style={{
|
||||
flex: 1,
|
||||
flexWrap: 'wrap',
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
}}
|
||||
>
|
||||
{item.map(emoji => {
|
||||
const uri = reduceMotionEnabled ? emoji.static_url : emoji.url
|
||||
if (validUrl.isHttpsUri(uri)) {
|
||||
@ -64,7 +76,12 @@ const EmojisList = React.memo(
|
||||
'screenCompose:content.root.footer.emojis.accessibilityHint'
|
||||
)}
|
||||
source={{ uri }}
|
||||
style={styles.emoji}
|
||||
style={{
|
||||
width: 32,
|
||||
height: 32,
|
||||
padding: StyleConstants.Spacing.S,
|
||||
margin: StyleConstants.Spacing.S
|
||||
}}
|
||||
/>
|
||||
</Pressable>
|
||||
)
|
||||
@ -104,23 +121,4 @@ const EmojisList = React.memo(
|
||||
() => true
|
||||
)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
group: {
|
||||
position: 'absolute',
|
||||
...StyleConstants.FontStyle.S
|
||||
},
|
||||
emojis: {
|
||||
flex: 1,
|
||||
flexWrap: 'wrap',
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
},
|
||||
emoji: {
|
||||
width: 32,
|
||||
height: 32,
|
||||
padding: StyleConstants.Spacing.S,
|
||||
margin: StyleConstants.Spacing.S
|
||||
}
|
||||
})
|
||||
|
||||
export default EmojisList
|
||||
|
@ -4,8 +4,9 @@ import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useCallback } from 'react'
|
||||
import { Pressable, StyleSheet, Text } from 'react-native'
|
||||
import { Pressable } from 'react-native'
|
||||
import analytics from './analytics'
|
||||
import CustomText from './Text'
|
||||
|
||||
export interface Props {
|
||||
hashtag: Mastodon.Tag
|
||||
@ -30,23 +31,14 @@ const ComponentHashtag: React.FC<Props> = ({
|
||||
return (
|
||||
<Pressable
|
||||
accessibilityRole='button'
|
||||
style={styles.itemDefault}
|
||||
style={{ padding: StyleConstants.Spacing.S * 1.5 }}
|
||||
onPress={customOnPress || onPress}
|
||||
>
|
||||
<Text style={[styles.itemHashtag, { color: colors.primaryDefault }]}>
|
||||
<CustomText fontStyle='M' style={{ color: colors.primaryDefault }}>
|
||||
#{hashtag.name}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</Pressable>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
itemDefault: {
|
||||
padding: StyleConstants.Spacing.S * 1.5
|
||||
},
|
||||
itemHashtag: {
|
||||
...StyleConstants.FontStyle.M
|
||||
}
|
||||
})
|
||||
|
||||
export default ComponentHashtag
|
||||
|
@ -1,7 +1,7 @@
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { StyleSheet, Text } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
content: string
|
||||
@ -14,11 +14,12 @@ const HeaderCenter = React.memo(
|
||||
const { colors } = useTheme()
|
||||
|
||||
return (
|
||||
<Text
|
||||
style={[
|
||||
styles.text,
|
||||
{ color: inverted ? colors.primaryOverlay : colors.primaryDefault }
|
||||
]}
|
||||
<CustomText
|
||||
style={{
|
||||
fontSize: 18,
|
||||
fontWeight: StyleConstants.Font.Weight.Bold,
|
||||
color: inverted ? colors.primaryOverlay : colors.primaryDefault
|
||||
}}
|
||||
children={content}
|
||||
/>
|
||||
)
|
||||
@ -26,11 +27,4 @@ const HeaderCenter = React.memo(
|
||||
(prev, next) => prev.content === next.content
|
||||
)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
text: {
|
||||
fontSize: 18,
|
||||
fontWeight: StyleConstants.Font.Weight.Bold
|
||||
}
|
||||
})
|
||||
|
||||
export default HeaderCenter
|
||||
|
@ -1,8 +1,9 @@
|
||||
import Icon from '@components/Icon'
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useMemo } from 'react'
|
||||
import { Pressable, StyleSheet, Text } from 'react-native'
|
||||
import { Pressable } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
type?: 'icon' | 'text'
|
||||
@ -34,8 +35,9 @@ const HeaderLeft: React.FC<Props> = ({
|
||||
)
|
||||
case 'text':
|
||||
return (
|
||||
<Text
|
||||
style={[styles.text, { color: colors.primaryDefault }]}
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{ color: colors.primaryDefault }}
|
||||
children={content}
|
||||
/>
|
||||
)
|
||||
@ -46,38 +48,27 @@ const HeaderLeft: React.FC<Props> = ({
|
||||
<Pressable
|
||||
onPress={onPress}
|
||||
children={children}
|
||||
style={[
|
||||
styles.base,
|
||||
{
|
||||
backgroundColor: background
|
||||
? colors.backgroundOverlayDefault
|
||||
: undefined,
|
||||
minHeight: 44,
|
||||
minWidth: 44,
|
||||
marginLeft: native
|
||||
? -StyleConstants.Spacing.S
|
||||
: StyleConstants.Spacing.S,
|
||||
...(type === 'icon' && {
|
||||
borderRadius: 100
|
||||
}),
|
||||
...(type === 'text' && {
|
||||
paddingHorizontal: StyleConstants.Spacing.S
|
||||
})
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: background
|
||||
? colors.backgroundOverlayDefault
|
||||
: undefined,
|
||||
minHeight: 44,
|
||||
minWidth: 44,
|
||||
marginLeft: native
|
||||
? -StyleConstants.Spacing.S
|
||||
: StyleConstants.Spacing.S,
|
||||
...(type === 'icon' && {
|
||||
borderRadius: 100
|
||||
}),
|
||||
...(type === 'text' && {
|
||||
paddingHorizontal: StyleConstants.Spacing.S
|
||||
})
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
text: {
|
||||
...StyleConstants.FontStyle.M
|
||||
}
|
||||
})
|
||||
|
||||
export default HeaderLeft
|
||||
|
@ -1,14 +1,9 @@
|
||||
import Icon from '@components/Icon'
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useMemo } from 'react'
|
||||
import {
|
||||
AccessibilityProps,
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
} from 'react-native'
|
||||
import { AccessibilityProps, Pressable, View } from 'react-native'
|
||||
import { Flow } from 'react-native-animated-spinkit'
|
||||
|
||||
export interface Props {
|
||||
@ -72,14 +67,12 @@ const HeaderRight: React.FC<Props> = ({
|
||||
case 'text':
|
||||
return (
|
||||
<>
|
||||
<Text
|
||||
style={[
|
||||
styles.text,
|
||||
{
|
||||
color: disabled ? colors.secondary : colors.primaryDefault,
|
||||
opacity: loading ? 0 : 1
|
||||
}
|
||||
]}
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
color: disabled ? colors.secondary : colors.primaryDefault,
|
||||
opacity: loading ? 0 : 1
|
||||
}}
|
||||
children={content}
|
||||
/>
|
||||
{loading && loadingSpinkit}
|
||||
@ -97,38 +90,27 @@ const HeaderRight: React.FC<Props> = ({
|
||||
onPress={onPress}
|
||||
children={children}
|
||||
disabled={disabled || loading}
|
||||
style={[
|
||||
styles.base,
|
||||
{
|
||||
backgroundColor: background
|
||||
? colors.backgroundOverlayDefault
|
||||
: undefined,
|
||||
minHeight: 44,
|
||||
minWidth: 44,
|
||||
marginRight: native
|
||||
? -StyleConstants.Spacing.S
|
||||
: StyleConstants.Spacing.S,
|
||||
...(type === 'icon' && {
|
||||
borderRadius: 100
|
||||
}),
|
||||
...(type === 'text' && {
|
||||
paddingHorizontal: StyleConstants.Spacing.S
|
||||
})
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: background
|
||||
? colors.backgroundOverlayDefault
|
||||
: undefined,
|
||||
minHeight: 44,
|
||||
minWidth: 44,
|
||||
marginRight: native
|
||||
? -StyleConstants.Spacing.S
|
||||
: StyleConstants.Spacing.S,
|
||||
...(type === 'icon' && {
|
||||
borderRadius: 100
|
||||
}),
|
||||
...(type === 'text' && {
|
||||
paddingHorizontal: StyleConstants.Spacing.S
|
||||
})
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
text: {
|
||||
...StyleConstants.FontStyle.M
|
||||
}
|
||||
})
|
||||
|
||||
export default HeaderRight
|
||||
|
@ -9,17 +9,11 @@ import React, {
|
||||
useRef,
|
||||
useState
|
||||
} from 'react'
|
||||
import {
|
||||
Platform,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
TextInputProps,
|
||||
View
|
||||
} from 'react-native'
|
||||
import { Platform, TextInput, TextInputProps, View } from 'react-native'
|
||||
import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated'
|
||||
import { ComponentEmojis, EmojisButton, EmojisList } from './Emojis'
|
||||
import EmojisContext from './Emojis/helpers/EmojisContext'
|
||||
import CustomText from './Text'
|
||||
|
||||
export interface Props {
|
||||
autoFocus?: boolean
|
||||
@ -106,14 +100,14 @@ const Input: React.FC<Props> = ({
|
||||
maxLength={options?.maxLength}
|
||||
>
|
||||
<View
|
||||
style={[
|
||||
styles.base,
|
||||
{
|
||||
borderColor: colors.border,
|
||||
flexDirection: multiline ? 'column' : 'row',
|
||||
alignItems: 'stretch'
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
marginVertical: StyleConstants.Spacing.S,
|
||||
padding: StyleConstants.Spacing.S,
|
||||
borderColor: colors.border,
|
||||
flexDirection: multiline ? 'column' : 'row',
|
||||
alignItems: 'stretch'
|
||||
}}
|
||||
>
|
||||
<EmojisContext.Consumer>
|
||||
{({ emojisDispatch }) => (
|
||||
@ -124,16 +118,15 @@ const Input: React.FC<Props> = ({
|
||||
setInputFocused(false)
|
||||
emojisDispatch({ type: 'activate', payload: false })
|
||||
}}
|
||||
style={[
|
||||
styles.textInput,
|
||||
{
|
||||
color: colors.primaryDefault,
|
||||
minHeight:
|
||||
Platform.OS === 'ios' && multiline
|
||||
? StyleConstants.Font.LineHeight.M * 5
|
||||
: undefined
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
flex: 1,
|
||||
fontSize: StyleConstants.Font.Size.M,
|
||||
color: colors.primaryDefault,
|
||||
minHeight:
|
||||
Platform.OS === 'ios' && multiline
|
||||
? StyleConstants.Font.LineHeight.M * 5
|
||||
: undefined
|
||||
}}
|
||||
onChangeText={setValue}
|
||||
onSelectionChange={onSelectionChange}
|
||||
value={value}
|
||||
@ -149,16 +142,25 @@ const Input: React.FC<Props> = ({
|
||||
</EmojisContext.Consumer>
|
||||
{title ? (
|
||||
<Animated.Text
|
||||
style={[styles.title, animateTitle, { color: colors.secondary }]}
|
||||
style={[
|
||||
animateTitle,
|
||||
{ position: 'absolute', color: colors.secondary }
|
||||
]}
|
||||
>
|
||||
{title}
|
||||
</Animated.Text>
|
||||
) : null}
|
||||
<View style={{ flexDirection: 'row', alignSelf: 'flex-end' }}>
|
||||
{options?.maxLength && value?.length ? (
|
||||
<Text style={[styles.maxLength, { color: colors.secondary }]}>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
paddingLeft: StyleConstants.Spacing.XS,
|
||||
color: colors.secondary
|
||||
}}
|
||||
>
|
||||
{value?.length} / {options.maxLength}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
{inputFocused ? <EmojisButton /> : null}
|
||||
</View>
|
||||
@ -168,24 +170,4 @@ const Input: React.FC<Props> = ({
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
alignItems: 'flex-end',
|
||||
borderWidth: 1,
|
||||
marginVertical: StyleConstants.Spacing.S,
|
||||
padding: StyleConstants.Spacing.S
|
||||
},
|
||||
title: {
|
||||
position: 'absolute'
|
||||
},
|
||||
textInput: {
|
||||
flex: 1,
|
||||
fontSize: StyleConstants.Font.Size.M
|
||||
},
|
||||
maxLength: {
|
||||
...StyleConstants.FontStyle.S,
|
||||
paddingLeft: StyleConstants.Spacing.XS
|
||||
}
|
||||
})
|
||||
|
||||
export default Input
|
||||
|
@ -15,8 +15,6 @@ import {
|
||||
Image,
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
View
|
||||
} from 'react-native'
|
||||
@ -26,6 +24,7 @@ import { Placeholder } from 'rn-placeholder'
|
||||
import analytics from './analytics'
|
||||
import InstanceAuth from './Instance/Auth'
|
||||
import InstanceInfo from './Instance/Info'
|
||||
import CustomText from './Text'
|
||||
|
||||
export interface Props {
|
||||
scrollViewRef?: RefObject<ScrollView>
|
||||
@ -134,40 +133,50 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
|
||||
>
|
||||
{!disableHeaderImage ? (
|
||||
<View style={styles.imageContainer}>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<Image
|
||||
source={require('assets/images/welcome.png')}
|
||||
style={styles.image}
|
||||
style={{ resizeMode: 'contain', flex: 1, aspectRatio: 16 / 9 }}
|
||||
/>
|
||||
</View>
|
||||
) : null}
|
||||
<View style={styles.base}>
|
||||
<View style={styles.inputRow}>
|
||||
<View
|
||||
style={{
|
||||
marginTop: StyleConstants.Spacing.L,
|
||||
marginHorizontal: StyleConstants.Spacing.Global.PagePadding
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
marginHorizontal: StyleConstants.Spacing.Global.PagePadding
|
||||
}}
|
||||
>
|
||||
<TextInput
|
||||
accessible={false}
|
||||
accessibilityRole='none'
|
||||
style={[
|
||||
styles.prefix,
|
||||
{
|
||||
color: colors.primaryDefault,
|
||||
borderBottomColor: instanceQuery.isError
|
||||
? colors.red
|
||||
: colors.border
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
borderBottomWidth: 1,
|
||||
...StyleConstants.FontStyle.M,
|
||||
color: colors.primaryDefault,
|
||||
borderBottomColor: instanceQuery.isError
|
||||
? colors.red
|
||||
: colors.border
|
||||
}}
|
||||
editable={false}
|
||||
defaultValue='https://'
|
||||
/>
|
||||
<TextInput
|
||||
style={[
|
||||
styles.textInput,
|
||||
{
|
||||
color: colors.primaryDefault,
|
||||
borderBottomColor: instanceQuery.isError
|
||||
? colors.red
|
||||
: colors.border
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
flex: 1,
|
||||
borderBottomWidth: 1,
|
||||
...StyleConstants.FontStyle.M,
|
||||
marginRight: StyleConstants.Spacing.M,
|
||||
color: colors.primaryDefault,
|
||||
borderBottomColor: instanceQuery.isError
|
||||
? colors.red
|
||||
: colors.border
|
||||
}}
|
||||
onChangeText={onChangeText}
|
||||
autoCapitalize='none'
|
||||
clearButtonMode='never'
|
||||
@ -205,9 +214,9 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
content={instanceQuery.data?.title || undefined}
|
||||
potentialWidth={2}
|
||||
/>
|
||||
<View style={styles.instanceStats}>
|
||||
<View style={{ flex: 1, flexDirection: 'row' }}>
|
||||
<InstanceInfo
|
||||
style={styles.stat1}
|
||||
style={{ alignItems: 'flex-start' }}
|
||||
header={t('server.information.accounts')}
|
||||
content={
|
||||
instanceQuery.data?.stats?.user_count?.toString() || undefined
|
||||
@ -215,7 +224,7 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
potentialWidth={4}
|
||||
/>
|
||||
<InstanceInfo
|
||||
style={styles.stat2}
|
||||
style={{ alignItems: 'center' }}
|
||||
header={t('server.information.statuses')}
|
||||
content={
|
||||
instanceQuery.data?.stats?.status_count?.toString() ||
|
||||
@ -224,7 +233,7 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
potentialWidth={4}
|
||||
/>
|
||||
<InstanceInfo
|
||||
style={styles.stat3}
|
||||
style={{ alignItems: 'flex-end' }}
|
||||
header={t('server.information.domains')}
|
||||
content={
|
||||
instanceQuery.data?.stats?.domain_count?.toString() ||
|
||||
@ -234,15 +243,28 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
/>
|
||||
</View>
|
||||
</Placeholder>
|
||||
<View style={styles.disclaimer}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
marginHorizontal: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginVertical: StyleConstants.Spacing.M
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
name='Lock'
|
||||
size={StyleConstants.Font.Size.S}
|
||||
color={colors.secondary}
|
||||
style={styles.disclaimerIcon}
|
||||
style={{
|
||||
marginTop:
|
||||
(StyleConstants.Font.LineHeight.S -
|
||||
StyleConstants.Font.Size.S) /
|
||||
2,
|
||||
marginRight: StyleConstants.Spacing.XS
|
||||
}}
|
||||
/>
|
||||
<Text
|
||||
style={[styles.disclaimerText, { color: colors.secondary }]}
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{ flex: 1, color: colors.secondary }}
|
||||
accessibilityRole='link'
|
||||
onPress={() => {
|
||||
if (screenReaderEnabled) {
|
||||
@ -254,7 +276,7 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
}}
|
||||
>
|
||||
{t('server.disclaimer.base')}
|
||||
<Text
|
||||
<CustomText
|
||||
accessible
|
||||
style={{ color: colors.blue }}
|
||||
onPress={() => {
|
||||
@ -265,8 +287,8 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
}}
|
||||
>
|
||||
{t('server.disclaimer.privacy')}
|
||||
</Text>
|
||||
</Text>
|
||||
</CustomText>
|
||||
</CustomText>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
@ -276,54 +298,4 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
imageContainer: { flexDirection: 'row' },
|
||||
image: { resizeMode: 'contain', flex: 1, aspectRatio: 16 / 9 },
|
||||
base: {
|
||||
marginTop: StyleConstants.Spacing.L,
|
||||
marginHorizontal: StyleConstants.Spacing.Global.PagePadding
|
||||
},
|
||||
inputRow: {
|
||||
flexDirection: 'row',
|
||||
marginHorizontal: StyleConstants.Spacing.Global.PagePadding
|
||||
},
|
||||
prefix: {
|
||||
borderBottomWidth: 1,
|
||||
...StyleConstants.FontStyle.M
|
||||
},
|
||||
textInput: {
|
||||
flex: 1,
|
||||
borderBottomWidth: 1,
|
||||
...StyleConstants.FontStyle.M,
|
||||
marginRight: StyleConstants.Spacing.M
|
||||
},
|
||||
instanceStats: {
|
||||
flex: 1,
|
||||
flexDirection: 'row'
|
||||
},
|
||||
stat1: {
|
||||
alignItems: 'flex-start'
|
||||
},
|
||||
stat2: {
|
||||
alignItems: 'center'
|
||||
},
|
||||
stat3: {
|
||||
alignItems: 'flex-end'
|
||||
},
|
||||
disclaimer: {
|
||||
flexDirection: 'row',
|
||||
marginHorizontal: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginVertical: StyleConstants.Spacing.M
|
||||
},
|
||||
disclaimerIcon: {
|
||||
marginTop:
|
||||
(StyleConstants.Font.LineHeight.S - StyleConstants.Font.Size.S) / 2,
|
||||
marginRight: StyleConstants.Spacing.XS
|
||||
},
|
||||
disclaimerText: {
|
||||
flex: 1,
|
||||
...StyleConstants.FontStyle.S
|
||||
}
|
||||
})
|
||||
|
||||
export default ComponentInstance
|
||||
|
@ -1,7 +1,8 @@
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { StyleSheet, Text, View, ViewStyle } from 'react-native'
|
||||
import { View, ViewStyle } from 'react-native'
|
||||
import { PlaceholderLine } from 'rn-placeholder'
|
||||
|
||||
export interface Props {
|
||||
@ -16,14 +17,33 @@ const InstanceInfo = React.memo(
|
||||
const { colors } = useTheme()
|
||||
|
||||
return (
|
||||
<View style={[styles.base, style]} accessible>
|
||||
<Text style={[styles.header, { color: colors.primaryDefault }]}>
|
||||
{header}
|
||||
</Text>
|
||||
<View
|
||||
style={[
|
||||
{
|
||||
flex: 1,
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
paddingLeft: StyleConstants.Spacing.Global.PagePadding,
|
||||
paddingRight: StyleConstants.Spacing.Global.PagePadding
|
||||
},
|
||||
style
|
||||
]}
|
||||
accessible
|
||||
>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
fontWeight: StyleConstants.Font.Weight.Bold,
|
||||
marginBottom: StyleConstants.Spacing.XS,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
children={header}
|
||||
/>
|
||||
{content ? (
|
||||
<Text style={[styles.content, { color: colors.primaryDefault }]}>
|
||||
{content}
|
||||
</Text>
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{ color: colors.primaryDefault }}
|
||||
children={content}
|
||||
/>
|
||||
) : (
|
||||
<PlaceholderLine
|
||||
width={
|
||||
@ -43,21 +63,4 @@ const InstanceInfo = React.memo(
|
||||
(prev, next) => prev.content === next.content
|
||||
)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
flex: 1,
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
paddingLeft: StyleConstants.Spacing.Global.PagePadding,
|
||||
paddingRight: StyleConstants.Spacing.Global.PagePadding
|
||||
},
|
||||
header: {
|
||||
...StyleConstants.FontStyle.S,
|
||||
fontWeight: StyleConstants.Font.Weight.Bold,
|
||||
marginBottom: StyleConstants.Spacing.XS
|
||||
},
|
||||
content: {
|
||||
...StyleConstants.FontStyle.M
|
||||
}
|
||||
})
|
||||
|
||||
export default InstanceInfo
|
||||
|
@ -1,7 +1,8 @@
|
||||
import React from 'react'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import CustomText from '@components/Text'
|
||||
|
||||
export interface Props {
|
||||
heading: string
|
||||
@ -11,20 +12,16 @@ const MenuHeader: React.FC<Props> = ({ heading }) => {
|
||||
const { colors } = useTheme()
|
||||
|
||||
return (
|
||||
<View style={styles.base}>
|
||||
<Text style={[styles.text, { color: colors.secondary }]}>{heading}</Text>
|
||||
<View style={{ paddingBottom: StyleConstants.Spacing.S }}>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
fontWeight='Bold'
|
||||
style={{ color: colors.secondary }}
|
||||
>
|
||||
{heading}
|
||||
</CustomText>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
paddingBottom: StyleConstants.Spacing.S
|
||||
},
|
||||
text: {
|
||||
...StyleConstants.FontStyle.S,
|
||||
fontWeight: StyleConstants.Font.Weight.Bold
|
||||
}
|
||||
})
|
||||
|
||||
export default MenuHeader
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Icon from '@components/Icon'
|
||||
import CustomText from '@components/Text'
|
||||
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
@ -99,12 +100,13 @@ const MenuRow: React.FC<Props> = ({
|
||||
/>
|
||||
) : null}
|
||||
<View style={styles.main}>
|
||||
<Text
|
||||
style={[styles.title, { color: colors.primaryDefault }]}
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{ color: colors.primaryDefault }}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{title}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@ -112,18 +114,15 @@ const MenuRow: React.FC<Props> = ({
|
||||
<View style={styles.back}>
|
||||
{content ? (
|
||||
typeof content === 'string' ? (
|
||||
<Text
|
||||
style={[
|
||||
styles.content,
|
||||
{
|
||||
color: colors.secondary,
|
||||
opacity: !iconBack && loading ? 0 : 1
|
||||
}
|
||||
]}
|
||||
<CustomText
|
||||
style={{
|
||||
color: colors.secondary,
|
||||
opacity: !iconBack && loading ? 0 : 1
|
||||
}}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{content}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : (
|
||||
content
|
||||
)
|
||||
@ -150,9 +149,9 @@ const MenuRow: React.FC<Props> = ({
|
||||
) : null}
|
||||
</View>
|
||||
{description ? (
|
||||
<Text style={[styles.description, { color: colors.secondary }]}>
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
{description}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
</View>
|
||||
</TapGestureHandler>
|
||||
@ -187,9 +186,6 @@ const styles = StyleSheet.create({
|
||||
main: {
|
||||
flex: 1
|
||||
},
|
||||
title: {
|
||||
...StyleConstants.FontStyle.M
|
||||
},
|
||||
description: {
|
||||
...StyleConstants.FontStyle.S
|
||||
},
|
||||
|
@ -1,10 +1,11 @@
|
||||
import CustomText from '@components/Text'
|
||||
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
||||
import { getSettingsFontsize } from '@utils/slices/settingsSlice'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { adaptiveScale } from '@utils/styles/scaling'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useMemo } from 'react'
|
||||
import { StyleSheet, Text } from 'react-native'
|
||||
import { StyleSheet } from 'react-native'
|
||||
import FastImage from 'react-native-fast-image'
|
||||
import { useSelector } from 'react-redux'
|
||||
import validUrl from 'valid-url'
|
||||
@ -57,7 +58,7 @@ const ParseEmojis = React.memo(
|
||||
}, [theme, adaptiveFontsize])
|
||||
|
||||
return (
|
||||
<Text style={styles.text}>
|
||||
<CustomText style={styles.text}>
|
||||
{emojis ? (
|
||||
content
|
||||
.split(regexEmoji)
|
||||
@ -69,30 +70,34 @@ const ParseEmojis = React.memo(
|
||||
return emojiShortcode === `:${emoji.shortcode}:`
|
||||
})
|
||||
if (emojiIndex === -1) {
|
||||
return <Text key={emojiShortcode + i}>{emojiShortcode}</Text>
|
||||
return (
|
||||
<CustomText key={emojiShortcode + i}>
|
||||
{emojiShortcode}
|
||||
</CustomText>
|
||||
)
|
||||
} else {
|
||||
const uri = reduceMotionEnabled
|
||||
? emojis[emojiIndex].static_url
|
||||
: emojis[emojiIndex].url
|
||||
if (validUrl.isHttpsUri(uri)) {
|
||||
return (
|
||||
<Text key={emojiShortcode + i}>
|
||||
<CustomText key={emojiShortcode + i}>
|
||||
{i === 0 ? ' ' : undefined}
|
||||
<FastImage source={{ uri }} style={styles.image} />
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return <Text key={i}>{str}</Text>
|
||||
return <CustomText key={i}>{str}</CustomText>
|
||||
}
|
||||
})
|
||||
) : (
|
||||
<Text>{content}</Text>
|
||||
<CustomText>{content}</CustomText>
|
||||
)}
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
},
|
||||
(prev, next) => prev.content === next.content
|
||||
|
@ -2,6 +2,7 @@ import analytics from '@components/analytics'
|
||||
import Icon from '@components/Icon'
|
||||
import openLink from '@components/openLink'
|
||||
import ParseEmojis from '@components/Parse/Emojis'
|
||||
import CustomText from '@components/Text'
|
||||
import { useNavigation, useRoute } from '@react-navigation/native'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
||||
@ -12,7 +13,7 @@ import { adaptiveScale } from '@utils/styles/scaling'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Pressable, Text, View } from 'react-native'
|
||||
import { Pressable, View } from 'react-native'
|
||||
import HTMLView from 'react-native-htmlview'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
@ -53,7 +54,7 @@ const renderNode = ({
|
||||
? routeParams.hashtag !== tag[1] && routeParams.hashtag !== tag[2]
|
||||
: true
|
||||
return (
|
||||
<Text
|
||||
<CustomText
|
||||
accessible
|
||||
key={index}
|
||||
style={{
|
||||
@ -72,7 +73,7 @@ const renderNode = ({
|
||||
>
|
||||
{node.children[0].data}
|
||||
{node.children[1]?.children[0].data}
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
} else if (classes.includes('mention') && mentions) {
|
||||
const accountIndex = mentions.findIndex(
|
||||
@ -82,7 +83,7 @@ const renderNode = ({
|
||||
? routeParams.account.id !== mentions[accountIndex]?.id
|
||||
: true
|
||||
return (
|
||||
<Text
|
||||
<CustomText
|
||||
key={index}
|
||||
style={{
|
||||
color:
|
||||
@ -102,7 +103,7 @@ const renderNode = ({
|
||||
>
|
||||
{node.children[0].data}
|
||||
{node.children[1]?.children[0].data}
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
}
|
||||
} else {
|
||||
@ -113,7 +114,7 @@ const renderNode = ({
|
||||
const shouldBeTag =
|
||||
tags && tags.filter(tag => `#${tag.name}` === content).length > 0
|
||||
return (
|
||||
<Text
|
||||
<CustomText
|
||||
key={index}
|
||||
style={{
|
||||
color: colors.blue,
|
||||
@ -142,7 +143,7 @@ const renderNode = ({
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
}
|
||||
break
|
||||
@ -252,7 +253,7 @@ const ParseHTML = React.memo(
|
||||
|
||||
return (
|
||||
<View style={{ overflow: 'hidden' }}>
|
||||
<Text
|
||||
<CustomText
|
||||
children={children}
|
||||
onTextLayout={onTextLayout}
|
||||
numberOfLines={
|
||||
@ -275,7 +276,7 @@ const ParseHTML = React.memo(
|
||||
backgroundColor: colors.backgroundDefault
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
<CustomText
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
...StyleConstants.FontStyle.S,
|
||||
|
76
src/components/Text.tsx
Normal file
76
src/components/Text.tsx
Normal file
@ -0,0 +1,76 @@
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { AccessibilityInfo, Text, TextProps, TextStyle } from 'react-native'
|
||||
|
||||
type Props =
|
||||
| {
|
||||
style?: Omit<TextStyle, 'fontSize' | 'lineHeight' | 'fontWeight'>
|
||||
fontStyle?: undefined
|
||||
fontSize?: 'S' | 'M' | 'L'
|
||||
lineHeight?: 'S' | 'M' | 'L'
|
||||
fontWeight?: 'Normal' | 'Bold'
|
||||
}
|
||||
| {
|
||||
style?: Omit<TextStyle, 'fontSize' | 'lineHeight' | 'fontWeight'>
|
||||
fontStyle: 'S' | 'M' | 'L'
|
||||
fontSize?: undefined
|
||||
lineHeight?: undefined
|
||||
fontWeight?: 'Normal' | 'Bold'
|
||||
}
|
||||
|
||||
const CustomText: React.FC<Props & TextProps> = ({
|
||||
children,
|
||||
style,
|
||||
fontStyle,
|
||||
fontSize,
|
||||
fontWeight = 'Normal',
|
||||
lineHeight,
|
||||
...rest
|
||||
}) => {
|
||||
const [isBoldText, setIsBoldText] = useState(false)
|
||||
useEffect(() => {
|
||||
const boldTextChangedSubscription = AccessibilityInfo.addEventListener(
|
||||
'boldTextChanged',
|
||||
boldTextChanged => {
|
||||
setIsBoldText(boldTextChanged)
|
||||
}
|
||||
)
|
||||
|
||||
AccessibilityInfo.isBoldTextEnabled().then(boldTextEnabled => {
|
||||
setIsBoldText(boldTextEnabled)
|
||||
})
|
||||
|
||||
return () => {
|
||||
boldTextChangedSubscription.remove()
|
||||
}
|
||||
}, [])
|
||||
enum BoldMapping {
|
||||
'Normal' = '600',
|
||||
'Bold' = '800'
|
||||
}
|
||||
|
||||
return (
|
||||
<Text
|
||||
style={[
|
||||
style,
|
||||
{ ...(fontStyle && StyleConstants.FontStyle[fontStyle]) },
|
||||
{ ...(fontSize && { fontSize: StyleConstants.Font.Size[fontSize] }) },
|
||||
{
|
||||
...(lineHeight && {
|
||||
lineHeight: StyleConstants.Font.LineHeight[lineHeight]
|
||||
})
|
||||
},
|
||||
{
|
||||
fontWeight: isBoldText
|
||||
? BoldMapping[fontWeight]
|
||||
: StyleConstants.Font.Weight[fontWeight]
|
||||
}
|
||||
]}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
|
||||
export default CustomText
|
@ -1,12 +1,13 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Button from '@components/Button'
|
||||
import Icon from '@components/Icon'
|
||||
import CustomText from '@components/Text'
|
||||
import { QueryKeyTimeline, useTimelineQuery } from '@utils/queryHooks/timeline'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
import { Circle } from 'react-native-animated-spinkit'
|
||||
|
||||
export interface Props {
|
||||
@ -40,9 +41,16 @@ const TimelineEmpty = React.memo(
|
||||
size={StyleConstants.Font.Size.L}
|
||||
color={colors.primaryDefault}
|
||||
/>
|
||||
<Text style={[styles.error, { color: colors.primaryDefault }]}>
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
marginTop: StyleConstants.Spacing.S,
|
||||
marginBottom: StyleConstants.Spacing.L,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{t('empty.error.message')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
<Button
|
||||
type='text'
|
||||
content={t('empty.error.button')}
|
||||
@ -61,9 +69,16 @@ const TimelineEmpty = React.memo(
|
||||
size={StyleConstants.Font.Size.L}
|
||||
color={colors.primaryDefault}
|
||||
/>
|
||||
<Text style={[styles.error, { color: colors.primaryDefault }]}>
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
marginTop: StyleConstants.Spacing.S,
|
||||
marginBottom: StyleConstants.Spacing.L,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{t('empty.success.message')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@ -85,12 +100,4 @@ const TimelineEmpty = React.memo(
|
||||
() => true
|
||||
)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
error: {
|
||||
...StyleConstants.FontStyle.M,
|
||||
marginTop: StyleConstants.Spacing.S,
|
||||
marginBottom: StyleConstants.Spacing.L
|
||||
}
|
||||
})
|
||||
|
||||
export default TimelineEmpty
|
||||
|
@ -1,10 +1,11 @@
|
||||
import Icon from '@components/Icon'
|
||||
import CustomText from '@components/Text'
|
||||
import { QueryKeyTimeline, useTimelineQuery } from '@utils/queryHooks/timeline'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { Text, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
import { Circle } from 'react-native-animated-spinkit'
|
||||
|
||||
export interface Props {
|
||||
@ -38,9 +39,7 @@ const TimelineFooter = React.memo(
|
||||
{!disableInfinity && hasNextPage ? (
|
||||
<Circle size={StyleConstants.Font.Size.L} color={colors.secondary} />
|
||||
) : (
|
||||
<Text
|
||||
style={{ ...StyleConstants.FontStyle.S, color: colors.secondary }}
|
||||
>
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
<Trans
|
||||
i18nKey='componentTimeline:end.message'
|
||||
components={[
|
||||
@ -51,7 +50,7 @@ const TimelineFooter = React.memo(
|
||||
/>
|
||||
]}
|
||||
/>
|
||||
</Text>
|
||||
</CustomText>
|
||||
)}
|
||||
</View>
|
||||
)
|
||||
|
@ -1,8 +1,9 @@
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Text, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
|
||||
const TimelineLookback = React.memo(
|
||||
() => {
|
||||
@ -19,14 +20,9 @@ const TimelineLookback = React.memo(
|
||||
backgroundColor: colors.backgroundDefault
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
...StyleConstants.FontStyle.S,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
<CustomText fontStyle='S' style={{ color: colors.primaryDefault }}>
|
||||
{t('lookback.message')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
)
|
||||
},
|
||||
|
@ -1,5 +1,6 @@
|
||||
import haptics from '@components/haptics'
|
||||
import Icon from '@components/Icon'
|
||||
import CustomText from '@components/Text'
|
||||
import {
|
||||
QueryKeyTimeline,
|
||||
TimelineData,
|
||||
@ -9,7 +10,7 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { RefObject, useCallback, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { FlatList, Platform, StyleSheet, Text, View } from 'react-native'
|
||||
import { FlatList, Platform, View } from 'react-native'
|
||||
import { Circle } from 'react-native-animated-spinkit'
|
||||
import Animated, {
|
||||
Extrapolate,
|
||||
@ -251,9 +252,18 @@ const TimelineRefresh: React.FC<Props> = ({
|
||||
|
||||
return (
|
||||
<Animated.View style={headerPadding}>
|
||||
<View style={styles.base}>
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: CONTAINER_HEIGHT * 2,
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
{isFetching ? (
|
||||
<View style={styles.container2}>
|
||||
<View style={{ height: CONTAINER_HEIGHT, justifyContent: 'center' }}>
|
||||
<Circle
|
||||
size={StyleConstants.Font.Size.L}
|
||||
color={colors.secondary}
|
||||
@ -261,9 +271,19 @@ const TimelineRefresh: React.FC<Props> = ({
|
||||
</View>
|
||||
) : (
|
||||
<>
|
||||
<View style={styles.container1}>
|
||||
<Text
|
||||
style={[styles.explanation, { color: colors.primaryDefault }]}
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
height: CONTAINER_HEIGHT
|
||||
}}
|
||||
>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
lineHeight: CONTAINER_HEIGHT,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
onLayout={onLayout}
|
||||
children={t('refresh.fetchPreviousPage')}
|
||||
/>
|
||||
@ -285,9 +305,15 @@ const TimelineRefresh: React.FC<Props> = ({
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.container2}>
|
||||
<Text
|
||||
style={[styles.explanation, { color: colors.primaryDefault }]}
|
||||
<View
|
||||
style={{ height: CONTAINER_HEIGHT, justifyContent: 'center' }}
|
||||
>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
lineHeight: CONTAINER_HEIGHT,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
onLayout={onLayout}
|
||||
children={t('refresh.refetch')}
|
||||
/>
|
||||
@ -299,25 +325,4 @@ const TimelineRefresh: React.FC<Props> = ({
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: CONTAINER_HEIGHT * 2,
|
||||
alignItems: 'center'
|
||||
},
|
||||
container1: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
height: CONTAINER_HEIGHT
|
||||
},
|
||||
container2: { height: CONTAINER_HEIGHT, justifyContent: 'center' },
|
||||
explanation: {
|
||||
fontSize: StyleConstants.Font.Size.S,
|
||||
lineHeight: CONTAINER_HEIGHT
|
||||
}
|
||||
})
|
||||
|
||||
export default TimelineRefresh
|
||||
|
@ -1,6 +1,7 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Icon from '@components/Icon'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import CustomText from '@components/Text'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import { RootStackParamList } from '@utils/navigation/navigators'
|
||||
@ -13,7 +14,7 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Pressable, StyleSheet, Text, View } from 'react-native'
|
||||
import { Pressable, StyleSheet, View } from 'react-native'
|
||||
import { useQueryClient } from 'react-query'
|
||||
|
||||
export interface Props {
|
||||
@ -185,7 +186,7 @@ const TimelineActions: React.FC<Props> = ({
|
||||
size={StyleConstants.Font.Size.L}
|
||||
/>
|
||||
{status.replies_count > 0 ? (
|
||||
<Text
|
||||
<CustomText
|
||||
style={{
|
||||
color: colors.secondary,
|
||||
fontSize: StyleConstants.Font.Size.M,
|
||||
@ -193,7 +194,7 @@ const TimelineActions: React.FC<Props> = ({
|
||||
}}
|
||||
>
|
||||
{status.replies_count}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
</>
|
||||
),
|
||||
@ -213,7 +214,7 @@ const TimelineActions: React.FC<Props> = ({
|
||||
size={StyleConstants.Font.Size.L}
|
||||
/>
|
||||
{status.reblogs_count > 0 ? (
|
||||
<Text
|
||||
<CustomText
|
||||
style={{
|
||||
color: color(status.reblogged),
|
||||
fontSize: StyleConstants.Font.Size.M,
|
||||
@ -221,7 +222,7 @@ const TimelineActions: React.FC<Props> = ({
|
||||
}}
|
||||
>
|
||||
{status.reblogs_count}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
@ -236,7 +237,7 @@ const TimelineActions: React.FC<Props> = ({
|
||||
size={StyleConstants.Font.Size.L}
|
||||
/>
|
||||
{status.favourites_count > 0 ? (
|
||||
<Text
|
||||
<CustomText
|
||||
style={{
|
||||
color: color(status.favourited),
|
||||
fontSize: StyleConstants.Font.Size.M,
|
||||
@ -245,7 +246,7 @@ const TimelineActions: React.FC<Props> = ({
|
||||
}}
|
||||
>
|
||||
{status.favourites_count}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
@ -269,7 +270,7 @@ const TimelineActions: React.FC<Props> = ({
|
||||
: StyleConstants.Avatar.M + StyleConstants.Spacing.S
|
||||
}}
|
||||
>
|
||||
<View style={styles.actions}>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<Pressable
|
||||
{...(highlighted
|
||||
? {
|
||||
@ -334,9 +335,6 @@ const TimelineActions: React.FC<Props> = ({
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
actions: {
|
||||
flexDirection: 'row'
|
||||
},
|
||||
action: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
|
@ -1,11 +1,12 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Button from '@components/Button'
|
||||
import openLink from '@components/openLink'
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
import { Blurhash } from 'react-native-blurhash'
|
||||
import attachmentAspectRatio from './aspectRatio'
|
||||
|
||||
@ -27,10 +28,14 @@ const AttachmentUnsupported: React.FC<Props> = ({
|
||||
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
styles.base,
|
||||
{ aspectRatio: attachmentAspectRatio({ total, index }) }
|
||||
]}
|
||||
style={{
|
||||
flex: 1,
|
||||
flexBasis: '50%',
|
||||
padding: StyleConstants.Spacing.XS / 2,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
aspectRatio: attachmentAspectRatio({ total, index })
|
||||
}}
|
||||
>
|
||||
{attachment.blurhash ? (
|
||||
<Blurhash
|
||||
@ -44,18 +49,18 @@ const AttachmentUnsupported: React.FC<Props> = ({
|
||||
) : null}
|
||||
{!sensitiveShown ? (
|
||||
<>
|
||||
<Text
|
||||
style={[
|
||||
styles.text,
|
||||
{
|
||||
color: attachment.blurhash
|
||||
? colors.backgroundDefault
|
||||
: colors.primaryDefault
|
||||
}
|
||||
]}
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
marginBottom: StyleConstants.Spacing.S,
|
||||
color: attachment.blurhash
|
||||
? colors.backgroundDefault
|
||||
: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{t('shared.attachment.unsupported.text')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
{attachment.remote_url ? (
|
||||
<Button
|
||||
type='text'
|
||||
@ -74,19 +79,4 @@ const AttachmentUnsupported: React.FC<Props> = ({
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
flex: 1,
|
||||
flexBasis: '50%',
|
||||
padding: StyleConstants.Spacing.XS / 2,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
text: {
|
||||
...StyleConstants.FontStyle.S,
|
||||
textAlign: 'center',
|
||||
marginBottom: StyleConstants.Spacing.S
|
||||
}
|
||||
})
|
||||
|
||||
export default AttachmentUnsupported
|
||||
|
@ -1,11 +1,12 @@
|
||||
import analytics from '@components/analytics'
|
||||
import GracefullyImage from '@components/GracefullyImage'
|
||||
import openLink from '@components/openLink'
|
||||
import CustomText from '@components/Text'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { Pressable, StyleSheet, Text, View } from 'react-native'
|
||||
import { Pressable, StyleSheet, View } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
card: Pick<
|
||||
@ -22,7 +23,16 @@ const TimelineCard = React.memo(({ card }: Props) => {
|
||||
<Pressable
|
||||
accessible
|
||||
accessibilityRole='link'
|
||||
style={[styles.card, { borderColor: colors.border }]}
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
height: StyleConstants.Font.LineHeight.M * 5,
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderRadius: 6,
|
||||
overflow: 'hidden',
|
||||
borderColor: colors.border
|
||||
}}
|
||||
onPress={async () => {
|
||||
analytics('timeline_shared_card_press')
|
||||
await openLink(card.url, navigation)
|
||||
@ -33,71 +43,46 @@ const TimelineCard = React.memo(({ card }: Props) => {
|
||||
<GracefullyImage
|
||||
uri={{ original: card.image }}
|
||||
blurhash={card.blurhash}
|
||||
style={styles.left}
|
||||
imageStyle={styles.image}
|
||||
style={{ flexBasis: StyleConstants.Font.LineHeight.M * 5 }}
|
||||
imageStyle={{ borderTopLeftRadius: 6, borderBottomLeftRadius: 6 }}
|
||||
/>
|
||||
) : null}
|
||||
<View style={styles.right}>
|
||||
<Text
|
||||
<View style={{ flex: 1, padding: StyleConstants.Spacing.S }}>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
numberOfLines={2}
|
||||
style={[styles.rightTitle, { color: colors.primaryDefault }]}
|
||||
style={{
|
||||
marginBottom: StyleConstants.Spacing.XS,
|
||||
fontWeight: StyleConstants.Font.Weight.Bold,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
testID='title'
|
||||
>
|
||||
{card.title}
|
||||
</Text>
|
||||
</CustomText>
|
||||
{card.description ? (
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
numberOfLines={1}
|
||||
style={[styles.rightDescription, { color: colors.primaryDefault }]}
|
||||
style={{
|
||||
marginBottom: StyleConstants.Spacing.XS,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
testID='description'
|
||||
>
|
||||
{card.description}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
numberOfLines={1}
|
||||
style={[styles.rightLink, { color: colors.secondary }]}
|
||||
style={{ color: colors.secondary }}
|
||||
>
|
||||
{card.url}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
</Pressable>
|
||||
)
|
||||
})
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
card: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
height: StyleConstants.Font.LineHeight.M * 5,
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderRadius: 6,
|
||||
overflow: 'hidden'
|
||||
},
|
||||
left: {
|
||||
flexBasis: StyleConstants.Font.LineHeight.M * 5
|
||||
},
|
||||
image: {
|
||||
borderTopLeftRadius: 6,
|
||||
borderBottomLeftRadius: 6
|
||||
},
|
||||
right: {
|
||||
flex: 1,
|
||||
padding: StyleConstants.Spacing.S
|
||||
},
|
||||
rightTitle: {
|
||||
...StyleConstants.FontStyle.S,
|
||||
marginBottom: StyleConstants.Spacing.XS,
|
||||
fontWeight: StyleConstants.Font.Weight.Bold
|
||||
},
|
||||
rightDescription: {
|
||||
...StyleConstants.FontStyle.S,
|
||||
marginBottom: StyleConstants.Spacing.XS
|
||||
},
|
||||
rightLink: {
|
||||
...StyleConstants.FontStyle.S
|
||||
}
|
||||
})
|
||||
|
||||
export default TimelineCard
|
||||
|
@ -1,4 +1,5 @@
|
||||
import analytics from '@components/analytics'
|
||||
import CustomText from '@components/Text'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
||||
@ -7,7 +8,7 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
status: Pick<
|
||||
@ -37,7 +38,7 @@ const TimelineFeedback = React.memo(
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
{status.reblogs_count > 0 ? (
|
||||
<Text
|
||||
<CustomText
|
||||
accessibilityLabel={t(
|
||||
'shared.actionsUsers.reblogged_by.accessibilityLabel',
|
||||
{
|
||||
@ -64,10 +65,10 @@ const TimelineFeedback = React.memo(
|
||||
{t('shared.actionsUsers.reblogged_by.text', {
|
||||
count: status.reblogs_count
|
||||
})}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
{status.favourites_count > 0 ? (
|
||||
<Text
|
||||
<CustomText
|
||||
accessibilityLabel={t(
|
||||
'shared.actionsUsers.favourited_by.accessibilityLabel',
|
||||
{
|
||||
@ -94,12 +95,12 @@ const TimelineFeedback = React.memo(
|
||||
{t('shared.actionsUsers.favourited_by.text', {
|
||||
count: status.favourites_count
|
||||
})}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
</View>
|
||||
<View>
|
||||
{data && data.length > 1 ? (
|
||||
<Text
|
||||
<CustomText
|
||||
accessibilityLabel={t(
|
||||
'shared.actionsUsers.history.accessibilityLabel',
|
||||
{
|
||||
@ -121,7 +122,7 @@ const TimelineFeedback = React.memo(
|
||||
{t('shared.actionsUsers.history.text', {
|
||||
count: data.length - 1
|
||||
})}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
</View>
|
||||
</View>
|
||||
|
@ -1,3 +1,4 @@
|
||||
import CustomText from '@components/Text'
|
||||
import { store } from '@root/store'
|
||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||
import { getInstance, getInstanceAccount } from '@utils/slices/instancesSlice'
|
||||
@ -6,7 +7,7 @@ import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import htmlparser2 from 'htmlparser2-without-node-native'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Text, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
|
||||
const TimelineFiltered = React.memo(
|
||||
() => {
|
||||
@ -15,9 +16,9 @@ const TimelineFiltered = React.memo(
|
||||
|
||||
return (
|
||||
<View style={{ backgroundColor: colors.backgroundDefault }}>
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
...StyleConstants.FontStyle.S,
|
||||
color: colors.secondary,
|
||||
textAlign: 'center',
|
||||
paddingVertical: StyleConstants.Spacing.S,
|
||||
@ -25,7 +26,7 @@ const TimelineFiltered = React.memo(
|
||||
}}
|
||||
>
|
||||
{t('shared.filtered')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
)
|
||||
},
|
||||
|
@ -1,9 +1,9 @@
|
||||
import CustomText from '@components/Text'
|
||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Text } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
queryKey?: QueryKeyTimeline
|
||||
@ -22,15 +22,15 @@ const TimelineFullConversation = React.memo(
|
||||
status.mentions.filter(
|
||||
mention => mention.id !== status.in_reply_to_account_id
|
||||
).length) ? (
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
...StyleConstants.FontStyle.S,
|
||||
color: colors.blue,
|
||||
marginTop: StyleConstants.Spacing.S
|
||||
}}
|
||||
>
|
||||
{t('shared.fullConversation')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null
|
||||
},
|
||||
() => true
|
||||
|
@ -2,6 +2,7 @@ import analytics from '@components/analytics'
|
||||
import Icon from '@components/Icon'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import { ParseEmojis } from '@components/Parse'
|
||||
import CustomText from '@components/Text'
|
||||
import {
|
||||
QueryKeyTimeline,
|
||||
useTimelineMutation
|
||||
@ -10,7 +11,7 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Pressable, Text, View } from 'react-native'
|
||||
import { Pressable, View } from 'react-native'
|
||||
import { useQueryClient } from 'react-query'
|
||||
import HeaderSharedCreated from './HeaderShared/Created'
|
||||
import HeaderSharedMuted from './HeaderShared/Muted'
|
||||
@ -20,22 +21,22 @@ const Names = ({ accounts }: { accounts: Mastodon.Account[] }) => {
|
||||
const { colors } = useTheme()
|
||||
|
||||
return (
|
||||
<Text
|
||||
<CustomText
|
||||
numberOfLines={1}
|
||||
style={{ ...StyleConstants.FontStyle.M, color: colors.secondary }}
|
||||
>
|
||||
<Text>{t('shared.header.conversation.withAccounts')}</Text>
|
||||
<CustomText>{t('shared.header.conversation.withAccounts')}</CustomText>
|
||||
{accounts.map((account, index) => (
|
||||
<Text key={account.id} numberOfLines={1}>
|
||||
<CustomText key={account.id} numberOfLines={1}>
|
||||
{index !== 0 ? t('common:separator') : undefined}
|
||||
<ParseEmojis
|
||||
content={account.display_name || account.username}
|
||||
emojis={account.emojis}
|
||||
fontBold
|
||||
/>
|
||||
</Text>
|
||||
</CustomText>
|
||||
))}
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
import CustomText from '@components/Text'
|
||||
import { ParseEmojis } from '@root/components/Parse'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
account: Mastodon.Account
|
||||
@ -16,13 +17,13 @@ const HeaderSharedAccount = React.memo(
|
||||
const { colors } = useTheme()
|
||||
|
||||
return (
|
||||
<View style={styles.base}>
|
||||
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
||||
{withoutName ? null : (
|
||||
<Text
|
||||
<CustomText
|
||||
accessibilityHint={t(
|
||||
'shared.header.shared.account.name.accessibilityHint'
|
||||
)}
|
||||
style={styles.name}
|
||||
style={{ marginRight: StyleConstants.Spacing.XS }}
|
||||
numberOfLines={1}
|
||||
>
|
||||
<ParseEmojis
|
||||
@ -30,34 +31,21 @@ const HeaderSharedAccount = React.memo(
|
||||
emojis={account.emojis}
|
||||
fontBold
|
||||
/>
|
||||
</Text>
|
||||
</CustomText>
|
||||
)}
|
||||
<Text
|
||||
<CustomText
|
||||
accessibilityHint={t(
|
||||
'shared.header.shared.account.account.accessibilityHint'
|
||||
)}
|
||||
style={[styles.acct, { color: colors.secondary }]}
|
||||
style={{ flexShrink: 1, color: colors.secondary }}
|
||||
numberOfLines={1}
|
||||
>
|
||||
@{account.acct}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
)
|
||||
},
|
||||
() => true
|
||||
)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
name: {
|
||||
marginRight: StyleConstants.Spacing.XS
|
||||
},
|
||||
acct: {
|
||||
flexShrink: 1
|
||||
}
|
||||
})
|
||||
|
||||
export default HeaderSharedAccount
|
||||
|
@ -1,10 +1,10 @@
|
||||
import analytics from '@components/analytics'
|
||||
import openLink from '@components/openLink'
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
application?: Mastodon.Application
|
||||
@ -16,7 +16,8 @@ const HeaderSharedApplication = React.memo(
|
||||
const { t } = useTranslation('componentTimeline')
|
||||
|
||||
return application && application.name !== 'Web' ? (
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
accessibilityRole='link'
|
||||
onPress={async () => {
|
||||
analytics('timeline_shared_header_application_press', {
|
||||
@ -24,24 +25,20 @@ const HeaderSharedApplication = React.memo(
|
||||
})
|
||||
application.website && (await openLink(application.website))
|
||||
}}
|
||||
style={[styles.application, { color: colors.secondary }]}
|
||||
style={{
|
||||
flex: 1,
|
||||
marginLeft: StyleConstants.Spacing.S,
|
||||
color: colors.secondary
|
||||
}}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{t('shared.header.shared.application', {
|
||||
application: application.name
|
||||
})}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null
|
||||
},
|
||||
() => true
|
||||
)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
application: {
|
||||
flex: 1,
|
||||
...StyleConstants.FontStyle.S,
|
||||
marginLeft: StyleConstants.Spacing.S
|
||||
}
|
||||
})
|
||||
|
||||
export default HeaderSharedApplication
|
||||
|
@ -1,13 +1,13 @@
|
||||
import Icon from '@components/Icon'
|
||||
import RelativeTime from '@components/RelativeTime'
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Text } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
created_at: Mastodon.Status['created_at']
|
||||
created_at: Mastodon.Status['created_at'] | number
|
||||
edited_at?: Mastodon.Status['edited_at']
|
||||
}
|
||||
|
||||
@ -18,11 +18,9 @@ const HeaderSharedCreated = React.memo(
|
||||
|
||||
return (
|
||||
<>
|
||||
<Text
|
||||
style={{ ...StyleConstants.FontStyle.S, color: colors.secondary }}
|
||||
>
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
<RelativeTime date={edited_at || created_at} />
|
||||
</Text>
|
||||
</CustomText>
|
||||
{edited_at ? (
|
||||
<Icon
|
||||
accessibilityLabel={t(
|
||||
|
@ -5,6 +5,7 @@ import Icon from '@components/Icon'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import { ParseEmojis } from '@components/Parse'
|
||||
import RelativeTime from '@components/RelativeTime'
|
||||
import CustomText from '@components/Text'
|
||||
import {
|
||||
MutationVarsTimelineUpdateStatusProperty,
|
||||
QueryKeyTimeline,
|
||||
@ -83,7 +84,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
if (!poll.expired) {
|
||||
if (!sameAccount && !poll.voted) {
|
||||
return (
|
||||
<View style={styles.button}>
|
||||
<View style={{ marginRight: StyleConstants.Spacing.S }}>
|
||||
<Button
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_vote_vote_press')
|
||||
@ -110,7 +111,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<View style={styles.button}>
|
||||
<View style={{ marginRight: StyleConstants.Spacing.S }}>
|
||||
<Button
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_vote_refresh_press')
|
||||
@ -147,19 +148,19 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
const pollExpiration = useMemo(() => {
|
||||
if (poll.expired) {
|
||||
return (
|
||||
<Text style={[styles.expiration, { color: colors.secondary }]}>
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
{t('shared.poll.meta.expiration.expired')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
} else {
|
||||
if (poll.expires_at) {
|
||||
return (
|
||||
<Text style={[styles.expiration, { color: colors.secondary }]}>
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
<Trans
|
||||
i18nKey='componentTimeline:shared.poll.meta.expiration.until'
|
||||
components={[<RelativeTime date={poll.expires_at} />]}
|
||||
/>
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -179,10 +180,17 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
option => option.votes_count
|
||||
)?.votes_count
|
||||
return poll.options.map((option, index) => (
|
||||
<View key={index} style={styles.optionContainer}>
|
||||
<View style={styles.optionContent}>
|
||||
<View
|
||||
key={index}
|
||||
style={{ flex: 1, paddingVertical: StyleConstants.Spacing.S }}
|
||||
>
|
||||
<View style={{ flex: 1, flexDirection: 'row' }}>
|
||||
<Icon
|
||||
style={styles.optionSelection}
|
||||
style={{
|
||||
paddingTop:
|
||||
StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
}}
|
||||
name={
|
||||
`${poll.own_votes?.includes(index) ? 'Check' : ''}${
|
||||
poll.multiple ? 'Square' : 'Circle'
|
||||
@ -193,11 +201,18 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
poll.own_votes?.includes(index) ? colors.blue : colors.disabled
|
||||
}
|
||||
/>
|
||||
<Text style={styles.optionText}>
|
||||
<CustomText style={{ flex: 1 }}>
|
||||
<ParseEmojis content={option.title} emojis={poll.emojis} />
|
||||
</Text>
|
||||
<Text
|
||||
style={[styles.optionPercentage, { color: colors.primaryDefault }]}
|
||||
</CustomText>
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
alignSelf: 'center',
|
||||
marginLeft: StyleConstants.Spacing.S,
|
||||
flexBasis: '20%',
|
||||
textAlign: 'center',
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{poll.votes_count
|
||||
? Math.round(
|
||||
@ -207,21 +222,24 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
)
|
||||
: 0}
|
||||
%
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={[
|
||||
styles.background,
|
||||
{
|
||||
width: `${Math.round(
|
||||
(option.votes_count / (poll.voters_count || poll.votes_count)) *
|
||||
100
|
||||
)}%`,
|
||||
backgroundColor:
|
||||
option.votes_count === maxValue ? colors.blue : colors.disabled
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
height: StyleConstants.Spacing.XS,
|
||||
minWidth: 2,
|
||||
borderTopRightRadius: 10,
|
||||
borderBottomRightRadius: 10,
|
||||
marginTop: StyleConstants.Spacing.XS,
|
||||
marginBottom: StyleConstants.Spacing.S,
|
||||
width: `${Math.round(
|
||||
(option.votes_count / (poll.voters_count || poll.votes_count)) *
|
||||
100
|
||||
)}%`,
|
||||
backgroundColor:
|
||||
option.votes_count === maxValue ? colors.blue : colors.disabled
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
))
|
||||
@ -230,7 +248,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
return poll.options.map((option, index) => (
|
||||
<Pressable
|
||||
key={index}
|
||||
style={styles.optionContainer}
|
||||
style={{ flex: 1, paddingVertical: StyleConstants.Spacing.S }}
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_vote_option_press')
|
||||
!allOptions[index] && haptics('Light')
|
||||
@ -253,16 +271,20 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<View style={[styles.optionContent]}>
|
||||
<View style={{ flex: 1, flexDirection: 'row' }}>
|
||||
<Icon
|
||||
style={styles.optionSelection}
|
||||
style={{
|
||||
paddingTop:
|
||||
StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
}}
|
||||
name={isSelected(index)}
|
||||
size={StyleConstants.Font.Size.M}
|
||||
color={colors.primaryDefault}
|
||||
/>
|
||||
<Text style={styles.optionText}>
|
||||
<CustomText style={{ flex: 1 }}>
|
||||
<ParseEmojis content={option.title} emojis={poll.emojis} />
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
</Pressable>
|
||||
))
|
||||
@ -271,25 +293,32 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
const pollVoteCounts = useMemo(() => {
|
||||
if (poll.voters_count !== null) {
|
||||
return (
|
||||
<Text style={[styles.votes, { color: colors.secondary }]}>
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
{t('shared.poll.meta.count.voters', { count: poll.voters_count })}
|
||||
{' • '}
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
} else if (poll.votes_count !== null) {
|
||||
return (
|
||||
<Text style={[styles.votes, { color: colors.secondary }]}>
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
{t('shared.poll.meta.count.votes', { count: poll.votes_count })}
|
||||
{' • '}
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
}
|
||||
}, [poll.voters_count, poll.votes_count])
|
||||
|
||||
return (
|
||||
<View style={styles.base}>
|
||||
<View style={{ marginTop: StyleConstants.Spacing.M }}>
|
||||
{poll.expired || poll.voted ? pollBodyDisallow : pollBodyAllow}
|
||||
<View style={styles.meta}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginTop: StyleConstants.Spacing.XS
|
||||
}}
|
||||
>
|
||||
{pollButton}
|
||||
{pollVoteCounts}
|
||||
{pollExpiration}
|
||||
@ -298,55 +327,4 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
marginTop: StyleConstants.Spacing.M
|
||||
},
|
||||
optionContainer: {
|
||||
flex: 1,
|
||||
paddingVertical: StyleConstants.Spacing.S
|
||||
},
|
||||
optionContent: {
|
||||
flex: 1,
|
||||
flexDirection: 'row'
|
||||
},
|
||||
optionText: {
|
||||
flex: 1
|
||||
},
|
||||
optionSelection: {
|
||||
paddingTop: StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
},
|
||||
optionPercentage: {
|
||||
...StyleConstants.FontStyle.M,
|
||||
alignSelf: 'center',
|
||||
marginLeft: StyleConstants.Spacing.S,
|
||||
flexBasis: '20%',
|
||||
textAlign: 'center'
|
||||
},
|
||||
background: {
|
||||
height: StyleConstants.Spacing.XS,
|
||||
minWidth: 2,
|
||||
borderTopRightRadius: 10,
|
||||
borderBottomRightRadius: 10,
|
||||
marginTop: StyleConstants.Spacing.XS,
|
||||
marginBottom: StyleConstants.Spacing.S
|
||||
},
|
||||
meta: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginTop: StyleConstants.Spacing.XS
|
||||
},
|
||||
button: {
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
},
|
||||
votes: {
|
||||
...StyleConstants.FontStyle.S
|
||||
},
|
||||
expiration: {
|
||||
...StyleConstants.FontStyle.S
|
||||
}
|
||||
})
|
||||
|
||||
export default TimelinePoll
|
||||
|
@ -1,5 +1,6 @@
|
||||
import analytics from '@components/analytics'
|
||||
import { ParseHTML } from '@components/Parse'
|
||||
import CustomText from '@components/Text'
|
||||
import { useTranslateQuery } from '@utils/queryHooks/translate'
|
||||
import { getSettingsLanguage } from '@utils/slices/settingsSlice'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
@ -7,7 +8,7 @@ import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import * as Localization from 'expo-localization'
|
||||
import React, { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Pressable, Text } from 'react-native'
|
||||
import { Pressable } from 'react-native'
|
||||
import { Circle } from 'react-native-animated-spinkit'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
@ -85,9 +86,9 @@ const TimelineTranslate = React.memo(
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
...StyleConstants.FontStyle.M,
|
||||
color:
|
||||
isLoading || isSuccess
|
||||
? colors.secondary
|
||||
@ -106,14 +107,14 @@ const TimelineTranslate = React.memo(
|
||||
source: data?.sourceLanguage
|
||||
})
|
||||
: t('shared.translate.default')}
|
||||
</Text>
|
||||
<Text>
|
||||
</CustomText>
|
||||
<CustomText>
|
||||
{__DEV__
|
||||
? ` Source: ${status.language}; Target: ${
|
||||
Localization.locale || settingsLanguage || 'en'
|
||||
}`
|
||||
: undefined}
|
||||
</Text>
|
||||
</CustomText>
|
||||
{isLoading ? (
|
||||
<Circle
|
||||
size={StyleConstants.Font.Size.M}
|
||||
|
@ -165,7 +165,8 @@
|
||||
"content": {
|
||||
"accessibilityHint": "Saved draft, tap to edit this draft",
|
||||
"textEmpty": "Content empty"
|
||||
}
|
||||
},
|
||||
"checkAttachment": "Checking attachments on the server..."
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ import Button from '@components/Button'
|
||||
import haptics from '@components/haptics'
|
||||
import { ParseHTML } from '@components/Parse'
|
||||
import RelativeTime from '@components/RelativeTime'
|
||||
import CustomText from '@components/Text'
|
||||
import { BlurView } from '@react-native-community/blur'
|
||||
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
||||
import { RootStackScreenProps } from '@utils/navigation/navigators'
|
||||
@ -14,14 +15,7 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import {
|
||||
Dimensions,
|
||||
Platform,
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
} from 'react-native'
|
||||
import { Dimensions, Platform, Pressable, StyleSheet, View } from 'react-native'
|
||||
import { Circle } from 'react-native-animated-spinkit'
|
||||
import FastImage from 'react-native-fast-image'
|
||||
import { FlatList, ScrollView } from 'react-native-gesture-handler'
|
||||
@ -64,27 +58,48 @@ const ScreenAnnouncements: React.FC<
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ item, index }: { item: Mastodon.Announcement; index: number }) => (
|
||||
<View key={index} style={styles.announcementContainer}>
|
||||
<View
|
||||
key={index}
|
||||
style={{
|
||||
width: Dimensions.get('screen').width,
|
||||
padding: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginVertical: StyleConstants.Spacing.Global.PagePadding,
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
<Pressable
|
||||
style={styles.pressable}
|
||||
style={StyleSheet.absoluteFillObject}
|
||||
onPress={() => navigation.goBack()}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
styles.announcement,
|
||||
{
|
||||
borderColor: colors.primaryDefault,
|
||||
backgroundColor: colors.backgroundDefault
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
flexShrink: 1,
|
||||
padding: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginTop: StyleConstants.Spacing.Global.PagePadding,
|
||||
borderWidth: 1,
|
||||
borderRadius: 6,
|
||||
borderColor: colors.primaryDefault,
|
||||
backgroundColor: colors.backgroundDefault
|
||||
}}
|
||||
>
|
||||
<Text style={[styles.published, { color: colors.secondary }]}>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
marginBottom: StyleConstants.Spacing.S,
|
||||
color: colors.secondary
|
||||
}}
|
||||
>
|
||||
<Trans
|
||||
i18nKey='screenAnnouncements:content.published'
|
||||
components={[<RelativeTime date={item.published_at} />]}
|
||||
/>
|
||||
</Text>
|
||||
<ScrollView style={styles.scrollView} showsVerticalScrollIndicator>
|
||||
</CustomText>
|
||||
<ScrollView
|
||||
style={{
|
||||
marginBottom: StyleConstants.Spacing.Global.PagePadding / 2
|
||||
}}
|
||||
showsVerticalScrollIndicator
|
||||
>
|
||||
<ParseHTML
|
||||
content={item.content}
|
||||
size='M'
|
||||
@ -95,21 +110,31 @@ const ScreenAnnouncements: React.FC<
|
||||
/>
|
||||
</ScrollView>
|
||||
{item.reactions?.length ? (
|
||||
<View style={styles.reactions}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
marginBottom: StyleConstants.Spacing.Global.PagePadding / 2
|
||||
}}
|
||||
>
|
||||
{item.reactions?.map(reaction => (
|
||||
<Pressable
|
||||
key={reaction.name}
|
||||
style={[
|
||||
styles.reaction,
|
||||
{
|
||||
borderColor: reaction.me
|
||||
? colors.disabled
|
||||
: colors.primaryDefault,
|
||||
backgroundColor: reaction.me
|
||||
? colors.disabled
|
||||
: colors.backgroundDefault
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
padding: StyleConstants.Spacing.Global.PagePadding / 2,
|
||||
marginTop: StyleConstants.Spacing.Global.PagePadding / 2,
|
||||
marginBottom: StyleConstants.Spacing.Global.PagePadding / 2,
|
||||
marginRight: StyleConstants.Spacing.M,
|
||||
borderRadius: 6,
|
||||
flexDirection: 'row',
|
||||
borderColor: reaction.me
|
||||
? colors.disabled
|
||||
: colors.primaryDefault,
|
||||
backgroundColor: reaction.me
|
||||
? colors.disabled
|
||||
: colors.backgroundDefault
|
||||
}}
|
||||
onPress={() => {
|
||||
analytics('accnouncement_reaction_press', {
|
||||
current: reaction.me
|
||||
@ -129,20 +154,24 @@ const ScreenAnnouncements: React.FC<
|
||||
? reaction.static_url
|
||||
: reaction.url
|
||||
}}
|
||||
style={[styles.reactionImage]}
|
||||
style={{
|
||||
width: StyleConstants.Font.LineHeight.M + 3,
|
||||
height: StyleConstants.Font.LineHeight.M
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<Text style={[styles.reactionText]}>{reaction.name}</Text>
|
||||
<CustomText fontStyle='M'>{reaction.name}</CustomText>
|
||||
)}
|
||||
{reaction.count ? (
|
||||
<Text
|
||||
style={[
|
||||
styles.reactionCount,
|
||||
{ color: colors.primaryDefault }
|
||||
]}
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
marginLeft: StyleConstants.Spacing.S,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{reaction.count}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
</Pressable>
|
||||
))}
|
||||
@ -210,10 +239,10 @@ const ScreenAnnouncements: React.FC<
|
||||
<BlurView
|
||||
blurType={mode}
|
||||
blurAmount={20}
|
||||
style={styles.base}
|
||||
style={{ flex: 1 }}
|
||||
reducedTransparencyFallbackColor={colors.backgroundDefault}
|
||||
>
|
||||
<SafeAreaView style={styles.base}>
|
||||
<SafeAreaView style={{ flex: 1 }}>
|
||||
<FlatList
|
||||
horizontal
|
||||
data={query.data}
|
||||
@ -223,22 +252,30 @@ const ScreenAnnouncements: React.FC<
|
||||
onMomentumScrollEnd={onMomentumScrollEnd}
|
||||
ListEmptyComponent={ListEmptyComponent}
|
||||
/>
|
||||
<View style={styles.indicators}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
minHeight: 49
|
||||
}}
|
||||
>
|
||||
{query.data && query.data.length > 1 ? (
|
||||
<>
|
||||
{query.data.map((d, i) => (
|
||||
<View
|
||||
key={i}
|
||||
style={[
|
||||
styles.indicator,
|
||||
{
|
||||
borderColor: colors.primaryDefault,
|
||||
backgroundColor:
|
||||
i === index ? colors.primaryDefault : undefined,
|
||||
marginLeft:
|
||||
i === query.data.length ? 0 : StyleConstants.Spacing.S
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
width: StyleConstants.Spacing.S,
|
||||
height: StyleConstants.Spacing.S,
|
||||
borderRadius: StyleConstants.Spacing.S,
|
||||
borderWidth: 1,
|
||||
borderColor: colors.primaryDefault,
|
||||
backgroundColor:
|
||||
i === index ? colors.primaryDefault : undefined,
|
||||
marginLeft:
|
||||
i === query.data.length ? 0 : StyleConstants.Spacing.S
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
@ -248,7 +285,7 @@ const ScreenAnnouncements: React.FC<
|
||||
</BlurView>
|
||||
) : (
|
||||
<SafeAreaView
|
||||
style={[styles.base, { backgroundColor: colors.backgroundDefault }]}
|
||||
style={{ flex: 1, backgroundColor: colors.backgroundDefault }}
|
||||
>
|
||||
<FlatList
|
||||
horizontal
|
||||
@ -259,22 +296,30 @@ const ScreenAnnouncements: React.FC<
|
||||
onMomentumScrollEnd={onMomentumScrollEnd}
|
||||
ListEmptyComponent={ListEmptyComponent}
|
||||
/>
|
||||
<View style={styles.indicators}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
minHeight: 49
|
||||
}}
|
||||
>
|
||||
{query.data && query.data.length > 1 ? (
|
||||
<>
|
||||
{query.data.map((d, i) => (
|
||||
<View
|
||||
key={i}
|
||||
style={[
|
||||
styles.indicator,
|
||||
{
|
||||
borderColor: colors.primaryDefault,
|
||||
backgroundColor:
|
||||
i === index ? colors.primaryDefault : undefined,
|
||||
marginLeft:
|
||||
i === query.data.length ? 0 : StyleConstants.Spacing.S
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
width: StyleConstants.Spacing.S,
|
||||
height: StyleConstants.Spacing.S,
|
||||
borderRadius: StyleConstants.Spacing.S,
|
||||
borderWidth: 1,
|
||||
borderColor: colors.primaryDefault,
|
||||
backgroundColor:
|
||||
i === index ? colors.primaryDefault : undefined,
|
||||
marginLeft:
|
||||
i === query.data.length ? 0 : StyleConstants.Spacing.S
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
@ -284,69 +329,4 @@ const ScreenAnnouncements: React.FC<
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
flex: 1
|
||||
},
|
||||
invisibleTextInput: { ...StyleSheet.absoluteFillObject },
|
||||
announcementContainer: {
|
||||
width: Dimensions.get('screen').width,
|
||||
padding: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginVertical: StyleConstants.Spacing.Global.PagePadding,
|
||||
justifyContent: 'center'
|
||||
},
|
||||
published: {
|
||||
...StyleConstants.FontStyle.S,
|
||||
marginBottom: StyleConstants.Spacing.S
|
||||
},
|
||||
pressable: { ...StyleSheet.absoluteFillObject },
|
||||
announcement: {
|
||||
flexShrink: 1,
|
||||
padding: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginTop: StyleConstants.Spacing.Global.PagePadding,
|
||||
borderWidth: 1,
|
||||
borderRadius: 6
|
||||
},
|
||||
scrollView: {
|
||||
marginBottom: StyleConstants.Spacing.Global.PagePadding / 2
|
||||
},
|
||||
reactions: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
marginBottom: StyleConstants.Spacing.Global.PagePadding / 2
|
||||
},
|
||||
reaction: {
|
||||
borderWidth: 1,
|
||||
padding: StyleConstants.Spacing.Global.PagePadding / 2,
|
||||
marginTop: StyleConstants.Spacing.Global.PagePadding / 2,
|
||||
marginBottom: StyleConstants.Spacing.Global.PagePadding / 2,
|
||||
marginRight: StyleConstants.Spacing.M,
|
||||
borderRadius: 6,
|
||||
flexDirection: 'row'
|
||||
},
|
||||
reactionImage: {
|
||||
width: StyleConstants.Font.LineHeight.M + 3,
|
||||
height: StyleConstants.Font.LineHeight.M
|
||||
},
|
||||
reactionText: {
|
||||
...StyleConstants.FontStyle.M
|
||||
},
|
||||
reactionCount: {
|
||||
...StyleConstants.FontStyle.S,
|
||||
marginLeft: StyleConstants.Spacing.S
|
||||
},
|
||||
indicators: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
minHeight: 49
|
||||
},
|
||||
indicator: {
|
||||
width: StyleConstants.Spacing.S,
|
||||
height: StyleConstants.Spacing.S,
|
||||
borderRadius: StyleConstants.Spacing.S,
|
||||
borderWidth: 1
|
||||
}
|
||||
})
|
||||
|
||||
export default ScreenAnnouncements
|
||||
|
@ -1,6 +1,7 @@
|
||||
import apiInstance from '@api/instance'
|
||||
import Icon from '@components/Icon'
|
||||
import ComponentSeparator from '@components/Separator'
|
||||
import CustomText from '@components/Text'
|
||||
import HeaderSharedCreated from '@components/Timeline/Shared/HeaderShared/Created'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { useAppDispatch } from '@root/store'
|
||||
@ -18,8 +19,6 @@ import {
|
||||
Modal,
|
||||
Platform,
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
} from 'react-native'
|
||||
import { PanGestureHandler } from 'react-native-gesture-handler'
|
||||
@ -54,10 +53,15 @@ const ComposeDraftsListRoot: React.FC<Props> = ({ timestamp }) => {
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ item }: { item: ComposeStateDraft }) => {
|
||||
console.log('timestamp', item.timestamp)
|
||||
return (
|
||||
<Pressable
|
||||
accessibilityHint={t('content.draftsList.content.accessibilityHint')}
|
||||
style={[styles.draft, { backgroundColor: colors.backgroundDefault }]}
|
||||
style={{
|
||||
flex: 1,
|
||||
padding: StyleConstants.Spacing.Global.PagePadding,
|
||||
backgroundColor: colors.backgroundDefault
|
||||
}}
|
||||
onPress={async () => {
|
||||
setCheckingAttachments(true)
|
||||
let tempDraft = item
|
||||
@ -103,23 +107,42 @@ const ComposeDraftsListRoot: React.FC<Props> = ({ timestamp }) => {
|
||||
>
|
||||
<View style={{ flex: 1 }}>
|
||||
<HeaderSharedCreated created_at={item.timestamp} />
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
numberOfLines={2}
|
||||
style={[styles.text, { color: colors.primaryDefault }]}
|
||||
style={{
|
||||
marginTop: StyleConstants.Spacing.XS,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{item.text ||
|
||||
item.spoiler ||
|
||||
t('content.draftsList.content.textEmpty')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
{item.attachments?.uploads.length ? (
|
||||
<View style={styles.attachments}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
marginTop: StyleConstants.Spacing.S
|
||||
}}
|
||||
>
|
||||
{item.attachments.uploads.map((attachment, index) => (
|
||||
<Image
|
||||
key={index}
|
||||
style={[
|
||||
styles.attachment,
|
||||
{ marginLeft: index !== 0 ? StyleConstants.Spacing.S : 0 }
|
||||
]}
|
||||
style={{
|
||||
width:
|
||||
(Dimensions.get('screen').width -
|
||||
StyleConstants.Spacing.Global.PagePadding * 2 -
|
||||
StyleConstants.Spacing.S * 3) /
|
||||
4,
|
||||
height:
|
||||
(Dimensions.get('screen').width -
|
||||
StyleConstants.Spacing.Global.PagePadding * 2 -
|
||||
StyleConstants.Spacing.S * 3) /
|
||||
4,
|
||||
marginLeft: index !== 0 ? StyleConstants.Spacing.S : 0
|
||||
}}
|
||||
source={{
|
||||
uri:
|
||||
attachment.local?.local_thumbnail ||
|
||||
@ -138,10 +161,21 @@ const ComposeDraftsListRoot: React.FC<Props> = ({ timestamp }) => {
|
||||
const renderHiddenItem = useCallback(
|
||||
({ item }) => (
|
||||
<View
|
||||
style={[styles.hiddenBase, { backgroundColor: colors.red }]}
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
backgroundColor: colors.red
|
||||
}}
|
||||
children={
|
||||
<Pressable
|
||||
style={styles.action}
|
||||
style={{
|
||||
flexBasis:
|
||||
StyleConstants.Font.Size.L +
|
||||
StyleConstants.Spacing.Global.PagePadding * 4,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}
|
||||
onPress={() => removeDraft(item.timestamp)}
|
||||
children={
|
||||
<Icon
|
||||
@ -183,17 +217,17 @@ const ComposeDraftsListRoot: React.FC<Props> = ({ timestamp }) => {
|
||||
visible={checkingAttachments}
|
||||
children={
|
||||
<View
|
||||
style={[
|
||||
styles.modal,
|
||||
{ backgroundColor: colors.backgroundOverlayInvert }
|
||||
]}
|
||||
style={{
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: colors.backgroundOverlayInvert
|
||||
}}
|
||||
children={
|
||||
<Text
|
||||
children='检查附件在服务器的状态…'
|
||||
style={{
|
||||
...StyleConstants.FontStyle.M,
|
||||
color: colors.primaryOverlay
|
||||
}}
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
children={t('content.draftsList.checkAttachment')}
|
||||
style={{ color: colors.primaryOverlay }}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
@ -203,49 +237,4 @@ const ComposeDraftsListRoot: React.FC<Props> = ({ timestamp }) => {
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
draft: {
|
||||
flex: 1,
|
||||
padding: StyleConstants.Spacing.Global.PagePadding
|
||||
},
|
||||
text: {
|
||||
marginTop: StyleConstants.Spacing.XS,
|
||||
...StyleConstants.FontStyle.M
|
||||
},
|
||||
attachments: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
marginTop: StyleConstants.Spacing.S
|
||||
},
|
||||
attachment: {
|
||||
width:
|
||||
(Dimensions.get('screen').width -
|
||||
StyleConstants.Spacing.Global.PagePadding * 2 -
|
||||
StyleConstants.Spacing.S * 3) /
|
||||
4,
|
||||
height:
|
||||
(Dimensions.get('screen').width -
|
||||
StyleConstants.Spacing.Global.PagePadding * 2 -
|
||||
StyleConstants.Spacing.S * 3) /
|
||||
4
|
||||
},
|
||||
hiddenBase: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end'
|
||||
},
|
||||
action: {
|
||||
flexBasis:
|
||||
StyleConstants.Font.Size.L +
|
||||
StyleConstants.Spacing.Global.PagePadding * 4,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
modal: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}
|
||||
})
|
||||
|
||||
export default ComposeDraftsListRoot
|
||||
|
@ -1,9 +1,10 @@
|
||||
import CustomText from '@components/Text'
|
||||
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useContext } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Dimensions, Image, StyleSheet, Text, View } from 'react-native'
|
||||
import { Dimensions, Image, View } from 'react-native'
|
||||
import { PanGestureHandler } from 'react-native-gesture-handler'
|
||||
import Animated, {
|
||||
Extrapolate,
|
||||
@ -120,7 +121,7 @@ const ComposeEditAttachmentImage: React.FC<Props> = ({ index }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<View style={styles.base}>
|
||||
<View style={{ overflow: 'hidden', flex: 1, alignItems: 'center' }}>
|
||||
<Image
|
||||
style={{
|
||||
width: imageDimensionis.width,
|
||||
@ -168,20 +169,18 @@ const ComposeEditAttachmentImage: React.FC<Props> = ({ index }) => {
|
||||
</PanGestureHandler>
|
||||
</View>
|
||||
{screenReaderEnabled ? null : (
|
||||
<Text style={[styles.imageFocusText, { color: colors.primaryDefault }]}>
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
padding: StyleConstants.Spacing.Global.PagePadding,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{t('content.editAttachment.content.imageFocus')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: { overflow: 'hidden', flex: 1, alignItems: 'center' },
|
||||
imageFocusText: {
|
||||
...StyleConstants.FontStyle.M,
|
||||
padding: StyleConstants.Spacing.Global.PagePadding
|
||||
}
|
||||
})
|
||||
|
||||
export default ComposeEditAttachmentImage
|
||||
|
@ -1,9 +1,10 @@
|
||||
import CustomText from '@components/Text'
|
||||
import AttachmentVideo from '@components/Timeline/Shared/Attachment/Video'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useContext, useMemo, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { ScrollView, StyleSheet, Text, TextInput, View } from 'react-native'
|
||||
import { ScrollView, StyleSheet, TextInput, View } from 'react-native'
|
||||
import ComposeContext from '../utils/createContext'
|
||||
import ComposeEditAttachmentImage from './Image'
|
||||
|
||||
@ -60,17 +61,28 @@ const ComposeEditAttachmentRoot: React.FC<Props> = ({ index }) => {
|
||||
return (
|
||||
<ScrollView ref={scrollViewRef}>
|
||||
{mediaDisplay}
|
||||
<View style={styles.altTextContainer}>
|
||||
<Text
|
||||
style={[styles.altTextInputHeading, { color: colors.primaryDefault }]}
|
||||
<View style={{ padding: StyleConstants.Spacing.Global.PagePadding }}>
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
fontWeight: StyleConstants.Font.Weight.Bold,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{t('content.editAttachment.content.altText.heading')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
<TextInput
|
||||
style={[
|
||||
styles.altTextInput,
|
||||
{ borderColor: colors.border, color: colors.primaryDefault }
|
||||
]}
|
||||
style={{
|
||||
height: 200,
|
||||
...StyleConstants.FontStyle.M,
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
marginBottom: StyleConstants.Spacing.S,
|
||||
padding: StyleConstants.Spacing.Global.PagePadding,
|
||||
paddingTop: StyleConstants.Spacing.S * 1.5,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderColor: colors.border,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
onFocus={() => scrollViewRef.current?.scrollToEnd()}
|
||||
autoCapitalize='none'
|
||||
autoCorrect={false}
|
||||
@ -83,35 +95,20 @@ const ComposeEditAttachmentRoot: React.FC<Props> = ({ index }) => {
|
||||
value={theAttachment.description}
|
||||
keyboardAppearance={mode}
|
||||
/>
|
||||
<Text style={[styles.altTextLength, { color: colors.secondary }]}>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
textAlign: 'right',
|
||||
marginRight: StyleConstants.Spacing.S,
|
||||
marginBottom: StyleConstants.Spacing.M,
|
||||
color: colors.secondary
|
||||
}}
|
||||
>
|
||||
{theAttachment.description?.length || 0} / 1500
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
altTextContainer: { padding: StyleConstants.Spacing.Global.PagePadding },
|
||||
altTextInputHeading: {
|
||||
...StyleConstants.FontStyle.M,
|
||||
fontWeight: StyleConstants.Font.Weight.Bold
|
||||
},
|
||||
altTextInput: {
|
||||
height: 200,
|
||||
...StyleConstants.FontStyle.M,
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
marginBottom: StyleConstants.Spacing.S,
|
||||
padding: StyleConstants.Spacing.Global.PagePadding,
|
||||
paddingTop: StyleConstants.Spacing.S * 1.5,
|
||||
borderWidth: StyleSheet.hairlineWidth
|
||||
},
|
||||
altTextLength: {
|
||||
textAlign: 'right',
|
||||
marginRight: StyleConstants.Spacing.S,
|
||||
...StyleConstants.FontStyle.S,
|
||||
marginBottom: StyleConstants.Spacing.M
|
||||
}
|
||||
})
|
||||
|
||||
export default ComposeEditAttachmentRoot
|
||||
|
@ -2,6 +2,7 @@ import analytics from '@components/analytics'
|
||||
import Button from '@components/Button'
|
||||
import haptics from '@components/haptics'
|
||||
import Icon from '@components/Icon'
|
||||
import CustomText from '@components/Text'
|
||||
import { useActionSheet } from '@expo/react-native-action-sheet'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
@ -16,14 +17,7 @@ import React, {
|
||||
useRef
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import {
|
||||
FlatList,
|
||||
Image,
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
} from 'react-native'
|
||||
import { FlatList, Image, Pressable, StyleSheet, View } from 'react-native'
|
||||
import { Circle } from 'react-native-animated-spinkit'
|
||||
import ComposeContext from '../../utils/createContext'
|
||||
import { ExtendedAttachment } from '../../utils/types'
|
||||
@ -122,33 +116,46 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||
return (
|
||||
<View
|
||||
key={index}
|
||||
style={[styles.container, { width: calculateWidth(item) }]}
|
||||
style={{
|
||||
height: DEFAULT_HEIGHT,
|
||||
marginLeft: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginTop: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginBottom: StyleConstants.Spacing.Global.PagePadding,
|
||||
width: calculateWidth(item)
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
style={styles.image}
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
source={{
|
||||
uri: item.local?.local_thumbnail || item.remote?.preview_url
|
||||
}}
|
||||
/>
|
||||
{item.remote?.meta?.original?.duration ? (
|
||||
<Text
|
||||
style={[
|
||||
styles.duration,
|
||||
{
|
||||
color: colors.backgroundDefault,
|
||||
backgroundColor: colors.backgroundOverlayInvert
|
||||
}
|
||||
]}
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
position: 'absolute',
|
||||
bottom: StyleConstants.Spacing.S,
|
||||
left: StyleConstants.Spacing.S,
|
||||
paddingLeft: StyleConstants.Spacing.S,
|
||||
paddingRight: StyleConstants.Spacing.S,
|
||||
paddingTop: StyleConstants.Spacing.XS,
|
||||
paddingBottom: StyleConstants.Spacing.XS,
|
||||
color: colors.backgroundDefault,
|
||||
backgroundColor: colors.backgroundOverlayInvert
|
||||
}}
|
||||
>
|
||||
{item.remote.meta.original.duration}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
{item.uploading ? (
|
||||
<View
|
||||
style={[
|
||||
styles.uploading,
|
||||
{ backgroundColor: colors.backgroundOverlayInvert }
|
||||
]}
|
||||
style={{
|
||||
...StyleSheet.absoluteFillObject,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: colors.backgroundOverlayInvert
|
||||
}}
|
||||
>
|
||||
<Circle
|
||||
size={StyleConstants.Font.Size.L}
|
||||
@ -156,7 +163,15 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<View style={styles.actions}>
|
||||
<View
|
||||
style={{
|
||||
...StyleSheet.absoluteFillObject,
|
||||
justifyContent: 'space-between',
|
||||
alignContent: 'flex-end',
|
||||
alignItems: 'flex-end',
|
||||
padding: StyleConstants.Spacing.S
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
accessibilityLabel={t(
|
||||
'content.root.footer.attachments.remove.accessibilityLabel',
|
||||
@ -209,16 +224,20 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||
accessibilityLabel={t(
|
||||
'content.root.footer.attachments.upload.accessibilityLabel'
|
||||
)}
|
||||
style={[
|
||||
styles.container,
|
||||
{
|
||||
width: DEFAULT_HEIGHT,
|
||||
backgroundColor: colors.backgroundOverlayInvert
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
height: DEFAULT_HEIGHT,
|
||||
marginLeft: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginTop: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginBottom: StyleConstants.Spacing.Global.PagePadding,
|
||||
width: DEFAULT_HEIGHT,
|
||||
backgroundColor: colors.backgroundOverlayInvert
|
||||
}}
|
||||
onPress={async () => {
|
||||
analytics('compose_attachment_add_container_press')
|
||||
await chooseAndUploadAttachment({ composeDispatch, showActionSheetWithOptions })
|
||||
await chooseAndUploadAttachment({
|
||||
composeDispatch,
|
||||
showActionSheetWithOptions
|
||||
})
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
@ -229,7 +248,10 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||
overlay
|
||||
onPress={async () => {
|
||||
analytics('compose_attachment_add_button_press')
|
||||
await chooseAndUploadAttachment({ composeDispatch, showActionSheetWithOptions })
|
||||
await chooseAndUploadAttachment({
|
||||
composeDispatch,
|
||||
showActionSheetWithOptions
|
||||
})
|
||||
}}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
@ -250,16 +272,38 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||
[]
|
||||
)
|
||||
return (
|
||||
<View style={styles.base} ref={accessibleRefAttachments} accessible>
|
||||
<Pressable style={styles.sensitive} onPress={sensitiveOnPress}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
marginRight: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginTop: StyleConstants.Spacing.M
|
||||
}}
|
||||
ref={accessibleRefAttachments}
|
||||
accessible
|
||||
>
|
||||
<Pressable
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginLeft: StyleConstants.Spacing.Global.PagePadding
|
||||
}}
|
||||
onPress={sensitiveOnPress}
|
||||
>
|
||||
<Icon
|
||||
name={composeState.attachments.sensitive ? 'CheckCircle' : 'Circle'}
|
||||
size={StyleConstants.Font.Size.L}
|
||||
color={colors.primaryDefault}
|
||||
/>
|
||||
<Text style={[styles.sensitiveText, { color: colors.primaryDefault }]}>
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
marginLeft: StyleConstants.Spacing.S,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{t('content.root.footer.attachments.sensitive')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</Pressable>
|
||||
<FlatList
|
||||
horizontal
|
||||
@ -283,54 +327,4 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
flex: 1,
|
||||
marginRight: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginTop: StyleConstants.Spacing.M
|
||||
},
|
||||
sensitive: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginLeft: StyleConstants.Spacing.Global.PagePadding
|
||||
},
|
||||
sensitiveText: {
|
||||
...StyleConstants.FontStyle.M,
|
||||
marginLeft: StyleConstants.Spacing.S
|
||||
},
|
||||
container: {
|
||||
height: DEFAULT_HEIGHT,
|
||||
marginLeft: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginTop: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginBottom: StyleConstants.Spacing.Global.PagePadding
|
||||
},
|
||||
image: {
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
},
|
||||
duration: {
|
||||
position: 'absolute',
|
||||
bottom: StyleConstants.Spacing.S,
|
||||
left: StyleConstants.Spacing.S,
|
||||
...StyleConstants.FontStyle.S,
|
||||
paddingLeft: StyleConstants.Spacing.S,
|
||||
paddingRight: StyleConstants.Spacing.S,
|
||||
paddingTop: StyleConstants.Spacing.XS,
|
||||
paddingBottom: StyleConstants.Spacing.XS
|
||||
},
|
||||
uploading: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
actions: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
justifyContent: 'space-between',
|
||||
alignContent: 'flex-end',
|
||||
alignItems: 'flex-end',
|
||||
padding: StyleConstants.Spacing.S
|
||||
}
|
||||
})
|
||||
|
||||
export default React.memo(ComposeAttachments, () => true)
|
||||
|
@ -1,4 +1,5 @@
|
||||
import haptics from '@components/haptics'
|
||||
import CustomText from '@components/Text'
|
||||
import { useAppDispatch } from '@root/store'
|
||||
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
||||
import { countInstanceEmoji } from '@utils/slices/instancesSlice'
|
||||
@ -11,8 +12,6 @@ import {
|
||||
findNodeHandle,
|
||||
Pressable,
|
||||
SectionList,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
} from 'react-native'
|
||||
import FastImage from 'react-native-fast-image'
|
||||
@ -40,7 +39,16 @@ const ComposeEmojis: React.FC<Props> = ({ accessibleRefEmojis }) => {
|
||||
|
||||
const listHeader = useCallback(
|
||||
({ section: { title } }) => (
|
||||
<Text style={[styles.group, { color: colors.secondary }]}>{title}</Text>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: StyleConstants.Spacing.L,
|
||||
color: colors.secondary
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</CustomText>
|
||||
),
|
||||
[]
|
||||
)
|
||||
@ -48,7 +56,15 @@ const ComposeEmojis: React.FC<Props> = ({ accessibleRefEmojis }) => {
|
||||
const listItem = useCallback(
|
||||
({ index, item }: { item: Mastodon.Emoji[]; index: number }) => {
|
||||
return (
|
||||
<View key={index} style={styles.emojis}>
|
||||
<View
|
||||
key={index}
|
||||
style={{
|
||||
flex: 1,
|
||||
flexWrap: 'wrap',
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
marginLeft: StyleConstants.Spacing.M
|
||||
}}
|
||||
>
|
||||
{item.map(emoji => {
|
||||
const uri = reduceMotionEnabled ? emoji.static_url : emoji.url
|
||||
if (validUrl.isHttpsUri(uri)) {
|
||||
@ -77,7 +93,12 @@ const ComposeEmojis: React.FC<Props> = ({ accessibleRefEmojis }) => {
|
||||
'screenCompose:content.root.footer.emojis.accessibilityHint'
|
||||
)}
|
||||
source={{ uri }}
|
||||
style={styles.emoji}
|
||||
style={{
|
||||
width: 32,
|
||||
height: 32,
|
||||
padding: StyleConstants.Spacing.S,
|
||||
margin: StyleConstants.Spacing.S
|
||||
}}
|
||||
/>
|
||||
</Pressable>
|
||||
)
|
||||
@ -92,7 +113,15 @@ const ComposeEmojis: React.FC<Props> = ({ accessibleRefEmojis }) => {
|
||||
)
|
||||
|
||||
return (
|
||||
<View style={styles.base}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'space-around',
|
||||
height: 260
|
||||
}}
|
||||
>
|
||||
<SectionList
|
||||
accessible
|
||||
ref={accessibleRefEmojis}
|
||||
@ -108,31 +137,4 @@ const ComposeEmojis: React.FC<Props> = ({ accessibleRefEmojis }) => {
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'space-around',
|
||||
height: 260
|
||||
},
|
||||
group: {
|
||||
position: 'absolute',
|
||||
left: StyleConstants.Spacing.L,
|
||||
...StyleConstants.FontStyle.S
|
||||
},
|
||||
emojis: {
|
||||
flex: 1,
|
||||
flexWrap: 'wrap',
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
marginLeft: StyleConstants.Spacing.M
|
||||
},
|
||||
emoji: {
|
||||
width: 32,
|
||||
height: 32,
|
||||
padding: StyleConstants.Spacing.S,
|
||||
margin: StyleConstants.Spacing.S
|
||||
}
|
||||
})
|
||||
|
||||
export default React.memo(ComposeEmojis, () => true)
|
||||
|
@ -2,13 +2,14 @@ import analytics from '@components/analytics'
|
||||
import Button from '@components/Button'
|
||||
import Icon from '@components/Icon'
|
||||
import { MenuRow } from '@components/Menu'
|
||||
import CustomText from '@components/Text'
|
||||
import { useActionSheet } from '@expo/react-native-action-sheet'
|
||||
import { getInstanceConfigurationPoll } from '@utils/slices/instancesSlice'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useContext, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text, TextInput, View } from 'react-native'
|
||||
import { StyleSheet, TextInput, View } from 'react-native'
|
||||
import { useSelector } from 'react-redux'
|
||||
import ComposeContext from '../../utils/createContext'
|
||||
|
||||
@ -39,8 +40,21 @@ const ComposePoll: React.FC = () => {
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<View style={[styles.base, { borderColor: colors.border }]}>
|
||||
<View style={styles.options}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderRadius: 6,
|
||||
margin: StyleConstants.Spacing.Global.PagePadding,
|
||||
borderColor: colors.border
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
marginBottom: StyleConstants.Spacing.S
|
||||
}}
|
||||
>
|
||||
{[...Array(total)].map((e, i) => {
|
||||
const restOptions = Object.keys(options).filter(
|
||||
o => parseInt(o) !== i && parseInt(o) < total
|
||||
@ -66,13 +80,16 @@ const ComposePoll: React.FC = () => {
|
||||
)}
|
||||
keyboardAppearance={mode}
|
||||
{...(i === 0 && firstRender && { autoFocus: true })}
|
||||
style={[
|
||||
styles.textInput,
|
||||
{
|
||||
borderColor: colors.border,
|
||||
color: hasConflict ? colors.red : colors.primaryDefault
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
flex: 1,
|
||||
padding: StyleConstants.Spacing.S,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderRadius: 6,
|
||||
...StyleConstants.FontStyle.M,
|
||||
marginLeft: StyleConstants.Spacing.S,
|
||||
borderColor: colors.border,
|
||||
color: hasConflict ? colors.red : colors.primaryDefault
|
||||
}}
|
||||
placeholder={
|
||||
multiple
|
||||
? t('content.root.footer.poll.option.placeholder.multiple')
|
||||
@ -93,7 +110,15 @@ const ComposePoll: React.FC = () => {
|
||||
)
|
||||
})}
|
||||
</View>
|
||||
<View style={styles.controlAmount}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-end',
|
||||
marginRight: StyleConstants.Spacing.M
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
{...(total > 2
|
||||
? {
|
||||
@ -121,9 +146,14 @@ const ComposePoll: React.FC = () => {
|
||||
round
|
||||
disabled={!(total > 2)}
|
||||
/>
|
||||
<Text style={[styles.controlCount, { color: colors.secondary }]}>
|
||||
<CustomText
|
||||
style={{
|
||||
marginHorizontal: StyleConstants.Spacing.S,
|
||||
color: colors.secondary
|
||||
}}
|
||||
>
|
||||
{total} / {MAX_OPTIONS}
|
||||
</Text>
|
||||
</CustomText>
|
||||
<Button
|
||||
{...(total < MAX_OPTIONS
|
||||
? {
|
||||
@ -152,7 +182,9 @@ const ComposePoll: React.FC = () => {
|
||||
disabled={!(total < MAX_OPTIONS)}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.controlOptions}>
|
||||
<View
|
||||
style={{ paddingHorizontal: StyleConstants.Spacing.Global.PagePadding }}
|
||||
>
|
||||
<MenuRow
|
||||
title={t('content.root.footer.poll.multiple.heading')}
|
||||
content={
|
||||
@ -238,43 +270,12 @@ const ComposePoll: React.FC = () => {
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
flex: 1,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderRadius: 6,
|
||||
margin: StyleConstants.Spacing.Global.PagePadding
|
||||
},
|
||||
options: {
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
marginBottom: StyleConstants.Spacing.S
|
||||
},
|
||||
option: {
|
||||
marginLeft: StyleConstants.Spacing.M,
|
||||
marginRight: StyleConstants.Spacing.M,
|
||||
marginBottom: StyleConstants.Spacing.S,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
textInput: {
|
||||
flex: 1,
|
||||
padding: StyleConstants.Spacing.S,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderRadius: 6,
|
||||
...StyleConstants.FontStyle.M,
|
||||
marginLeft: StyleConstants.Spacing.S
|
||||
},
|
||||
controlAmount: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-end',
|
||||
marginRight: StyleConstants.Spacing.M
|
||||
},
|
||||
controlOptions: {
|
||||
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding
|
||||
},
|
||||
controlCount: {
|
||||
marginHorizontal: StyleConstants.Spacing.S
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
import CustomText from '@components/Text'
|
||||
import {
|
||||
getInstanceAccount,
|
||||
getInstanceUri
|
||||
} from '@utils/slices/instancesSlice'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text } from 'react-native'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
const ComposePostingAs = React.memo(
|
||||
@ -21,21 +20,15 @@ const ComposePostingAs = React.memo(
|
||||
const instanceUri = useSelector(getInstanceUri)
|
||||
|
||||
return (
|
||||
<Text style={[styles.text, { color: colors.secondary }]}>
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
{t('content.root.header.postingAs', {
|
||||
acct: instanceAccount?.acct,
|
||||
domain: instanceUri
|
||||
})}
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
},
|
||||
() => true
|
||||
)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
text: {
|
||||
...StyleConstants.FontStyle.S
|
||||
}
|
||||
})
|
||||
|
||||
export default ComposePostingAs
|
||||
|
@ -1,8 +1,9 @@
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useContext, useEffect, useState } from 'react'
|
||||
import React, { useContext } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text, TextInput } from 'react-native'
|
||||
import { TextInput } from 'react-native'
|
||||
import formatText from '../../formatText'
|
||||
import ComposeContext from '../../utils/createContext'
|
||||
|
||||
@ -14,13 +15,16 @@ const ComposeSpoilerInput: React.FC = () => {
|
||||
return (
|
||||
<TextInput
|
||||
keyboardAppearance={mode}
|
||||
style={[
|
||||
styles.spoilerInput,
|
||||
{
|
||||
color: colors.primaryDefault,
|
||||
borderBottomColor: colors.border
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
...StyleConstants.FontStyle.M,
|
||||
marginTop: StyleConstants.Spacing.S,
|
||||
paddingBottom: StyleConstants.Spacing.M,
|
||||
marginLeft: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginRight: StyleConstants.Spacing.Global.PagePadding,
|
||||
borderBottomWidth: 0.5,
|
||||
color: colors.primaryDefault,
|
||||
borderBottomColor: colors.border
|
||||
}}
|
||||
autoCapitalize='none'
|
||||
autoCorrect={false}
|
||||
autoFocus
|
||||
@ -53,20 +57,9 @@ const ComposeSpoilerInput: React.FC = () => {
|
||||
})
|
||||
}
|
||||
>
|
||||
<Text>{composeState.spoiler.formatted}</Text>
|
||||
<CustomText>{composeState.spoiler.formatted}</CustomText>
|
||||
</TextInput>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
spoilerInput: {
|
||||
...StyleConstants.FontStyle.M,
|
||||
marginTop: StyleConstants.Spacing.S,
|
||||
paddingBottom: StyleConstants.Spacing.M,
|
||||
marginLeft: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginRight: StyleConstants.Spacing.Global.PagePadding,
|
||||
borderBottomWidth: 0.5
|
||||
}
|
||||
})
|
||||
|
||||
export default ComposeSpoilerInput
|
||||
|
@ -1,8 +1,9 @@
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useContext } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text, TextInput } from 'react-native'
|
||||
import { TextInput } from 'react-native'
|
||||
import formatText from '../../formatText'
|
||||
import ComposeContext from '../../utils/createContext'
|
||||
|
||||
@ -14,13 +15,15 @@ const ComposeTextInput: React.FC = () => {
|
||||
return (
|
||||
<TextInput
|
||||
keyboardAppearance={mode}
|
||||
style={[
|
||||
styles.textInput,
|
||||
{
|
||||
color: colors.primaryDefault,
|
||||
borderBottomColor: colors.border
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
...StyleConstants.FontStyle.M,
|
||||
marginTop: StyleConstants.Spacing.S,
|
||||
paddingBottom: StyleConstants.Spacing.M,
|
||||
marginLeft: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginRight: StyleConstants.Spacing.Global.PagePadding,
|
||||
color: colors.primaryDefault,
|
||||
borderBottomColor: colors.border
|
||||
}}
|
||||
autoFocus
|
||||
enablesReturnKeyAutomatically
|
||||
multiline
|
||||
@ -52,19 +55,9 @@ const ComposeTextInput: React.FC = () => {
|
||||
ref={composeState.textInputFocus.refs.text}
|
||||
scrollEnabled={false}
|
||||
>
|
||||
<Text>{composeState.text.formatted}</Text>
|
||||
<CustomText>{composeState.text.formatted}</CustomText>
|
||||
</TextInput>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
textInput: {
|
||||
...StyleConstants.FontStyle.M,
|
||||
marginTop: StyleConstants.Spacing.S,
|
||||
paddingBottom: StyleConstants.Spacing.M,
|
||||
marginLeft: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginRight: StyleConstants.Spacing.Global.PagePadding
|
||||
}
|
||||
})
|
||||
|
||||
export default ComposeTextInput
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { debounce, differenceWith, isEqual } from 'lodash'
|
||||
import React, { createElement, Dispatch } from 'react'
|
||||
import { Text } from 'react-native'
|
||||
import { FetchOptions } from 'react-query/types/core/query'
|
||||
import Autolinker from '@root/modules/autolinker'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import { ComposeAction, ComposeState } from './utils/types'
|
||||
import { instanceConfigurationStatusCharsURL } from './Root'
|
||||
import CustomText from '@components/Text'
|
||||
|
||||
export interface Params {
|
||||
textInput: ComposeState['textInputFocus']['current']
|
||||
@ -18,7 +18,7 @@ export interface Params {
|
||||
const TagText = ({ text }: { text: string }) => {
|
||||
const { colors } = useTheme()
|
||||
|
||||
return <Text style={{ color: colors.blue }}>{text}</Text>
|
||||
return <CustomText style={{ color: colors.blue }}>{text}</CustomText>
|
||||
}
|
||||
|
||||
const debouncedSuggestions = debounce(
|
||||
@ -120,7 +120,7 @@ const formatText = ({
|
||||
payload: {
|
||||
count: contentLength,
|
||||
raw: content,
|
||||
formatted: createElement(Text, null, children)
|
||||
formatted: createElement(CustomText, null, children)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { HeaderLeft, HeaderRight } from '@components/Header'
|
||||
import Input from '@components/Input'
|
||||
import CustomText from '@components/Text'
|
||||
import { TabMeProfileStackScreenProps } from '@utils/navigation/navigators'
|
||||
import { useProfileMutation } from '@utils/queryHooks/profile'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
@ -7,7 +8,7 @@ import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import { isEqual } from 'lodash'
|
||||
import React, { RefObject, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Alert, StyleSheet, Text, View } from 'react-native'
|
||||
import { Alert, View } from 'react-native'
|
||||
import FlashMessage from 'react-native-flash-message'
|
||||
import { ScrollView } from 'react-native-gesture-handler'
|
||||
|
||||
@ -100,13 +101,25 @@ const TabMeProfileFields: React.FC<
|
||||
}, [theme, i18n.language, dirty, status, newFields])
|
||||
|
||||
return (
|
||||
<ScrollView style={styles.base} keyboardShouldPersistTaps='always'>
|
||||
<ScrollView
|
||||
style={{
|
||||
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginBottom: StyleConstants.Spacing.L
|
||||
}}
|
||||
keyboardShouldPersistTaps='always'
|
||||
>
|
||||
<View style={{ marginBottom: StyleConstants.Spacing.L * 2 }}>
|
||||
{Array.from(Array(4).keys()).map(index => (
|
||||
<View key={index} style={styles.group}>
|
||||
<Text style={[styles.headline, { color: colors.primaryDefault }]}>
|
||||
<View key={index} style={{ marginBottom: StyleConstants.Spacing.M }}>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
marginBottom: StyleConstants.Spacing.XS,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{t('me.profile.fields.group', { index: index + 1 })}
|
||||
</Text>
|
||||
</CustomText>
|
||||
<Input
|
||||
title={t('me.profile.fields.label')}
|
||||
autoFocus={false}
|
||||
@ -142,18 +155,4 @@ const TabMeProfileFields: React.FC<
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding,
|
||||
marginBottom: StyleConstants.Spacing.L
|
||||
},
|
||||
group: {
|
||||
marginBottom: StyleConstants.Spacing.M
|
||||
},
|
||||
headline: {
|
||||
...StyleConstants.FontStyle.S,
|
||||
marginBottom: StyleConstants.Spacing.XS
|
||||
}
|
||||
})
|
||||
|
||||
export default TabMeProfileFields
|
||||
|
@ -2,6 +2,7 @@ import analytics from '@components/analytics'
|
||||
import Button from '@components/Button'
|
||||
import Icon from '@components/Icon'
|
||||
import { MenuContainer, MenuRow } from '@components/Menu'
|
||||
import CustomText from '@components/Text'
|
||||
import { useAppDispatch } from '@root/store'
|
||||
import { isDevelopment } from '@utils/checkEnvironment'
|
||||
import { updateInstancePush } from '@utils/slices/instances/updatePush'
|
||||
@ -20,7 +21,7 @@ import * as Notifications from 'expo-notifications'
|
||||
import * as WebBrowser from 'expo-web-browser'
|
||||
import React, { useState, useEffect, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { AppState, Linking, ScrollView, Text, View } from 'react-native'
|
||||
import { AppState, Linking, ScrollView, View } from 'react-native'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
const TabMePush: React.FC = () => {
|
||||
@ -205,14 +206,9 @@ const TabMePush: React.FC = () => {
|
||||
size={StyleConstants.Font.Size.L}
|
||||
color={colors.primaryDefault}
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
...StyleConstants.FontStyle.M,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
<CustomText fontStyle='M' style={{ color: colors.primaryDefault }}>
|
||||
{t('me.push.notAvailable')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
)}
|
||||
</ScrollView>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { MenuContainer, MenuRow } from '@components/Menu'
|
||||
import CustomText from '@components/Text'
|
||||
import { useAppDispatch } from '@root/store'
|
||||
import { getInstanceVersion } from '@utils/slices/instancesSlice'
|
||||
import {
|
||||
@ -10,7 +11,6 @@ import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import Constants from 'expo-constants'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Text } from 'react-native'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
const SettingsAnalytics: React.FC = () => {
|
||||
@ -31,25 +31,25 @@ const SettingsAnalytics: React.FC = () => {
|
||||
dispatch(changeAnalytics(!settingsAnalytics))
|
||||
}
|
||||
/>
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
...StyleConstants.FontStyle.S,
|
||||
marginTop: StyleConstants.Spacing.S,
|
||||
color: colors.secondary
|
||||
}}
|
||||
>
|
||||
{t('me.settings.version', { version: Constants.manifest?.version })}
|
||||
</Text>
|
||||
<Text
|
||||
</CustomText>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
...StyleConstants.FontStyle.S,
|
||||
color: colors.secondary
|
||||
}}
|
||||
>
|
||||
{t('me.settings.instanceVersion', { version: instanceVersion })}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</MenuContainer>
|
||||
)
|
||||
}
|
||||
|
@ -1,13 +1,14 @@
|
||||
import Button from '@components/Button'
|
||||
import { MenuContainer, MenuRow } from '@components/Menu'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import CustomText from '@components/Text'
|
||||
import { useActionSheet } from '@expo/react-native-action-sheet'
|
||||
import { persistor } from '@root/store'
|
||||
import { getInstanceActive, getInstances } from '@utils/slices/instancesSlice'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { DevSettings, Text } from 'react-native'
|
||||
import { DevSettings } from 'react-native'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
const SettingsDev: React.FC = () => {
|
||||
@ -18,16 +19,16 @@ const SettingsDev: React.FC = () => {
|
||||
|
||||
return (
|
||||
<MenuContainer>
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
selectable
|
||||
style={{
|
||||
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding,
|
||||
...StyleConstants.FontStyle.S,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{instances[instanceActive]?.token}
|
||||
</Text>
|
||||
</CustomText>
|
||||
<MenuRow
|
||||
title={'Local active index'}
|
||||
content={typeof instanceActive + ' - ' + instanceActive}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import Button from '@components/Button'
|
||||
import haptics from '@components/haptics'
|
||||
import ComponentSeparator from '@components/Separator'
|
||||
import CustomText from '@components/Text'
|
||||
import TimelineDefault from '@components/Timeline/Default'
|
||||
import { useAppDispatch } from '@root/store'
|
||||
import { TabMeStackScreenProps } from '@utils/navigation/navigators'
|
||||
@ -14,7 +15,7 @@ import { adaptiveScale } from '@utils/styles/scaling'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
import { ScrollView } from 'react-native-gesture-handler'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
@ -76,31 +77,26 @@ const TabMeSettingsFontsize: React.FC<
|
||||
return (
|
||||
<>
|
||||
{([-1, 0, 1, 2, 3] as [-1, 0, 1, 2, 3]).map(size => (
|
||||
<Text
|
||||
<CustomText
|
||||
key={size}
|
||||
style={[
|
||||
styles.size,
|
||||
{
|
||||
fontSize: adaptiveScale(StyleConstants.Font.Size.M, size),
|
||||
lineHeight: adaptiveScale(
|
||||
StyleConstants.Font.LineHeight.M,
|
||||
size
|
||||
),
|
||||
fontWeight:
|
||||
initialSize === size
|
||||
? StyleConstants.Font.Weight.Bold
|
||||
: undefined,
|
||||
color:
|
||||
initialSize === size
|
||||
? colors.primaryDefault
|
||||
: colors.secondary,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderColor: colors.border
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
marginHorizontal: StyleConstants.Spacing.XS,
|
||||
paddingHorizontal: StyleConstants.Spacing.XS,
|
||||
marginBottom: StyleConstants.Spacing.M,
|
||||
fontSize: adaptiveScale(StyleConstants.Font.Size.M, size),
|
||||
lineHeight: adaptiveScale(StyleConstants.Font.LineHeight.M, size),
|
||||
fontWeight:
|
||||
initialSize === size
|
||||
? StyleConstants.Font.Weight.Bold
|
||||
: undefined,
|
||||
color:
|
||||
initialSize === size ? colors.primaryDefault : colors.secondary,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderColor: colors.border
|
||||
}}
|
||||
>
|
||||
{t(`me.fontSize.sizes.${mapFontsizeToName(size)}`)}
|
||||
</Text>
|
||||
</CustomText>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
@ -108,9 +104,17 @@ const TabMeSettingsFontsize: React.FC<
|
||||
|
||||
return (
|
||||
<ScrollView scrollEnabled={false}>
|
||||
<Text style={[styles.header, { color: colors.primaryDefault }]}>
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
marginBottom: StyleConstants.Spacing.M,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{t('me.fontSize.showcase')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
<View>
|
||||
<ComponentSeparator
|
||||
extraMarginLeft={-StyleConstants.Spacing.Global.PagePadding}
|
||||
@ -127,11 +131,33 @@ const TabMeSettingsFontsize: React.FC<
|
||||
extraMarginRight={-StyleConstants.Spacing.Global.PagePadding}
|
||||
/>
|
||||
</View>
|
||||
<Text style={[styles.header, { color: colors.primaryDefault }]}>
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
marginBottom: StyleConstants.Spacing.M,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{t('me.fontSize.availableSizes')}
|
||||
</Text>
|
||||
<View style={styles.sizesDemo}>{sizesDemo}</View>
|
||||
<View style={styles.controls}>
|
||||
</CustomText>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
{sizesDemo}
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
onPress={() => {
|
||||
if (initialSize > -1) {
|
||||
@ -144,7 +170,7 @@ const TabMeSettingsFontsize: React.FC<
|
||||
content='Minus'
|
||||
round
|
||||
disabled={initialSize <= -1}
|
||||
style={styles.control}
|
||||
style={{ marginHorizontal: StyleConstants.Spacing.S }}
|
||||
/>
|
||||
<Button
|
||||
onPress={() => {
|
||||
@ -158,38 +184,11 @@ const TabMeSettingsFontsize: React.FC<
|
||||
content='Plus'
|
||||
round
|
||||
disabled={initialSize >= 3}
|
||||
style={styles.control}
|
||||
style={{ marginHorizontal: StyleConstants.Spacing.S }}
|
||||
/>
|
||||
</View>
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
header: {
|
||||
...StyleConstants.FontStyle.M,
|
||||
textAlign: 'center',
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
marginBottom: StyleConstants.Spacing.M
|
||||
},
|
||||
sizesDemo: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
size: {
|
||||
marginHorizontal: StyleConstants.Spacing.XS,
|
||||
paddingHorizontal: StyleConstants.Spacing.XS,
|
||||
marginBottom: StyleConstants.Spacing.M
|
||||
},
|
||||
controls: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
control: {
|
||||
marginHorizontal: StyleConstants.Spacing.S
|
||||
}
|
||||
})
|
||||
|
||||
export default TabMeSettingsFontsize
|
||||
|
@ -2,6 +2,7 @@ import analytics from '@components/analytics'
|
||||
import Button from '@components/Button'
|
||||
import haptics from '@components/haptics'
|
||||
import ComponentInstance from '@components/Instance'
|
||||
import CustomText from '@components/Text'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import initQuery from '@utils/initQuery'
|
||||
import {
|
||||
@ -13,13 +14,7 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useEffect, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import {
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
} from 'react-native'
|
||||
import { KeyboardAvoidingView, Platform, StyleSheet, View } from 'react-native'
|
||||
import { ScrollView } from 'react-native-gesture-handler'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
@ -35,7 +30,10 @@ const AccountButton: React.FC<Props> = ({ instance, selected = false }) => {
|
||||
<Button
|
||||
type='text'
|
||||
selected={selected}
|
||||
style={styles.button}
|
||||
style={{
|
||||
marginBottom: StyleConstants.Spacing.M,
|
||||
marginRight: StyleConstants.Spacing.M
|
||||
}}
|
||||
content={`@${instance.account.acct}@${instance.uri}${
|
||||
selected ? ' ✓' : ''
|
||||
}`}
|
||||
@ -70,13 +68,20 @@ const TabMeSwitch: React.FC = () => {
|
||||
>
|
||||
<ScrollView
|
||||
ref={scrollViewRef}
|
||||
style={styles.base}
|
||||
style={{ marginBottom: StyleConstants.Spacing.L * 2 }}
|
||||
keyboardShouldPersistTaps='always'
|
||||
>
|
||||
<View>
|
||||
<Text style={[styles.header, { color: colors.primaryDefault }]}>
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
paddingVertical: StyleConstants.Spacing.S,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{t('me.switch.new')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
<ComponentInstance
|
||||
scrollViewRef={scrollViewRef}
|
||||
disableHeaderImage
|
||||
@ -85,12 +90,32 @@ const TabMeSwitch: React.FC = () => {
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={[styles.firstSection, , { borderTopColor: colors.border }]}
|
||||
style={{
|
||||
marginTop: StyleConstants.Spacing.S,
|
||||
paddingTop: StyleConstants.Spacing.M,
|
||||
marginHorizontal: StyleConstants.Spacing.Global.PagePadding,
|
||||
borderTopWidth: StyleSheet.hairlineWidth,
|
||||
borderTopColor: colors.border
|
||||
}}
|
||||
>
|
||||
<Text style={[styles.header, { color: colors.primaryDefault }]}>
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
paddingVertical: StyleConstants.Spacing.S,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{t('me.switch.existing')}
|
||||
</Text>
|
||||
<View style={styles.accountButtons}>
|
||||
</CustomText>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
marginTop: StyleConstants.Spacing.M
|
||||
}}
|
||||
>
|
||||
{instances.length
|
||||
? instances
|
||||
.slice()
|
||||
@ -121,31 +146,4 @@ const TabMeSwitch: React.FC = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
marginBottom: StyleConstants.Spacing.L * 2
|
||||
},
|
||||
header: {
|
||||
...StyleConstants.FontStyle.M,
|
||||
textAlign: 'center',
|
||||
paddingVertical: StyleConstants.Spacing.S
|
||||
},
|
||||
firstSection: {
|
||||
marginTop: StyleConstants.Spacing.S,
|
||||
paddingTop: StyleConstants.Spacing.M,
|
||||
marginHorizontal: StyleConstants.Spacing.Global.PagePadding,
|
||||
borderTopWidth: StyleSheet.hairlineWidth
|
||||
},
|
||||
accountButtons: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
marginTop: StyleConstants.Spacing.M
|
||||
},
|
||||
button: {
|
||||
marginBottom: StyleConstants.Spacing.M,
|
||||
marginRight: StyleConstants.Spacing.M
|
||||
}
|
||||
})
|
||||
|
||||
export default TabMeSwitch
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Icon from '@components/Icon'
|
||||
import CustomText from '@components/Text'
|
||||
import {
|
||||
getInstanceAccount,
|
||||
getInstanceUri
|
||||
@ -6,7 +7,7 @@ import {
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useMemo } from 'react'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { PlaceholderLine } from 'rn-placeholder'
|
||||
|
||||
@ -26,27 +27,19 @@ const AccountInformationAccount: React.FC<Props> = ({
|
||||
)
|
||||
const instanceUri = useSelector(getInstanceUri)
|
||||
|
||||
const movedStyle = useMemo(
|
||||
() =>
|
||||
StyleSheet.create({
|
||||
base: {
|
||||
textDecorationLine: account?.moved ? 'line-through' : undefined
|
||||
}
|
||||
}),
|
||||
[account?.moved]
|
||||
)
|
||||
const movedContent = useMemo(() => {
|
||||
if (account?.moved) {
|
||||
return (
|
||||
<Text
|
||||
style={[
|
||||
styles.moved,
|
||||
{ color: colors.secondary, ...StyleConstants.FontStyle.M }
|
||||
]}
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
marginLeft: StyleConstants.Spacing.S,
|
||||
color: colors.secondary
|
||||
}}
|
||||
selectable
|
||||
>
|
||||
@{account.moved.acct}
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
}
|
||||
}, [account?.moved])
|
||||
@ -54,26 +47,29 @@ const AccountInformationAccount: React.FC<Props> = ({
|
||||
if (account || (localInstance && instanceAccount)) {
|
||||
return (
|
||||
<View
|
||||
style={[styles.base, { flexDirection: 'row', alignItems: 'center' }]}
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
borderRadius: 0,
|
||||
marginBottom: StyleConstants.Spacing.L
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
movedStyle.base,
|
||||
{
|
||||
color: colors.secondary,
|
||||
...StyleConstants.FontStyle.M
|
||||
}
|
||||
]}
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
textDecorationLine: account?.moved ? 'line-through' : undefined,
|
||||
color: colors.secondary
|
||||
}}
|
||||
selectable
|
||||
>
|
||||
@{localInstance ? instanceAccount?.acct : account?.acct}
|
||||
{localInstance ? `@${instanceUri}` : null}
|
||||
</Text>
|
||||
</CustomText>
|
||||
{movedContent}
|
||||
{account?.locked ? (
|
||||
<Icon
|
||||
name='Lock'
|
||||
style={styles.type}
|
||||
style={{ marginLeft: StyleConstants.Spacing.S }}
|
||||
color={colors.secondary}
|
||||
size={StyleConstants.Font.Size.M}
|
||||
/>
|
||||
@ -81,7 +77,7 @@ const AccountInformationAccount: React.FC<Props> = ({
|
||||
{account?.bot ? (
|
||||
<Icon
|
||||
name='HardDrive'
|
||||
style={styles.type}
|
||||
style={{ marginLeft: StyleConstants.Spacing.S }}
|
||||
color={colors.secondary}
|
||||
size={StyleConstants.Font.Size.M}
|
||||
/>
|
||||
@ -95,23 +91,12 @@ const AccountInformationAccount: React.FC<Props> = ({
|
||||
height={StyleConstants.Font.LineHeight.M}
|
||||
color={colors.shimmerDefault}
|
||||
noMargin
|
||||
style={styles.base}
|
||||
style={{ borderRadius: 0, marginBottom: StyleConstants.Spacing.L }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
borderRadius: 0,
|
||||
marginBottom: StyleConstants.Spacing.L
|
||||
},
|
||||
type: { marginLeft: StyleConstants.Spacing.S },
|
||||
moved: {
|
||||
marginLeft: StyleConstants.Spacing.S
|
||||
}
|
||||
})
|
||||
|
||||
export default React.memo(
|
||||
AccountInformationAccount,
|
||||
(_, next) => next.account === undefined
|
||||
|
@ -1,9 +1,10 @@
|
||||
import Icon from '@components/Icon'
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
import { PlaceholderLine } from 'rn-placeholder'
|
||||
|
||||
export interface Props {
|
||||
@ -24,20 +25,20 @@ const AccountInformationCreated = React.memo(
|
||||
if (account) {
|
||||
return (
|
||||
<View
|
||||
style={[styles.base, { flexDirection: 'row', alignItems: 'center' }]}
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
borderRadius: 0,
|
||||
marginBottom: StyleConstants.Spacing.M
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
name='Calendar'
|
||||
size={StyleConstants.Font.Size.S}
|
||||
color={colors.secondary}
|
||||
style={styles.icon}
|
||||
style={{ marginRight: StyleConstants.Spacing.XS }}
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
color: colors.secondary,
|
||||
...StyleConstants.FontStyle.S
|
||||
}}
|
||||
>
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
{t('shared.account.created_at', {
|
||||
date: new Date(account.created_at || '').toLocaleDateString(
|
||||
i18n.language,
|
||||
@ -48,7 +49,7 @@ const AccountInformationCreated = React.memo(
|
||||
}
|
||||
)
|
||||
})}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
)
|
||||
} else {
|
||||
@ -58,7 +59,7 @@ const AccountInformationCreated = React.memo(
|
||||
height={StyleConstants.Font.LineHeight.S}
|
||||
color={colors.shimmerDefault}
|
||||
noMargin
|
||||
style={styles.base}
|
||||
style={{ borderRadius: 0, marginBottom: StyleConstants.Spacing.M }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@ -66,14 +67,4 @@ const AccountInformationCreated = React.memo(
|
||||
(_, next) => next.account === undefined
|
||||
)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
borderRadius: 0,
|
||||
marginBottom: StyleConstants.Spacing.M
|
||||
},
|
||||
icon: {
|
||||
marginRight: StyleConstants.Spacing.XS
|
||||
}
|
||||
})
|
||||
|
||||
export default AccountInformationCreated
|
||||
|
@ -1,9 +1,10 @@
|
||||
import Input from '@components/Input'
|
||||
import { ParseEmojis } from '@components/Parse'
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useMemo, useState } from 'react'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
import { PlaceholderLine } from 'rn-placeholder'
|
||||
|
||||
export interface Props {
|
||||
@ -17,7 +18,7 @@ const AccountInformationName: React.FC<Props> = ({ account, edit }) => {
|
||||
const movedContent = useMemo(() => {
|
||||
if (account?.moved) {
|
||||
return (
|
||||
<View style={styles.moved}>
|
||||
<View style={{ marginLeft: StyleConstants.Spacing.S }}>
|
||||
<ParseEmojis
|
||||
content={account.moved.display_name || account.moved.username}
|
||||
emojis={account.moved.emojis}
|
||||
@ -32,13 +33,20 @@ const AccountInformationName: React.FC<Props> = ({ account, edit }) => {
|
||||
const [displatName, setDisplayName] = useState(account?.display_name)
|
||||
|
||||
return (
|
||||
<View style={[styles.base, { flexDirection: 'row' }]}>
|
||||
<View
|
||||
style={{
|
||||
borderRadius: 0,
|
||||
marginTop: StyleConstants.Spacing.S,
|
||||
marginBottom: StyleConstants.Spacing.XS,
|
||||
flexDirection: 'row'
|
||||
}}
|
||||
>
|
||||
{account ? (
|
||||
edit ? (
|
||||
<Input title='昵称' value={displatName} setValue={setDisplayName} />
|
||||
) : (
|
||||
<>
|
||||
<Text
|
||||
<CustomText
|
||||
style={{
|
||||
textDecorationLine: account?.moved ? 'line-through' : undefined
|
||||
}}
|
||||
@ -49,7 +57,7 @@ const AccountInformationName: React.FC<Props> = ({ account, edit }) => {
|
||||
size='L'
|
||||
fontBold
|
||||
/>
|
||||
</Text>
|
||||
</CustomText>
|
||||
{movedContent}
|
||||
</>
|
||||
)
|
||||
@ -66,17 +74,6 @@ const AccountInformationName: React.FC<Props> = ({ account, edit }) => {
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
borderRadius: 0,
|
||||
marginTop: StyleConstants.Spacing.S,
|
||||
marginBottom: StyleConstants.Spacing.XS
|
||||
},
|
||||
moved: {
|
||||
marginLeft: StyleConstants.Spacing.S
|
||||
}
|
||||
})
|
||||
|
||||
export default React.memo(
|
||||
AccountInformationName,
|
||||
(_, next) => next.account === undefined
|
||||
|
@ -1,4 +1,5 @@
|
||||
import analytics from '@components/analytics'
|
||||
import CustomText from '@components/Text'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import { StyleConstants } from '@root/utils/styles/constants'
|
||||
@ -6,7 +7,7 @@ import { useTheme } from '@root/utils/styles/ThemeManager'
|
||||
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
import { PlaceholderLine } from 'rn-placeholder'
|
||||
|
||||
export interface Props {
|
||||
@ -23,7 +24,7 @@ const AccountInformationStats: React.FC<Props> = ({ account, myInfo }) => {
|
||||
return (
|
||||
<View style={[styles.stats, { flexDirection: 'row' }]}>
|
||||
{account ? (
|
||||
<Text
|
||||
<CustomText
|
||||
style={[styles.stat, { color: colors.primaryDefault }]}
|
||||
children={t('shared.account.summary.statuses_count', {
|
||||
count: account.statuses_count || 0
|
||||
@ -45,7 +46,7 @@ const AccountInformationStats: React.FC<Props> = ({ account, myInfo }) => {
|
||||
/>
|
||||
)}
|
||||
{account ? (
|
||||
<Text
|
||||
<CustomText
|
||||
style={[
|
||||
styles.stat,
|
||||
{ color: colors.primaryDefault, textAlign: 'right' }
|
||||
@ -75,7 +76,7 @@ const AccountInformationStats: React.FC<Props> = ({ account, myInfo }) => {
|
||||
/>
|
||||
)}
|
||||
{account ? (
|
||||
<Text
|
||||
<CustomText
|
||||
style={[
|
||||
styles.stat,
|
||||
{ color: colors.primaryDefault, textAlign: 'center' }
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { ParseEmojis } from '@components/Parse'
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { Dimensions, StyleSheet, Text, View } from 'react-native'
|
||||
import { Dimensions, StyleSheet, View } from 'react-native'
|
||||
import Animated, {
|
||||
Extrapolate,
|
||||
interpolate,
|
||||
@ -46,29 +47,33 @@ const AccountNav = React.memo(
|
||||
return (
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.base,
|
||||
styleOpacity,
|
||||
{ backgroundColor: colors.backgroundDefault, height: headerHeight }
|
||||
{
|
||||
...StyleSheet.absoluteFillObject,
|
||||
zIndex: 99,
|
||||
backgroundColor: colors.backgroundDefault,
|
||||
height: headerHeight
|
||||
}
|
||||
]}
|
||||
>
|
||||
<View
|
||||
style={[
|
||||
styles.content,
|
||||
{
|
||||
marginTop:
|
||||
useSafeAreaInsets().top + (44 - StyleConstants.Font.Size.L) / 2
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
overflow: 'hidden',
|
||||
marginTop:
|
||||
useSafeAreaInsets().top + (44 - StyleConstants.Font.Size.L) / 2
|
||||
}}
|
||||
>
|
||||
<Animated.View style={[styles.display_name, styleMarginTop]}>
|
||||
<Animated.View style={[{ flexDirection: 'row' }, styleMarginTop]}>
|
||||
{account ? (
|
||||
<Text numberOfLines={1}>
|
||||
<CustomText numberOfLines={1}>
|
||||
<ParseEmojis
|
||||
content={account.display_name || account.username}
|
||||
emojis={account.emojis}
|
||||
fontBold
|
||||
/>
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
</Animated.View>
|
||||
</View>
|
||||
@ -78,19 +83,4 @@ const AccountNav = React.memo(
|
||||
(_, next) => next.account === undefined
|
||||
)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
zIndex: 99
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
overflow: 'hidden'
|
||||
},
|
||||
display_name: {
|
||||
flexDirection: 'row'
|
||||
}
|
||||
})
|
||||
|
||||
export default AccountNav
|
||||
|
@ -1,6 +1,7 @@
|
||||
import Icon from '@components/Icon'
|
||||
import { ParseEmojis } from '@components/Parse'
|
||||
import ComponentSeparator from '@components/Separator'
|
||||
import CustomText from '@components/Text'
|
||||
import TimelineAttachment from '@components/Timeline/Shared/Attachment'
|
||||
import TimelineContent from '@components/Timeline/Shared/Content'
|
||||
import HeaderSharedCreated from '@components/Timeline/Shared/HeaderShared/Created'
|
||||
@ -9,7 +10,7 @@ import { useStatusHistory } from '@utils/queryHooks/statusesHistory'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { Text, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
import { ScrollView } from 'react-native-gesture-handler'
|
||||
|
||||
const ContentView = ({
|
||||
@ -52,12 +53,12 @@ const ContentView = ({
|
||||
size={StyleConstants.Font.Size.M}
|
||||
color={colors.disabled}
|
||||
/>
|
||||
<Text style={{ flex: 1 }}>
|
||||
<CustomText style={{ flex: 1 }}>
|
||||
<ParseEmojis
|
||||
content={option.title}
|
||||
emojis={history.poll?.emojis}
|
||||
/>
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
</View>
|
||||
))
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { HeaderCenter, HeaderLeft } from '@components/Header'
|
||||
import { ParseEmojis } from '@components/Parse'
|
||||
import CustomText from '@components/Text'
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack'
|
||||
import TabSharedAccount from '@screens/Tabs/Shared/Account'
|
||||
import TabSharedAttachments from '@screens/Tabs/Shared/Attachments'
|
||||
@ -14,7 +15,7 @@ import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import { debounce } from 'lodash'
|
||||
import React from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { Platform, StyleSheet, Text, TextInput, View } from 'react-native'
|
||||
import { Platform, TextInput, View } from 'react-native'
|
||||
|
||||
const TabSharedRoot = ({
|
||||
Stack
|
||||
@ -61,7 +62,7 @@ const TabSharedRoot = ({
|
||||
}: TabSharedStackScreenProps<'Tab-Shared-Attachments'>) => {
|
||||
return {
|
||||
headerTitle: () => (
|
||||
<Text numberOfLines={1}>
|
||||
<CustomText numberOfLines={1}>
|
||||
<Trans
|
||||
i18nKey='screenTabs:shared.attachments.name'
|
||||
components={[
|
||||
@ -70,16 +71,16 @@ const TabSharedRoot = ({
|
||||
emojis={account.emojis}
|
||||
fontBold
|
||||
/>,
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
...StyleConstants.FontStyle.M,
|
||||
color: colors.primaryDefault,
|
||||
fontWeight: StyleConstants.Font.Weight.Bold
|
||||
}}
|
||||
/>
|
||||
]}
|
||||
/>
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
}
|
||||
}}
|
||||
@ -126,28 +127,30 @@ const TabSharedRoot = ({
|
||||
}
|
||||
)
|
||||
return (
|
||||
<View style={styles.searchBar}>
|
||||
<View
|
||||
style={{
|
||||
flexBasis: '80%',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
<TextInput
|
||||
editable={false}
|
||||
style={[
|
||||
styles.textInput,
|
||||
{
|
||||
color: colors.primaryDefault
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
fontSize: StyleConstants.Font.Size.M,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
defaultValue={t('shared.search.header.prefix')}
|
||||
/>
|
||||
<TextInput
|
||||
accessibilityRole='search'
|
||||
keyboardAppearance={mode}
|
||||
style={[
|
||||
styles.textInput,
|
||||
{
|
||||
flex: 1,
|
||||
color: colors.primaryDefault,
|
||||
paddingLeft: StyleConstants.Spacing.XS
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
fontSize: StyleConstants.Font.Size.M,
|
||||
flex: 1,
|
||||
color: colors.primaryDefault,
|
||||
paddingLeft: StyleConstants.Spacing.XS
|
||||
}}
|
||||
autoFocus
|
||||
onChangeText={onChangeText}
|
||||
autoCapitalize='none'
|
||||
@ -199,15 +202,4 @@ const TabSharedRoot = ({
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
searchBar: {
|
||||
flexBasis: '80%',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
textInput: {
|
||||
fontSize: StyleConstants.Font.Size.M
|
||||
}
|
||||
})
|
||||
|
||||
export default TabSharedRoot
|
||||
|
@ -1,6 +1,7 @@
|
||||
import ComponentAccount from '@components/Account'
|
||||
import ComponentHashtag from '@components/Hashtag'
|
||||
import ComponentSeparator from '@components/Separator'
|
||||
import CustomText from '@components/Text'
|
||||
import TimelineDefault from '@components/Timeline/Default'
|
||||
import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
|
||||
import { useSearchQuery } from '@utils/queryHooks/search'
|
||||
@ -13,7 +14,6 @@ import {
|
||||
Platform,
|
||||
SectionList,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
} from 'react-native'
|
||||
import { Circle } from 'react-native-animated-spinkit'
|
||||
@ -66,10 +66,15 @@ const TabSharedSearch: React.FC<
|
||||
|
||||
const listEmpty = useMemo(() => {
|
||||
return (
|
||||
<View style={styles.emptyBase}>
|
||||
<View
|
||||
style={{
|
||||
marginVertical: StyleConstants.Spacing.Global.PagePadding,
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
<View>
|
||||
{status === 'loading' ? (
|
||||
<View style={styles.loading}>
|
||||
<View style={{ flex: 1, alignItems: 'center' }}>
|
||||
<Circle
|
||||
size={StyleConstants.Font.Size.M * 1.25}
|
||||
color={colors.secondary}
|
||||
@ -77,53 +82,61 @@ const TabSharedSearch: React.FC<
|
||||
</View>
|
||||
) : (
|
||||
<>
|
||||
<Text
|
||||
style={[
|
||||
styles.emptyDefault,
|
||||
styles.emptyFontSize,
|
||||
{ color: colors.primaryDefault }
|
||||
]}
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
marginBottom: StyleConstants.Spacing.L,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
<Trans
|
||||
i18nKey='screenTabs:shared.search.empty.general'
|
||||
components={{ bold: <Text style={styles.emptyFontBold} /> }}
|
||||
components={{
|
||||
bold: (
|
||||
<CustomText
|
||||
style={{ fontWeight: StyleConstants.Font.Weight.Bold }}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</Text>
|
||||
<Text
|
||||
</CustomText>
|
||||
<CustomText
|
||||
style={[styles.emptyAdvanced, { color: colors.primaryDefault }]}
|
||||
>
|
||||
{t('shared.search.empty.advanced.header')}
|
||||
</Text>
|
||||
<Text
|
||||
</CustomText>
|
||||
<CustomText
|
||||
style={[styles.emptyAdvanced, { color: colors.primaryDefault }]}
|
||||
>
|
||||
<Text style={{ color: colors.secondary }}>
|
||||
<CustomText style={{ color: colors.secondary }}>
|
||||
@username@domain
|
||||
</Text>
|
||||
</CustomText>
|
||||
{' '}
|
||||
{t('shared.search.empty.advanced.example.account')}
|
||||
</Text>
|
||||
<Text
|
||||
</CustomText>
|
||||
<CustomText
|
||||
style={[styles.emptyAdvanced, { color: colors.primaryDefault }]}
|
||||
>
|
||||
<Text style={{ color: colors.secondary }}>#example</Text>
|
||||
<CustomText style={{ color: colors.secondary }}>
|
||||
#example
|
||||
</CustomText>
|
||||
{' '}
|
||||
{t('shared.search.empty.advanced.example.hashtag')}
|
||||
</Text>
|
||||
<Text
|
||||
</CustomText>
|
||||
<CustomText
|
||||
style={[styles.emptyAdvanced, { color: colors.primaryDefault }]}
|
||||
>
|
||||
<Text style={{ color: colors.secondary }}>URL</Text>
|
||||
<CustomText style={{ color: colors.secondary }}>URL</CustomText>
|
||||
{' '}
|
||||
{t('shared.search.empty.advanced.example.statusLink')}
|
||||
</Text>
|
||||
<Text
|
||||
</CustomText>
|
||||
<CustomText
|
||||
style={[styles.emptyAdvanced, { color: colors.primaryDefault }]}
|
||||
>
|
||||
<Text style={{ color: colors.secondary }}>URL</Text>
|
||||
<CustomText style={{ color: colors.secondary }}>URL</CustomText>
|
||||
{' '}
|
||||
{t('shared.search.empty.advanced.example.accountLink')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
@ -133,16 +146,21 @@ const TabSharedSearch: React.FC<
|
||||
const sectionHeader = useCallback(
|
||||
({ section: { translation } }) => (
|
||||
<View
|
||||
style={[
|
||||
styles.sectionHeader,
|
||||
{ backgroundColor: colors.backgroundDefault }
|
||||
]}
|
||||
style={{
|
||||
padding: StyleConstants.Spacing.M,
|
||||
backgroundColor: colors.backgroundDefault
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={[styles.sectionHeaderText, { color: colors.primaryDefault }]}
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
fontWeight: StyleConstants.Font.Weight.Bold,
|
||||
textAlign: 'center',
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{translation}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
),
|
||||
[]
|
||||
@ -151,18 +169,27 @@ const TabSharedSearch: React.FC<
|
||||
({ section: { data, translation } }) =>
|
||||
!data.length ? (
|
||||
<View
|
||||
style={[
|
||||
styles.sectionFooter,
|
||||
{ backgroundColor: colors.backgroundDefault }
|
||||
]}
|
||||
style={{
|
||||
padding: StyleConstants.Spacing.S,
|
||||
backgroundColor: colors.backgroundDefault
|
||||
}}
|
||||
>
|
||||
<Text style={[styles.sectionFooterText, { color: colors.secondary }]}>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{ textAlign: 'center', color: colors.secondary }}
|
||||
>
|
||||
<Trans
|
||||
i18nKey='screenTabs:shared.search.notFound'
|
||||
values={{ searchTerm: text, type: translation }}
|
||||
components={{ bold: <Text style={styles.emptyFontBold} /> }}
|
||||
components={{
|
||||
bold: (
|
||||
<CustomText
|
||||
style={{ fontWeight: StyleConstants.Font.Weight.Bold }}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
) : null,
|
||||
[text]
|
||||
@ -186,7 +213,7 @@ const TabSharedSearch: React.FC<
|
||||
style={{ flex: 1 }}
|
||||
>
|
||||
<SectionList
|
||||
style={styles.base}
|
||||
style={{ minHeight: '100%' }}
|
||||
renderItem={listItem}
|
||||
stickySectionHeadersEnabled
|
||||
sections={data || []}
|
||||
@ -203,38 +230,8 @@ const TabSharedSearch: React.FC<
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
minHeight: '100%'
|
||||
},
|
||||
emptyBase: {
|
||||
marginVertical: StyleConstants.Spacing.Global.PagePadding,
|
||||
alignItems: 'center'
|
||||
},
|
||||
loading: { flex: 1, alignItems: 'center' },
|
||||
emptyFontSize: { ...StyleConstants.FontStyle.S },
|
||||
emptyFontBold: {
|
||||
fontWeight: StyleConstants.Font.Weight.Bold
|
||||
},
|
||||
emptyDefault: {
|
||||
marginBottom: StyleConstants.Spacing.L
|
||||
},
|
||||
emptyAdvanced: {
|
||||
marginBottom: StyleConstants.Spacing.S
|
||||
},
|
||||
sectionHeader: {
|
||||
padding: StyleConstants.Spacing.M
|
||||
},
|
||||
sectionHeaderText: {
|
||||
...StyleConstants.FontStyle.M,
|
||||
fontWeight: StyleConstants.Font.Weight.Bold,
|
||||
textAlign: 'center'
|
||||
},
|
||||
sectionFooter: {
|
||||
padding: StyleConstants.Spacing.S
|
||||
},
|
||||
sectionFooterText: {
|
||||
...StyleConstants.FontStyle.S,
|
||||
textAlign: 'center'
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -3,11 +3,7 @@ const Base = 4
|
||||
export const StyleConstants = {
|
||||
Font: {
|
||||
Size: { S: 14, M: 16, L: 18 },
|
||||
LineHeight: {
|
||||
S: 20,
|
||||
M: 22,
|
||||
L: 28
|
||||
},
|
||||
LineHeight: { S: 20, M: 22, L: 28 },
|
||||
Weight: { Normal: '400' as '400', Bold: '600' as '600' }
|
||||
},
|
||||
FontStyle: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user