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