1
0
mirror of https://github.com/tooot-app/app synced 2025-06-05 22:19:13 +02:00

Merge branch 'main' into candidate

This commit is contained in:
xmflsct
2023-01-25 00:15:59 +01:00
97 changed files with 1010 additions and 1092 deletions

View File

@@ -1,5 +1,5 @@
diff --git a/RNFastImage.podspec b/RNFastImage.podspec
index db0fada63fc06191f8620d336d244edde6c3dba3..b6ffe6c77ab1fd5b821525f6f0b7363a13cba3a0 100644
index db0fada63fc06191f8620d336d244edde6c3dba3..9c22c36f6978530da21afe143324ff79b4e96454 100644
--- a/RNFastImage.podspec
+++ b/RNFastImage.podspec
@@ -16,6 +16,6 @@ Pod::Spec.new do |s|
@@ -8,7 +8,7 @@ index db0fada63fc06191f8620d336d244edde6c3dba3..b6ffe6c77ab1fd5b821525f6f0b7363a
s.dependency 'React-Core'
- s.dependency 'SDWebImage', '~> 5.11.1'
- s.dependency 'SDWebImageWebPCoder', '~> 0.8.4'
+ s.dependency 'SDWebImage', '~> 5.14.3'
+ s.dependency 'SDWebImage', '~> 5.15.0'
+ s.dependency 'SDWebImageWebPCoder', '~> 0.9.1'
end
diff --git a/android/build.gradle b/android/build.gradle

View File

@@ -16,7 +16,7 @@ PODS:
- ExpoModulesCore
- EXNotifications (0.17.0):
- ExpoModulesCore
- Expo (47.0.12):
- Expo (47.0.13):
- ExpoModulesCore
- ExpoCrypto (12.1.0):
- ExpoModulesCore
@@ -301,11 +301,11 @@ PODS:
- React-Core
- react-native-blurhash (1.1.10):
- React-Core
- react-native-cameraroll (5.2.1):
- react-native-cameraroll (5.2.3):
- React-Core
- react-native-image-picker (4.10.3):
- react-native-image-picker (5.0.1):
- React-Core
- react-native-ios-context-menu (1.15.1):
- react-native-ios-context-menu (1.15.3):
- React-Core
- react-native-language-detection (0.2.2):
- React
@@ -318,12 +318,12 @@ PODS:
- React-Core
- react-native-pager-view (6.1.2):
- React-Core
- react-native-paste-input (0.5.2):
- react-native-paste-input (0.6.0):
- React-Core
- Swime (= 3.0.6)
- react-native-quick-base64 (2.0.5):
- React-Core
- react-native-safe-area-context (4.4.1):
- react-native-safe-area-context (4.5.0):
- RCT-Folly
- RCTRequired
- RCTTypeSafety
@@ -403,11 +403,11 @@ PODS:
- React-Core
- RNFastImage (8.6.3):
- React-Core
- SDWebImage (~> 5.14.3)
- SDWebImage (~> 5.15.0)
- SDWebImageWebPCoder (~> 0.9.1)
- RNGestureHandler (2.8.0):
- RNGestureHandler (2.9.0):
- React-Core
- RNReanimated (2.13.0):
- RNReanimated (2.14.4):
- DoubleConversion
- FBLazyVector
- FBReactNativeSpec
@@ -434,23 +434,23 @@ PODS:
- React-RCTText
- ReactCommon/turbomodule/core
- Yoga
- RNScreens (3.18.2):
- RNScreens (3.19.0):
- React-Core
- React-RCTImage
- RNSentry (4.12.0):
- RNSentry (4.13.0):
- React-Core
- Sentry/HybridSDK (= 7.31.3)
- Sentry/HybridSDK (= 7.31.5)
- RNShareMenu (6.0.0):
- React
- RNSVG (13.6.0):
- RNSVG (13.7.0):
- React-Core
- SDWebImage (5.14.3):
- SDWebImage/Core (= 5.14.3)
- SDWebImage/Core (5.14.3)
- SDWebImage (5.15.0):
- SDWebImage/Core (= 5.15.0)
- SDWebImage/Core (5.15.0)
- SDWebImageWebPCoder (0.9.1):
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.13)
- Sentry/HybridSDK (7.31.3)
- Sentry/HybridSDK (7.31.5)
- Swime (3.0.6)
- Yoga (1.14.0)
@@ -716,7 +716,7 @@ SPEC CHECKSUMS:
EXFileSystem: 60602b6eefa6873f97172c684b7537c9760b50d6
EXFont: 319606bfe48c33b5b5063fb0994afdc496befe80
EXNotifications: babce2a87b7922051354fcfe7a74dd279b7e272a
Expo: f48d305fda3e4e501d686e6bad7d8c8373828279
Expo: b9fa98bf260992312ee3c424400819fb9beadafe
ExpoCrypto: 6eb2a5ede7d95b7359a5f0391ee0c5d2ecd144b3
ExpoHaptics: 129d3f8d44c2205adcdf8db760602818463d5437
ExpoKeepAwake: 69b59d0a8d2b24de9f82759c39b3821fec030318
@@ -756,17 +756,17 @@ SPEC CHECKSUMS:
React-logger: 1623c216abaa88974afce404dc8f479406bbc3a0
react-native-blur: 50c9feabacbc5f49b61337ebc32192c6be7ec3c3
react-native-blurhash: add4df9a937b4e021a24bc67a0714f13e0bd40b7
react-native-cameraroll: f94bf9f46c998963ecd2bb6e9a3f9cca59b6d9f1
react-native-image-picker: 60f4246eb5bb7187fc15638a8c1f13abd3820695
react-native-ios-context-menu: b170594b4448c0cd10c79e13432216bac99de1ac
react-native-cameraroll: 5b25d0be40185d02e522bf2abf8a1ba4e8faa107
react-native-image-picker: 8cb4280e2c1efc3daeb2d9d597f9429a60472e40
react-native-ios-context-menu: e529171ba760a1af7f2ef0729f5a7f4d226171c5
react-native-language-detection: f414937fa715108ab50a6269a3de0bcb95e4ceb0
react-native-menu: 9d7d6f819cc7fa14a15cf86888c53f3240d86f1b
react-native-mmkv: 69b9c003f10afdd01addf7c6ee784ce42ee2eff3
react-native-netinfo: 2517ad504b3d303e90d7a431b0fcaef76d207983
react-native-pager-view: 54bed894cecebe28cede54c01038d9d1e122de43
react-native-paste-input: 88709b4fd586ea8cc56ba5e2fc4cdfe90597730c
react-native-paste-input: 5182843692fd2ec72be50f241a38a49796e225d7
react-native-quick-base64: e657e9197e61b60a9dec49807843052b830da254
react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a
react-native-safe-area-context: 39c2d8be3328df5d437ac1700f4f3a4f75716acc
react-native-segmented-control: 65df6cd0619b780b3843d574a72d4c7cec396097
React-perflogger: 8c79399b0500a30ee8152d0f9f11beae7fc36595
React-RCTActionSheet: 7316773acabb374642b926c19aef1c115df5c466
@@ -782,16 +782,16 @@ SPEC CHECKSUMS:
ReactCommon: 349be31adeecffc7986a0de875d7fb0dcf4e251c
RNCAsyncStorage: 8616bd5a58af409453ea4e1b246521bb76578d60
RNCClipboard: 2834e1c4af68697089cdd455ee4a4cdd198fa7dd
RNFastImage: 756ab178acb5e3f11d8b0a931956fbd9da8d6e54
RNGestureHandler: 62232ba8f562f7dea5ba1b3383494eb5bf97a4d3
RNReanimated: ce445c233a6ff5600223484a88ad5704945d972a
RNScreens: 34cc502acf1b916c582c60003dc3089fa01dc66d
RNSentry: 4c09f4dd9740cb9b33e94303de5b6d0dbeb0737d
RNFastImage: bd611b5635f1e0f43c8ccf597b1ef6ee0d0f966d
RNGestureHandler: 071d7a9ad81e8b83fe7663b303d132406a7d8f39
RNReanimated: 6668b0587bebd4b15dd849b99e5a9c70fc12ed95
RNScreens: ea4cd3a853063cda19a4e3c28d2e52180c80f4eb
RNSentry: acebe4104a6f5915ae871eb59dc73f13dcc92ef7
RNShareMenu: cb9dac548c8bf147d06f0bf07296ad51ea9f5fc3
RNSVG: 3a79c0c4992213e4f06c08e62730c5e7b9e4dc17
SDWebImage: 9c36e66c8ce4620b41a7407698dda44211a96764
RNSVG: d787d64ca06b9158e763ad2638a8c4edce00782a
SDWebImage: 9bec4c5cdd9579e1f57104735ee0c37df274d593
SDWebImageWebPCoder: 18503de6621dd2c420d680e33d46bf8e1d5169b0
Sentry: 08884c523575ec0f6690d94ed3ccb0246a1600bf
Sentry: 4c9babff9034785067c896fd580b1f7de44da020
Swime: d7b2c277503b6cea317774aedc2dce05613f8b0b
Yoga: 99caf8d5ab45e9d637ee6e0174ec16fbbb01bcfc

View File

@@ -1,6 +1,6 @@
{
"name": "tooot",
"version": "4.8.3",
"version": "4.8.4",
"description": "tooot for Mastodon",
"author": "xmflsct <me@xmflsct.com>",
"license": "GPL-3.0-or-later",
@@ -24,26 +24,26 @@
"@formatjs/intl-numberformat": "^8.3.3",
"@formatjs/intl-pluralrules": "^5.1.8",
"@formatjs/intl-relativetimeformat": "^11.1.8",
"@mattermost/react-native-paste-input": "^0.5.2",
"@mattermost/react-native-paste-input": "^0.6.0",
"@neverdull-agency/expo-unlimited-secure-store": "^1.0.10",
"@react-native-async-storage/async-storage": "~1.17.11",
"@react-native-camera-roll/camera-roll": "^5.2.1",
"@react-native-camera-roll/camera-roll": "^5.2.3",
"@react-native-clipboard/clipboard": "^1.11.1",
"@react-native-community/blur": "^4.3.0",
"@react-native-community/netinfo": "9.3.7",
"@react-native-community/segmented-control": "^2.2.2",
"@react-native-firebase/app": "^16.5.0",
"@react-native-firebase/app": "^16.5.2",
"@react-native-menu/menu": "^0.7.3",
"@react-navigation/bottom-tabs": "^6.5.2",
"@react-navigation/native": "^6.1.1",
"@react-navigation/native-stack": "^6.9.7",
"@react-navigation/stack": "^6.3.10",
"@sentry/react-native": "4.12.0",
"@react-navigation/bottom-tabs": "^6.5.3",
"@react-navigation/native": "^6.1.2",
"@react-navigation/native-stack": "^6.9.8",
"@react-navigation/stack": "^6.3.11",
"@sentry/react-native": "4.13.0",
"@sharcoux/slider": "^6.1.1",
"@tanstack/react-query": "^4.20.9",
"axios": "^1.2.2",
"@tanstack/react-query": "^4.23.0",
"axios": "^1.2.4",
"diff": "^5.1.0",
"expo": "^47.0.12",
"expo": "^47.0.13",
"expo-auth-session": "^3.8.0",
"expo-av": "^13.1.0",
"expo-constants": "^14.1.0",
@@ -62,7 +62,7 @@
"expo-video-thumbnails": "^7.1.0",
"expo-web-browser": "~12.0.0",
"htmlparser2": "^8.0.1",
"i18next": "^22.4.8",
"i18next": "^22.4.9",
"linkify-it": "^4.0.1",
"lodash": "^4.17.21",
"react": "^18.2.0",
@@ -72,21 +72,20 @@
"react-native": "^0.70.6",
"react-native-blurhash": "^1.1.10",
"react-native-fast-image": "^8.6.3",
"react-native-feather": "^1.1.2",
"react-native-flash-message": "^0.4.0",
"react-native-gesture-handler": "~2.8.0",
"react-native-image-picker": "^4.10.3",
"react-native-ios-context-menu": "^1.15.1",
"react-native-gesture-handler": "~2.9.0",
"react-native-image-picker": "^5.0.1",
"react-native-ios-context-menu": "^1.15.3",
"react-native-language-detection": "^0.2.2",
"react-native-mmkv": "^2.5.1",
"react-native-pager-view": "^6.1.2",
"react-native-quick-base64": "^2.0.5",
"react-native-reanimated": "^2.13.0",
"react-native-reanimated": "^2.14.4",
"react-native-reanimated-zoom": "^0.3.3",
"react-native-safe-area-context": "^4.4.1",
"react-native-screens": "^3.18.2",
"react-native-safe-area-context": "^4.5.0",
"react-native-screens": "^3.19.0",
"react-native-share-menu": "^6.0.0",
"react-native-svg": "^13.6.0",
"react-native-svg": "^13.7.0",
"react-native-swipe-list-view": "^3.2.9",
"react-native-tab-view": "^3.3.4",
"react-redux": "^8.0.5",
@@ -102,14 +101,15 @@
"@types/diff": "^5.0.2",
"@types/linkify-it": "^3.0.2",
"@types/lodash": "^4.14.191",
"@types/react": "^18.0.26",
"@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10",
"@types/react-native": "^0.70.8",
"@types/react-native": "^0.70.9",
"@types/react-native-share-menu": "^5.0.2",
"@types/url-parse": "^1.4.8",
"babel-plugin-module-resolver": "^4.1.0",
"babel-plugin-module-resolver": "^5.0.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"chalk": "^4.1.2",
"deprecated-react-native-prop-types": "^4.0.0",
"dotenv": "^16.0.3",
"react-native-clean-project": "^4.0.1",
"typescript": "^4.9.4"

View File

@@ -452,6 +452,7 @@ declare namespace Mastodon {
'posting:default:language'?: string
'reading:expand:media'?: 'default' | 'show_all' | 'hide_all'
'reading:expand:spoilers'?: boolean
'reading:autoplay:gifs'?: boolean
}
type PushSubscription = {

View File

@@ -1,5 +1,4 @@
declare module 'gl-react-blurhash'
declare module 'react-native-feather'
declare module 'react-native-toast-message'
declare module 'rtl-detect'

View File

@@ -68,7 +68,7 @@ const ComponentAccount: React.FC<PropsWithChildren & Props> = ({ account, props,
</View>
{props.onPress && !props.disabled ? (
<Icon
name='ChevronRight'
name='chevron-right'
size={StyleConstants.Font.Size.L}
color={colors.secondary}
style={{ marginLeft: 8 }}

View File

@@ -1,4 +1,4 @@
import Icon from '@components/Icon'
import Icon, { IconName } from '@components/Icon'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { useState } from 'react'
@@ -6,21 +6,17 @@ import { AccessibilityProps, Pressable, StyleProp, View, ViewStyle } from 'react
import { Loading } from './Loading'
import CustomText from './Text'
export interface Props {
export type Props = {
accessibilityLabel?: AccessibilityProps['accessibilityLabel']
accessibilityHint?: AccessibilityProps['accessibilityHint']
style?: StyleProp<ViewStyle>
type: 'icon' | 'text'
content: string
selected?: boolean
loading?: boolean
destructive?: boolean
disabled?: boolean
strokeWidth?: number
size?: 'S' | 'M' | 'L'
fontBold?: boolean
spacing?: 'XS' | 'S' | 'M' | 'L'
@@ -28,7 +24,7 @@ export interface Props {
overlay?: boolean
onPress: () => void
}
} & ({ type: 'icon'; content: IconName } | { type: 'text'; content: string })
const Button: React.FC<Props> = ({
accessibilityLabel,
@@ -40,7 +36,6 @@ const Button: React.FC<Props> = ({
loading = false,
destructive = false,
disabled = false,
strokeWidth,
size = 'M',
fontBold = false,
spacing = 'S',
@@ -81,7 +76,6 @@ const Button: React.FC<Props> = ({
<Icon
name={content}
color={mainColor()}
strokeWidth={strokeWidth}
style={{ opacity: loading ? 0 : 1 }}
size={StyleConstants.Font.Size[size] * (size === 'L' ? 1.25 : 1)}
/>

View File

@@ -39,7 +39,7 @@ const EmojisButton: React.FC = () => {
}}
>
<Icon
name={emojis.current && emojis.current.length ? 'Smile' : 'Meh'}
name={emojis.current && emojis.current.length ? 'smile' : 'meh'}
size={24}
color={
emojis.current && emojis.current.length ? colors.primaryDefault : colors.disabled

View File

@@ -188,7 +188,7 @@ const EmojisList = () => {
paddingRight: StyleConstants.Spacing.S
}}
>
<Icon name='Search' size={StyleConstants.Font.Size.L} color={colors.secondary} />
<Icon name='search' size={StyleConstants.Font.Size.L} color={colors.secondary} />
</View>
<TextInput
style={{
@@ -214,7 +214,7 @@ const EmojisList = () => {
emojisDispatch({ type: 'target', payload: -1 })
}}
>
<Icon name='ChevronDown' size={StyleConstants.Font.Size.L} color={colors.secondary} />
<Icon name='chevron-down' size={StyleConstants.Font.Size.L} color={colors.secondary} />
</Pressable>
</View>
<SectionList

View File

@@ -1,21 +1,19 @@
import Icon from '@components/Icon'
import Icon, { IconName } from '@components/Icon'
import CustomText from '@components/Text'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React from 'react'
import { Pressable } from 'react-native'
export interface Props {
type?: 'icon' | 'text'
content?: string
export type Props = {
native?: boolean
background?: boolean
onPress: () => void
}
} & ({ type?: undefined; content?: IconName } | { type: 'text'; content: string })
const HeaderLeft: React.FC<Props> = ({
type = 'icon',
type,
content,
native = true,
background = false,
@@ -25,18 +23,18 @@ const HeaderLeft: React.FC<Props> = ({
const children = () => {
switch (type) {
case 'icon':
return (
<Icon
color={colors.primaryDefault}
name={content || 'ChevronLeft'}
size={StyleConstants.Spacing.M * 1.25}
/>
)
case 'text':
return (
<CustomText fontStyle='M' style={{ color: colors.primaryDefault }} children={content} />
)
default:
return (
<Icon
color={colors.primaryDefault}
name={content || 'chevron-left'}
size={StyleConstants.Spacing.M * 1.25}
/>
)
}
}
@@ -52,7 +50,7 @@ const HeaderLeft: React.FC<Props> = ({
minHeight: 44,
minWidth: 44,
marginLeft: native ? -StyleConstants.Spacing.S : StyleConstants.Spacing.S,
...(type === 'icon' && {
...(type === undefined && {
borderRadius: 100
}),
...(type === 'text' && {

View File

@@ -1,4 +1,4 @@
import Icon from '@components/Icon'
import Icon, { IconName } from '@components/Icon'
import { Loading } from '@components/Loading'
import CustomText from '@components/Text'
import { StyleConstants } from '@utils/styles/constants'
@@ -6,13 +6,11 @@ import { useTheme } from '@utils/styles/ThemeManager'
import React from 'react'
import { AccessibilityProps, Pressable, View } from 'react-native'
export interface Props {
export type Props = {
accessibilityLabel?: string
accessibilityHint?: string
accessibilityState?: AccessibilityProps['accessibilityState']
type?: 'icon' | 'text'
content: string
native?: boolean
background?: boolean
@@ -21,7 +19,7 @@ export interface Props {
destructive?: boolean
onPress: () => void
}
} & ({ type?: undefined; content: IconName } | { type: 'text'; content: string })
const HeaderRight: React.FC<Props> = ({
// Accessibility - Start
@@ -29,7 +27,7 @@ const HeaderRight: React.FC<Props> = ({
accessibilityHint,
accessibilityState,
// Accessibility - End
type = 'icon',
type,
content,
native = true,
background = false,
@@ -38,7 +36,7 @@ const HeaderRight: React.FC<Props> = ({
destructive = false,
onPress
}) => {
const { colors, theme } = useTheme()
const { colors } = useTheme()
const loadingSpinkit = () =>
loading ? (
@@ -49,18 +47,6 @@ const HeaderRight: React.FC<Props> = ({
const children = () => {
switch (type) {
case 'icon':
return (
<>
<Icon
name={content}
style={{ opacity: loading ? 0 : 1 }}
size={StyleConstants.Spacing.M * 1.25}
color={disabled ? colors.secondary : destructive ? colors.red : colors.primaryDefault}
/>
{loadingSpinkit()}
</>
)
case 'text':
return (
<>
@@ -80,6 +66,18 @@ const HeaderRight: React.FC<Props> = ({
{loadingSpinkit()}
</>
)
default:
return (
<>
<Icon
name={content}
style={{ opacity: loading ? 0 : 1 }}
size={StyleConstants.Spacing.M * 1.25}
color={disabled ? colors.secondary : destructive ? colors.red : colors.primaryDefault}
/>
{loadingSpinkit()}
</>
)
}
}
@@ -100,7 +98,7 @@ const HeaderRight: React.FC<Props> = ({
minHeight: 44,
minWidth: 44,
marginRight: native ? -StyleConstants.Spacing.S : StyleConstants.Spacing.S,
...(type === 'icon' && {
...(type === undefined && {
borderRadius: 100
}),
...(type === 'text' && {

View File

@@ -1,15 +1,16 @@
import React, { createElement } from 'react'
import FeatherNames from '@expo/vector-icons/build/vendor/react-native-vector-icons/glyphmaps/Feather.json'
import Feather from '@expo/vector-icons/Feather'
import React from 'react'
import { AccessibilityProps, StyleProp, View, ViewStyle } from 'react-native'
import * as FeatherIcon from 'react-native-feather'
export type IconName = keyof typeof FeatherNames
export interface Props {
accessibilityLabel?: AccessibilityProps['accessibilityLabel']
name: string
name: IconName
size: number
color: string
fill?: string
strokeWidth?: number
style?: StyleProp<ViewStyle>
crossOut?: boolean
}
@@ -19,8 +20,6 @@ const Icon: React.FC<Props> = ({
name,
size,
color,
fill,
strokeWidth = 2,
style,
crossOut = false
}) => {
@@ -37,13 +36,7 @@ const Icon: React.FC<Props> = ({
}
]}
>
{createElement(FeatherIcon[name], {
width: size,
height: size,
color,
fill,
strokeWidth
})}
<Feather name={name} size={size} color={color} />
{crossOut ? (
<View
style={{
@@ -51,7 +44,7 @@ const Icon: React.FC<Props> = ({
transform: [{ rotate: '45deg' }],
width: size * 1.35,
borderBottomColor: color,
borderBottomWidth: strokeWidth
borderBottomWidth: 2
}}
/>
) : null}

View File

@@ -345,7 +345,7 @@ const ComponentInstance: React.FC<Props> = ({
}}
>
<Icon
name='Lock'
name='lock'
size={StyleConstants.Font.Size.S}
color={colors.secondary}
style={{
@@ -365,7 +365,7 @@ const ComponentInstance: React.FC<Props> = ({
}}
>
<Icon
name='CheckSquare'
name='check-square'
size={StyleConstants.Font.Size.S}
color={colors.secondary}
style={{

View File

@@ -1,17 +1,19 @@
import { StyleConstants } from '@utils/styles/constants'
import React from 'react'
import { View } from 'react-native'
import { View, ViewStyle } from 'react-native'
export interface Props {
style?: ViewStyle
children: React.ReactNode
}
const MenuContainer: React.FC<Props> = ({ children }) => {
const MenuContainer: React.FC<Props> = ({ style, children }) => {
return (
<View
style={{
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding,
marginBottom: StyleConstants.Spacing.Global.PagePadding
marginBottom: StyleConstants.Spacing.Global.PagePadding,
...style
}}
>
{children}

View File

@@ -1,4 +1,4 @@
import Icon from '@components/Icon'
import Icon, { IconName } from '@components/Icon'
import { Loading } from '@components/Loading'
import CustomText from '@components/Text'
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
@@ -10,7 +10,7 @@ import { View } from 'react-native'
import { State, Switch, TapGestureHandler } from 'react-native-gesture-handler'
export interface Props {
iconFront?: any
iconFront?: IconName
iconFrontColor?: ColorDefinitions
title: string
@@ -22,7 +22,7 @@ export interface Props {
switchDisabled?: boolean
switchOnValueChange?: () => void
iconBack?: 'ChevronRight' | 'ExternalLink' | 'Check'
iconBack?: 'chevron-right' | 'external-link' | 'check'
iconBackColor?: ColorDefinitions
loading?: boolean

View File

@@ -54,13 +54,13 @@ const Message = React.forwardRef<FlashMessage>((_, ref) => {
const { colors, theme } = useTheme()
enum iconMapping {
success = 'CheckCircle',
danger = 'XCircle',
warning = 'AlertCircle',
none = '',
default = '',
info = '',
auto = ''
success = 'check-circle',
danger = 'x-circle',
warning = 'alert-circle',
none = 'x',
default = 'x',
info = 'x',
auto = 'x'
}
enum colorMapping {
success = 'blue',

View File

@@ -69,6 +69,7 @@ const ParseHTML: React.FC<Props> = ({
const [followedTags] = useAccountStorage.object('followed_tags')
const MAX_ALLOWED_LINES = 30
const [totalLines, setTotalLines] = useState<number>()
const [expanded, setExpanded] = useState(highlighted)
@@ -275,14 +276,18 @@ const ParseHTML: React.FC<Props> = ({
hint: expandHint,
moreLines:
numberOfLines > 1 && typeof totalLines === 'number'
? t('HTML.moreLines', { count: totalLines - numberOfLines })
? t('HTML.moreLines', {
count:
totalLines === MAX_ALLOWED_LINES
? (`${totalLines - numberOfLines}+` as unknown as number)
: totalLines - numberOfLines
})
: ''
})}
/>
<Icon
name={expanded ? 'Minimize2' : 'Maximize2'}
name={expanded ? 'minimize-2' : 'maximize-2'}
color={colors.primaryDefault}
strokeWidth={2}
size={StyleConstants.Font.Size[size]}
/>
</Pressable>
@@ -304,7 +309,7 @@ const ParseHTML: React.FC<Props> = ({
height: numberOfLines === 1 && !expanded ? 0 : undefined
}}
numberOfLines={
typeof totalLines === 'number' ? (expanded ? 999 : numberOfLines) : undefined
typeof totalLines === 'number' ? (expanded ? 999 : numberOfLines) : MAX_ALLOWED_LINES
}
selectable={selectable}
/>

View File

@@ -51,7 +51,7 @@ const RelationshipIncoming: React.FC<Props> = ({ id }) => {
<Button
round
type='icon'
content='X'
content='x'
loading={mutation.isLoading}
onPress={() =>
mutation.mutate({
@@ -64,7 +64,7 @@ const RelationshipIncoming: React.FC<Props> = ({ id }) => {
<Button
round
type='icon'
content='Check'
content='check'
loading={mutation.isLoading}
onPress={() =>
mutation.mutate({

View File

@@ -13,7 +13,6 @@ import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { View } from 'react-native'
export interface Props {
id: Mastodon.Account['id']
@@ -127,11 +126,11 @@ const RelationshipOutgoing: React.FC<Props> = ({ id }: Props) => {
const isPageNotifications = name === 'Tab-Notifications-Root'
return (
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<>
{!isPageNotifications && canFollowNotify && query.data?.following ? (
<Button
type='icon'
content={query.data.notifying ? 'BellOff' : 'Bell'}
content={query.data.notifying ? 'bell-off' : 'bell'}
round
onPress={() =>
mutation.mutate({
@@ -155,7 +154,7 @@ const RelationshipOutgoing: React.FC<Props> = ({ id }: Props) => {
loading={query.isLoading || mutation.isLoading}
disabled={query.isError || query.data?.blocked_by}
/>
</View>
</>
)
}

View File

@@ -22,10 +22,14 @@ const Selections: React.FC<Props> = ({
}) => {
const { colors } = useTheme()
const isSelected = (index: number): string =>
const isSelected = (index: number) =>
options[index].selected
? `Check${multiple ? 'Square' : 'Circle'}`
: `${multiple ? 'Square' : 'Circle'}`
? multiple
? 'check-square'
: 'check-circle'
: multiple
? 'square'
: 'circle'
return (
<View>

View File

@@ -29,7 +29,7 @@ const TimelineEmpty: React.FC<Props> = ({ queryKey }) => {
case 'error':
return (
<>
<Icon name='Frown' size={StyleConstants.Font.Size.L} color={colors.primaryDefault} />
<Icon name='frown' size={StyleConstants.Font.Size.L} color={colors.primaryDefault} />
<CustomText
fontStyle='M'
style={{
@@ -47,7 +47,7 @@ const TimelineEmpty: React.FC<Props> = ({ queryKey }) => {
return (
<>
<Icon
name='Smartphone'
name='smartphone'
size={StyleConstants.Font.Size.L}
color={colors.primaryDefault}
/>

View File

@@ -38,7 +38,7 @@ const TimelineFooter: React.FC<Props> = ({ queryKey, disableInfinity }) => {
ns='componentTimeline'
i18nKey='end.message'
components={[
<Icon name='Coffee' size={StyleConstants.Font.Size.S} color={colors.secondary} />
<Icon name='coffee' size={StyleConstants.Font.Size.S} color={colors.secondary} />
]}
/>
</CustomText>

View File

@@ -276,7 +276,7 @@ const TimelineRefresh: React.FC<Props> = ({
]}
children={
<Icon
name='ArrowLeft'
name='arrow-left'
size={StyleConstants.Font.Size.M}
color={colors.primaryDefault}
/>

View File

@@ -46,7 +46,7 @@ const TimelineActioned: React.FC<Props> = ({ action, isNotification, ...rest })
return (
<>
<Icon
name='Anchor'
name='anchor'
size={StyleConstants.Font.Size.S}
color={iconColor}
style={styles.icon}
@@ -58,7 +58,7 @@ const TimelineActioned: React.FC<Props> = ({ action, isNotification, ...rest })
return (
<>
<Icon
name='Heart'
name='heart'
size={StyleConstants.Font.Size.S}
color={iconColor}
style={styles.icon}
@@ -72,7 +72,7 @@ const TimelineActioned: React.FC<Props> = ({ action, isNotification, ...rest })
return (
<>
<Icon
name='UserPlus'
name='user-plus'
size={StyleConstants.Font.Size.S}
color={iconColor}
style={styles.icon}
@@ -86,7 +86,7 @@ const TimelineActioned: React.FC<Props> = ({ action, isNotification, ...rest })
return (
<>
<Icon
name='UserPlus'
name='user-plus'
size={StyleConstants.Font.Size.S}
color={iconColor}
style={styles.icon}
@@ -100,7 +100,7 @@ const TimelineActioned: React.FC<Props> = ({ action, isNotification, ...rest })
return (
<>
<Icon
name='BarChart2'
name='bar-chart-2'
size={StyleConstants.Font.Size.S}
color={iconColor}
style={styles.icon}
@@ -112,7 +112,7 @@ const TimelineActioned: React.FC<Props> = ({ action, isNotification, ...rest })
return (
<>
<Icon
name='Repeat'
name='repeat'
size={StyleConstants.Font.Size.S}
color={iconColor}
style={styles.icon}
@@ -130,7 +130,7 @@ const TimelineActioned: React.FC<Props> = ({ action, isNotification, ...rest })
return (
<>
<Icon
name='Activity'
name='activity'
size={StyleConstants.Font.Size.S}
color={iconColor}
style={styles.icon}
@@ -144,7 +144,7 @@ const TimelineActioned: React.FC<Props> = ({ action, isNotification, ...rest })
return (
<>
<Icon
name='BarChart2'
name='bar-chart-2'
size={StyleConstants.Font.Size.S}
color={iconColor}
style={styles.icon}
@@ -156,7 +156,7 @@ const TimelineActioned: React.FC<Props> = ({ action, isNotification, ...rest })
return (
<>
<Icon
name='Users'
name='users'
size={StyleConstants.Font.Size.S}
color={iconColor}
style={styles.icon}
@@ -168,7 +168,7 @@ const TimelineActioned: React.FC<Props> = ({ action, isNotification, ...rest })
return (
<>
<Icon
name='AlertOctagon'
name='alert-octagon'
size={StyleConstants.Font.Size.S}
color={colors.red}
style={styles.icon}

View File

@@ -165,7 +165,7 @@ const TimelineActions: React.FC = () => {
const childrenReply = () => (
<>
<Icon name='MessageCircle' color={iconColor} size={StyleConstants.Font.Size.L} />
<Icon name='message-circle' color={iconColor} size={StyleConstants.Font.Size.L} />
{status.replies_count > 0 ? (
<CustomText
fontStyle='S'
@@ -186,7 +186,7 @@ const TimelineActions: React.FC = () => {
return (
<>
<Icon
name='Repeat'
name='repeat'
color={disabled ? colors.disabled : color(status.reblogged)}
crossOut={disabled}
size={StyleConstants.Font.Size.L}
@@ -212,7 +212,7 @@ const TimelineActions: React.FC = () => {
const color = (state: boolean) => (state ? colors.red : colors.secondary)
return (
<>
<Icon name='Heart' color={color(status.favourited)} size={StyleConstants.Font.Size.L} />
<Icon name='heart' color={color(status.favourited)} size={StyleConstants.Font.Size.L} />
{status.favourites_count > 0 ? (
<CustomText
fontStyle='S'
@@ -227,7 +227,7 @@ const TimelineActions: React.FC = () => {
const childrenBookmark = () => {
const color = (state: boolean) => (state ? colors.yellow : colors.secondary)
return (
<Icon name='Bookmark' color={color(status.bookmarked)} size={StyleConstants.Font.Size.L} />
<Icon name='bookmark' color={color(status.bookmarked)} size={StyleConstants.Font.Size.L} />
)
}

View File

@@ -216,7 +216,7 @@ const TimelineAttachment = () => {
) : (
<Button
type='icon'
content='EyeOff'
content='eye-off'
round
overlay
onPress={() => {

View File

@@ -92,7 +92,7 @@ const AttachmentAudio: React.FC<Props> = ({ total, index, sensitiveShown, audio
) : null}
<Button
type='icon'
content={audioPlaying ? 'PauseCircle' : 'PlayCircle'}
content={audioPlaying ? 'pause-circle' : 'play-circle'}
size='L'
round
overlay

View File

@@ -1,6 +1,6 @@
import Button from '@components/Button'
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
import { useGlobalStorage } from '@utils/storage/actions'
import { useAccountStorage, useGlobalStorage } from '@utils/storage/actions'
import { StyleConstants } from '@utils/styles/constants'
import { ResizeMode, Video, VideoFullscreenUpdate } from 'expo-av'
import { Platform } from 'expo-modules-core'
@@ -28,6 +28,11 @@ const AttachmentVideo: React.FC<Props> = ({
}) => {
const { reduceMotionEnabled } = useAccessibility()
const [autoplayGifv] = useGlobalStorage.boolean('app.auto_play_gifv')
const [preferences] = useAccountStorage.object('preferences')
const shouldAutoplayGifv =
preferences?.['reading:autoplay:gifs'] !== undefined
? preferences['reading:autoplay:gifs']
: autoplayGifv
const videoPlayer = useRef<Video>(null)
const [videoLoading, setVideoLoading] = useState(false)
@@ -63,7 +68,7 @@ const AttachmentVideo: React.FC<Props> = ({
resizeMode={videoResizeMode}
{...(gifv
? {
shouldPlay: reduceMotionEnabled || !autoplayGifv ? false : true,
shouldPlay: reduceMotionEnabled || !shouldAutoplayGifv ? false : true,
isMuted: true,
isLooping: true,
source: { uri: video.url }
@@ -82,7 +87,7 @@ const AttachmentVideo: React.FC<Props> = ({
Platform.OS === 'android' &&
(await ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT))
Platform.OS === 'android' && setVideoResizeMode(ResizeMode.COVER)
if (gifv && !reduceMotionEnabled && autoplayGifv) {
if (gifv && !reduceMotionEnabled && shouldAutoplayGifv) {
videoPlayer.current?.playAsync()
} else {
videoPlayer.current?.pauseAsync()
@@ -116,20 +121,20 @@ const AttachmentVideo: React.FC<Props> = ({
video.blurhash ? (
<Blurhash blurhash={video.blurhash} style={{ width: '100%', height: '100%' }} />
) : null
) : !gifv || (gifv && (reduceMotionEnabled || !autoplayGifv)) ? (
) : !gifv || (gifv && (reduceMotionEnabled || !shouldAutoplayGifv)) ? (
<Button
round
overlay
size='L'
type='icon'
content='PlayCircle'
content='play-circle'
onPress={playOnPress}
loading={videoLoading}
/>
) : null}
<AttachmentAltText sensitiveShown={sensitiveShown} text={video.description} />
</Pressable>
{gifv && !autoplayGifv ? (
{gifv && !shouldAutoplayGifv ? (
<Button
style={{
position: 'absolute',

View File

@@ -43,7 +43,7 @@ const TimelineHeaderAndroid: React.FC = () => {
}}
>
<Icon
name='MoreHorizontal'
name='more-horizontal'
color={colors.secondary}
size={StyleConstants.Font.Size.L}
/>

View File

@@ -87,7 +87,7 @@ const HeaderConversation = ({ conversation }: Props) => {
id: conversation.id
})
}
children={<Icon name='Trash' color={colors.secondary} size={StyleConstants.Font.Size.L} />}
children={<Icon name='trash' color={colors.secondary} size={StyleConstants.Font.Size.L} />}
/>
</View>
)

View File

@@ -58,7 +58,7 @@ const TimelineHeaderDefault: React.FC = () => {
>
{isRemote ? (
<Icon
name='Wifi'
name='wifi'
size={StyleConstants.Font.Size.M}
color={colors.secondary}
style={{ marginRight: StyleConstants.Spacing.S }}
@@ -80,7 +80,7 @@ const TimelineHeaderDefault: React.FC = () => {
<DropdownMenu.Root onOpenChange={setOpenChange}>
<DropdownMenu.Trigger>
<Icon
name='MoreHorizontal'
name='more-horizontal'
color={colors.secondary}
size={StyleConstants.Font.Size.L}
/>

View File

@@ -81,7 +81,7 @@ const TimelineHeaderNotification: React.FC<Props> = ({ notification }) => {
<DropdownMenu.Root onOpenChange={setOpenChange}>
<DropdownMenu.Trigger>
<Icon
name='MoreHorizontal'
name='more-horizontal'
color={colors.secondary}
size={StyleConstants.Font.Size.L}
/>

View File

@@ -35,7 +35,7 @@ const HeaderSharedCreated: React.FC<Props> = ({ created_at }) => {
{status.edited_at && !highlighted ? (
<Icon
accessibilityLabel={t('shared.header.shared.edited.accessibilityLabel')}
name='Edit'
name='edit'
size={StyleConstants.Font.Size.S}
color={colors.secondary}
style={{ marginLeft: StyleConstants.Spacing.S }}

View File

@@ -13,7 +13,7 @@ const HeaderSharedMuted: React.FC = () => {
return status?.muted ? (
<Icon
accessibilityLabel={t('shared.header.shared.muted.accessibilityLabel')}
name='VolumeX'
name='volume-x'
size={StyleConstants.Font.Size.M}
color={colors.secondary}
style={{ marginLeft: StyleConstants.Spacing.S }}

View File

@@ -16,7 +16,7 @@ const HeaderSharedVisibility: React.FC = () => {
return (
<Icon
accessibilityLabel={t('shared.header.shared.visibility.private.accessibilityLabel')}
name='Unlock'
name='unlock'
size={StyleConstants.Font.Size.S}
color={colors.secondary}
style={styles.visibility}
@@ -26,7 +26,7 @@ const HeaderSharedVisibility: React.FC = () => {
return (
<Icon
accessibilityLabel={t('shared.header.shared.visibility.private.accessibilityLabel')}
name='Lock'
name='lock'
size={StyleConstants.Font.Size.S}
color={colors.secondary}
style={styles.visibility}
@@ -36,7 +36,7 @@ const HeaderSharedVisibility: React.FC = () => {
return (
<Icon
accessibilityLabel={t('shared.header.shared.visibility.direct.accessibilityLabel')}
name='Mail'
name='mail'
size={StyleConstants.Font.Size.S}
color={colors.secondary}
style={styles.visibility}

View File

@@ -117,10 +117,14 @@ const TimelinePoll: React.FC = () => {
}
}
const isSelected = (index: number): string =>
const isSelected = (index: number) =>
allOptions[index]
? `Check${poll.multiple ? 'Square' : 'Circle'}`
: `${poll.multiple ? 'Square' : 'Circle'}`
? poll.multiple
? 'check-square'
: 'check-circle'
: poll.multiple
? 'square'
: 'circle'
const pollBodyDisallow = () => {
const maxValue = maxBy(poll.options, option => option.votes_count)?.votes_count

View File

@@ -73,17 +73,18 @@ const openLink = async (url: string, navigation?: any) => {
}
}
// Some links might end with an empty space at the end that triggers an error
switch (getGlobalStorage.string('app.browser')) {
// Some links might end with an empty space at the end that triggers an error
case 'external':
await Linking.openURL(url.trim())
break
case 'internal':
default:
await WebBrowser.openBrowserAsync(url.trim(), {
dismissButtonStyle: 'close',
enableBarCollapsing: true,
...(await browserPackage())
})
break
case 'external':
await Linking.openURL(url.trim())
}).catch(() => Linking.openURL(url.trim()))
break
}
}

View File

@@ -153,8 +153,7 @@
"altText": {
"heading": "Describe media for the visually impaired",
"placeholder": "You can add a description, sometimes called alt-text, to your media so they are accessible to even more people, including those who are blind or visually impaired.\n\nGood descriptions are concise, but present what is in your media accurately enough to understand their context."
},
"imageFocus": "Drag the focus circle to update focus point"
}
}
},
"draftsList": {

View File

@@ -69,6 +69,9 @@
"push": {
"name": "Push Notification"
},
"preferences": {
"name": "Preferences"
},
"profile": {
"name": "Edit Profile"
},
@@ -84,9 +87,6 @@
"settings": {
"name": "App Settings"
},
"webSettings": {
"name": "More Account Settings"
},
"switch": {
"name": "Switch Account"
}
@@ -125,6 +125,37 @@
"message": "This action is not recoverable."
}
},
"preferences": {
"visibility": {
"title": "Posting visibility",
"options": {
"public": "Public",
"unlisted": "Unlisted",
"private": "Followers only"
}
},
"sensitive": {
"title": "Posting media sensitive"
},
"media": {
"title": "Media display",
"options": {
"default": "Hide media marked as sensitive",
"show_all": "Always show media",
"hide_all": "Always hide media"
}
},
"spoilers": {
"title": "Auto expand toots with content warning",
},
"autoplay_gifs": {
"title": "Autoplay GIF in toots"
},
"web_only": {
"title": "Update settings",
"description": "Settings below can only be updated using the web UI"
}
},
"profile": {
"feedback": {
"succeed": "{{type}} updated",
@@ -150,17 +181,6 @@
"total_one": "{{count}} field",
"total_other": "{{count}} fields"
},
"visibility": {
"title": "Posting Visibility",
"options": {
"public": "Public",
"unlisted": "Unlisted",
"private": "Followers only"
}
},
"sensitive": {
"title": "Posting Media Sensitive"
},
"lock": {
"title": "Lock Account",
"description": "Requires you to manually approve followers"

View File

@@ -40,7 +40,7 @@ const ComposeDraftsList: React.FC<ScreenComposeStackScreenProps<'Screen-Compose-
navigation.setOptions({
title: t('content.draftsList.header.title'),
headerLeft: () => (
<HeaderLeft type='icon' content='ChevronDown' onPress={() => navigation.goBack()} />
<HeaderLeft content='chevron-down' onPress={() => navigation.goBack()} />
)
})
}, [])
@@ -65,7 +65,7 @@ const ComposeDraftsList: React.FC<ScreenComposeStackScreenProps<'Screen-Compose-
}}
>
<Icon
name='AlertTriangle'
name='alert-triangle'
color={colors.secondary}
size={StyleConstants.Font.Size.M}
style={{ marginRight: StyleConstants.Spacing.S }}
@@ -187,7 +187,7 @@ const ComposeDraftsList: React.FC<ScreenComposeStackScreenProps<'Screen-Compose-
}}
children={
<Icon
name='Trash'
name='trash'
size={StyleConstants.Font.Size.L}
color={colors.primaryOverlay}
/>

View File

@@ -1,12 +1,14 @@
import haptics from '@components/haptics'
import { HeaderLeft, HeaderRight } from '@components/Header'
import CustomText from '@components/Text'
import apiInstance from '@utils/api/instance'
import { ScreenComposeStackScreenProps } from '@utils/navigation/navigators'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { useContext, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Alert, KeyboardAvoidingView, Platform } from 'react-native'
import { Alert, KeyboardAvoidingView, Platform, ScrollView, TextInput } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import ComposeEditAttachmentRoot from './EditAttachment/Root'
import ComposeContext from './utils/createContext'
const ComposeEditAttachment: React.FC<
@@ -17,26 +19,36 @@ const ComposeEditAttachment: React.FC<
params: { index }
}
}) => {
const { colors } = useTheme()
const { t } = useTranslation('screenCompose')
const { composeState } = useContext(ComposeContext)
const { composeState, composeDispatch } = useContext(ComposeContext)
const [isSubmitting, setIsSubmitting] = useState(false)
const theAttachment = composeState.attachments.uploads[index].remote!
const theAttachment = composeState.attachments.uploads[index].remote
if (!theAttachment) {
navigation.goBack()
return null
}
useEffect(() => {
navigation.setOptions({
title: t('content.editAttachment.header.title'),
headerLeft: () => (
<HeaderLeft type='icon' content='ChevronDown' onPress={() => navigation.goBack()} />
<HeaderLeft content='chevron-down' onPress={() => navigation.goBack()} />
),
headerRight: () => (
<HeaderRight
accessibilityLabel={t('content.editAttachment.header.right.accessibilityLabel')}
type='icon'
content='Save'
content='save'
loading={isSubmitting}
onPress={() => {
if (composeState.type === 'edit') {
composeDispatch({ type: 'attachment/edit', payload: { ...theAttachment } })
navigation.goBack()
return
}
setIsSubmitting(true)
const formData = new FormData()
if (theAttachment.description) {
@@ -80,8 +92,53 @@ const ComposeEditAttachment: React.FC<
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={{ flex: 1 }}
>
<SafeAreaView style={{ flex: 1 }} edges={['left', 'right', 'bottom']}>
<ComposeEditAttachmentRoot index={index} />
<SafeAreaView
style={{ flex: 1, padding: StyleConstants.Spacing.Global.PagePadding }}
edges={['left', 'right', 'bottom']}
>
<ScrollView>
<CustomText fontStyle='M' style={{ color: colors.primaryDefault }} fontWeight='Bold'>
{t('content.editAttachment.content.altText.heading')}
</CustomText>
<TextInput
style={{
height:
StyleConstants.Font.Size.M * 11 + StyleConstants.Spacing.Global.PagePadding * 2,
...StyleConstants.FontStyle.M,
marginTop: StyleConstants.Spacing.M,
marginBottom: StyleConstants.Spacing.S,
padding: StyleConstants.Spacing.Global.PagePadding,
borderWidth: 1,
borderColor: colors.border,
color: colors.primaryDefault
}}
maxLength={1500}
multiline
onChangeText={e =>
composeDispatch({
type: 'attachment/edit',
payload: {
...theAttachment,
description: e
}
})
}
placeholder={t('content.editAttachment.content.altText.placeholder')}
placeholderTextColor={colors.secondary}
value={theAttachment.description}
/>
<CustomText
fontStyle='S'
style={{
textAlign: 'right',
marginRight: StyleConstants.Spacing.S,
marginBottom: StyleConstants.Spacing.M,
color: colors.secondary
}}
>
{theAttachment.description?.length || 0} / 1500
</CustomText>
</ScrollView>
</SafeAreaView>
</KeyboardAvoidingView>
)

View File

@@ -1,173 +0,0 @@
import CustomText from '@components/Text'
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { useContext } from 'react'
import { useTranslation } from 'react-i18next'
import { Dimensions, Image, View } from 'react-native'
import { Gesture, GestureDetector } from 'react-native-gesture-handler'
import Animated, {
Extrapolate,
interpolate,
runOnJS,
useAnimatedStyle,
useSharedValue
} from 'react-native-reanimated'
import ComposeContext from '../utils/createContext'
export interface Props {
index: number
}
const ComposeEditAttachmentImage: React.FC<Props> = ({ index }) => {
const { t } = useTranslation('screenCompose')
const { colors } = useTheme()
const { screenReaderEnabled } = useAccessibility()
const { composeState, composeDispatch } = useContext(ComposeContext)
const theAttachmentRemote = composeState.attachments.uploads[index].remote!
const theAttachmentLocal = composeState.attachments.uploads[index].local
const windowWidth = Dimensions.get('window').width
const imageWidthBase =
theAttachmentRemote?.meta?.original?.aspect < 1
? windowWidth * theAttachmentRemote?.meta?.original?.aspect
: windowWidth
const imageDimensions = {
width: imageWidthBase,
height:
imageWidthBase /
((theAttachmentRemote as Mastodon.AttachmentImage)?.meta?.original?.aspect || 1)
}
const updateFocus = ({ x, y }: { x: number; y: number }) => {
composeDispatch({
type: 'attachment/edit',
payload: {
...theAttachmentRemote,
meta: {
...theAttachmentRemote.meta,
focus: {
x: x > 1 ? 1 : x,
y: y > 1 ? 1 : y
}
}
}
})
}
const pan = useSharedValue({
x:
(((theAttachmentRemote as Mastodon.AttachmentImage)?.meta?.focus?.x || 0) *
imageDimensions.width) /
2,
y:
(((theAttachmentRemote as Mastodon.AttachmentImage)?.meta?.focus?.y || 0) *
imageDimensions.height) /
2
})
const start = useSharedValue({ x: 0, y: 0 })
const gesture = Gesture.Pan()
.onBegin(() => {
start.value = pan.value
})
.onUpdate(e => {
pan.value = {
x: e.translationX + start.value.x,
y: e.translationY + start.value.y
}
})
.onEnd(() => {
runOnJS(updateFocus)({
x: pan.value.x / (imageDimensions.width / 2),
y: pan.value.y / (imageDimensions.height / 2)
})
})
.onFinalize(() => {
start.value = pan.value
})
const styleTransform = useAnimatedStyle(() => {
return {
transform: [
{
translateX: interpolate(
pan.value.x,
[-imageDimensions.width / 2, imageDimensions.width / 2],
[-imageDimensions.width / 2, imageDimensions.width / 2],
Extrapolate.CLAMP
)
},
{
translateY: interpolate(
pan.value.y,
[-imageDimensions.height / 2, imageDimensions.height / 2],
[-imageDimensions.height / 2, imageDimensions.height / 2],
Extrapolate.CLAMP
)
}
]
}
})
return (
<>
<CustomText
fontStyle='M'
style={{
color: colors.primaryDefault,
padding: StyleConstants.Spacing.Global.PagePadding,
paddingTop: 0
}}
fontWeight='Bold'
>
{t('content.editAttachment.content.imageFocus')}
</CustomText>
<View style={{ overflow: 'hidden', flex: 1, alignItems: 'center' }}>
<Image
style={{
width: imageDimensions.width,
height: imageDimensions.height
}}
source={{
uri: theAttachmentLocal?.uri ? theAttachmentLocal.uri : theAttachmentRemote?.preview_url
}}
/>
<GestureDetector gesture={gesture}>
<Animated.View
style={[
styleTransform,
{
width: windowWidth * 2,
height: imageDimensions.height * 2,
position: 'absolute',
left: -windowWidth / 2,
top: -imageDimensions.height / 2,
backgroundColor: colors.backgroundOverlayInvert,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center'
}
]}
children={
<View
style={{
width: 48,
height: 48,
borderRadius: 24,
borderWidth: 2,
borderColor: colors.primaryOverlay,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center'
}}
/>
}
/>
</GestureDetector>
</View>
</>
)
}
export default ComposeEditAttachmentImage

View File

@@ -1,100 +0,0 @@
import CustomText from '@components/Text'
import AttachmentVideo from '@components/Timeline/Shared/Attachment/Video'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { useContext } from 'react'
import { useTranslation } from 'react-i18next'
import { ScrollView, StyleSheet, TextInput, View } from 'react-native'
import ComposeContext from '../utils/createContext'
import ComposeEditAttachmentImage from './Image'
export interface Props {
index: number
}
const ComposeEditAttachmentRoot: React.FC<Props> = ({ index }) => {
const { t } = useTranslation('screenCompose')
const { colors, mode } = useTheme()
const { composeState, composeDispatch } = useContext(ComposeContext)
const theAttachment = composeState.attachments.uploads[index].remote!
const mediaDisplay = () => {
if (theAttachment) {
switch (theAttachment.type) {
case 'image':
return <ComposeEditAttachmentImage index={index} />
case 'video':
case 'gifv':
const video = composeState.attachments.uploads[index]
return (
<AttachmentVideo
total={1}
index={0}
sensitiveShown={false}
video={
video.local
? ({
url: video.local.uri,
preview_url: video.local.thumbnail,
blurhash: video.remote?.blurhash
} as Mastodon.AttachmentVideo)
: (video.remote as Mastodon.AttachmentVideo)
}
/>
)
}
}
return null
}
return (
<ScrollView>
<View style={{ padding: StyleConstants.Spacing.Global.PagePadding, paddingBottom: 0 }}>
<CustomText fontStyle='M' style={{ color: colors.primaryDefault }} fontWeight='Bold'>
{t('content.editAttachment.content.altText.heading')}
</CustomText>
<TextInput
style={{
height: StyleConstants.Font.Size.M * 11 + StyleConstants.Spacing.Global.PagePadding * 2,
...StyleConstants.FontStyle.M,
marginTop: StyleConstants.Spacing.M,
marginBottom: StyleConstants.Spacing.S,
padding: StyleConstants.Spacing.Global.PagePadding,
borderWidth: StyleSheet.hairlineWidth,
borderColor: colors.border,
color: colors.primaryDefault
}}
maxLength={1500}
multiline
onChangeText={e =>
composeDispatch({
type: 'attachment/edit',
payload: {
...theAttachment,
description: e
}
})
}
placeholder={t('content.editAttachment.content.altText.placeholder')}
placeholderTextColor={colors.secondary}
value={theAttachment.description}
keyboardAppearance={mode}
/>
<CustomText
fontStyle='S'
style={{
textAlign: 'right',
marginRight: StyleConstants.Spacing.S,
marginBottom: StyleConstants.Spacing.M,
color: colors.secondary
}}
>
{theAttachment.description?.length || 0} / 1500
</CustomText>
</View>
{mediaDisplay()}
</ScrollView>
)
}
export default ComposeEditAttachmentRoot

View File

@@ -60,13 +60,13 @@ const ComposeActions: React.FC = () => {
const visibilityIcon = () => {
switch (composeState.visibility) {
case 'public':
return 'Globe'
return 'globe'
case 'unlisted':
return 'Unlock'
return 'unlock'
case 'private':
return 'Lock'
return 'lock'
case 'direct':
return 'Mail'
return 'mail'
}
}
const visibilityOnPress = () => {
@@ -162,7 +162,7 @@ const ComposeActions: React.FC = () => {
}}
style={styles.button}
onPress={attachmentOnPress}
children={<Icon name='Camera' size={24} color={attachmentColor()} />}
children={<Icon name='camera' size={24} color={attachmentColor()} />}
/>
<Pressable
accessibilityRole='button'
@@ -174,7 +174,7 @@ const ComposeActions: React.FC = () => {
}}
style={styles.button}
onPress={pollOnPress}
children={<Icon name='BarChart2' size={24} color={pollColor()} />}
children={<Icon name='bar-chart-2' size={24} color={pollColor()} />}
/>
<Pressable
accessibilityRole='button'
@@ -200,7 +200,7 @@ const ComposeActions: React.FC = () => {
onPress={spoilerOnPress}
children={
<Icon
name='AlertTriangle'
name='alert-triangle'
size={24}
color={composeState.spoiler.active ? colors.primaryDefault : colors.secondary}
/>
@@ -216,7 +216,7 @@ const ComposeActions: React.FC = () => {
}}
style={styles.button}
onPress={emojiOnPress}
children={<Icon name='Smile' size={24} color={emojiColor()} />}
children={<Icon name='smile' size={24} color={emojiColor()} />}
/>
</View>
)

View File

@@ -6,6 +6,7 @@ import { MAX_MEDIA_ATTACHMENTS } from '@components/mediaSelector'
import CustomText from '@components/Text'
import { useActionSheet } from '@expo/react-native-action-sheet'
import { useNavigation } from '@react-navigation/native'
import { featureCheck } from '@utils/helpers/featureCheck'
import { StyleConstants } from '@utils/styles/constants'
import layoutAnimation from '@utils/styles/layoutAnimation'
import { useTheme } from '@utils/styles/ThemeManager'
@@ -104,9 +105,7 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
>
<FastImage
style={{ width: '100%', height: '100%' }}
source={{
uri: item.local?.thumbnail || item.remote?.preview_url
}}
source={{ uri: item.local?.thumbnail || item.remote?.preview_url }}
/>
{item.remote?.meta?.original?.duration ? (
<CustomText
@@ -152,7 +151,7 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
attachment: index + 1
})}
type='icon'
content='X'
content='x'
spacing='M'
round
overlay
@@ -165,21 +164,17 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
haptics('Success')
}}
/>
{!composeState.attachments.disallowEditing ? (
{composeState.type === 'edit' && featureCheck('edit_media_details') ? (
<Button
accessibilityLabel={t('content.root.footer.attachments.edit.accessibilityLabel', {
attachment: index + 1
})}
type='icon'
content='Edit'
content='edit'
spacing='M'
round
overlay
onPress={() => {
navigation.navigate('Screen-Compose-EditAttachment', {
index
})
}}
onPress={() => navigation.navigate('Screen-Compose-EditAttachment', { index })}
/>
) : null}
</View>
@@ -208,7 +203,7 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
onPress={sensitiveOnPress}
>
<Icon
name={composeState.attachments.sensitive ? 'CheckCircle' : 'Circle'}
name={composeState.attachments.sensitive ? 'check-circle' : 'circle'}
size={StyleConstants.Font.Size.L}
color={colors.primaryDefault}
/>
@@ -256,7 +251,7 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
>
<Button
type='icon'
content='UploadCloud'
content='upload-cloud'
spacing='M'
round
overlay

View File

@@ -50,21 +50,12 @@ const ComposePoll: React.FC = () => {
marginBottom: StyleConstants.Spacing.S
}}
>
{[...Array(total)].map((e, i) => {
const restOptions = Object.keys(options).filter(
o => parseInt(o) !== i && parseInt(o) < total
)
let hasConflict = false
restOptions.forEach(o => {
// @ts-ignore
if (options[o] === options[i]) {
hasConflict = true
}
})
{[...Array(total)].map((_, i) => {
const hasConflict = options.filter((_, ii) => ii !== i && ii < total).includes(options[i])
return (
<View key={i} style={styles.option}>
<Icon
name={multiple ? 'Square' : 'Circle'}
name={multiple ? 'square' : 'circle'}
size={StyleConstants.Font.Size.L}
color={colors.secondary}
/>
@@ -92,14 +83,15 @@ const ComposePoll: React.FC = () => {
}
placeholderTextColor={colors.disabled}
maxLength={MAX_CHARS_PER_OPTION}
// @ts-ignore
value={options[i]}
onChangeText={e =>
onChangeText={e => {
const newOptions = [...options]
newOptions[i] = e
composeDispatch({
type: 'poll',
payload: { options: { ...options, [i]: e } }
payload: { options: [...newOptions] }
})
}
}}
/>
</View>
)
@@ -136,7 +128,7 @@ const ComposePoll: React.FC = () => {
})
}}
type='icon'
content='Minus'
content='minus'
round
disabled={!(total > 2)}
/>
@@ -170,7 +162,7 @@ const ComposePoll: React.FC = () => {
})
}}
type='icon'
content='Plus'
content='plus'
round
disabled={!(total < MAX_OPTIONS)}
/>
@@ -204,7 +196,7 @@ const ComposePoll: React.FC = () => {
}
)
}
iconBack='ChevronRight'
iconBack='chevron-right'
/>
<MenuRow
title={t('screenCompose:content.root.footer.poll.expiration.heading')}
@@ -244,7 +236,7 @@ const ComposePoll: React.FC = () => {
}
)
}}
iconBack='ChevronRight'
iconBack='chevron-right'
/>
</View>
</View>

View File

@@ -93,7 +93,7 @@ const ComposeRootSuggestions: React.FC = () => {
props={{ onPress: () => onPress(`@${account.acct}`) }}
children={
<Icon
name='Plus'
name='plus'
size={StyleConstants.Font.Size.L}
color={colors.secondary}
style={{ marginLeft: 8 }}

View File

@@ -1,5 +1,5 @@
import React, { useEffect, useRef } from 'react'
import { AccessibilityInfo, findNodeHandle, ScrollView, View } from 'react-native'
import { AccessibilityInfo, findNodeHandle, ScrollView } from 'react-native'
import ComposePosting from '../Posting'
import ComposeActions from './Actions'
import ComposeDrafts from './Drafts'

View File

@@ -2,6 +2,7 @@ import { createRef } from 'react'
import { ComposeState } from './types'
const composeInitialState: Omit<ComposeState, 'timestamp'> = {
type: undefined,
dirty: false,
posting: false,
spoiler: {
@@ -21,12 +22,7 @@ const composeInitialState: Omit<ComposeState, 'timestamp'> = {
poll: {
active: false,
total: 2,
options: {
'0': undefined,
'1': undefined,
'2': undefined,
'3': undefined
},
options: [],
multiple: false,
expire: '86400'
},

View File

@@ -36,11 +36,12 @@ const composeParseState = (
): ComposeState => {
switch (params.type) {
case 'share':
return { ...composeInitialState, dirty: true, timestamp: Date.now() }
return { ...composeInitialState, type: params.type, dirty: true, timestamp: Date.now() }
case 'edit':
case 'deleteEdit':
return {
...composeInitialState,
type: params.type,
dirty: true,
timestamp: Date.now(),
...(params.incomingStatus.spoiler_text && {
@@ -50,19 +51,13 @@ const composeParseState = (
poll: {
active: true,
total: params.incomingStatus.poll.options.length,
options: {
'0': params.incomingStatus.poll.options[0]?.title || undefined,
'1': params.incomingStatus.poll.options[1]?.title || undefined,
'2': params.incomingStatus.poll.options[2]?.title || undefined,
'3': params.incomingStatus.poll.options[3]?.title || undefined
},
options: params.incomingStatus.poll.options.map(option => option.title),
multiple: params.incomingStatus.poll.multiple,
expire: '86400' // !!!
}
}),
...(params.incomingStatus.media_attachments && {
attachments: {
...(params.type === 'edit' && { disallowEditing: true }),
sensitive: params.incomingStatus.sensitive,
uploads: params.incomingStatus.media_attachments.map(media => ({
remote: media
@@ -77,6 +72,7 @@ const composeParseState = (
const actualStatus = params.incomingStatus.reblog || params.incomingStatus
return {
...composeInitialState,
type: params.type,
dirty: true,
timestamp: Date.now(),
...(actualStatus.spoiler_text && {
@@ -88,6 +84,7 @@ const composeParseState = (
case 'conversation':
return {
...composeInitialState,
type: params.type,
dirty: true,
timestamp: Date.now(),
...assignVisibility(params.visibility || 'direct')

View File

@@ -9,13 +9,27 @@ const composePost = async (
params: RootStackParamList['Screen-Compose'],
composeState: ComposeState
): Promise<Mastodon.Status> => {
const formData = new FormData()
const body: {
language?: string
in_reply_to_id?: string
spoiler_text?: string
status: string
visibility: ComposeState['visibility']
sensitive?: boolean
media_ids?: string[]
media_attributes?: { id: string; description?: string }[]
poll?: {
expires_in: string
multiple: boolean
options: (string | undefined)[]
}
} = { status: composeState.text.raw, visibility: composeState.visibility }
const detectedLanguage = await detectLanguage(
getPureContent([composeState.spoiler.raw, composeState.text.raw].join('\n\n'))
)
if (detectedLanguage) {
formData.append('language', detectedLanguage.language)
body.language = detectedLanguage.language
}
if (composeState.replyToStatus) {
@@ -29,29 +43,44 @@ const composePost = async (
return Promise.reject({ removeReply: true })
}
}
formData.append('in_reply_to_id', composeState.replyToStatus.id)
body.in_reply_to_id = composeState.replyToStatus.id
}
if (composeState.spoiler.active) {
formData.append('spoiler_text', composeState.spoiler.raw)
body.spoiler_text = composeState.spoiler.raw
}
formData.append('status', composeState.text.raw)
if (composeState.poll.active) {
Object.values(composeState.poll.options).forEach(
e => e && e.length && formData.append('poll[options][]', e)
)
formData.append('poll[expires_in]', composeState.poll.expire)
formData.append('poll[multiple]', composeState.poll.multiple?.toString())
body.poll = {
expires_in: composeState.poll.expire,
multiple: composeState.poll.multiple,
options: composeState.poll.options.filter(option => !!option)
}
}
if (composeState.attachments.uploads.filter(upload => upload.remote && upload.remote.id).length) {
formData.append('sensitive', composeState.attachments.sensitive?.toString())
composeState.attachments.uploads.forEach(e => formData.append('media_ids[]', e.remote!.id!))
}
body.sensitive = composeState.attachments.sensitive
body.media_ids = []
if (params?.type === 'edit') {
body.media_attributes = []
}
formData.append('visibility', composeState.visibility)
composeState.attachments.uploads.forEach((attachment, index) => {
body.media_ids?.push(attachment.remote!.id)
if (params?.type === 'edit') {
if (
attachment.remote?.description !==
params.incomingStatus.media_attachments[index].description
) {
body.media_attributes?.push({
id: attachment.remote!.id,
description: attachment.remote!.description
})
}
}
})
}
return apiInstance<Mastodon.Status>({
method: params?.type === 'edit' ? 'put' : 'post',
@@ -73,7 +102,7 @@ const composePost = async (
(params?.type === 'edit' || params?.type === 'deleteEdit' ? Math.random().toString() : '')
)
},
body: formData
body
}).then(res => res.body)
}

View File

@@ -1,3 +1,4 @@
import type { RootStackParamList } from '@utils/navigation/navigators'
import { RefObject } from 'react'
import { Asset } from 'react-native-image-picker'
@@ -19,6 +20,7 @@ export type ComposeStateDraft = {
}
export type ComposeState = {
type: NonNullable<RootStackParamList['Screen-Compose']>['type'] | undefined
dirty: boolean
timestamp: number
posting: boolean
@@ -44,14 +46,11 @@ export type ComposeState = {
poll: {
active: boolean
total: number
options: {
[key: string]: string | undefined
}
options: (string | undefined)[]
multiple: boolean
expire: '300' | '1800' | '3600' | '21600' | '86400' | '259200' | '604800'
}
attachments: {
disallowEditing?: boolean // https://github.com/mastodon/mastodon/pull/20878
sensitive: boolean
uploads: ExtendedAttachment[]
}

View File

@@ -71,14 +71,14 @@ const ScreenImagesViewer = ({
zIndex: 999
}}
>
<HeaderLeft content='X' native={false} background onPress={() => navigation.goBack()} />
<HeaderLeft content='x' native={false} background onPress={() => navigation.goBack()} />
{!hideCounter ? (
<HeaderCenter inverted content={`${currentIndex + 1} / ${imageUrls.length}`} />
) : null}
<HeaderRight
accessibilityLabel={t('screenImageViewer:content.actions.accessibilityLabel')}
accessibilityHint={t('screenImageViewer:content.actions.accessibilityHint')}
content='MoreHorizontal'
content='more-horizontal'
native={false}
background
onPress={() =>

View File

@@ -38,7 +38,7 @@ const Root: React.FC<NativeStackScreenProps<TabLocalStackParamList, 'Tab-Local-R
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
{page.page === 'List' ? (
<Icon
name='List'
name='list'
size={StyleConstants.Font.Size.M}
color={colors.primaryDefault}
style={{ marginRight: StyleConstants.Spacing.S }}
@@ -57,7 +57,7 @@ const Root: React.FC<NativeStackScreenProps<TabLocalStackParamList, 'Tab-Local-R
/>
{page.page === 'Following' && !pageLocal?.showBoosts ? (
<Icon
name='Repeat'
name='repeat'
size={StyleConstants.Font.Size.M}
color={colors.red}
style={{ marginLeft: StyleConstants.Spacing.S }}
@@ -66,7 +66,7 @@ const Root: React.FC<NativeStackScreenProps<TabLocalStackParamList, 'Tab-Local-R
) : null}
{page.page === 'Following' && !pageLocal?.showReplies ? (
<Icon
name='MessageCircle'
name='message-circle'
size={StyleConstants.Font.Size.M}
color={colors.red}
style={{ marginLeft: StyleConstants.Spacing.S }}
@@ -74,7 +74,7 @@ const Root: React.FC<NativeStackScreenProps<TabLocalStackParamList, 'Tab-Local-R
/>
) : null}
<Icon
name='ChevronDown'
name='chevron-down'
size={StyleConstants.Font.Size.M}
color={colors.primaryDefault}
style={{ marginLeft: StyleConstants.Spacing.S }}
@@ -169,7 +169,7 @@ const Root: React.FC<NativeStackScreenProps<TabLocalStackParamList, 'Tab-Local-R
<HeaderRight
accessibilityLabel={t('common.search.accessibilityLabel')}
accessibilityHint={t('common.search.accessibilityHint')}
content='Search'
content='search'
onPress={() => navigation.navigate('Tab-Shared-Search')}
/>
)

View File

@@ -50,7 +50,7 @@ const TabMeListAccounts: React.FC<TabMeStackScreenProps<'Tab-Me-List-Accounts'>>
children={
<Button
type='icon'
content='X'
content='x'
round
onPress={() =>
mutation.mutate({ type: 'delete', payload: { id: params.id, accounts: [item.id] } })

View File

@@ -90,7 +90,7 @@ const TabMeListEdit: React.FC<TabMeStackScreenProps<'Tab-Me-List-Edit'>> = ({
: t('screenTabs:me.stacks.listEdit.name'),
headerLeft: () => (
<HeaderLeft
content='X'
content='x'
onPress={() => {
if (params.type === 'edit' ? params.payload.title !== title : title.length) {
Alert.alert(t('common:discard.title'), t('common:discard.message'), [
@@ -112,7 +112,7 @@ const TabMeListEdit: React.FC<TabMeStackScreenProps<'Tab-Me-List-Edit'>> = ({
),
headerRight: () => (
<HeaderRight
content='Save'
content='save'
disabled={!title.length}
loading={mutation.isLoading}
onPress={() => {

View File

@@ -26,8 +26,8 @@ const TabMeListList: React.FC<TabMeStackScreenProps<'Tab-Me-List-List'>> = ({ na
{data?.map((list, index) => (
<MenuRow
key={index}
iconFront='List'
iconBack='ChevronRight'
iconFront='list'
iconBack='chevron-right'
title={list.title}
onPress={() => navigation.navigate('Tab-Me-List', { list })}
/>

View File

@@ -51,7 +51,7 @@ const TabMeList: React.FC<NativeStackScreenProps<TabMeStackParamList, 'Tab-Me-Li
<DropdownMenu.Root>
<DropdownMenu.Trigger>
<Icon
name='MoreHorizontal'
name='more-horizontal'
size={StyleConstants.Spacing.M * 1.25}
color={colors.primaryDefault}
/>

View File

@@ -0,0 +1,158 @@
import { MenuContainer, MenuRow } from '@components/Menu'
import { Message } from '@components/Message'
import { useActionSheet } from '@expo/react-native-action-sheet'
import { androidActionSheetStyles } from '@utils/helpers/androidActionSheetStyles'
import browserPackage from '@utils/helpers/browserPackage'
import { TabMeProfileStackScreenProps } from '@utils/navigation/navigators'
import { usePreferencesQuery } from '@utils/queryHooks/preferences'
import { useProfileMutation } from '@utils/queryHooks/profile'
import { getAccountStorage } from '@utils/storage/actions'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import * as WebBrowser from 'expo-web-browser'
import React, { useRef } from 'react'
import { useTranslation } from 'react-i18next'
import FlashMessage from 'react-native-flash-message'
import { ScrollView } from 'react-native-gesture-handler'
const TabMePreferences: React.FC<TabMeProfileStackScreenProps<'Tab-Me-Profile-Root'>> = () => {
const { colors } = useTheme()
const { t } = useTranslation(['common', 'screenTabs'])
const { showActionSheetWithOptions } = useActionSheet()
const { mutateAsync } = useProfileMutation()
const { data, isFetching, refetch } = usePreferencesQuery()
const messageRef = useRef<FlashMessage>(null)
return (
<ScrollView>
<MenuContainer>
{data?.['posting:default:visibility'] !== 'direct' ? (
<MenuRow
title={t('screenTabs:me.preferences.visibility.title')}
content={
data?.['posting:default:visibility']
? t(
`screenTabs:me.preferences.visibility.options.${data['posting:default:visibility']}`
)
: undefined
}
loading={isFetching}
iconBack='chevron-right'
onPress={() =>
showActionSheetWithOptions(
{
title: t('screenTabs:me.preferences.visibility.title'),
options: [
t('screenTabs:me.preferences.visibility.options.public'),
t('screenTabs:me.preferences.visibility.options.unlisted'),
t('screenTabs:me.preferences.visibility.options.private'),
t('common:buttons.cancel')
],
cancelButtonIndex: 3,
...androidActionSheetStyles(colors)
},
async buttonIndex => {
switch (buttonIndex) {
case 0:
case 1:
case 2:
const indexVisibilityMapping = ['public', 'unlisted', 'private'] as [
'public',
'unlisted',
'private'
]
if (
data?.['posting:default:visibility'] &&
data['posting:default:visibility'] !== indexVisibilityMapping[buttonIndex]
) {
mutateAsync({
messageRef,
message: {
text: 'me.profile.root.visibility.title',
succeed: false,
failed: true
},
type: 'source[privacy]',
data: indexVisibilityMapping[buttonIndex]
}).then(() => refetch())
}
break
}
}
)
}
/>
) : null}
<MenuRow
title={t('screenTabs:me.preferences.sensitive.title')}
switchValue={data?.['posting:default:sensitive']}
switchOnValueChange={() =>
mutateAsync({
messageRef,
message: {
text: 'me.profile.root.sensitive.title',
succeed: false,
failed: true
},
type: 'source[sensitive]',
data:
data?.['posting:default:sensitive'] === undefined
? true
: !data['posting:default:sensitive']
}).then(() => refetch())
}
loading={isFetching}
/>
</MenuContainer>
<MenuContainer style={{ marginTop: StyleConstants.Spacing.L }}>
<MenuRow
iconBack='external-link'
title={t('screenTabs:me.preferences.web_only.title')}
description={t('screenTabs:me.preferences.web_only.description')}
onPress={async () =>
WebBrowser.openAuthSessionAsync(
`https://${getAccountStorage.string('auth.domain')}/settings/preferences`,
'tooot://tooot',
{
...(await browserPackage()),
dismissButtonStyle: 'done',
readerMode: false
}
).then(() => refetch())
}
/>
<MenuRow
title={t('screenTabs:me.preferences.media.title')}
content={
data?.['reading:expand:media']
? t(`screenTabs:me.preferences.media.options.${data['reading:expand:media']}`)
: undefined
}
loading={isFetching}
/>
<MenuRow
title={t('screenTabs:me.preferences.spoilers.title')}
switchValue={data?.['reading:expand:spoilers'] || false}
switchDisabled={true}
loading={isFetching}
/>
{data?.['reading:autoplay:gifs'] !== undefined ? (
<MenuRow
title={t('screenTabs:me.preferences.autoplay_gifs.title')}
switchValue={data['reading:autoplay:gifs'] || false}
switchDisabled={true}
loading={isFetching}
/>
) : null}
</MenuContainer>
<Message ref={messageRef} />
</ScrollView>
)
}
export default TabMePreferences

View File

@@ -90,7 +90,7 @@ const TabMeProfileFields: React.FC<
navigation.setOptions({
headerLeft: () => (
<HeaderLeft
content='X'
content='x'
onPress={() => {
if (dirty) {
Alert.alert(t('common:discard.title'), t('common:discard.message'), [
@@ -114,7 +114,7 @@ const TabMeProfileFields: React.FC<
<HeaderRight
disabled={!dirty}
loading={status === 'loading'}
content='Save'
content='save'
onPress={async () => {
mutateAsync({
messageRef,

View File

@@ -44,7 +44,7 @@ const TabMeProfileName: React.FC<
navigation.setOptions({
headerLeft: () => (
<HeaderLeft
content='X'
content='x'
onPress={() => {
if (dirty) {
Alert.alert(t('common:discard.title'), t('common:discard.message'), [
@@ -68,7 +68,7 @@ const TabMeProfileName: React.FC<
<HeaderRight
disabled={!dirty}
loading={status === 'loading'}
content='Save'
content='save'
onPress={async () => {
mutateAsync({
messageRef,

View File

@@ -44,7 +44,7 @@ const TabMeProfileNote: React.FC<
navigation.setOptions({
headerLeft: () => (
<HeaderLeft
content='X'
content='x'
onPress={() => {
if (dirty) {
Alert.alert(t('common:discard.title'), t('common:discard.message'), [
@@ -68,7 +68,7 @@ const TabMeProfileNote: React.FC<
<HeaderRight
disabled={!dirty}
loading={status === 'loading'}
content='Save'
content='save'
onPress={async () => {
mutateAsync({
messageRef,

View File

@@ -1,11 +1,6 @@
import { MenuContainer, MenuRow } from '@components/Menu'
import { useActionSheet } from '@expo/react-native-action-sheet'
import { androidActionSheetStyles } from '@utils/helpers/androidActionSheetStyles'
import { TabMeProfileStackScreenProps } from '@utils/navigation/navigators'
import { queryClient } from '@utils/queryHooks'
import { QueryKeyPreferences } from '@utils/queryHooks/preferences'
import { useProfileMutation, useProfileQuery } from '@utils/queryHooks/profile'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { RefObject } from 'react'
import { useTranslation } from 'react-i18next'
import FlashMessage from 'react-native-flash-message'
@@ -17,19 +12,11 @@ const TabMeProfileRoot: React.FC<
messageRef: RefObject<FlashMessage>
}
> = ({ messageRef, navigation }) => {
const { colors } = useTheme()
const { t } = useTranslation(['common', 'screenTabs'])
const { showActionSheetWithOptions } = useActionSheet()
const { data, isFetching } = useProfileQuery()
const { mutateAsync } = useProfileMutation()
const refetchPreferences = () => {
const queryKeyPreferences: QueryKeyPreferences = ['Preferences']
queryClient.refetchQueries(queryKeyPreferences)
}
return (
<ScrollView>
<MenuContainer>
@@ -37,7 +24,7 @@ const TabMeProfileRoot: React.FC<
title={t('screenTabs:me.profile.root.name.title')}
content={data?.display_name}
loading={isFetching}
iconBack='ChevronRight'
iconBack='chevron-right'
onPress={() => {
data &&
navigation.navigate('Tab-Me-Profile-Name', {
@@ -51,7 +38,7 @@ const TabMeProfileRoot: React.FC<
title={t('screenTabs:me.profile.root.note.title')}
content={data?.source?.note}
loading={isFetching}
iconBack='ChevronRight'
iconBack='chevron-right'
onPress={() => {
data &&
navigation.navigate('Tab-Me-Profile-Note', {
@@ -69,7 +56,7 @@ const TabMeProfileRoot: React.FC<
: undefined
}
loading={isFetching}
iconBack='ChevronRight'
iconBack='chevron-right'
onPress={() => {
navigation.navigate('Tab-Me-Profile-Fields', {
fields: data?.source.fields
@@ -77,77 +64,6 @@ const TabMeProfileRoot: React.FC<
}}
/>
</MenuContainer>
<MenuContainer>
{data?.source.privacy !== 'direct' ? (
<MenuRow
title={t('screenTabs:me.profile.root.visibility.title')}
content={
data?.source.privacy
? t(`screenTabs:me.profile.root.visibility.options.${data.source.privacy}`)
: undefined
}
loading={isFetching}
iconBack='ChevronRight'
onPress={() =>
showActionSheetWithOptions(
{
title: t('screenTabs:me.profile.root.visibility.title'),
options: [
t('screenTabs:me.profile.root.visibility.options.public'),
t('screenTabs:me.profile.root.visibility.options.unlisted'),
t('screenTabs:me.profile.root.visibility.options.private'),
t('common:buttons.cancel')
],
cancelButtonIndex: 3,
...androidActionSheetStyles(colors)
},
async buttonIndex => {
switch (buttonIndex) {
case 0:
case 1:
case 2:
const indexVisibilityMapping = ['public', 'unlisted', 'private'] as [
'public',
'unlisted',
'private'
]
if (data?.source.privacy !== indexVisibilityMapping[buttonIndex]) {
mutateAsync({
messageRef,
message: {
text: 'me.profile.root.visibility.title',
succeed: false,
failed: true
},
type: 'source[privacy]',
data: indexVisibilityMapping[buttonIndex]
}).then(() => refetchPreferences())
}
break
}
}
)
}
/>
) : null}
<MenuRow
title={t('screenTabs:me.profile.root.sensitive.title')}
switchValue={data?.source.sensitive}
switchOnValueChange={() =>
mutateAsync({
messageRef,
message: {
text: 'me.profile.root.sensitive.title',
succeed: false,
failed: true
},
type: 'source[sensitive]',
data: data?.source.sensitive === undefined ? true : !data.source.sensitive
}).then(() => refetchPreferences())
}
loading={isFetching}
/>
</MenuContainer>
<MenuContainer>
<MenuRow
title={t('screenTabs:me.profile.root.lock.title')}

View File

@@ -25,7 +25,7 @@ const ProfileAvatarHeader: React.FC<Props> = ({ type, messageRef }) => {
title={t(`screenTabs:me.profile.root.${type}.title`)}
description={t(`screenTabs:me.profile.root.${type}.description`)}
loading={query.isFetching || mutation.isLoading}
iconBack='ChevronRight'
iconBack='chevron-right'
onPress={async () => {
const image = await mediaSelector({
mediaType: 'photo',

View File

@@ -28,7 +28,7 @@ const TabMeProfile: React.FC<TabMeStackScreenProps<'Tab-Me-Switch'>> = ({ naviga
options={{
title: t('me.stacks.profile.name'),
headerLeft: () => (
<HeaderLeft content='ChevronDown' onPress={() => navigation.goBack()} />
<HeaderLeft content='chevron-down' onPress={() => navigation.goBack()} />
)
}}
>

View File

@@ -265,7 +265,7 @@ const TabMePush: React.FC = () => {
/>
<MenuRow
title={t('me.push.howitworks')}
iconBack='ExternalLink'
iconBack='external-link'
onPress={async () =>
WebBrowser.openBrowserAsync('https://tooot.app/how-push-works', {
...(await browserPackage())
@@ -286,7 +286,7 @@ const TabMePush: React.FC = () => {
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding
}}
>
<Icon name='Frown' size={StyleConstants.Font.Size.L} color={colors.primaryDefault} />
<Icon name='frown' size={StyleConstants.Font.Size.L} color={colors.primaryDefault} />
<CustomText
fontStyle='M'
style={{
@@ -310,7 +310,7 @@ const TabMePush: React.FC = () => {
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding
}}
>
<Icon name='Frown' size={StyleConstants.Font.Size.L} color={colors.primaryDefault} />
<Icon name='frown' size={StyleConstants.Font.Size.L} color={colors.primaryDefault} />
<CustomText
fontStyle='M'
style={{

View File

@@ -43,43 +43,43 @@ const Collections: React.FC = () => {
return (
<MenuContainer>
<MenuRow
iconFront='Mail'
iconBack='ChevronRight'
iconFront='mail'
iconBack='chevron-right'
title={t('screenTabs:me.stacks.conversations.name')}
onPress={() => navigation.navigate('Tab-Me-Conversations')}
/>
<MenuRow
iconFront='Bookmark'
iconBack='ChevronRight'
iconFront='bookmark'
iconBack='chevron-right'
title={t('screenTabs:me.stacks.bookmarks.name')}
onPress={() => navigation.navigate('Tab-Me-Bookmarks')}
/>
<MenuRow
iconFront='Heart'
iconBack='ChevronRight'
iconFront='heart'
iconBack='chevron-right'
title={t('screenTabs:me.stacks.favourites.name')}
onPress={() => navigation.navigate('Tab-Me-Favourites')}
/>
{pageMe?.lists?.shown ? (
<MenuRow
iconFront='List'
iconBack='ChevronRight'
iconFront='list'
iconBack='chevron-right'
title={t('screenTabs:me.stacks.lists.name')}
onPress={() => navigation.navigate('Tab-Me-List-List')}
/>
) : null}
{pageMe?.followedTags?.shown ? (
<MenuRow
iconFront='Hash'
iconBack='ChevronRight'
iconFront='hash'
iconBack='chevron-right'
title={t('screenTabs:me.stacks.followedTags.name')}
onPress={() => navigation.navigate('Tab-Me-FollowedTags')}
/>
) : null}
{pageMe?.announcements?.shown ? (
<MenuRow
iconFront='Clipboard'
iconBack='ChevronRight'
iconFront='clipboard'
iconBack='chevron-right'
title={t('screenAnnouncements:heading')}
content={
pageMe.announcements.unread
@@ -92,8 +92,8 @@ const Collections: React.FC = () => {
/>
) : null}
<MenuRow
iconFront={instancePush ? 'Bell' : 'BellOff'}
iconBack='ChevronRight'
iconFront={instancePush ? 'bell' : 'bell-off'}
iconBack='chevron-right'
title={t('screenTabs:me.stacks.push.name')}
content={
typeof instancePush.global === 'boolean'

View File

@@ -1,8 +1,5 @@
import { MenuContainer, MenuRow } from '@components/Menu'
import { useNavigation } from '@react-navigation/native'
import browserPackage from '@utils/helpers/browserPackage'
import { getAccountStorage, useGlobalStorage } from '@utils/storage/actions'
import * as WebBrowser from 'expo-web-browser'
import React from 'react'
import { useTranslation } from 'react-i18next'
@@ -10,34 +7,14 @@ const Settings: React.FC = () => {
const { t } = useTranslation('screenTabs')
const navigation = useNavigation<any>()
const [accountActive] = useGlobalStorage.string('account.active')
return (
<MenuContainer>
<MenuRow
iconFront='Settings'
iconBack='ChevronRight'
iconFront='settings'
iconBack='chevron-right'
title={t('me.stacks.settings.name')}
onPress={() => navigation.navigate('Tab-Me-Settings')}
/>
{accountActive ? (
<MenuRow
iconFront='Sliders'
iconBack='ExternalLink'
title={t('me.stacks.webSettings.name')}
onPress={async () =>
WebBrowser.openAuthSessionAsync(
`https://${getAccountStorage.string('auth.domain')}/settings/preferences`,
'tooot://tooot',
{
...(await browserPackage()),
dismissButtonStyle: 'done',
readerMode: false
}
)
}
/>
) : null}
</MenuContainer>
)
}

View File

@@ -29,7 +29,7 @@ const SettingsApp: React.FC = () => {
<MenuRow
title={t('screenTabs:me.stacks.fontSize.name')}
content={t(`screenTabs:me.fontSize.sizes.${mapFontsizeToName(fontSize || 0)}`)}
iconBack='ChevronRight'
iconBack='chevron-right'
onPress={() => navigation.navigate('Tab-Me-Settings-Fontsize')}
/>
<MenuRow
@@ -42,7 +42,7 @@ const SettingsApp: React.FC = () => {
: i18n.language.toLowerCase()
]
}
iconBack='ChevronRight'
iconBack='chevron-right'
onPress={() =>
Platform.OS === 'ios'
? Linking.openSettings()
@@ -52,7 +52,7 @@ const SettingsApp: React.FC = () => {
<MenuRow
title={t('screenTabs:me.settings.theme.heading')}
content={t(`screenTabs:me.settings.theme.options.${theme || 'auto'}`)}
iconBack='ChevronRight'
iconBack='chevron-right'
onPress={() =>
showActionSheetWithOptions(
{
@@ -88,7 +88,7 @@ const SettingsApp: React.FC = () => {
<MenuRow
title={t('screenTabs:me.settings.darkTheme.heading')}
content={t(`screenTabs:me.settings.darkTheme.options.${themeDark || 'lighter'}`)}
iconBack='ChevronRight'
iconBack='chevron-right'
onPress={() =>
showActionSheetWithOptions(
{
@@ -119,7 +119,7 @@ const SettingsApp: React.FC = () => {
<MenuRow
title={t('screenTabs:me.settings.browser.heading')}
content={t(`screenTabs:me.settings.browser.options.${browser || 'internal'}`)}
iconBack='ChevronRight'
iconBack='chevron-right'
onPress={() =>
showActionSheetWithOptions(
{

View File

@@ -27,7 +27,7 @@ const SettingsDev: React.FC = () => {
<MenuRow
title={'Saved local instances'}
content={accounts?.length.toString()}
iconBack='ChevronRight'
iconBack='chevron-right'
onPress={() =>
showActionSheetWithOptions(
{

View File

@@ -24,22 +24,22 @@ const SettingsTooot: React.FC = () => {
<MenuContainer>
<MenuRow
title={t('me.settings.support.heading')}
content={<Icon name='Heart' size={StyleConstants.Font.Size.M} color={colors.red} />}
iconBack='ChevronRight'
content={<Icon name='heart' size={StyleConstants.Font.Size.M} color={colors.red} />}
iconBack='chevron-right'
onPress={() => Linking.openURL('https://www.buymeacoffee.com/xmflsct')}
/>
<MenuRow
title={t('me.settings.feedback.heading')}
content={
<Icon name='MessageSquare' size={StyleConstants.Font.Size.M} color={colors.secondary} />
<Icon name='message-square' size={StyleConstants.Font.Size.M} color={colors.secondary} />
}
iconBack='ChevronRight'
iconBack='chevron-right'
onPress={() => Linking.openURL('https://feedback.tooot.app/feature-requests')}
/>
<MenuRow
title={t('me.settings.contact.heading')}
content={<Icon name='Mail' size={StyleConstants.Font.Size.M} color={colors.secondary} />}
iconBack='ChevronRight'
content={<Icon name='mail' size={StyleConstants.Font.Size.M} color={colors.secondary} />}
iconBack='chevron-right'
onPress={async () => {
if (accountActive) {
navigation.navigate('Screen-Compose', {

View File

@@ -114,7 +114,7 @@ const TabMeSettingsFontsize: React.FC<TabMeStackScreenProps<'Tab-Me-Settings-Fon
}
}}
type='icon'
content='Minus'
content='minus'
round
disabled={(fontSize || 0) <= -1}
style={{ marginHorizontal: StyleConstants.Spacing.S }}
@@ -128,7 +128,7 @@ const TabMeSettingsFontsize: React.FC<TabMeStackScreenProps<'Tab-Me-Settings-Fon
}
}}
type='icon'
content='Plus'
content='plus'
round
disabled={(fontSize || 0) >= 3}
style={{ marginHorizontal: StyleConstants.Spacing.S }}

View File

@@ -41,7 +41,7 @@ const TabMeSettingsLanguage: React.FC<TabMeStackScreenProps<'Tab-Me-Settings-Lan
<MenuRow
key={item[0]}
title={item[1]}
iconBack={item[0] === i18n.language ? 'Check' : undefined}
iconBack={item[0] === i18n.language ? 'check' : undefined}
iconBackColor={'blue'}
onPress={() => item[0] !== i18n.language && change(item[0])}
/>

View File

@@ -12,6 +12,7 @@ import TabMeList from './List'
import TabMeListAccounts from './List/Accounts'
import TabMeListEdit from './List/Edit'
import TabMeListList from './List/List'
import TabMePreferences from './Preferences'
import TabMeProfile from './Profile'
import TabMePush from './Push'
import TabMeRoot from './Root'
@@ -100,13 +101,19 @@ const TabMe: React.FC = () => {
headerLeft: () => <HeaderLeft onPress={() => navigation.pop(1)} />
})}
/>
<Stack.Screen
name='Tab-Me-Preferences'
component={TabMePreferences}
options={({ navigation }: any) => ({
presentation: 'modal',
title: t('me.stacks.preferences.name'),
headerLeft: () => <HeaderLeft content='chevron-down' onPress={() => navigation.pop(1)} />
})}
/>
<Stack.Screen
name='Tab-Me-Profile'
component={TabMeProfile}
options={{
headerShown: false,
presentation: 'modal'
}}
options={{ headerShown: false, presentation: 'modal' }}
/>
<Stack.Screen
name='Tab-Me-Push'
@@ -147,7 +154,7 @@ const TabMe: React.FC = () => {
presentation: 'modal',
headerShown: true,
title: t('me.stacks.switch.name'),
headerLeft: () => <HeaderLeft content='ChevronDown' onPress={() => navigation.goBack()} />
headerLeft: () => <HeaderLeft content='chevron-down' onPress={() => navigation.goBack()} />
})}
/>

View File

@@ -26,7 +26,7 @@ const TabNotificationsFilters: React.FC<
title: t('screenTabs:notifications.filters.title'),
headerLeft: () => (
<HeaderLeft
content='ChevronDown'
content='chevron-down'
onPress={() => {
if (changed) {
Alert.alert(t('common:discard.title'), t('common:discard.message'), [

View File

@@ -25,7 +25,7 @@ const Root: React.FC<
<HeaderRight
accessibilityLabel={t('notifications.filters.accessibilityLabel')}
accessibilityHint={t('notifications.filters.accessibilityHint')}
content='Filter'
content='filter'
onPress={() => navigation.navigate('Tab-Notifications-Filters')}
/>
)

View File

@@ -64,7 +64,7 @@ const Root: React.FC<NativeStackScreenProps<TabPublicStackParamList, 'Tab-Public
<HeaderRight
accessibilityLabel={t('common.search.accessibilityLabel')}
accessibilityHint={t('common.search.accessibilityHint')}
content='Search'
content='search'
onPress={() => navigation.navigate('Tab-Shared-Search')}
/>
)

View File

@@ -70,7 +70,7 @@ const AccountAttachments: React.FC = () => {
}}
children={
<Icon
name='MoreHorizontal'
name='more-horizontal'
color={colors.primaryOverlay}
size={StyleConstants.Font.Size.L * 1.5}
/>

View File

@@ -1,6 +1,6 @@
import Icon from '@components/Icon'
import CustomText from '@components/Text'
import { getAccountStorage, useAccountStorage } from '@utils/storage/actions'
import { useAccountStorage } from '@utils/storage/actions'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { useContext } from 'react'
@@ -16,7 +16,7 @@ const AccountInformationAccount: React.FC = () => {
const { colors } = useTheme()
const [acct] = useAccountStorage.string('auth.account.acct')
const domain = getAccountStorage.string('auth.account.domain')
const [domain] = useAccountStorage.string('auth.account.domain')
const localInstance = account?.acct?.includes('@') ? account?.acct?.includes(`@${domain}`) : true
@@ -50,7 +50,7 @@ const AccountInformationAccount: React.FC = () => {
</CustomText>
{account?.locked ? (
<Icon
name='Lock'
name='lock'
style={{ marginLeft: StyleConstants.Spacing.S }}
color={colors.secondary}
size={StyleConstants.Font.Size.M}
@@ -58,7 +58,7 @@ const AccountInformationAccount: React.FC = () => {
) : null}
{account?.bot ? (
<Icon
name='HardDrive'
name='hard-drive'
style={{ marginLeft: StyleConstants.Spacing.S }}
color={colors.secondary}
size={StyleConstants.Font.Size.M}

View File

@@ -42,6 +42,14 @@ const AccountInformationActions: React.FC = () => {
content={t('me.stacks.profile.name')}
onPress={() => navigation.navigate('Tab-Me-Profile')}
/>
<Button
round
type='icon'
disabled={account === undefined}
content='sliders'
style={{ marginLeft: StyleConstants.Spacing.S }}
onPress={() => navigation.navigate('Tab-Me-Preferences')}
/>
</View>
)
}
@@ -60,8 +68,8 @@ const AccountInformationActions: React.FC = () => {
<Button
round
type='icon'
content='AtSign'
style={{ marginRight: StyleConstants.Spacing.S }}
content='at-sign'
style={{ flex: 1, marginRight: StyleConstants.Spacing.S }}
onPress={() => {}}
/>
</DropdownMenu.Trigger>
@@ -119,7 +127,7 @@ const styles = StyleSheet.create({
base: {
alignSelf: 'flex-end',
flexDirection: 'row',
alignItems: 'center'
alignItems: 'stretch'
}
})

View File

@@ -3,7 +3,7 @@ import { useNavigation } from '@react-navigation/native'
import { StackNavigationProp } from '@react-navigation/stack'
import navigationRef from '@utils/navigation/navigationRef'
import { TabLocalStackParamList } from '@utils/navigation/navigators'
import { useGlobalStorage } from '@utils/storage/actions'
import { useAccountStorage } from '@utils/storage/actions'
import { StyleConstants } from '@utils/styles/constants'
import React, { useContext } from 'react'
import AccountContext from '../Context'
@@ -13,7 +13,7 @@ const AccountInformationAvatar: React.FC = () => {
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
useGlobalStorage.string('account.active')
const [accountAvatarStatic] = useAccountStorage.string('auth.account.avatar_static')
return (
<GracefullyImage
@@ -24,7 +24,10 @@ const AccountInformationAvatar: React.FC = () => {
width: StyleConstants.Avatar.L,
height: StyleConstants.Avatar.L
}}
uri={{ original: account?.avatar, static: account?.avatar_static }}
uri={{
original: account?.avatar || (pageMe ? accountAvatarStatic : undefined),
static: account?.avatar_static || (pageMe ? accountAvatarStatic : undefined)
}}
onPress={() => {
if (account) {
if (pageMe) {

View File

@@ -30,7 +30,7 @@ const AccountInformationCreated: React.FC = () => {
}}
>
<Icon
name='Calendar'
name='calendar'
size={StyleConstants.Font.Size.S}
color={colors.secondary}
style={{ marginRight: StyleConstants.Spacing.XS }}

View File

@@ -87,7 +87,7 @@ const TabSharedAccount: React.FC<TabSharedStackScreenProps<'Tab-Shared-Account'>
user: account.acct
})}
accessibilityHint={t('shared.account.actions.accessibilityHint')}
content='MoreHorizontal'
content='more-horizontal'
onPress={() => {}}
background
/>

View File

@@ -79,11 +79,11 @@ const TabSharedAccountInLists: React.FC<
renderItem={({ index, item, section }) => (
<MenuRow
key={index}
iconFront='List'
iconFront='list'
content={
<Button
type='icon'
content={section.id === 'in' ? 'Minus' : 'Plus'}
content={section.id === 'in' ? 'minus' : 'plus'}
round
disabled={accountInListsQuery.isFetching}
onPress={() => {

View File

@@ -103,7 +103,7 @@ const ContentView: React.FC<{
paddingTop: StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
marginRight: StyleConstants.Spacing.S
}}
name={item.poll?.multiple ? 'Square' : 'Circle'}
name={item.poll?.multiple ? 'square' : 'circle'}
size={StyleConstants.Font.Size.M}
color={
prevItem?.poll?.multiple !== item.poll?.multiple ? colors.red : colors.disabled

View File

@@ -51,7 +51,7 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
>
{hasRemoteContent ? (
<Icon
name='Wifi'
name='wifi'
size={StyleConstants.Font.Size.M}
color={colors.primaryDefault}
style={{ marginRight: StyleConstants.Spacing.S }}

View File

@@ -115,7 +115,7 @@ const TabSharedUsers: React.FC<TabSharedStackScreenProps<'Tab-Shared-Users'>> =
}}
>
<Icon
name='AlertCircle'
name='alert-circle'
color={colors.secondary}
size={StyleConstants.Font.Size.M}
style={{ marginRight: StyleConstants.Spacing.S }}

View File

@@ -41,13 +41,13 @@ const ScreenTabs = ({ navigation }: RootStackScreenProps<'Screen-Tabs'>) => {
}) => {
switch (route.name) {
case 'Tab-Local':
return <Icon name='Home' size={size} color={color} />
return <Icon name='home' size={size} color={color} />
case 'Tab-Public':
return <Icon name='Globe' size={size} color={color} />
return <Icon name='globe' size={size} color={color} />
case 'Tab-Compose':
return <Icon name='Plus' size={size} color={color} />
return <Icon name='plus' size={size} color={color} />
case 'Tab-Notifications':
return <Icon name='Bell' size={size} color={color} />
return <Icon name='bell' size={size} color={color} />
case 'Tab-Me':
return (
<GracefullyImage
@@ -65,7 +65,7 @@ const ScreenTabs = ({ navigation }: RootStackScreenProps<'Screen-Tabs'>) => {
/>
)
default:
return <Icon name='AlertOctagon' size={size} color={color} />
return <Icon name='alert-octagon' size={size} color={color} />
}
}
})}

View File

@@ -248,7 +248,7 @@ const Screens: React.FC = () => {
headerShadowVisible: false,
headerTransparent: true,
headerStyle: { backgroundColor: 'transparent' },
headerLeft: () => <HeaderLeft content='X' onPress={() => navigation.goBack()} />,
headerLeft: () => <HeaderLeft content='x' onPress={() => navigation.goBack()} />,
title: t('screenAnnouncements:heading')
})}
/>

View File

@@ -1,5 +1,5 @@
import axios from 'axios'
import { ctx, handleError, PagedResponse, parseHeaderLinks, userAgent } from './helpers'
import { ctx, handleError, PagedResponse, parseHeaderLinks, processBody, userAgent } from './helpers'
export type Params = {
method: 'get' | 'post' | 'put' | 'delete'
@@ -39,15 +39,11 @@ const apiGeneral = async <T = unknown>({
url,
params,
headers: {
'Content-Type': body && body instanceof FormData ? 'multipart/form-data' : 'application/json',
Accept: '*/*',
Accept: 'application/json',
...userAgent,
...headers
},
...(body &&
(body instanceof FormData
? (body as (FormData & { _parts: [][] }) | undefined)?._parts?.length
: Object.keys(body).length) && { data: body })
data: processBody(body)
})
.then(response => ({ body: response.data, links: parseHeaderLinks(response.headers.link) }))
.catch(handleError())

View File

@@ -94,7 +94,6 @@ export const parseHeaderLinks = (headerLink?: string): PagedResponse['links'] =>
}
}
type LinkFormat = { id: string; isOffset: boolean }
export type PagedResponse<T = unknown> = {
body: T
links?: {
@@ -103,4 +102,20 @@ export type PagedResponse<T = unknown> = {
}
}
export const processBody = (body?: FormData | Object): FormData | Object | undefined => {
if (!body) return
if (body instanceof FormData) {
if ((body as FormData & { _parts: [][] })._parts?.length) {
return body
} else {
return
}
}
if (Object.keys(body).length) {
return body
}
}
export { ctx, handleError, userAgent }

View File

@@ -1,7 +1,14 @@
import { getAccountDetails } from '@utils/storage/actions'
import { StorageGlobal } from '@utils/storage/global'
import axios, { AxiosRequestConfig } from 'axios'
import { ctx, handleError, PagedResponse, parseHeaderLinks, userAgent } from './helpers'
import {
ctx,
handleError,
PagedResponse,
parseHeaderLinks,
processBody,
userAgent
} from './helpers'
export type Params = {
account?: StorageGlobal['account.active']
@@ -12,7 +19,7 @@ export type Params = {
[key: string]: string | number | boolean | string[] | number[] | boolean[]
}
headers?: { [key: string]: string }
body?: FormData
body?: FormData | Object
extras?: Omit<AxiosRequestConfig, 'method' | 'baseURL' | 'url' | 'params' | 'headers' | 'data'>
}
@@ -51,13 +58,12 @@ const apiInstance = async <T = unknown>({
url,
params,
headers: {
'Content-Type': body && body instanceof FormData ? 'multipart/form-data' : 'application/json',
Accept: '*/*',
Accept: 'application/json',
...userAgent,
...headers,
Authorization: `Bearer ${accountDetails['auth.token']}`
},
...((body as (FormData & { _parts: [][] }) | undefined)?._parts.length && { data: body }),
data: processBody(body),
...extras
})
.then(response => ({ body: response.data, links: parseHeaderLinks(response.headers.link) }))

View File

@@ -1,6 +1,6 @@
import { mapEnvironment } from '@utils/helpers/checkEnvironment'
import axios from 'axios'
import { ctx, handleError, userAgent } from './helpers'
import { ctx, handleError, processBody, userAgent } from './helpers'
export type Params = {
method: 'get' | 'post' | 'put' | 'delete'
@@ -42,15 +42,11 @@ const apiTooot = async <T = unknown>({
url: `${url}`,
params,
headers: {
'Content-Type': body && body instanceof FormData ? 'multipart/form-data' : 'application/json',
Accept: '*/*',
Accept: 'application/json',
...userAgent,
...headers
},
...(body &&
(body instanceof FormData
? (body as (FormData & { _parts: [][] }) | undefined)?._parts?.length
: Object.keys(body).length) && { data: body })
data: processBody(body)
})
.then(response => {
return Promise.resolve({

View File

@@ -1,56 +1,38 @@
import { getAccountStorage } from '@utils/storage/actions'
const features = [
{
feature: 'account_follow_notify',
version: 3.3
},
{
feature: 'notification_type_status',
version: 3.3
},
{
feature: 'account_return_suspended',
version: 3.3
},
{
feature: 'edit_post',
version: 3.5
},
{
feature: 'deprecate_auth_follow',
version: 3.5
},
{
feature: 'notification_type_update',
version: 3.5
},
{
feature: 'notification_type_admin_signup',
version: 3.5
},
{
feature: 'notification_types_positive_filter',
version: 3.5
},
{
feature: 'trends_new_path',
version: 3.5
},
{
feature: 'follow_tags',
version: 4.0
},
{
feature: 'notification_type_admin_report',
version: 4.0
},
{
feature: 'filter_server_side',
version: 4.0
}
type Features =
| 'account_follow_notify'
| 'notification_type_status'
| 'account_return_suspended'
| 'edit_post'
| 'deprecate_auth_follow'
| 'notification_type_update'
| 'notification_type_admin_signup'
| 'notification_types_positive_filter'
| 'trends_new_path'
| 'follow_tags'
| 'notification_type_admin_report'
| 'filter_server_side'
| 'instance_new_path'
| 'edit_media_details'
const features: { feature: Features; version: number }[] = [
{ feature: 'account_follow_notify', version: 3.3 },
{ feature: 'notification_type_status', version: 3.3 },
{ feature: 'account_return_suspended', version: 3.3 },
{ feature: 'edit_post', version: 3.5 },
{ feature: 'deprecate_auth_follow', version: 3.5 },
{ feature: 'notification_type_update', version: 3.5 },
{ feature: 'notification_type_admin_signup', version: 3.5 },
{ feature: 'notification_types_positive_filter', version: 3.5 },
{ feature: 'trends_new_path', version: 3.5 },
{ feature: 'follow_tags', version: 4.0 },
{ feature: 'notification_type_admin_report', version: 4.0 },
{ feature: 'filter_server_side', version: 4.0 },
{ feature: 'instance_new_path', version: 4.0 },
{ feature: 'edit_media_details', version: 4.1 }
]
export const featureCheck = (feature: string, v?: string): boolean =>
export const featureCheck = (feature: Features, v?: string): boolean =>
(features.find(f => f.feature === feature)?.version || 999) <=
parseFloat(v || getAccountStorage.string('version'))

View File

@@ -157,6 +157,7 @@ export type TabMeStackParamList = {
key: string // To update title after successful mutation
}
'Tab-Me-List-List': undefined
'Tab-Me-Preferences': undefined
'Tab-Me-Profile': undefined
'Tab-Me-Push': undefined
'Tab-Me-Settings': undefined

View File

@@ -19,7 +19,7 @@ const usePreferencesQuery = (params?: {
...params?.options,
staleTime: Infinity,
cacheTime: Infinity,
initialData: getAccountStorage.object('preferences'),
placeholderData: getAccountStorage.object('preferences'),
onSuccess: data => setAccountStorage([{ key: 'preferences', value: data }])
})
}

545
yarn.lock
View File

@@ -2276,15 +2276,15 @@ __metadata:
languageName: node
linkType: hard
"@mattermost/react-native-paste-input@npm:^0.5.2":
version: 0.5.2
resolution: "@mattermost/react-native-paste-input@npm:0.5.2"
"@mattermost/react-native-paste-input@npm:^0.6.0":
version: 0.6.0
resolution: "@mattermost/react-native-paste-input@npm:0.6.0"
dependencies:
deprecated-react-native-prop-types: ^2.3.0
semver: 7.3.8
peerDependencies:
react: "*"
react-native: "*"
checksum: 85def4f7e41d5331061160889b1365fa822472df291f8e58dcabaed966623826ddb56451ae90e5658ab6a4727359672027dc5ca4fe78082adc769cd58fe88c29
checksum: 95fe8d9652f80793a245ad3a6b3cfebc152ea9a0243982507d3ac83844e6ca21723e62337fa3db7690af33d9f9427ad097c75863793b55321c0a0d55f53f7a11
languageName: node
linkType: hard
@@ -2744,12 +2744,12 @@ __metadata:
languageName: node
linkType: hard
"@react-native-camera-roll/camera-roll@npm:^5.2.1":
version: 5.2.1
resolution: "@react-native-camera-roll/camera-roll@npm:5.2.1"
"@react-native-camera-roll/camera-roll@npm:^5.2.3":
version: 5.2.3
resolution: "@react-native-camera-roll/camera-roll@npm:5.2.3"
peerDependencies:
react-native: ">=0.59"
checksum: db901554170cced81db4b01c0e89324905fe4c6915a41e4cf4b6d1fa35f5894d18d1d734304d516824bff434784e4b571e9fa379e850f8dd4d42a28e3eab9eee
checksum: 791028c52e1cadade5eebbb19ad5815273969e187d0325326c8e38439023c10aff3caed3bedf956c1acebf6b6d8471f4c75373a45bf860d9b18c37537e68247c
languageName: node
linkType: hard
@@ -2979,9 +2979,9 @@ __metadata:
languageName: node
linkType: hard
"@react-native-firebase/app@npm:^16.5.0":
version: 16.5.0
resolution: "@react-native-firebase/app@npm:16.5.0"
"@react-native-firebase/app@npm:^16.5.2":
version: 16.5.2
resolution: "@react-native-firebase/app@npm:16.5.2"
dependencies:
"@expo/config-plugins": ^5.0.4
opencollective-postinstall: ^2.0.1
@@ -2989,7 +2989,7 @@ __metadata:
peerDependencies:
react: "*"
react-native: "*"
checksum: 2eab11544f8b4e932127119b6485e43788214df8264f1f84b06695ad1ca0ae88e9969c9e8d8005ab986637223991617960b1556dee43453cc38716d537d9c81a
checksum: 8fd7dd614523f53e34e7488c7baf9cb279db1e0db8e0a3ab0aabc71a77c054af7876dc070e4c86ffb0406bae2fb240495954e95891a7047ed1c6e74f4a4de716
languageName: node
linkType: hard
@@ -3010,17 +3010,24 @@ __metadata:
languageName: node
linkType: hard
"@react-native/normalize-color@npm:*, @react-native/normalize-color@npm:^2.0.0":
"@react-native/normalize-color@npm:2.0.0":
version: 2.0.0
resolution: "@react-native/normalize-color@npm:2.0.0"
checksum: 2da373297f0d22b700edb9ab1b2cca34684e94a5dfe172e1cfd114e74ac17e139e802bc671e9868e0a580190eccbf3fa804f67be8cc1d9cbd0e216e994495931
languageName: node
linkType: hard
"@react-native/normalize-color@npm:^2.0.0":
version: 2.1.0
resolution: "@react-native/normalize-color@npm:2.1.0"
checksum: 8ccbd40b3c7629f1dc97b3e9aadd95fd3507fcf2e37535a6299a70436ab891c34cbdc4240b07380553d6e85dd909e23d5773b5be1da2906b026312e0b0768838
languageName: node
linkType: hard
"@react-native/normalize-color@npm:2.0.0":
version: 2.0.0
resolution: "@react-native/normalize-color@npm:2.0.0"
checksum: 2da373297f0d22b700edb9ab1b2cca34684e94a5dfe172e1cfd114e74ac17e139e802bc671e9868e0a580190eccbf3fa804f67be8cc1d9cbd0e216e994495931
"@react-native/normalize-colors@npm:*":
version: 0.72.0
resolution: "@react-native/normalize-colors@npm:0.72.0"
checksum: c8ec577663394a3390eb34c3cd531350521172bcfad7de309ab111e5f9e3d27c966d4a4387f00972302107be3d8cad584c5794ccfa30939aecc56162e4ddbe25
languageName: node
linkType: hard
@@ -3031,11 +3038,11 @@ __metadata:
languageName: node
linkType: hard
"@react-navigation/bottom-tabs@npm:^6.5.2":
version: 6.5.2
resolution: "@react-navigation/bottom-tabs@npm:6.5.2"
"@react-navigation/bottom-tabs@npm:^6.5.3":
version: 6.5.3
resolution: "@react-navigation/bottom-tabs@npm:6.5.3"
dependencies:
"@react-navigation/elements": ^1.3.12
"@react-navigation/elements": ^1.3.13
color: ^4.2.3
warn-once: ^0.1.0
peerDependencies:
@@ -3044,13 +3051,13 @@ __metadata:
react-native: "*"
react-native-safe-area-context: ">= 3.0.0"
react-native-screens: ">= 3.0.0"
checksum: 166fdf793f7e7976dba0e3304ecf710b11b3366f1b61385a884bfbc16a074cc6ee014aab3a323bf90168a3bf95868df4e6c55c366150382440644c57872daa9b
checksum: 7e222f39035e84d8bc98ba4937fea0e0ece1307c85b7102a6e3f19ce5b2550cfc83c1c1b68ef6e885b3d325863df442ca524d5ab34c262837cea179366383358
languageName: node
linkType: hard
"@react-navigation/core@npm:^6.4.5":
version: 6.4.5
resolution: "@react-navigation/core@npm:6.4.5"
"@react-navigation/core@npm:^6.4.6":
version: 6.4.6
resolution: "@react-navigation/core@npm:6.4.6"
dependencies:
"@react-navigation/routers": ^6.1.6
escape-string-regexp: ^4.0.0
@@ -3060,27 +3067,27 @@ __metadata:
use-latest-callback: ^0.1.5
peerDependencies:
react: "*"
checksum: 90d0153aff2ab85e4b97cda1bb93626f4e8e0a2d248e67276c6953df52504efbc65672fbdbdbf335d31a941c551360db1eb77de94b58836fced13bf048ed0912
checksum: 0e77504d333a989bbdfe6377c5d840ad5a422810aabc54775f80c6023d2680af722b6b73882483578f7f58073625580a37f88cbe275de2971fa96987d9465ff1
languageName: node
linkType: hard
"@react-navigation/elements@npm:^1.3.12":
version: 1.3.12
resolution: "@react-navigation/elements@npm:1.3.12"
"@react-navigation/elements@npm:^1.3.13":
version: 1.3.13
resolution: "@react-navigation/elements@npm:1.3.13"
peerDependencies:
"@react-navigation/native": ^6.0.0
react: "*"
react-native: "*"
react-native-safe-area-context: ">= 3.0.0"
checksum: 070bedf8caf0f35fb7c80452eff21413d41c9ac72f9017da969373f9caac74dfd3541df028a648852fe6e6881cd4158b4ddf3eda1afa1a414a9297cd475f902f
checksum: 341d8d44ecda16bbed990d40f10bedd368d579ffe1fd4568f0293f97299768167a110763170da92ff14ccff3916704dbc133465776ecdc9ac65cc8bf3caa1e31
languageName: node
linkType: hard
"@react-navigation/native-stack@npm:^6.9.7":
version: 6.9.7
resolution: "@react-navigation/native-stack@npm:6.9.7"
"@react-navigation/native-stack@npm:^6.9.8":
version: 6.9.8
resolution: "@react-navigation/native-stack@npm:6.9.8"
dependencies:
"@react-navigation/elements": ^1.3.12
"@react-navigation/elements": ^1.3.13
warn-once: ^0.1.0
peerDependencies:
"@react-navigation/native": ^6.0.0
@@ -3088,22 +3095,22 @@ __metadata:
react-native: "*"
react-native-safe-area-context: ">= 3.0.0"
react-native-screens: ">= 3.0.0"
checksum: 4b267aa6a9d2a9c5268b942b5dce681014b4c4e7da5222ce0b9704bc821e34765fb15bd65bd4ebebba42cea3d8587512ef68ba1d53eaca40f5aee235f37ee07c
checksum: 37413ffc79f442860cc1cbd51d4f9c8160e5a01826ca7e1b815e88f2a24b5df53dc6c604a76e099aa6a2ad809c093b253924095e975ad76325fdc443e6457b02
languageName: node
linkType: hard
"@react-navigation/native@npm:^6.1.1":
version: 6.1.1
resolution: "@react-navigation/native@npm:6.1.1"
"@react-navigation/native@npm:^6.1.2":
version: 6.1.2
resolution: "@react-navigation/native@npm:6.1.2"
dependencies:
"@react-navigation/core": ^6.4.5
"@react-navigation/core": ^6.4.6
escape-string-regexp: ^4.0.0
fast-deep-equal: ^3.1.3
nanoid: ^3.1.23
peerDependencies:
react: "*"
react-native: "*"
checksum: 31befabaf2aeb1d47d7635cfd0611474ad1a648cf39bb7a76c8cd9073b3a4af7a2cd0f3aaf11f7b17becd94e04e4a971ff55dec48cede7603f70abb463761798
checksum: 1bdf5339cccc1c40f780929738790f6d7d80533c80c3db80c598870f124782d83f4842b63a2bced55e040d120fc0de419d780fd906108c5358a83cde540b595e
languageName: node
linkType: hard
@@ -3116,11 +3123,11 @@ __metadata:
languageName: node
linkType: hard
"@react-navigation/stack@npm:^6.3.10":
version: 6.3.10
resolution: "@react-navigation/stack@npm:6.3.10"
"@react-navigation/stack@npm:^6.3.11":
version: 6.3.11
resolution: "@react-navigation/stack@npm:6.3.11"
dependencies:
"@react-navigation/elements": ^1.3.12
"@react-navigation/elements": ^1.3.13
color: ^4.2.3
warn-once: ^0.1.0
peerDependencies:
@@ -3130,7 +3137,7 @@ __metadata:
react-native-gesture-handler: ">= 1.0.0"
react-native-safe-area-context: ">= 3.0.0"
react-native-screens: ">= 3.0.0"
checksum: 6efac9780dceeb0de65e69634ea75b955fdc9ebab6807f455d60c1037b67bf5a0cb5708790cf7808616a2ec53159822bba766c719648fb91a2c7fd9e4cd5f51a
checksum: a826f3ed56b280e27762c08e822e88c33b395d51cfa5b277dd45f7d7ef1884674222ce316a102c36ea5f96e554f7f45673e87c0715799689f9533ddc272b0d2d
languageName: node
linkType: hard
@@ -3144,15 +3151,16 @@ __metadata:
languageName: node
linkType: hard
"@sentry/browser@npm:7.26.0":
version: 7.26.0
resolution: "@sentry/browser@npm:7.26.0"
"@sentry/browser@npm:7.29.0":
version: 7.29.0
resolution: "@sentry/browser@npm:7.29.0"
dependencies:
"@sentry/core": 7.26.0
"@sentry/types": 7.26.0
"@sentry/utils": 7.26.0
"@sentry/core": 7.29.0
"@sentry/replay": 7.29.0
"@sentry/types": 7.29.0
"@sentry/utils": 7.29.0
tslib: ^1.9.3
checksum: dc4e15f55869528ea45483323d0e332216110c14b8af625e96e395a563d4f134789bc37f0761f389284569d9e6266aa691876809fe45fcc8f33ed6cd2331ef28
checksum: 136b9d03a9ff38e72f4d8fd335f23469341d0095d1f075a36d85ef2cd6bd0763635a7e1cbc7abe14508291e88cffe549eda6016c858564b55c1d4e81ef67882f
languageName: node
linkType: hard
@@ -3190,103 +3198,116 @@ __metadata:
languageName: node
linkType: hard
"@sentry/core@npm:7.26.0":
version: 7.26.0
resolution: "@sentry/core@npm:7.26.0"
"@sentry/core@npm:7.29.0":
version: 7.29.0
resolution: "@sentry/core@npm:7.29.0"
dependencies:
"@sentry/types": 7.26.0
"@sentry/utils": 7.26.0
"@sentry/types": 7.29.0
"@sentry/utils": 7.29.0
tslib: ^1.9.3
checksum: d5f8c1e1b2463312438ec02d4878c3d248493c5cc566ef161bad0b8f5644efc40bb453e8f43d4a68b3c27b3990e33c983fcf5caa2e502ff19b5808e70ce71a57
checksum: d9330ed3528f2328b524cb237e400368dcb6c36b8afb791d28141e98ab5c0b56dc306a65cfc7164108cb5616346dabe793a39a140257f723906dc25a03b7ebcd
languageName: node
linkType: hard
"@sentry/hub@npm:7.26.0":
version: 7.26.0
resolution: "@sentry/hub@npm:7.26.0"
"@sentry/hub@npm:7.29.0":
version: 7.29.0
resolution: "@sentry/hub@npm:7.29.0"
dependencies:
"@sentry/core": 7.26.0
"@sentry/types": 7.26.0
"@sentry/utils": 7.26.0
"@sentry/core": 7.29.0
"@sentry/types": 7.29.0
"@sentry/utils": 7.29.0
tslib: ^1.9.3
checksum: be5937ca6612d53316307542c18935e0c749ce4f76eed6318a1d1d30d732c1b46f976a5bda43f751ec03c0b9eea617df689ce3683d870348e094d7d27a066da7
checksum: dc6eb1744cb68eabfa5bd1a919b0ae0df721d34b36d1b8c5e9612b9d8ab9329560b89542b9b06157e39330c5cd34a157fa8a3a7509bb4a7f007b2083c5046f80
languageName: node
linkType: hard
"@sentry/integrations@npm:7.26.0":
version: 7.26.0
resolution: "@sentry/integrations@npm:7.26.0"
"@sentry/integrations@npm:7.29.0":
version: 7.29.0
resolution: "@sentry/integrations@npm:7.29.0"
dependencies:
"@sentry/types": 7.26.0
"@sentry/utils": 7.26.0
"@sentry/types": 7.29.0
"@sentry/utils": 7.29.0
localforage: ^1.8.1
tslib: ^1.9.3
checksum: 63f8ed3e5f0de8edd8d8e05172c14f03bf4ddffcea66e5bd73869d184fbcb97b8608eed2113af6f8c77dada00c140a18ba5b2f3533a18079db72472609cc4aaa
checksum: fec2b9b7902b9b097b5453ae4c797e4efa18ac05a3b539c58d037085e12846f443ebe2e8d916a273ee4df71a29891265db5723b7fd4b5e8287fe5864cb9b2e43
languageName: node
linkType: hard
"@sentry/react-native@npm:4.12.0":
version: 4.12.0
resolution: "@sentry/react-native@npm:4.12.0"
"@sentry/react-native@npm:4.13.0":
version: 4.13.0
resolution: "@sentry/react-native@npm:4.13.0"
dependencies:
"@sentry/browser": 7.26.0
"@sentry/browser": 7.29.0
"@sentry/cli": 1.74.4
"@sentry/core": 7.26.0
"@sentry/hub": 7.26.0
"@sentry/integrations": 7.26.0
"@sentry/react": 7.26.0
"@sentry/tracing": 7.26.0
"@sentry/types": 7.26.0
"@sentry/utils": 7.26.0
"@sentry/core": 7.29.0
"@sentry/hub": 7.29.0
"@sentry/integrations": 7.29.0
"@sentry/react": 7.29.0
"@sentry/tracing": 7.29.0
"@sentry/types": 7.29.0
"@sentry/utils": 7.29.0
"@sentry/wizard": 1.4.0
peerDependencies:
react: ">=16.4.1"
react-native: ">=0.56.0"
checksum: 186b372fdb4de58e2b1ebd52b169a203e80d00cf9f250f1bb15a83e13c50c97781080228105fd9755735157c3f0c90194f63b0072b699c76af27ec34b7aeb185
checksum: 8f83147409b31854ae2c1cc485ce20a86f8f70ef83dfa52d5547f3ffa3202e5de5bf14e306dff6c280752677b813e00505d80dfa6b1bf110c4749be9f6215919
languageName: node
linkType: hard
"@sentry/react@npm:7.26.0":
version: 7.26.0
resolution: "@sentry/react@npm:7.26.0"
"@sentry/react@npm:7.29.0":
version: 7.29.0
resolution: "@sentry/react@npm:7.29.0"
dependencies:
"@sentry/browser": 7.26.0
"@sentry/types": 7.26.0
"@sentry/utils": 7.26.0
"@sentry/browser": 7.29.0
"@sentry/types": 7.29.0
"@sentry/utils": 7.29.0
hoist-non-react-statics: ^3.3.2
tslib: ^1.9.3
peerDependencies:
react: 15.x || 16.x || 17.x || 18.x
checksum: e0aa9b698da17cb7cd6d18dc8a4debdd7bd0ba6d7f0302cd00e28cc94685a1823c542cdd325027c90bbff9dfb91591a13443a5b3cdfb39a8ee1e25efb6e13de8
checksum: 022bf398f2cf43bf5e1f7340cfc02ccfc4cdc026fb3d6805e760d182bcb2601d413cf412beaa37fecbbf0dc554ce38c4a01d9bf38d1591f80cd059ee5235205d
languageName: node
linkType: hard
"@sentry/tracing@npm:7.26.0":
version: 7.26.0
resolution: "@sentry/tracing@npm:7.26.0"
"@sentry/replay@npm:7.29.0":
version: 7.29.0
resolution: "@sentry/replay@npm:7.29.0"
dependencies:
"@sentry/core": 7.26.0
"@sentry/types": 7.26.0
"@sentry/utils": 7.26.0
tslib: ^1.9.3
checksum: f28805e750d5610a3e24d368e42c8ce8aa1c384265fe16dc8911c713a9620bb6fa7e99acd916157647ba64ee19331e61928db3a22838345968880746a01610ac
"@sentry/core": 7.29.0
"@sentry/types": 7.29.0
"@sentry/utils": 7.29.0
peerDependencies:
"@sentry/browser": ">=7.24.0"
checksum: 539e18c128bb7966c9d4ea91ebd9cde6d42f42f96fa648d7ead5bff699e643f3792f57a344376586fab26f659f5e1431176faf0e12e6ea53508fd48ba928dd12
languageName: node
linkType: hard
"@sentry/types@npm:7.26.0":
version: 7.26.0
resolution: "@sentry/types@npm:7.26.0"
checksum: 79cec061f989ba635f1278f46ff8a4b4a32a0c751a51abca43c286cf1da20302e2590102c312e44b2f25f541ee5dc21d03cf676da35d634751f93dbbd01b08f3
languageName: node
linkType: hard
"@sentry/utils@npm:7.26.0":
version: 7.26.0
resolution: "@sentry/utils@npm:7.26.0"
"@sentry/tracing@npm:7.29.0":
version: 7.29.0
resolution: "@sentry/tracing@npm:7.29.0"
dependencies:
"@sentry/types": 7.26.0
"@sentry/core": 7.29.0
"@sentry/types": 7.29.0
"@sentry/utils": 7.29.0
tslib: ^1.9.3
checksum: 51bac244259f68071f93cf74955b1aafb8e6ca50f84f2a8258cb447f3a7ce6e526fd3c695b3b44b6348c3ebbdf9766894b7d85feb2868c7a67cbfc40c576849b
checksum: 7ad9040664a8c65693aba2bdd9cecc8334ce25a296c01727d38649c7141106b78c92142626ce8e44983b4272e0f411010a3df99843a1af6d4f89e4f67ce6f57e
languageName: node
linkType: hard
"@sentry/types@npm:7.29.0":
version: 7.29.0
resolution: "@sentry/types@npm:7.29.0"
checksum: 53815b66662a193cfd7024b9fb2477afb8178a771aa59f3bef10578cc940a9d7207722f9f04e2ca65a8e118cef012ac42f4936aa921aacdfc00a914bec88b009
languageName: node
linkType: hard
"@sentry/utils@npm:7.29.0":
version: 7.29.0
resolution: "@sentry/utils@npm:7.29.0"
dependencies:
"@sentry/types": 7.29.0
tslib: ^1.9.3
checksum: 9914a2129692a5713453437d75b957a18ad5a4ef8085776e5499208ad329dea8da27ee2e2b74fdc089a3831b4e2929f8e6c0f3bc75528f41023d85de5077f462
languageName: node
linkType: hard
@@ -3346,18 +3367,18 @@ __metadata:
languageName: node
linkType: hard
"@tanstack/query-core@npm:4.20.9":
version: 4.20.9
resolution: "@tanstack/query-core@npm:4.20.9"
checksum: 679551353e6d5adcae771bc78b64959a6ecf4f85c1f74952b38b18a7425374cf84dc2e461cf6048be206d8bbac265468d36231f7f9d0b6689504a0e069dd5ac6
"@tanstack/query-core@npm:4.22.4":
version: 4.22.4
resolution: "@tanstack/query-core@npm:4.22.4"
checksum: 01663a36ad7ed5c43cb7cfa8ffcdf7df4de05cf68e9991bbc339be2a656a1c94f69e0b5405dfa972cf877b09dac3cba4cbdf8c91f5dffabc46ac32ec0ce5f4bb
languageName: node
linkType: hard
"@tanstack/react-query@npm:^4.20.9":
version: 4.20.9
resolution: "@tanstack/react-query@npm:4.20.9"
"@tanstack/react-query@npm:^4.23.0":
version: 4.23.0
resolution: "@tanstack/react-query@npm:4.23.0"
dependencies:
"@tanstack/query-core": 4.20.9
"@tanstack/query-core": 4.22.4
use-sync-external-store: ^1.2.0
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
@@ -3368,7 +3389,7 @@ __metadata:
optional: true
react-native:
optional: true
checksum: 4fc953d774c5c0f7f332f014dfb2fb9865387ae6e849fdf551e2ad70f07d55fbdbc4c6afb27a1f90bce3a2348bd1adf67ab78a4bc2cdf8d3e5ff90128730b467
checksum: 166140855f8806e951e9a4ebccb5ba354eb2abc314e6b6ff696d2a1a8720e9ea868221f62d58004101e44899b61fdf57a40fe286bb13233645e292cd5567545c
languageName: node
linkType: hard
@@ -3403,13 +3424,6 @@ __metadata:
languageName: node
linkType: hard
"@types/invariant@npm:^2.2.35":
version: 2.2.35
resolution: "@types/invariant@npm:2.2.35"
checksum: af1b624057c89789ed0917838fea3d42bb0c101cc22b829a24d8777c678be3bc79d6ae05992a13bdf607b94731262467a2e62a809602ea1f7eea5e8c2242660d
languageName: node
linkType: hard
"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0":
version: 2.0.4
resolution: "@types/istanbul-lib-coverage@npm:2.0.4"
@@ -3493,16 +3507,16 @@ __metadata:
languageName: node
linkType: hard
"@types/react-native@npm:^0.70.8":
version: 0.70.8
resolution: "@types/react-native@npm:0.70.8"
"@types/react-native@npm:^0.70.9":
version: 0.70.9
resolution: "@types/react-native@npm:0.70.9"
dependencies:
"@types/react": "*"
checksum: e951992178f0a6a2a5bc5312824ad67146594840c03ec51156022eacb23e8db7be7470d0c9ad61828dbae840e531bf0cf553205b9dc290b358091329746fd094
checksum: 52b362f518c8a912174ae7cda1b20532bee11c2767794efcc0300650b750f72bcd8852435105559155f202504a742fe6e50f4e3cc4c1a9836dea9db132410ce3
languageName: node
linkType: hard
"@types/react@npm:*, @types/react@npm:16 || 17 || 18, @types/react@npm:^18.0.26":
"@types/react@npm:*, @types/react@npm:16 || 17 || 18":
version: 18.0.26
resolution: "@types/react@npm:18.0.26"
dependencies:
@@ -3513,6 +3527,17 @@ __metadata:
languageName: node
linkType: hard
"@types/react@npm:^18.0.27":
version: 18.0.27
resolution: "@types/react@npm:18.0.27"
dependencies:
"@types/prop-types": "*"
"@types/scheduler": "*"
csstype: ^3.0.2
checksum: 600fdbc39a92ea4a77047db3e12f05f67776a710f5918248c0189a59ac2a38900c9db5a5d2e433a16df528a3ecab1aa114b322cacea573bb1ca2fc0b094c52d1
languageName: node
linkType: hard
"@types/scheduler@npm:*":
version: 0.16.2
resolution: "@types/scheduler@npm:0.16.2"
@@ -3968,14 +3993,14 @@ __metadata:
languageName: node
linkType: hard
"axios@npm:^1.2.2":
version: 1.2.2
resolution: "axios@npm:1.2.2"
"axios@npm:^1.2.4":
version: 1.2.4
resolution: "axios@npm:1.2.4"
dependencies:
follow-redirects: ^1.15.0
form-data: ^4.0.0
proxy-from-env: ^1.1.0
checksum: 6e357491b38426c5720f7328ecbafca3c643b03952c052d787570672ce7a9365717c2d64db4ce97cfbee3f830fa405101e360e14d0857ef7f96a9f4d814c4e03
checksum: 3454248d72028d69e90e348542140136c1226b448529e78beae5b88e65d6c67f85a3d0eb49f089b338cb54f173671b585c95ef3339f3cb28286eb2878fe47880
languageName: node
linkType: hard
@@ -4001,6 +4026,19 @@ __metadata:
languageName: node
linkType: hard
"babel-plugin-module-resolver@npm:^5.0.0":
version: 5.0.0
resolution: "babel-plugin-module-resolver@npm:5.0.0"
dependencies:
find-babel-config: ^2.0.0
glob: ^8.0.3
pkg-up: ^3.1.0
reselect: ^4.1.7
resolve: ^1.22.1
checksum: d6880e49fc8e7bac509a2c183b4303ee054a47a80032a59a6f7844bb468ebe5e333b5dc5378443afdab5839e2da2b31a6c8d9a985a0047cd076b82bb9161cc78
languageName: node
linkType: hard
"babel-plugin-polyfill-corejs2@npm:^0.3.3":
version: 0.3.3
resolution: "babel-plugin-polyfill-corejs2@npm:0.3.3"
@@ -5227,14 +5265,14 @@ __metadata:
languageName: node
linkType: hard
"deprecated-react-native-prop-types@npm:^2.3.0":
version: 2.3.0
resolution: "deprecated-react-native-prop-types@npm:2.3.0"
"deprecated-react-native-prop-types@npm:^4.0.0":
version: 4.0.0
resolution: "deprecated-react-native-prop-types@npm:4.0.0"
dependencies:
"@react-native/normalize-color": "*"
"@react-native/normalize-colors": "*"
invariant: "*"
prop-types: "*"
checksum: d14f4be1dfe780a7fa9197a31b4a9a2b409c8cf1bf677713fd92d06733dee1043578662d1a8858541cf06164ae91d295db6e595f29bf13e808d9fb37bc58c90b
checksum: 3542c70d0379153c946bc2e23202405df4337be3dc2a96601b6696247097e13405091efa7640841f8c920d3239145d8c024e13758c65a884a207b88ec2c826aa
languageName: node
linkType: hard
@@ -5703,9 +5741,9 @@ __metadata:
languageName: node
linkType: hard
"expo-modules-autolinking@npm:1.0.1":
version: 1.0.1
resolution: "expo-modules-autolinking@npm:1.0.1"
"expo-modules-autolinking@npm:1.0.2":
version: 1.0.2
resolution: "expo-modules-autolinking@npm:1.0.2"
dependencies:
chalk: ^4.1.0
commander: ^7.2.0
@@ -5714,7 +5752,7 @@ __metadata:
fs-extra: ^9.1.0
bin:
expo-modules-autolinking: bin/expo-modules-autolinking.js
checksum: b3123a3dae6ff2a238861724db553de5fb00aa2575fbaaadc2aa44a5d6735b010b07ecb70ea6555c8c2523a923fbd51c26b39ce8f1103510e5220e6f67539d64
checksum: 61d171c1947eee2434dcee160754e6c60ce7644b2475c93cfcf465eac712c0e71c9c7b8158981031af4c16b0eace794fd5831c1f97203f1e2f3504100338e909
languageName: node
linkType: hard
@@ -5826,9 +5864,9 @@ __metadata:
languageName: node
linkType: hard
"expo@npm:^47.0.12":
version: 47.0.12
resolution: "expo@npm:47.0.12"
"expo@npm:^47.0.13":
version: 47.0.13
resolution: "expo@npm:47.0.13"
dependencies:
"@babel/runtime": ^7.14.0
"@expo/cli": 0.4.11
@@ -5844,7 +5882,7 @@ __metadata:
expo-file-system: ~15.1.1
expo-font: ~11.0.1
expo-keep-awake: ~11.0.1
expo-modules-autolinking: 1.0.1
expo-modules-autolinking: 1.0.2
expo-modules-core: 1.1.1
fbemitter: ^3.0.0
getenv: ^1.0.0
@@ -5858,7 +5896,7 @@ __metadata:
optional: true
bin:
expo: bin/cli.js
checksum: 24f7073660fb4c4c76a398d722d1fcae1ea654463faf2a730e986f884618a93618d1ee9116fe6c8199338c2e8aa716c2d389344a967824d264e2440eb7f16340
checksum: 8972f8e94777f73cc0063c18bb97a96accab32006686ff8e3f836cc3b9447e101da20fb2468533faabf9ac9b99dcdb6abe8aed5a6dbdf51b0bfd8bbdcf7ea07d
languageName: node
linkType: hard
@@ -6046,6 +6084,16 @@ __metadata:
languageName: node
linkType: hard
"find-babel-config@npm:^2.0.0":
version: 2.0.0
resolution: "find-babel-config@npm:2.0.0"
dependencies:
json5: ^2.1.1
path-exists: ^4.0.0
checksum: d110308b02fe6a6411a0cfb7fd50af6740fbf5093eada3d6ddacf99b07fc8eea4aa3475356484710a0032433029a21ce733bb3ef88fda1d6e35c29a3e4983014
languageName: node
linkType: hard
"find-cache-dir@npm:^2.0.0":
version: 2.1.0
resolution: "find-cache-dir@npm:2.1.0"
@@ -6448,6 +6496,19 @@ __metadata:
languageName: node
linkType: hard
"glob@npm:^8.0.3":
version: 8.1.0
resolution: "glob@npm:8.1.0"
dependencies:
fs.realpath: ^1.0.0
inflight: ^1.0.4
inherits: 2
minimatch: ^5.0.1
once: ^1.3.0
checksum: 92fbea3221a7d12075f26f0227abac435de868dd0736a17170663783296d0dd8d3d532a5672b4488a439bf5d7fb85cdd07c11185d6cd39184f0385cbdfb86a47
languageName: node
linkType: hard
"globals@npm:^11.1.0":
version: 11.12.0
resolution: "globals@npm:11.12.0"
@@ -6711,12 +6772,12 @@ __metadata:
languageName: node
linkType: hard
"i18next@npm:^22.4.8":
version: 22.4.8
resolution: "i18next@npm:22.4.8"
"i18next@npm:^22.4.9":
version: 22.4.9
resolution: "i18next@npm:22.4.9"
dependencies:
"@babel/runtime": ^7.20.6
checksum: bac5eb763ba6e2e34ff58d52da2ad8ef506d42d0be9efb4abb116d649fef4d6af097a8be1bade3439ff1a1c66c207e661212a1c7caefd405f02a738e37e7bc37
checksum: 8cce4aaced4857e006fab2c9d4adb0eb1375829e459076be79d4d3532b1be6342b7003a720e187098f17bb276bea46df8b3fc2cf21f0f3a230bd519243048d1a
languageName: node
linkType: hard
@@ -7519,6 +7580,15 @@ __metadata:
languageName: node
linkType: hard
"json5@npm:^2.1.1, json5@npm:^2.2.2":
version: 2.2.3
resolution: "json5@npm:2.2.3"
bin:
json5: lib/cli.js
checksum: 2a7436a93393830bce797d4626275152e37e877b265e94ca69c99e3d20c2b9dab021279146a39cdb700e71b2dd32a4cebd1514cd57cee102b1af906ce5040349
languageName: node
linkType: hard
"json5@npm:^2.2.1":
version: 2.2.2
resolution: "json5@npm:2.2.2"
@@ -7528,15 +7598,6 @@ __metadata:
languageName: node
linkType: hard
"json5@npm:^2.2.2":
version: 2.2.3
resolution: "json5@npm:2.2.3"
bin:
json5: lib/cli.js
checksum: 2a7436a93393830bce797d4626275152e37e877b265e94ca69c99e3d20c2b9dab021279146a39cdb700e71b2dd32a4cebd1514cd57cee102b1af906ce5040349
languageName: node
linkType: hard
"jsonfile@npm:^2.1.0":
version: 2.4.0
resolution: "jsonfile@npm:2.4.0"
@@ -9592,21 +9653,11 @@ __metadata:
"react-native-fast-image@patch:react-native-fast-image@npm%3A8.6.3#./.yarn/patches/react-native-fast-image-npm-8.6.3-03ee2d23c0.patch::locator=tooot%40workspace%3A.":
version: 8.6.3
resolution: "react-native-fast-image@patch:react-native-fast-image@npm%3A8.6.3#./.yarn/patches/react-native-fast-image-npm-8.6.3-03ee2d23c0.patch::version=8.6.3&hash=d37d57&locator=tooot%40workspace%3A."
resolution: "react-native-fast-image@patch:react-native-fast-image@npm%3A8.6.3#./.yarn/patches/react-native-fast-image-npm-8.6.3-03ee2d23c0.patch::version=8.6.3&hash=65bdbb&locator=tooot%40workspace%3A."
peerDependencies:
react: ^17 || ^18
react-native: ">=0.60.0"
checksum: e5749406ed7608d606df8a7d298a6adaeefdf1077e5349ceb51b344e1fc9de62923f0af05c753c0baa59f476be6d46aee20a20c92c7840a30d8b473a156dfec5
languageName: node
linkType: hard
"react-native-feather@npm:^1.1.2":
version: 1.1.2
resolution: "react-native-feather@npm:1.1.2"
peerDependencies:
react-native: ">=0.46"
react-native-svg: ">=5.3"
checksum: a83d421a4629d9f3afd54f96d90fe2370108e9dbc62b62e9ecc8db235533ccdd2a0edd063492f7070640666a62707b420dbd0e5eefc21b0172ded11e5a05b7b5
checksum: 09d7ccebd6075b85fc06d60093edf2611d97a6571b5bcd7d915df0316866a09d3bf9a74960a64aa75ac8901c9840f78b70aac58ff8b6ac627968259151109328
languageName: node
linkType: hard
@@ -9624,9 +9675,9 @@ __metadata:
languageName: node
linkType: hard
"react-native-gesture-handler@npm:~2.8.0":
version: 2.8.0
resolution: "react-native-gesture-handler@npm:2.8.0"
"react-native-gesture-handler@npm:~2.9.0":
version: 2.9.0
resolution: "react-native-gesture-handler@npm:2.9.0"
dependencies:
"@egjs/hammerjs": ^2.0.17
hoist-non-react-statics: ^3.3.0
@@ -9636,7 +9687,7 @@ __metadata:
peerDependencies:
react: "*"
react-native: "*"
checksum: 3dc4ab5cf160e471b07cd644e24f6384bdc4fc777f259fb12dfb42a5c9a15f84f60043ce3a1cd737f8dc563892a52566c8ab33bed0b1635f2898ac8ba75c8668
checksum: 6bfdd9d23486193424dcfb0073dd821a216c2783dde746d73a3441e920602343f09efa10261c6f09fcbcb645d029a95305c86f61997053c01ad89751c8c6d236
languageName: node
linkType: hard
@@ -9647,37 +9698,25 @@ __metadata:
languageName: node
linkType: hard
"react-native-image-picker@npm:^4.10.3":
version: 4.10.3
resolution: "react-native-image-picker@npm:4.10.3"
"react-native-image-picker@npm:^5.0.1":
version: 5.0.1
resolution: "react-native-image-picker@npm:5.0.1"
peerDependencies:
react: "*"
react-native: "*"
checksum: 1f1c5cae5950790cfbdab2e1f547cfe065de9949c7cf0102dec512f43889f586eed1c265e1ecbc88df106696650b3dc5bf936b862078906787aca7e9ca2f145c
checksum: c14eb042ed55a6edbe6d0d5b09627e6191ca730451c4086b0ea218c6cfd10645372f7eabb77141ea8f63e35bb4b8c7ed0e4e100b3cd6bba5e51c4b38581505b0
languageName: node
linkType: hard
"react-native-ios-context-menu@npm:1.15.1":
version: 1.15.1
resolution: "react-native-ios-context-menu@npm:1.15.1"
"react-native-ios-context-menu@npm:^1.15.3":
version: 1.15.3
resolution: "react-native-ios-context-menu@npm:1.15.3"
dependencies:
"@dominicstop/ts-event-emitter": ^1.1.0
peerDependencies:
react: "*"
react-native: "*"
checksum: 3925783aa849e4af817ec2d7ad9e777da87587b0c95b44f1ee509c9a9b64d8471fb925f99ea9a5573a9028517fff75c441585b703f1d944c7451c0f7a708dd6e
languageName: node
linkType: hard
"react-native-ios-context-menu@patch:react-native-ios-context-menu@npm%3A1.15.1#./.yarn/patches/react-native-ios-context-menu-npm-1.15.1-0034bfa5ba.patch::locator=tooot%40workspace%3A.":
version: 1.15.1
resolution: "react-native-ios-context-menu@patch:react-native-ios-context-menu@npm%3A1.15.1#./.yarn/patches/react-native-ios-context-menu-npm-1.15.1-0034bfa5ba.patch::version=1.15.1&hash=e3f0c8&locator=tooot%40workspace%3A."
dependencies:
"@dominicstop/ts-event-emitter": ^1.1.0
peerDependencies:
react: "*"
react-native: "*"
checksum: ad6bcca2cb3816bc6c52922540cb83e02a5a5217347293e8e4d710742c533afbd244cfd8d3fbe7cf453ba0715435987168bfc1326efec841422ea70a1c9f4a6a
checksum: 5c587fe95296b8ae5d93caa98a9816c56425755ba3a113230a8eba70b1eb1e117aa793a1b043e7970eca8d51a32a52695947ffca7555349688bd8723a72df4c6
languageName: node
linkType: hard
@@ -9744,13 +9783,13 @@ __metadata:
languageName: node
linkType: hard
"react-native-reanimated@npm:^2.13.0":
version: 2.13.0
resolution: "react-native-reanimated@npm:2.13.0"
"react-native-reanimated@npm:^2.14.4":
version: 2.14.4
resolution: "react-native-reanimated@npm:2.14.4"
dependencies:
"@babel/plugin-transform-object-assign": ^7.16.7
"@babel/preset-typescript": ^7.16.7
"@types/invariant": ^2.2.35
convert-source-map: ^1.7.0
invariant: ^2.2.4
lodash.isequal: ^4.5.0
setimmediate: ^1.0.5
@@ -9759,30 +9798,30 @@ __metadata:
"@babel/core": ^7.0.0-0
react: "*"
react-native: "*"
checksum: 260249012b2e9d19f700bf7817b349c2643f71717b2a50a9da6e37e44eeadbbeee2bc02403f32e6a31617555a8b3ad5aabcbbac72300962908b32e14babbe503
checksum: ec24225a145a8636065b464660256bed99ba5f50c7f6c74899838f5563e59a342ea217c285a06be8bdd5549e2faaf1ebdac6986011a767ba814a4cf469ed9bdb
languageName: node
linkType: hard
"react-native-safe-area-context@npm:^4.4.1":
version: 4.4.1
resolution: "react-native-safe-area-context@npm:4.4.1"
"react-native-safe-area-context@npm:^4.5.0":
version: 4.5.0
resolution: "react-native-safe-area-context@npm:4.5.0"
peerDependencies:
react: "*"
react-native: "*"
checksum: ef7c41ea59a34b114c6481fb130e66ef85e8d5b88acb46279131367761ca9fbf22cd310fe613f49b6c9b56dbd83e044be640f0532eda1d3856bf708e96335a35
checksum: 958df1d20492aa89c23d746f88409a3a3bd1b0d397c80310a4b0bbec9888cbbeb7579c9c92dad46841e2e6536491806206228ba009b7c8af970670aef8273a30
languageName: node
linkType: hard
"react-native-screens@npm:^3.18.2":
version: 3.18.2
resolution: "react-native-screens@npm:3.18.2"
"react-native-screens@npm:^3.19.0":
version: 3.19.0
resolution: "react-native-screens@npm:3.19.0"
dependencies:
react-freeze: ^1.0.0
warn-once: ^0.1.0
peerDependencies:
react: "*"
react-native: "*"
checksum: 8f7202baced736220710138469aea2c7b543662d820eb47170bfc98a0503f8c764d7509596ccbcc76cac6158e47a2c029444d6e1f78c20e98bcafeda15027ac1
checksum: 3a0116bf0628a735bdb87d7e4648f4bbac278152599a2bdd973e4dec92f87cb2c805dd7adb844d01236c7c92bab017ea8de59bea44d9f58397fddb6f9f3077c5
languageName: node
linkType: hard
@@ -9800,16 +9839,16 @@ __metadata:
languageName: node
linkType: hard
"react-native-svg@npm:^13.6.0":
version: 13.6.0
resolution: "react-native-svg@npm:13.6.0"
"react-native-svg@npm:^13.7.0":
version: 13.7.0
resolution: "react-native-svg@npm:13.7.0"
dependencies:
css-select: ^5.1.0
css-tree: ^1.1.3
peerDependencies:
react: "*"
react-native: "*"
checksum: 6d9b43d12c885982e69fe81d0bccc9b417d977782d4f66ef6964eb33d87ebc79c0a7b7b2dcae60be2857a9ce9178efe35e28de1bc9da92a69bc736177d507770
checksum: f3609dbb9d2614323914a8cc5ae11092aacb3a140e6d5ff57b255ddb6a9d2dc2efd5c28f65c6232e0b7228ec3231359540a7fa11ec92f944e6e98d570b147483
languageName: node
linkType: hard
@@ -10181,7 +10220,7 @@ __metadata:
languageName: node
linkType: hard
"reselect@npm:^4.0.0":
"reselect@npm:^4.0.0, reselect@npm:^4.1.7":
version: 4.1.7
resolution: "reselect@npm:4.1.7"
checksum: 738d8e2b8f0dca154ad29de6a209c9fbca2d70ae6788fd85df87f2c74b95a65bbf2d16d43a9e2faff39de34d17a29d706ba08a6b2ee5660c09589edbd19af7e1
@@ -10209,7 +10248,7 @@ __metadata:
languageName: node
linkType: hard
"resolve@npm:^1.13.1, resolve@npm:^1.14.2":
"resolve@npm:^1.13.1, resolve@npm:^1.14.2, resolve@npm:^1.22.1":
version: 1.22.1
resolution: "resolve@npm:1.22.1"
dependencies:
@@ -10231,7 +10270,7 @@ __metadata:
languageName: node
linkType: hard
"resolve@patch:resolve@^1.13.1#~builtin<compat/resolve>, resolve@patch:resolve@^1.14.2#~builtin<compat/resolve>":
"resolve@patch:resolve@^1.13.1#~builtin<compat/resolve>, resolve@patch:resolve@^1.14.2#~builtin<compat/resolve>, resolve@patch:resolve@^1.22.1#~builtin<compat/resolve>":
version: 1.22.1
resolution: "resolve@patch:resolve@npm%3A1.22.1#~builtin<compat/resolve>::version=1.22.1&hash=c3c19d"
dependencies:
@@ -10460,6 +10499,17 @@ __metadata:
languageName: node
linkType: hard
"semver@npm:7.3.8, semver@npm:^7.3.5":
version: 7.3.8
resolution: "semver@npm:7.3.8"
dependencies:
lru-cache: ^6.0.0
bin:
semver: bin/semver.js
checksum: ba9c7cbbf2b7884696523450a61fee1a09930d888b7a8d7579025ad93d459b2d1949ee5bbfeb188b2be5f4ac163544c5e98491ad6152df34154feebc2cc337c1
languageName: node
linkType: hard
"semver@npm:^5.5.0, semver@npm:^5.6.0":
version: 5.7.1
resolution: "semver@npm:5.7.1"
@@ -10478,17 +10528,6 @@ __metadata:
languageName: node
linkType: hard
"semver@npm:^7.3.5":
version: 7.3.8
resolution: "semver@npm:7.3.8"
dependencies:
lru-cache: ^6.0.0
bin:
semver: bin/semver.js
checksum: ba9c7cbbf2b7884696523450a61fee1a09930d888b7a8d7579025ad93d459b2d1949ee5bbfeb188b2be5f4ac163544c5e98491ad6152df34154feebc2cc337c1
languageName: node
linkType: hard
"send@npm:0.18.0, send@npm:^0.18.0":
version: 0.18.0
resolution: "send@npm:0.18.0"
@@ -11356,38 +11395,39 @@ __metadata:
"@formatjs/intl-numberformat": ^8.3.3
"@formatjs/intl-pluralrules": ^5.1.8
"@formatjs/intl-relativetimeformat": ^11.1.8
"@mattermost/react-native-paste-input": ^0.5.2
"@mattermost/react-native-paste-input": ^0.6.0
"@neverdull-agency/expo-unlimited-secure-store": ^1.0.10
"@react-native-async-storage/async-storage": ~1.17.11
"@react-native-camera-roll/camera-roll": ^5.2.1
"@react-native-camera-roll/camera-roll": ^5.2.3
"@react-native-clipboard/clipboard": ^1.11.1
"@react-native-community/blur": ^4.3.0
"@react-native-community/netinfo": 9.3.7
"@react-native-community/segmented-control": ^2.2.2
"@react-native-firebase/app": ^16.5.0
"@react-native-firebase/app": ^16.5.2
"@react-native-menu/menu": ^0.7.3
"@react-navigation/bottom-tabs": ^6.5.2
"@react-navigation/native": ^6.1.1
"@react-navigation/native-stack": ^6.9.7
"@react-navigation/stack": ^6.3.10
"@sentry/react-native": 4.12.0
"@react-navigation/bottom-tabs": ^6.5.3
"@react-navigation/native": ^6.1.2
"@react-navigation/native-stack": ^6.9.8
"@react-navigation/stack": ^6.3.11
"@sentry/react-native": 4.13.0
"@sharcoux/slider": ^6.1.1
"@tanstack/react-query": ^4.20.9
"@tanstack/react-query": ^4.23.0
"@types/diff": ^5.0.2
"@types/linkify-it": ^3.0.2
"@types/lodash": ^4.14.191
"@types/react": ^18.0.26
"@types/react": ^18.0.27
"@types/react-dom": ^18.0.10
"@types/react-native": ^0.70.8
"@types/react-native": ^0.70.9
"@types/react-native-share-menu": ^5.0.2
"@types/url-parse": ^1.4.8
axios: ^1.2.2
babel-plugin-module-resolver: ^4.1.0
axios: ^1.2.4
babel-plugin-module-resolver: ^5.0.0
babel-plugin-transform-remove-console: ^6.9.4
chalk: ^4.1.2
deprecated-react-native-prop-types: ^4.0.0
diff: ^5.1.0
dotenv: ^16.0.3
expo: ^47.0.12
expo: ^47.0.13
expo-auth-session: ^3.8.0
expo-av: ^13.1.0
expo-constants: ^14.1.0
@@ -11406,7 +11446,7 @@ __metadata:
expo-video-thumbnails: ^7.1.0
expo-web-browser: ~12.0.0
htmlparser2: ^8.0.1
i18next: ^22.4.8
i18next: ^22.4.9
linkify-it: ^4.0.1
lodash: ^4.17.21
react: ^18.2.0
@@ -11417,21 +11457,20 @@ __metadata:
react-native-blurhash: ^1.1.10
react-native-clean-project: ^4.0.1
react-native-fast-image: ^8.6.3
react-native-feather: ^1.1.2
react-native-flash-message: ^0.4.0
react-native-gesture-handler: ~2.8.0
react-native-image-picker: ^4.10.3
react-native-ios-context-menu: ^1.15.1
react-native-gesture-handler: ~2.9.0
react-native-image-picker: ^5.0.1
react-native-ios-context-menu: ^1.15.3
react-native-language-detection: ^0.2.2
react-native-mmkv: ^2.5.1
react-native-pager-view: ^6.1.2
react-native-quick-base64: ^2.0.5
react-native-reanimated: ^2.13.0
react-native-reanimated: ^2.14.4
react-native-reanimated-zoom: ^0.3.3
react-native-safe-area-context: ^4.4.1
react-native-screens: ^3.18.2
react-native-safe-area-context: ^4.5.0
react-native-screens: ^3.19.0
react-native-share-menu: ^6.0.0
react-native-svg: ^13.6.0
react-native-svg: ^13.7.0
react-native-swipe-list-view: ^3.2.9
react-native-tab-view: ^3.3.4
react-redux: ^8.0.5