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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -188,7 +188,7 @@ const EmojisList = () => {
paddingRight: StyleConstants.Spacing.S 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> </View>
<TextInput <TextInput
style={{ style={{
@@ -214,7 +214,7 @@ const EmojisList = () => {
emojisDispatch({ type: 'target', payload: -1 }) 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> </Pressable>
</View> </View>
<SectionList <SectionList

View File

@@ -1,21 +1,19 @@
import Icon from '@components/Icon' import Icon, { IconName } from '@components/Icon'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import React from 'react' import React from 'react'
import { Pressable } from 'react-native' import { Pressable } from 'react-native'
export interface Props { export type Props = {
type?: 'icon' | 'text'
content?: string
native?: boolean native?: boolean
background?: boolean background?: boolean
onPress: () => void onPress: () => void
} } & ({ type?: undefined; content?: IconName } | { type: 'text'; content: string })
const HeaderLeft: React.FC<Props> = ({ const HeaderLeft: React.FC<Props> = ({
type = 'icon', type,
content, content,
native = true, native = true,
background = false, background = false,
@@ -25,18 +23,18 @@ const HeaderLeft: React.FC<Props> = ({
const children = () => { const children = () => {
switch (type) { switch (type) {
case 'icon':
return (
<Icon
color={colors.primaryDefault}
name={content || 'ChevronLeft'}
size={StyleConstants.Spacing.M * 1.25}
/>
)
case 'text': case 'text':
return ( return (
<CustomText fontStyle='M' style={{ color: colors.primaryDefault }} children={content} /> <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, minHeight: 44,
minWidth: 44, minWidth: 44,
marginLeft: native ? -StyleConstants.Spacing.S : StyleConstants.Spacing.S, marginLeft: native ? -StyleConstants.Spacing.S : StyleConstants.Spacing.S,
...(type === 'icon' && { ...(type === undefined && {
borderRadius: 100 borderRadius: 100
}), }),
...(type === 'text' && { ...(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 { Loading } from '@components/Loading'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
@@ -6,13 +6,11 @@ import { useTheme } from '@utils/styles/ThemeManager'
import React from 'react' import React from 'react'
import { AccessibilityProps, Pressable, View } from 'react-native' import { AccessibilityProps, Pressable, View } from 'react-native'
export interface Props { export type Props = {
accessibilityLabel?: string accessibilityLabel?: string
accessibilityHint?: string accessibilityHint?: string
accessibilityState?: AccessibilityProps['accessibilityState'] accessibilityState?: AccessibilityProps['accessibilityState']
type?: 'icon' | 'text'
content: string
native?: boolean native?: boolean
background?: boolean background?: boolean
@@ -21,7 +19,7 @@ export interface Props {
destructive?: boolean destructive?: boolean
onPress: () => void onPress: () => void
} } & ({ type?: undefined; content: IconName } | { type: 'text'; content: string })
const HeaderRight: React.FC<Props> = ({ const HeaderRight: React.FC<Props> = ({
// Accessibility - Start // Accessibility - Start
@@ -29,7 +27,7 @@ const HeaderRight: React.FC<Props> = ({
accessibilityHint, accessibilityHint,
accessibilityState, accessibilityState,
// Accessibility - End // Accessibility - End
type = 'icon', type,
content, content,
native = true, native = true,
background = false, background = false,
@@ -38,7 +36,7 @@ const HeaderRight: React.FC<Props> = ({
destructive = false, destructive = false,
onPress onPress
}) => { }) => {
const { colors, theme } = useTheme() const { colors } = useTheme()
const loadingSpinkit = () => const loadingSpinkit = () =>
loading ? ( loading ? (
@@ -49,18 +47,6 @@ const HeaderRight: React.FC<Props> = ({
const children = () => { const children = () => {
switch (type) { 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': case 'text':
return ( return (
<> <>
@@ -80,6 +66,18 @@ const HeaderRight: React.FC<Props> = ({
{loadingSpinkit()} {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, minHeight: 44,
minWidth: 44, minWidth: 44,
marginRight: native ? -StyleConstants.Spacing.S : StyleConstants.Spacing.S, marginRight: native ? -StyleConstants.Spacing.S : StyleConstants.Spacing.S,
...(type === 'icon' && { ...(type === undefined && {
borderRadius: 100 borderRadius: 100
}), }),
...(type === 'text' && { ...(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 { AccessibilityProps, StyleProp, View, ViewStyle } from 'react-native'
import * as FeatherIcon from 'react-native-feather'
export type IconName = keyof typeof FeatherNames
export interface Props { export interface Props {
accessibilityLabel?: AccessibilityProps['accessibilityLabel'] accessibilityLabel?: AccessibilityProps['accessibilityLabel']
name: string name: IconName
size: number size: number
color: string color: string
fill?: string
strokeWidth?: number
style?: StyleProp<ViewStyle> style?: StyleProp<ViewStyle>
crossOut?: boolean crossOut?: boolean
} }
@@ -19,8 +20,6 @@ const Icon: React.FC<Props> = ({
name, name,
size, size,
color, color,
fill,
strokeWidth = 2,
style, style,
crossOut = false crossOut = false
}) => { }) => {
@@ -37,13 +36,7 @@ const Icon: React.FC<Props> = ({
} }
]} ]}
> >
{createElement(FeatherIcon[name], { <Feather name={name} size={size} color={color} />
width: size,
height: size,
color,
fill,
strokeWidth
})}
{crossOut ? ( {crossOut ? (
<View <View
style={{ style={{
@@ -51,7 +44,7 @@ const Icon: React.FC<Props> = ({
transform: [{ rotate: '45deg' }], transform: [{ rotate: '45deg' }],
width: size * 1.35, width: size * 1.35,
borderBottomColor: color, borderBottomColor: color,
borderBottomWidth: strokeWidth borderBottomWidth: 2
}} }}
/> />
) : null} ) : null}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -165,7 +165,7 @@ const TimelineActions: React.FC = () => {
const childrenReply = () => ( 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 ? ( {status.replies_count > 0 ? (
<CustomText <CustomText
fontStyle='S' fontStyle='S'
@@ -186,7 +186,7 @@ const TimelineActions: React.FC = () => {
return ( return (
<> <>
<Icon <Icon
name='Repeat' name='repeat'
color={disabled ? colors.disabled : color(status.reblogged)} color={disabled ? colors.disabled : color(status.reblogged)}
crossOut={disabled} crossOut={disabled}
size={StyleConstants.Font.Size.L} size={StyleConstants.Font.Size.L}
@@ -212,7 +212,7 @@ const TimelineActions: React.FC = () => {
const color = (state: boolean) => (state ? colors.red : colors.secondary) const color = (state: boolean) => (state ? colors.red : colors.secondary)
return ( 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 ? ( {status.favourites_count > 0 ? (
<CustomText <CustomText
fontStyle='S' fontStyle='S'
@@ -227,7 +227,7 @@ const TimelineActions: React.FC = () => {
const childrenBookmark = () => { const childrenBookmark = () => {
const color = (state: boolean) => (state ? colors.yellow : colors.secondary) const color = (state: boolean) => (state ? colors.yellow : colors.secondary)
return ( 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 <Button
type='icon' type='icon'
content='EyeOff' content='eye-off'
round round
overlay overlay
onPress={() => { onPress={() => {

View File

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

View File

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

View File

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

View File

@@ -87,7 +87,7 @@ const HeaderConversation = ({ conversation }: Props) => {
id: conversation.id 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>
) )

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -153,8 +153,7 @@
"altText": { "altText": {
"heading": "Describe media for the visually impaired", "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." "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": { "draftsList": {

View File

@@ -69,6 +69,9 @@
"push": { "push": {
"name": "Push Notification" "name": "Push Notification"
}, },
"preferences": {
"name": "Preferences"
},
"profile": { "profile": {
"name": "Edit Profile" "name": "Edit Profile"
}, },
@@ -84,9 +87,6 @@
"settings": { "settings": {
"name": "App Settings" "name": "App Settings"
}, },
"webSettings": {
"name": "More Account Settings"
},
"switch": { "switch": {
"name": "Switch Account" "name": "Switch Account"
} }
@@ -125,6 +125,37 @@
"message": "This action is not recoverable." "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": { "profile": {
"feedback": { "feedback": {
"succeed": "{{type}} updated", "succeed": "{{type}} updated",
@@ -150,17 +181,6 @@
"total_one": "{{count}} field", "total_one": "{{count}} field",
"total_other": "{{count}} fields" "total_other": "{{count}} fields"
}, },
"visibility": {
"title": "Posting Visibility",
"options": {
"public": "Public",
"unlisted": "Unlisted",
"private": "Followers only"
}
},
"sensitive": {
"title": "Posting Media Sensitive"
},
"lock": { "lock": {
"title": "Lock Account", "title": "Lock Account",
"description": "Requires you to manually approve followers" "description": "Requires you to manually approve followers"

View File

@@ -40,7 +40,7 @@ const ComposeDraftsList: React.FC<ScreenComposeStackScreenProps<'Screen-Compose-
navigation.setOptions({ navigation.setOptions({
title: t('content.draftsList.header.title'), title: t('content.draftsList.header.title'),
headerLeft: () => ( 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 <Icon
name='AlertTriangle' name='alert-triangle'
color={colors.secondary} color={colors.secondary}
size={StyleConstants.Font.Size.M} size={StyleConstants.Font.Size.M}
style={{ marginRight: StyleConstants.Spacing.S }} style={{ marginRight: StyleConstants.Spacing.S }}
@@ -187,7 +187,7 @@ const ComposeDraftsList: React.FC<ScreenComposeStackScreenProps<'Screen-Compose-
}} }}
children={ children={
<Icon <Icon
name='Trash' name='trash'
size={StyleConstants.Font.Size.L} size={StyleConstants.Font.Size.L}
color={colors.primaryOverlay} color={colors.primaryOverlay}
/> />

View File

@@ -1,12 +1,14 @@
import haptics from '@components/haptics' import haptics from '@components/haptics'
import { HeaderLeft, HeaderRight } from '@components/Header' import { HeaderLeft, HeaderRight } from '@components/Header'
import CustomText from '@components/Text'
import apiInstance from '@utils/api/instance' import apiInstance from '@utils/api/instance'
import { ScreenComposeStackScreenProps } from '@utils/navigation/navigators' 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 React, { useContext, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next' 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 { SafeAreaView } from 'react-native-safe-area-context'
import ComposeEditAttachmentRoot from './EditAttachment/Root'
import ComposeContext from './utils/createContext' import ComposeContext from './utils/createContext'
const ComposeEditAttachment: React.FC< const ComposeEditAttachment: React.FC<
@@ -17,26 +19,36 @@ const ComposeEditAttachment: React.FC<
params: { index } params: { index }
} }
}) => { }) => {
const { colors } = useTheme()
const { t } = useTranslation('screenCompose') const { t } = useTranslation('screenCompose')
const { composeState } = useContext(ComposeContext) const { composeState, composeDispatch } = useContext(ComposeContext)
const [isSubmitting, setIsSubmitting] = useState(false) 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(() => { useEffect(() => {
navigation.setOptions({ navigation.setOptions({
title: t('content.editAttachment.header.title'), title: t('content.editAttachment.header.title'),
headerLeft: () => ( headerLeft: () => (
<HeaderLeft type='icon' content='ChevronDown' onPress={() => navigation.goBack()} /> <HeaderLeft content='chevron-down' onPress={() => navigation.goBack()} />
), ),
headerRight: () => ( headerRight: () => (
<HeaderRight <HeaderRight
accessibilityLabel={t('content.editAttachment.header.right.accessibilityLabel')} accessibilityLabel={t('content.editAttachment.header.right.accessibilityLabel')}
type='icon' content='save'
content='Save'
loading={isSubmitting} loading={isSubmitting}
onPress={() => { onPress={() => {
if (composeState.type === 'edit') {
composeDispatch({ type: 'attachment/edit', payload: { ...theAttachment } })
navigation.goBack()
return
}
setIsSubmitting(true) setIsSubmitting(true)
const formData = new FormData() const formData = new FormData()
if (theAttachment.description) { if (theAttachment.description) {
@@ -80,8 +92,53 @@ const ComposeEditAttachment: React.FC<
behavior={Platform.OS === 'ios' ? 'padding' : 'height'} behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={{ flex: 1 }} style={{ flex: 1 }}
> >
<SafeAreaView style={{ flex: 1 }} edges={['left', 'right', 'bottom']}> <SafeAreaView
<ComposeEditAttachmentRoot index={index} /> 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> </SafeAreaView>
</KeyboardAvoidingView> </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 = () => { const visibilityIcon = () => {
switch (composeState.visibility) { switch (composeState.visibility) {
case 'public': case 'public':
return 'Globe' return 'globe'
case 'unlisted': case 'unlisted':
return 'Unlock' return 'unlock'
case 'private': case 'private':
return 'Lock' return 'lock'
case 'direct': case 'direct':
return 'Mail' return 'mail'
} }
} }
const visibilityOnPress = () => { const visibilityOnPress = () => {
@@ -162,7 +162,7 @@ const ComposeActions: React.FC = () => {
}} }}
style={styles.button} style={styles.button}
onPress={attachmentOnPress} onPress={attachmentOnPress}
children={<Icon name='Camera' size={24} color={attachmentColor()} />} children={<Icon name='camera' size={24} color={attachmentColor()} />}
/> />
<Pressable <Pressable
accessibilityRole='button' accessibilityRole='button'
@@ -174,7 +174,7 @@ const ComposeActions: React.FC = () => {
}} }}
style={styles.button} style={styles.button}
onPress={pollOnPress} onPress={pollOnPress}
children={<Icon name='BarChart2' size={24} color={pollColor()} />} children={<Icon name='bar-chart-2' size={24} color={pollColor()} />}
/> />
<Pressable <Pressable
accessibilityRole='button' accessibilityRole='button'
@@ -200,7 +200,7 @@ const ComposeActions: React.FC = () => {
onPress={spoilerOnPress} onPress={spoilerOnPress}
children={ children={
<Icon <Icon
name='AlertTriangle' name='alert-triangle'
size={24} size={24}
color={composeState.spoiler.active ? colors.primaryDefault : colors.secondary} color={composeState.spoiler.active ? colors.primaryDefault : colors.secondary}
/> />
@@ -216,7 +216,7 @@ const ComposeActions: React.FC = () => {
}} }}
style={styles.button} style={styles.button}
onPress={emojiOnPress} onPress={emojiOnPress}
children={<Icon name='Smile' size={24} color={emojiColor()} />} children={<Icon name='smile' size={24} color={emojiColor()} />}
/> />
</View> </View>
) )

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
import React, { useEffect, useRef } from 'react' 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 ComposePosting from '../Posting'
import ComposeActions from './Actions' import ComposeActions from './Actions'
import ComposeDrafts from './Drafts' import ComposeDrafts from './Drafts'

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -50,7 +50,7 @@ const TabMeListAccounts: React.FC<TabMeStackScreenProps<'Tab-Me-List-Accounts'>>
children={ children={
<Button <Button
type='icon' type='icon'
content='X' content='x'
round round
onPress={() => onPress={() =>
mutation.mutate({ type: 'delete', payload: { id: params.id, accounts: [item.id] } }) 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'), : t('screenTabs:me.stacks.listEdit.name'),
headerLeft: () => ( headerLeft: () => (
<HeaderLeft <HeaderLeft
content='X' content='x'
onPress={() => { onPress={() => {
if (params.type === 'edit' ? params.payload.title !== title : title.length) { if (params.type === 'edit' ? params.payload.title !== title : title.length) {
Alert.alert(t('common:discard.title'), t('common:discard.message'), [ 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: () => (
<HeaderRight <HeaderRight
content='Save' content='save'
disabled={!title.length} disabled={!title.length}
loading={mutation.isLoading} loading={mutation.isLoading}
onPress={() => { onPress={() => {

View File

@@ -26,8 +26,8 @@ const TabMeListList: React.FC<TabMeStackScreenProps<'Tab-Me-List-List'>> = ({ na
{data?.map((list, index) => ( {data?.map((list, index) => (
<MenuRow <MenuRow
key={index} key={index}
iconFront='List' iconFront='list'
iconBack='ChevronRight' iconBack='chevron-right'
title={list.title} title={list.title}
onPress={() => navigation.navigate('Tab-Me-List', { list })} 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.Root>
<DropdownMenu.Trigger> <DropdownMenu.Trigger>
<Icon <Icon
name='MoreHorizontal' name='more-horizontal'
size={StyleConstants.Spacing.M * 1.25} size={StyleConstants.Spacing.M * 1.25}
color={colors.primaryDefault} 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({ navigation.setOptions({
headerLeft: () => ( headerLeft: () => (
<HeaderLeft <HeaderLeft
content='X' content='x'
onPress={() => { onPress={() => {
if (dirty) { if (dirty) {
Alert.alert(t('common:discard.title'), t('common:discard.message'), [ Alert.alert(t('common:discard.title'), t('common:discard.message'), [
@@ -114,7 +114,7 @@ const TabMeProfileFields: React.FC<
<HeaderRight <HeaderRight
disabled={!dirty} disabled={!dirty}
loading={status === 'loading'} loading={status === 'loading'}
content='Save' content='save'
onPress={async () => { onPress={async () => {
mutateAsync({ mutateAsync({
messageRef, messageRef,

View File

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

View File

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

View File

@@ -1,11 +1,6 @@
import { MenuContainer, MenuRow } from '@components/Menu' 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 { TabMeProfileStackScreenProps } from '@utils/navigation/navigators'
import { queryClient } from '@utils/queryHooks'
import { QueryKeyPreferences } from '@utils/queryHooks/preferences'
import { useProfileMutation, useProfileQuery } from '@utils/queryHooks/profile' import { useProfileMutation, useProfileQuery } from '@utils/queryHooks/profile'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { RefObject } from 'react' import React, { RefObject } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import FlashMessage from 'react-native-flash-message' import FlashMessage from 'react-native-flash-message'
@@ -17,19 +12,11 @@ const TabMeProfileRoot: React.FC<
messageRef: RefObject<FlashMessage> messageRef: RefObject<FlashMessage>
} }
> = ({ messageRef, navigation }) => { > = ({ messageRef, navigation }) => {
const { colors } = useTheme()
const { t } = useTranslation(['common', 'screenTabs']) const { t } = useTranslation(['common', 'screenTabs'])
const { showActionSheetWithOptions } = useActionSheet()
const { data, isFetching } = useProfileQuery() const { data, isFetching } = useProfileQuery()
const { mutateAsync } = useProfileMutation() const { mutateAsync } = useProfileMutation()
const refetchPreferences = () => {
const queryKeyPreferences: QueryKeyPreferences = ['Preferences']
queryClient.refetchQueries(queryKeyPreferences)
}
return ( return (
<ScrollView> <ScrollView>
<MenuContainer> <MenuContainer>
@@ -37,7 +24,7 @@ const TabMeProfileRoot: React.FC<
title={t('screenTabs:me.profile.root.name.title')} title={t('screenTabs:me.profile.root.name.title')}
content={data?.display_name} content={data?.display_name}
loading={isFetching} loading={isFetching}
iconBack='ChevronRight' iconBack='chevron-right'
onPress={() => { onPress={() => {
data && data &&
navigation.navigate('Tab-Me-Profile-Name', { navigation.navigate('Tab-Me-Profile-Name', {
@@ -51,7 +38,7 @@ const TabMeProfileRoot: React.FC<
title={t('screenTabs:me.profile.root.note.title')} title={t('screenTabs:me.profile.root.note.title')}
content={data?.source?.note} content={data?.source?.note}
loading={isFetching} loading={isFetching}
iconBack='ChevronRight' iconBack='chevron-right'
onPress={() => { onPress={() => {
data && data &&
navigation.navigate('Tab-Me-Profile-Note', { navigation.navigate('Tab-Me-Profile-Note', {
@@ -69,7 +56,7 @@ const TabMeProfileRoot: React.FC<
: undefined : undefined
} }
loading={isFetching} loading={isFetching}
iconBack='ChevronRight' iconBack='chevron-right'
onPress={() => { onPress={() => {
navigation.navigate('Tab-Me-Profile-Fields', { navigation.navigate('Tab-Me-Profile-Fields', {
fields: data?.source.fields fields: data?.source.fields
@@ -77,77 +64,6 @@ const TabMeProfileRoot: React.FC<
}} }}
/> />
</MenuContainer> </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> <MenuContainer>
<MenuRow <MenuRow
title={t('screenTabs:me.profile.root.lock.title')} 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`)} title={t(`screenTabs:me.profile.root.${type}.title`)}
description={t(`screenTabs:me.profile.root.${type}.description`)} description={t(`screenTabs:me.profile.root.${type}.description`)}
loading={query.isFetching || mutation.isLoading} loading={query.isFetching || mutation.isLoading}
iconBack='ChevronRight' iconBack='chevron-right'
onPress={async () => { onPress={async () => {
const image = await mediaSelector({ const image = await mediaSelector({
mediaType: 'photo', mediaType: 'photo',

View File

@@ -28,7 +28,7 @@ const TabMeProfile: React.FC<TabMeStackScreenProps<'Tab-Me-Switch'>> = ({ naviga
options={{ options={{
title: t('me.stacks.profile.name'), title: t('me.stacks.profile.name'),
headerLeft: () => ( 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 <MenuRow
title={t('me.push.howitworks')} title={t('me.push.howitworks')}
iconBack='ExternalLink' iconBack='external-link'
onPress={async () => onPress={async () =>
WebBrowser.openBrowserAsync('https://tooot.app/how-push-works', { WebBrowser.openBrowserAsync('https://tooot.app/how-push-works', {
...(await browserPackage()) ...(await browserPackage())
@@ -286,7 +286,7 @@ const TabMePush: React.FC = () => {
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding 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 <CustomText
fontStyle='M' fontStyle='M'
style={{ style={{
@@ -310,7 +310,7 @@ const TabMePush: React.FC = () => {
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding 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 <CustomText
fontStyle='M' fontStyle='M'
style={{ style={{

View File

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

View File

@@ -1,8 +1,5 @@
import { MenuContainer, MenuRow } from '@components/Menu' import { MenuContainer, MenuRow } from '@components/Menu'
import { useNavigation } from '@react-navigation/native' 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 React from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
@@ -10,34 +7,14 @@ const Settings: React.FC = () => {
const { t } = useTranslation('screenTabs') const { t } = useTranslation('screenTabs')
const navigation = useNavigation<any>() const navigation = useNavigation<any>()
const [accountActive] = useGlobalStorage.string('account.active')
return ( return (
<MenuContainer> <MenuContainer>
<MenuRow <MenuRow
iconFront='Settings' iconFront='settings'
iconBack='ChevronRight' iconBack='chevron-right'
title={t('me.stacks.settings.name')} title={t('me.stacks.settings.name')}
onPress={() => navigation.navigate('Tab-Me-Settings')} 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> </MenuContainer>
) )
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -42,6 +42,14 @@ const AccountInformationActions: React.FC = () => {
content={t('me.stacks.profile.name')} content={t('me.stacks.profile.name')}
onPress={() => navigation.navigate('Tab-Me-Profile')} 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> </View>
) )
} }
@@ -60,8 +68,8 @@ const AccountInformationActions: React.FC = () => {
<Button <Button
round round
type='icon' type='icon'
content='AtSign' content='at-sign'
style={{ marginRight: StyleConstants.Spacing.S }} style={{ flex: 1, marginRight: StyleConstants.Spacing.S }}
onPress={() => {}} onPress={() => {}}
/> />
</DropdownMenu.Trigger> </DropdownMenu.Trigger>
@@ -119,7 +127,7 @@ const styles = StyleSheet.create({
base: { base: {
alignSelf: 'flex-end', alignSelf: 'flex-end',
flexDirection: 'row', 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 { StackNavigationProp } from '@react-navigation/stack'
import navigationRef from '@utils/navigation/navigationRef' import navigationRef from '@utils/navigation/navigationRef'
import { TabLocalStackParamList } from '@utils/navigation/navigators' 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 { StyleConstants } from '@utils/styles/constants'
import React, { useContext } from 'react' import React, { useContext } from 'react'
import AccountContext from '../Context' import AccountContext from '../Context'
@@ -13,7 +13,7 @@ const AccountInformationAvatar: React.FC = () => {
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>() const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
useGlobalStorage.string('account.active') const [accountAvatarStatic] = useAccountStorage.string('auth.account.avatar_static')
return ( return (
<GracefullyImage <GracefullyImage
@@ -24,7 +24,10 @@ const AccountInformationAvatar: React.FC = () => {
width: StyleConstants.Avatar.L, width: StyleConstants.Avatar.L,
height: 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={() => { onPress={() => {
if (account) { if (account) {
if (pageMe) { if (pageMe) {

View File

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

View File

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

View File

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

View File

@@ -103,7 +103,7 @@ const ContentView: React.FC<{
paddingTop: StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M, paddingTop: StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
marginRight: StyleConstants.Spacing.S marginRight: StyleConstants.Spacing.S
}} }}
name={item.poll?.multiple ? 'Square' : 'Circle'} name={item.poll?.multiple ? 'square' : 'circle'}
size={StyleConstants.Font.Size.M} size={StyleConstants.Font.Size.M}
color={ color={
prevItem?.poll?.multiple !== item.poll?.multiple ? colors.red : colors.disabled 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 ? ( {hasRemoteContent ? (
<Icon <Icon
name='Wifi' name='wifi'
size={StyleConstants.Font.Size.M} size={StyleConstants.Font.Size.M}
color={colors.primaryDefault} color={colors.primaryDefault}
style={{ marginRight: StyleConstants.Spacing.S }} style={{ marginRight: StyleConstants.Spacing.S }}

View File

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

View File

@@ -41,13 +41,13 @@ const ScreenTabs = ({ navigation }: RootStackScreenProps<'Screen-Tabs'>) => {
}) => { }) => {
switch (route.name) { switch (route.name) {
case 'Tab-Local': case 'Tab-Local':
return <Icon name='Home' size={size} color={color} /> return <Icon name='home' size={size} color={color} />
case 'Tab-Public': case 'Tab-Public':
return <Icon name='Globe' size={size} color={color} /> return <Icon name='globe' size={size} color={color} />
case 'Tab-Compose': case 'Tab-Compose':
return <Icon name='Plus' size={size} color={color} /> return <Icon name='plus' size={size} color={color} />
case 'Tab-Notifications': case 'Tab-Notifications':
return <Icon name='Bell' size={size} color={color} /> return <Icon name='bell' size={size} color={color} />
case 'Tab-Me': case 'Tab-Me':
return ( return (
<GracefullyImage <GracefullyImage
@@ -65,7 +65,7 @@ const ScreenTabs = ({ navigation }: RootStackScreenProps<'Screen-Tabs'>) => {
/> />
) )
default: 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, headerShadowVisible: false,
headerTransparent: true, headerTransparent: true,
headerStyle: { backgroundColor: 'transparent' }, headerStyle: { backgroundColor: 'transparent' },
headerLeft: () => <HeaderLeft content='X' onPress={() => navigation.goBack()} />, headerLeft: () => <HeaderLeft content='x' onPress={() => navigation.goBack()} />,
title: t('screenAnnouncements:heading') title: t('screenAnnouncements:heading')
})} })}
/> />

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

545
yarn.lock
View File

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