mirror of https://github.com/tooot-app/app
Fixed #497
This commit is contained in:
parent
75800598c2
commit
de7498b218
|
@ -337,5 +337,3 @@ def isNewArchitectureEnabled() {
|
||||||
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
|
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
|
||||||
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
{
|
|
||||||
"project_info": {
|
|
||||||
"project_number": "661638997772",
|
|
||||||
"project_id": "xmflsct-mastodon-app",
|
|
||||||
"storage_bucket": "xmflsct-mastodon-app.appspot.com"
|
|
||||||
},
|
|
||||||
"client": [
|
|
||||||
{
|
|
||||||
"client_info": {
|
|
||||||
"mobilesdk_app_id": "1:661638997772:android:4fd02851f757f8fa9f8b29",
|
|
||||||
"android_client_info": {
|
|
||||||
"package_name": "com.xmflsct.app.tooot"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"oauth_client": [
|
|
||||||
{
|
|
||||||
"client_id": "661638997772-6aiqk97aema0rt280i7nfar3ha2mlgno.apps.googleusercontent.com",
|
|
||||||
"client_type": 3
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"api_key": [
|
|
||||||
{
|
|
||||||
"current_key": "AIzaSyDUw4s-mhQsHvs4hdIsldsi68ZIygM5MC4"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"services": {
|
|
||||||
"appinvite_service": {
|
|
||||||
"other_platform_oauth_client": [
|
|
||||||
{
|
|
||||||
"client_id": "661638997772-6aiqk97aema0rt280i7nfar3ha2mlgno.apps.googleusercontent.com",
|
|
||||||
"client_type": 3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"client_id": "661638997772-sqa4raeghhrieqt9guljhcul9b51dvna.apps.googleusercontent.com",
|
|
||||||
"client_type": 2,
|
|
||||||
"ios_info": {
|
|
||||||
"bundle_id": "com.xmflsct.app.mastodon"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"configuration_version": "1"
|
|
||||||
}
|
|
|
@ -22,7 +22,6 @@ buildscript {
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.google.gms:google-services:4.3.3'
|
|
||||||
classpath("com.android.tools.build:gradle:7.2.1")
|
classpath("com.android.tools.build:gradle:7.2.1")
|
||||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||||
classpath("de.undercouch:gradle-download-task:5.0.1")
|
classpath("de.undercouch:gradle-download-task:5.0.1")
|
||||||
|
|
|
@ -15,7 +15,6 @@ export default (): ExpoConfig => ({
|
||||||
},
|
},
|
||||||
android: {
|
android: {
|
||||||
package: 'com.xmflsct.app.tooot',
|
package: 'com.xmflsct.app.tooot',
|
||||||
googleServicesFile: './configs/google-services.json',
|
|
||||||
permissions: ['CAMERA', 'VIBRATE'],
|
permissions: ['CAMERA', 'VIBRATE'],
|
||||||
blockedPermissions: ['USE_BIOMETRIC', 'USE_FINGERPRINT']
|
blockedPermissions: ['USE_BIOMETRIC', 'USE_FINGERPRINT']
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>CLIENT_ID</key>
|
|
||||||
<string>661638997772-65g8ce369ugck3ii4ulk6jhb3ijg51kl.apps.googleusercontent.com</string>
|
|
||||||
<key>REVERSED_CLIENT_ID</key>
|
|
||||||
<string>com.googleusercontent.apps.661638997772-65g8ce369ugck3ii4ulk6jhb3ijg51kl</string>
|
|
||||||
<key>API_KEY</key>
|
|
||||||
<string>AIzaSyAOS1Yq_uNVctG89LB6Dl1PVhb_FAQRbRg</string>
|
|
||||||
<key>GCM_SENDER_ID</key>
|
|
||||||
<string>661638997772</string>
|
|
||||||
<key>PLIST_VERSION</key>
|
|
||||||
<string>1</string>
|
|
||||||
<key>BUNDLE_ID</key>
|
|
||||||
<string>com.xmflsct.app.tooot</string>
|
|
||||||
<key>PROJECT_ID</key>
|
|
||||||
<string>xmflsct-mastodon-app</string>
|
|
||||||
<key>STORAGE_BUCKET</key>
|
|
||||||
<string>xmflsct-mastodon-app.appspot.com</string>
|
|
||||||
<key>IS_ADS_ENABLED</key>
|
|
||||||
<false></false>
|
|
||||||
<key>IS_ANALYTICS_ENABLED</key>
|
|
||||||
<false></false>
|
|
||||||
<key>IS_APPINVITE_ENABLED</key>
|
|
||||||
<true></true>
|
|
||||||
<key>IS_GCM_ENABLED</key>
|
|
||||||
<true></true>
|
|
||||||
<key>IS_SIGNIN_ENABLED</key>
|
|
||||||
<true></true>
|
|
||||||
<key>GOOGLE_APP_ID</key>
|
|
||||||
<string>1:661638997772:ios:c8d2e09264a344b09f8b29</string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
|
@ -1,46 +0,0 @@
|
||||||
{
|
|
||||||
"project_info": {
|
|
||||||
"project_number": "661638997772",
|
|
||||||
"project_id": "xmflsct-mastodon-app",
|
|
||||||
"storage_bucket": "xmflsct-mastodon-app.appspot.com"
|
|
||||||
},
|
|
||||||
"client": [
|
|
||||||
{
|
|
||||||
"client_info": {
|
|
||||||
"mobilesdk_app_id": "1:661638997772:android:4fd02851f757f8fa9f8b29",
|
|
||||||
"android_client_info": {
|
|
||||||
"package_name": "com.xmflsct.app.tooot"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"oauth_client": [
|
|
||||||
{
|
|
||||||
"client_id": "661638997772-6aiqk97aema0rt280i7nfar3ha2mlgno.apps.googleusercontent.com",
|
|
||||||
"client_type": 3
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"api_key": [
|
|
||||||
{
|
|
||||||
"current_key": "AIzaSyDUw4s-mhQsHvs4hdIsldsi68ZIygM5MC4"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"services": {
|
|
||||||
"appinvite_service": {
|
|
||||||
"other_platform_oauth_client": [
|
|
||||||
{
|
|
||||||
"client_id": "661638997772-6aiqk97aema0rt280i7nfar3ha2mlgno.apps.googleusercontent.com",
|
|
||||||
"client_type": 3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"client_id": "661638997772-sqa4raeghhrieqt9guljhcul9b51dvna.apps.googleusercontent.com",
|
|
||||||
"client_type": 2,
|
|
||||||
"ios_info": {
|
|
||||||
"bundle_id": "com.xmflsct.app.mastodon"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"configuration_version": "1"
|
|
||||||
}
|
|
|
@ -15,12 +15,6 @@ target 'tooot' do
|
||||||
# Flags change depending on the env values.
|
# Flags change depending on the env values.
|
||||||
flags = get_default_flags()
|
flags = get_default_flags()
|
||||||
|
|
||||||
# https://stackoverflow.com/questions/72289521/swift-pods-cannot-yet-be-integrated-as-static-libraries-firebasecoreinternal-lib/72969220#72969220
|
|
||||||
pod 'Firebase', :modular_headers => true
|
|
||||||
pod 'FirebaseCore', :modular_headers => true
|
|
||||||
pod 'GoogleUtilities', :modular_headers => true
|
|
||||||
$RNFirebaseAsStaticFramework = true
|
|
||||||
|
|
||||||
use_react_native!(
|
use_react_native!(
|
||||||
:path => config[:reactNativePath],
|
:path => config[:reactNativePath],
|
||||||
:hermes_enabled => true,
|
:hermes_enabled => true,
|
||||||
|
|
147
ios/Podfile.lock
147
ios/Podfile.lock
|
@ -12,13 +12,6 @@ PODS:
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- EXFileSystem (15.1.1):
|
- EXFileSystem (15.1.1):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- EXFirebaseAnalytics (8.0.0):
|
|
||||||
- EXFirebaseCore
|
|
||||||
- ExpoModulesCore
|
|
||||||
- Firebase/Core (= 9.5.0)
|
|
||||||
- EXFirebaseCore (6.0.0):
|
|
||||||
- ExpoModulesCore
|
|
||||||
- Firebase/Core (= 9.5.0)
|
|
||||||
- EXFont (11.0.1):
|
- EXFont (11.0.1):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- EXNotifications (0.17.0):
|
- EXNotifications (0.17.0):
|
||||||
|
@ -59,107 +52,8 @@ PODS:
|
||||||
- React-Core (= 0.70.6)
|
- React-Core (= 0.70.6)
|
||||||
- React-jsi (= 0.70.6)
|
- React-jsi (= 0.70.6)
|
||||||
- ReactCommon/turbomodule/core (= 0.70.6)
|
- ReactCommon/turbomodule/core (= 0.70.6)
|
||||||
- Firebase (9.5.0):
|
|
||||||
- Firebase/Core (= 9.5.0)
|
|
||||||
- Firebase/Core (9.5.0):
|
|
||||||
- Firebase/CoreOnly
|
|
||||||
- FirebaseAnalytics (~> 9.5.0)
|
|
||||||
- Firebase/CoreOnly (9.5.0):
|
|
||||||
- FirebaseCore (= 9.5.0)
|
|
||||||
- FirebaseAnalytics (9.5.0):
|
|
||||||
- FirebaseAnalytics/AdIdSupport (= 9.5.0)
|
|
||||||
- FirebaseCore (~> 9.0)
|
|
||||||
- FirebaseInstallations (~> 9.0)
|
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
|
||||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
|
||||||
- GoogleUtilities/Network (~> 7.7)
|
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
|
||||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
|
||||||
- FirebaseAnalytics/AdIdSupport (9.5.0):
|
|
||||||
- FirebaseCore (~> 9.0)
|
|
||||||
- FirebaseInstallations (~> 9.0)
|
|
||||||
- GoogleAppMeasurement (= 9.5.0)
|
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
|
||||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
|
||||||
- GoogleUtilities/Network (~> 7.7)
|
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
|
||||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
|
||||||
- FirebaseCore (9.5.0):
|
|
||||||
- FirebaseCoreDiagnostics (~> 9.0)
|
|
||||||
- FirebaseCoreInternal (~> 9.0)
|
|
||||||
- GoogleUtilities/Environment (~> 7.7)
|
|
||||||
- GoogleUtilities/Logger (~> 7.7)
|
|
||||||
- FirebaseCoreDiagnostics (9.6.0):
|
|
||||||
- GoogleDataTransport (< 10.0.0, >= 9.1.4)
|
|
||||||
- GoogleUtilities/Environment (~> 7.7)
|
|
||||||
- GoogleUtilities/Logger (~> 7.7)
|
|
||||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
|
||||||
- FirebaseCoreInternal (9.6.0):
|
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
|
||||||
- FirebaseInstallations (9.6.0):
|
|
||||||
- FirebaseCore (~> 9.0)
|
|
||||||
- GoogleUtilities/Environment (~> 7.7)
|
|
||||||
- GoogleUtilities/UserDefaults (~> 7.7)
|
|
||||||
- PromisesObjC (~> 2.1)
|
|
||||||
- fmt (6.2.1)
|
- fmt (6.2.1)
|
||||||
- glog (0.3.5)
|
- glog (0.3.5)
|
||||||
- GoogleAppMeasurement (9.5.0):
|
|
||||||
- GoogleAppMeasurement/AdIdSupport (= 9.5.0)
|
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
|
||||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
|
||||||
- GoogleUtilities/Network (~> 7.7)
|
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
|
||||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
|
||||||
- GoogleAppMeasurement/AdIdSupport (9.5.0):
|
|
||||||
- GoogleAppMeasurement/WithoutAdIdSupport (= 9.5.0)
|
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
|
||||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
|
||||||
- GoogleUtilities/Network (~> 7.7)
|
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
|
||||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
|
||||||
- GoogleAppMeasurement/WithoutAdIdSupport (9.5.0):
|
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
|
||||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
|
||||||
- GoogleUtilities/Network (~> 7.7)
|
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
|
||||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
|
||||||
- GoogleDataTransport (9.2.0):
|
|
||||||
- GoogleUtilities/Environment (~> 7.7)
|
|
||||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
|
||||||
- PromisesObjC (< 3.0, >= 1.2)
|
|
||||||
- GoogleUtilities (7.10.0):
|
|
||||||
- GoogleUtilities/AppDelegateSwizzler (= 7.10.0)
|
|
||||||
- GoogleUtilities/Environment (= 7.10.0)
|
|
||||||
- GoogleUtilities/ISASwizzler (= 7.10.0)
|
|
||||||
- GoogleUtilities/Logger (= 7.10.0)
|
|
||||||
- GoogleUtilities/MethodSwizzler (= 7.10.0)
|
|
||||||
- GoogleUtilities/Network (= 7.10.0)
|
|
||||||
- "GoogleUtilities/NSData+zlib (= 7.10.0)"
|
|
||||||
- GoogleUtilities/Reachability (= 7.10.0)
|
|
||||||
- GoogleUtilities/SwizzlerTestHelpers (= 7.10.0)
|
|
||||||
- GoogleUtilities/UserDefaults (= 7.10.0)
|
|
||||||
- GoogleUtilities/AppDelegateSwizzler (7.10.0):
|
|
||||||
- GoogleUtilities/Environment
|
|
||||||
- GoogleUtilities/Logger
|
|
||||||
- GoogleUtilities/Network
|
|
||||||
- GoogleUtilities/Environment (7.10.0):
|
|
||||||
- PromisesObjC (< 3.0, >= 1.2)
|
|
||||||
- GoogleUtilities/ISASwizzler (7.10.0)
|
|
||||||
- GoogleUtilities/Logger (7.10.0):
|
|
||||||
- GoogleUtilities/Environment
|
|
||||||
- GoogleUtilities/MethodSwizzler (7.10.0):
|
|
||||||
- GoogleUtilities/Logger
|
|
||||||
- GoogleUtilities/Network (7.10.0):
|
|
||||||
- GoogleUtilities/Logger
|
|
||||||
- "GoogleUtilities/NSData+zlib"
|
|
||||||
- GoogleUtilities/Reachability
|
|
||||||
- "GoogleUtilities/NSData+zlib (7.10.0)"
|
|
||||||
- GoogleUtilities/Reachability (7.10.0):
|
|
||||||
- GoogleUtilities/Logger
|
|
||||||
- GoogleUtilities/SwizzlerTestHelpers (7.10.0):
|
|
||||||
- GoogleUtilities/MethodSwizzler
|
|
||||||
- GoogleUtilities/UserDefaults (7.10.0):
|
|
||||||
- GoogleUtilities/Logger
|
|
||||||
- hermes-engine (0.70.6)
|
- hermes-engine (0.70.6)
|
||||||
- libevent (2.1.12)
|
- libevent (2.1.12)
|
||||||
- libwebp (1.2.4):
|
- libwebp (1.2.4):
|
||||||
|
@ -171,12 +65,6 @@ PODS:
|
||||||
- libwebp/mux (1.2.4):
|
- libwebp/mux (1.2.4):
|
||||||
- libwebp/demux
|
- libwebp/demux
|
||||||
- libwebp/webp (1.2.4)
|
- libwebp/webp (1.2.4)
|
||||||
- nanopb (2.30909.0):
|
|
||||||
- nanopb/decode (= 2.30909.0)
|
|
||||||
- nanopb/encode (= 2.30909.0)
|
|
||||||
- nanopb/decode (2.30909.0)
|
|
||||||
- nanopb/encode (2.30909.0)
|
|
||||||
- PromisesObjC (2.1.1)
|
|
||||||
- RCT-Folly (2021.07.22.00):
|
- RCT-Folly (2021.07.22.00):
|
||||||
- boost
|
- boost
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
|
@ -563,8 +451,6 @@ DEPENDENCIES:
|
||||||
- EXConstants (from `../node_modules/expo-constants/ios`)
|
- EXConstants (from `../node_modules/expo-constants/ios`)
|
||||||
- EXErrorRecovery (from `../node_modules/expo-error-recovery/ios`)
|
- EXErrorRecovery (from `../node_modules/expo-error-recovery/ios`)
|
||||||
- EXFileSystem (from `../node_modules/expo-file-system/ios`)
|
- EXFileSystem (from `../node_modules/expo-file-system/ios`)
|
||||||
- EXFirebaseAnalytics (from `../node_modules/expo-firebase-analytics/ios`)
|
|
||||||
- EXFirebaseCore (from `../node_modules/expo-firebase-core/ios`)
|
|
||||||
- EXFont (from `../node_modules/expo-font/ios`)
|
- EXFont (from `../node_modules/expo-font/ios`)
|
||||||
- EXNotifications (from `../node_modules/expo-notifications/ios`)
|
- EXNotifications (from `../node_modules/expo-notifications/ios`)
|
||||||
- Expo (from `../node_modules/expo`)
|
- Expo (from `../node_modules/expo`)
|
||||||
|
@ -582,10 +468,7 @@ DEPENDENCIES:
|
||||||
- EXVideoThumbnails (from `../node_modules/expo-video-thumbnails/ios`)
|
- EXVideoThumbnails (from `../node_modules/expo-video-thumbnails/ios`)
|
||||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||||
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
|
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
|
||||||
- Firebase
|
|
||||||
- FirebaseCore
|
|
||||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||||
- GoogleUtilities
|
|
||||||
- hermes-engine (from `../node_modules/react-native/sdks/hermes/hermes-engine.podspec`)
|
- hermes-engine (from `../node_modules/react-native/sdks/hermes/hermes-engine.podspec`)
|
||||||
- libevent (~> 2.1.12)
|
- libevent (~> 2.1.12)
|
||||||
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||||
|
@ -641,20 +524,9 @@ DEPENDENCIES:
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- Firebase
|
|
||||||
- FirebaseAnalytics
|
|
||||||
- FirebaseCore
|
|
||||||
- FirebaseCoreDiagnostics
|
|
||||||
- FirebaseCoreInternal
|
|
||||||
- FirebaseInstallations
|
|
||||||
- fmt
|
- fmt
|
||||||
- GoogleAppMeasurement
|
|
||||||
- GoogleDataTransport
|
|
||||||
- GoogleUtilities
|
|
||||||
- libevent
|
- libevent
|
||||||
- libwebp
|
- libwebp
|
||||||
- nanopb
|
|
||||||
- PromisesObjC
|
|
||||||
- SDWebImage
|
- SDWebImage
|
||||||
- SDWebImageWebPCoder
|
- SDWebImageWebPCoder
|
||||||
- Sentry
|
- Sentry
|
||||||
|
@ -675,10 +547,6 @@ EXTERNAL SOURCES:
|
||||||
:path: "../node_modules/expo-error-recovery/ios"
|
:path: "../node_modules/expo-error-recovery/ios"
|
||||||
EXFileSystem:
|
EXFileSystem:
|
||||||
:path: "../node_modules/expo-file-system/ios"
|
:path: "../node_modules/expo-file-system/ios"
|
||||||
EXFirebaseAnalytics:
|
|
||||||
:path: "../node_modules/expo-firebase-analytics/ios"
|
|
||||||
EXFirebaseCore:
|
|
||||||
:path: "../node_modules/expo-firebase-core/ios"
|
|
||||||
EXFont:
|
EXFont:
|
||||||
:path: "../node_modules/expo-font/ios"
|
:path: "../node_modules/expo-font/ios"
|
||||||
EXNotifications:
|
EXNotifications:
|
||||||
|
@ -824,8 +692,6 @@ SPEC CHECKSUMS:
|
||||||
EXConstants: 3c86653c422dd77e40d10cbbabb3025003977415
|
EXConstants: 3c86653c422dd77e40d10cbbabb3025003977415
|
||||||
EXErrorRecovery: ae43433feb0608a64dc5b1c8363b3e7769a9ea24
|
EXErrorRecovery: ae43433feb0608a64dc5b1c8363b3e7769a9ea24
|
||||||
EXFileSystem: 60602b6eefa6873f97172c684b7537c9760b50d6
|
EXFileSystem: 60602b6eefa6873f97172c684b7537c9760b50d6
|
||||||
EXFirebaseAnalytics: 58d70e698859b070b2450ad8664d7b5bc6c6e3e1
|
|
||||||
EXFirebaseCore: d0d88cb904e893af07f809ab08c0892489bc6956
|
|
||||||
EXFont: 319606bfe48c33b5b5063fb0994afdc496befe80
|
EXFont: 319606bfe48c33b5b5063fb0994afdc496befe80
|
||||||
EXNotifications: babce2a87b7922051354fcfe7a74dd279b7e272a
|
EXNotifications: babce2a87b7922051354fcfe7a74dd279b7e272a
|
||||||
Expo: 36b5f625d36728adbdd1934d4d57182f319ab832
|
Expo: 36b5f625d36728adbdd1934d4d57182f319ab832
|
||||||
|
@ -843,22 +709,11 @@ SPEC CHECKSUMS:
|
||||||
EXVideoThumbnails: 8b3e48f3716679dd0cbf949217a31eab5c555799
|
EXVideoThumbnails: 8b3e48f3716679dd0cbf949217a31eab5c555799
|
||||||
FBLazyVector: 48289402952f4f7a4e235de70a9a590aa0b79ef4
|
FBLazyVector: 48289402952f4f7a4e235de70a9a590aa0b79ef4
|
||||||
FBReactNativeSpec: dd1186fd05255e3457baa2f4ca65e94c2cd1e3ac
|
FBReactNativeSpec: dd1186fd05255e3457baa2f4ca65e94c2cd1e3ac
|
||||||
Firebase: 800f16f07af493d98d017446a315c27af0552f41
|
|
||||||
FirebaseAnalytics: 1b60984a408320dda637306f3f733699ef8473d7
|
|
||||||
FirebaseCore: 25c0400b670fd1e2f2104349cd3b5dcce8d9418f
|
|
||||||
FirebaseCoreDiagnostics: 99a495094b10a57eeb3ae8efa1665700ad0bdaa6
|
|
||||||
FirebaseCoreInternal: bca76517fe1ed381e989f5e7d8abb0da8d85bed3
|
|
||||||
FirebaseInstallations: 0a115432c4e223c5ab20b0dbbe4cbefa793a0e8e
|
|
||||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||||
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
|
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
|
||||||
GoogleAppMeasurement: 6ee231473fbd75c11221dfce489894334024eead
|
|
||||||
GoogleDataTransport: 1c8145da7117bd68bbbed00cf304edb6a24de00f
|
|
||||||
GoogleUtilities: bad72cb363809015b1f7f19beb1f1cd23c589f95
|
|
||||||
hermes-engine: 2af7b7a59128f250adfd86f15aa1d5a2ecd39995
|
hermes-engine: 2af7b7a59128f250adfd86f15aa1d5a2ecd39995
|
||||||
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
|
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
|
||||||
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef
|
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef
|
||||||
nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431
|
|
||||||
PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb
|
|
||||||
RCT-Folly: 0080d0a6ebf2577475bda044aa59e2ca1f909cda
|
RCT-Folly: 0080d0a6ebf2577475bda044aa59e2ca1f909cda
|
||||||
RCTRequired: e1866f61af7049eb3d8e08e8b133abd38bc1ca7a
|
RCTRequired: e1866f61af7049eb3d8e08e8b133abd38bc1ca7a
|
||||||
RCTTypeSafety: 27c2ac1b00609a432ced1ae701247593f07f901e
|
RCTTypeSafety: 27c2ac1b00609a432ced1ae701247593f07f901e
|
||||||
|
@ -913,6 +768,6 @@ SPEC CHECKSUMS:
|
||||||
Swime: d7b2c277503b6cea317774aedc2dce05613f8b0b
|
Swime: d7b2c277503b6cea317774aedc2dce05613f8b0b
|
||||||
Yoga: 99caf8d5ab45e9d637ee6e0174ec16fbbb01bcfc
|
Yoga: 99caf8d5ab45e9d637ee6e0174ec16fbbb01bcfc
|
||||||
|
|
||||||
PODFILE CHECKSUM: e4191b63c8f15031b2365226730770e7978dca41
|
PODFILE CHECKSUM: 05bf71d31ba782dfda5a6b47d38e98a6f6bc079a
|
||||||
|
|
||||||
COCOAPODS: 1.11.3
|
COCOAPODS: 1.11.3
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
5EE088C926297820007E5FEC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5EE088CB26297820007E5FEC /* InfoPlist.strings */; };
|
5EE088C926297820007E5FEC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5EE088CB26297820007E5FEC /* InfoPlist.strings */; };
|
||||||
5EE44DD62600124E00A9BCED /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EE44DD52600124E00A9BCED /* File.swift */; };
|
5EE44DD62600124E00A9BCED /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EE44DD52600124E00A9BCED /* File.swift */; };
|
||||||
96905EF65AED1B983A6B3ABC /* libPods-tooot.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58EEBF8E8E6FB1BC6CAF49B5 /* libPods-tooot.a */; };
|
96905EF65AED1B983A6B3ABC /* libPods-tooot.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58EEBF8E8E6FB1BC6CAF49B5 /* libPods-tooot.a */; };
|
||||||
DA8B5B7F0DED488CAC0FF169 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B96B72E5384D44A7B240B27E /* GoogleService-Info.plist */; };
|
|
||||||
E3BC22F5F8ABE515E14CF199 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D878F932AF7A9974E06E461 /* ExpoModulesProvider.swift */; };
|
E3BC22F5F8ABE515E14CF199 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D878F932AF7A9974E06E461 /* ExpoModulesProvider.swift */; };
|
||||||
E613A80B28282A01003C97D6 /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = E613A80A28282A01003C97D6 /* AppDelegate.mm */; };
|
E613A80B28282A01003C97D6 /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = E613A80A28282A01003C97D6 /* AppDelegate.mm */; };
|
||||||
E633A42B281EAEAB000E540F /* ShareExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = E633A420281EAEAB000E540F /* ShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
E633A42B281EAEAB000E540F /* ShareExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = E633A420281EAEAB000E540F /* ShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
|
@ -69,7 +68,6 @@
|
||||||
7A4D352CD337FB3A3BF06240 /* Pods-tooot.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-tooot.release.xcconfig"; path = "Target Support Files/Pods-tooot/Pods-tooot.release.xcconfig"; sourceTree = "<group>"; };
|
7A4D352CD337FB3A3BF06240 /* Pods-tooot.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-tooot.release.xcconfig"; path = "Target Support Files/Pods-tooot/Pods-tooot.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
9D878F932AF7A9974E06E461 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-tooot/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
|
9D878F932AF7A9974E06E461 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-tooot/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
|
||||||
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = tooot/SplashScreen.storyboard; sourceTree = "<group>"; };
|
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = tooot/SplashScreen.storyboard; sourceTree = "<group>"; };
|
||||||
B96B72E5384D44A7B240B27E /* GoogleService-Info.plist */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "tooot/GoogleService-Info.plist"; sourceTree = "<group>"; };
|
|
||||||
DF8133F098604A10B0D94952 /* boop.mp3 */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = boop.mp3; path = tooot/boop.mp3; sourceTree = "<group>"; };
|
DF8133F098604A10B0D94952 /* boop.mp3 */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = boop.mp3; path = tooot/boop.mp3; sourceTree = "<group>"; };
|
||||||
E613A80A28282A01003C97D6 /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = tooot/AppDelegate.mm; sourceTree = "<group>"; };
|
E613A80A28282A01003C97D6 /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = tooot/AppDelegate.mm; sourceTree = "<group>"; };
|
||||||
E633A420281EAEAB000E540F /* ShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
E633A420281EAEAB000E540F /* ShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
@ -122,7 +120,6 @@
|
||||||
13B07FB71A68108700A75B9A /* main.m */,
|
13B07FB71A68108700A75B9A /* main.m */,
|
||||||
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */,
|
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */,
|
||||||
5E36538225C9B8BD009F93EE /* RootViewColor.xcassets */,
|
5E36538225C9B8BD009F93EE /* RootViewColor.xcassets */,
|
||||||
B96B72E5384D44A7B240B27E /* GoogleService-Info.plist */,
|
|
||||||
5EE088CB26297820007E5FEC /* InfoPlist.strings */,
|
5EE088CB26297820007E5FEC /* InfoPlist.strings */,
|
||||||
DF8133F098604A10B0D94952 /* boop.mp3 */,
|
DF8133F098604A10B0D94952 /* boop.mp3 */,
|
||||||
);
|
);
|
||||||
|
@ -319,7 +316,6 @@
|
||||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
|
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
|
||||||
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */,
|
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */,
|
||||||
DA8B5B7F0DED488CAC0FF169 /* GoogleService-Info.plist in Resources */,
|
|
||||||
4986628FD0DD4630BFE5F388 /* boop.mp3 in Resources */,
|
4986628FD0DD4630BFE5F388 /* boop.mp3 in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>CLIENT_ID</key>
|
|
||||||
<string>661638997772-65g8ce369ugck3ii4ulk6jhb3ijg51kl.apps.googleusercontent.com</string>
|
|
||||||
<key>REVERSED_CLIENT_ID</key>
|
|
||||||
<string>com.googleusercontent.apps.661638997772-65g8ce369ugck3ii4ulk6jhb3ijg51kl</string>
|
|
||||||
<key>API_KEY</key>
|
|
||||||
<string>AIzaSyAOS1Yq_uNVctG89LB6Dl1PVhb_FAQRbRg</string>
|
|
||||||
<key>GCM_SENDER_ID</key>
|
|
||||||
<string>661638997772</string>
|
|
||||||
<key>PLIST_VERSION</key>
|
|
||||||
<string>1</string>
|
|
||||||
<key>BUNDLE_ID</key>
|
|
||||||
<string>com.xmflsct.app.tooot</string>
|
|
||||||
<key>PROJECT_ID</key>
|
|
||||||
<string>xmflsct-mastodon-app</string>
|
|
||||||
<key>STORAGE_BUCKET</key>
|
|
||||||
<string>xmflsct-mastodon-app.appspot.com</string>
|
|
||||||
<key>IS_ADS_ENABLED</key>
|
|
||||||
<false></false>
|
|
||||||
<key>IS_ANALYTICS_ENABLED</key>
|
|
||||||
<false></false>
|
|
||||||
<key>IS_APPINVITE_ENABLED</key>
|
|
||||||
<true></true>
|
|
||||||
<key>IS_GCM_ENABLED</key>
|
|
||||||
<true></true>
|
|
||||||
<key>IS_SIGNIN_ENABLED</key>
|
|
||||||
<true></true>
|
|
||||||
<key>GOOGLE_APP_ID</key>
|
|
||||||
<string>1:661638997772:ios:c8d2e09264a344b09f8b29</string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
|
@ -47,7 +47,6 @@
|
||||||
"expo-constants": "^14.0.2",
|
"expo-constants": "^14.0.2",
|
||||||
"expo-crypto": "^12.0.0",
|
"expo-crypto": "^12.0.0",
|
||||||
"expo-file-system": "^15.1.1",
|
"expo-file-system": "^15.1.1",
|
||||||
"expo-firebase-analytics": "^8.0.0",
|
|
||||||
"expo-haptics": "^12.0.1",
|
"expo-haptics": "^12.0.1",
|
||||||
"expo-linking": "^3.2.3",
|
"expo-linking": "^3.2.3",
|
||||||
"expo-localization": "^14.0.0",
|
"expo-localization": "^14.0.0",
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import { HeaderLeft } from '@components/Header'
|
import { HeaderLeft } from '@components/Header'
|
||||||
import { displayMessage, Message } from '@components/Message'
|
import { displayMessage, Message } from '@components/Message'
|
||||||
import navigationRef from '@helpers/navigationRef'
|
import navigationRef from '@helpers/navigationRef'
|
||||||
|
@ -113,7 +112,6 @@ const Screens: React.FC<Props> = ({ localCorrupt }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (previousRoute?.name !== currentRoute?.name) {
|
if (previousRoute?.name !== currentRoute?.name) {
|
||||||
analytics('screen_view', { screen_name: currentRoute?.name })
|
|
||||||
Sentry.setContext('page', {
|
Sentry.setContext('page', {
|
||||||
previous: previousRoute,
|
previous: previousRoute,
|
||||||
current: currentRoute
|
current: currentRoute
|
||||||
|
|
|
@ -6,29 +6,19 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
import { Pressable, View } from 'react-native'
|
import { Pressable, View } from 'react-native'
|
||||||
import analytics from './analytics'
|
|
||||||
import GracefullyImage from './GracefullyImage'
|
import GracefullyImage from './GracefullyImage'
|
||||||
import CustomText from './Text'
|
import CustomText from './Text'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
account: Mastodon.Account
|
account: Mastodon.Account
|
||||||
onPress?: () => void
|
onPress?: () => void
|
||||||
origin?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ComponentAccount: React.FC<Props> = ({
|
const ComponentAccount: React.FC<Props> = ({ account, onPress: customOnPress }) => {
|
||||||
account,
|
|
||||||
onPress: customOnPress,
|
|
||||||
origin
|
|
||||||
}) => {
|
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
const navigation =
|
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||||
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
|
||||||
|
|
||||||
const onPress = useCallback(() => {
|
const onPress = useCallback(() => navigation.push('Tab-Shared-Account', { account }), [])
|
||||||
analytics('search_account_press', { page: origin })
|
|
||||||
navigation.push('Tab-Shared-Account', { account })
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Pressable
|
<Pressable
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
import { useRelationshipQuery } from '@utils/queryHooks/relationship'
|
import { useRelationshipQuery } from '@utils/queryHooks/relationship'
|
||||||
import {
|
import {
|
||||||
|
@ -135,9 +134,6 @@ const contextMenuAccount = ({ actions, type, queryKey, rootQueryKey, id: account
|
||||||
return // For Android
|
return // For Android
|
||||||
}
|
}
|
||||||
if (actions[index].id === 'account-mute') {
|
if (actions[index].id === 'account-mute') {
|
||||||
analytics('timeline_shared_headeractions_account_mute_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateAccountProperty',
|
type: 'updateAccountProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
|
@ -149,9 +145,6 @@ const contextMenuAccount = ({ actions, type, queryKey, rootQueryKey, id: account
|
||||||
actions[index].id === 'account-block' ||
|
actions[index].id === 'account-block' ||
|
||||||
(actions[index].id === 'account' && actions[index].actions?.[0].id === 'account-block')
|
(actions[index].id === 'account' && actions[index].actions?.[0].id === 'account-block')
|
||||||
) {
|
) {
|
||||||
analytics('timeline_shared_headeractions_account_block_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateAccountProperty',
|
type: 'updateAccountProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
|
@ -163,9 +156,6 @@ const contextMenuAccount = ({ actions, type, queryKey, rootQueryKey, id: account
|
||||||
actions[index].id === 'account-reports' ||
|
actions[index].id === 'account-reports' ||
|
||||||
(actions[index].id === 'account' && actions[index].actions?.[0].id === 'account-reports')
|
(actions[index].id === 'account' && actions[index].actions?.[0].id === 'account-reports')
|
||||||
) {
|
) {
|
||||||
analytics('timeline_shared_headeractions_account_reports_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateAccountProperty',
|
type: 'updateAccountProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
import { QueryKeyTimeline, useTimelineMutation } from '@utils/queryHooks/timeline'
|
import { QueryKeyTimeline, useTimelineMutation } from '@utils/queryHooks/timeline'
|
||||||
import { getInstanceUrl } from '@utils/slices/instancesSlice'
|
import { getInstanceUrl } from '@utils/slices/instancesSlice'
|
||||||
|
@ -71,9 +70,6 @@ const contextMenuInstance = ({ actions, status, queryKey, rootQueryKey }: Props)
|
||||||
actions[index].id === 'instance-block' ||
|
actions[index].id === 'instance-block' ||
|
||||||
(actions[index].id === 'instance' && actions[index].actions?.[0].id === 'instance-block')
|
(actions[index].id === 'instance' && actions[index].actions?.[0].id === 'instance-block')
|
||||||
) {
|
) {
|
||||||
analytics('timeline_shared_headeractions_domain_block_press', {
|
|
||||||
page: queryKey[1].page
|
|
||||||
})
|
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
t('instance.block.alert.title', { instance }),
|
t('instance.block.alert.title', { instance }),
|
||||||
t('instance.block.alert.message'),
|
t('instance.block.alert.message'),
|
||||||
|
@ -82,9 +78,6 @@ const contextMenuInstance = ({ actions, status, queryKey, rootQueryKey }: Props)
|
||||||
text: t('instance.block.alert.buttons.confirm'),
|
text: t('instance.block.alert.buttons.confirm'),
|
||||||
style: 'destructive',
|
style: 'destructive',
|
||||||
onPress: () => {
|
onPress: () => {
|
||||||
analytics('timeline_shared_headeractions_domain_block_confirm', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'domainBlock',
|
type: 'domainBlock',
|
||||||
queryKey,
|
queryKey,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
import Clipboard from '@react-native-clipboard/clipboard'
|
import Clipboard from '@react-native-clipboard/clipboard'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
|
@ -39,7 +38,6 @@ const contextMenuShare = ({ copiableContent, actions, type, url }: Props) => {
|
||||||
return // For Android
|
return // For Android
|
||||||
}
|
}
|
||||||
if (actions[index].id === 'copy') {
|
if (actions[index].id === 'copy') {
|
||||||
analytics('timeline_shared_headeractions_copy_press')
|
|
||||||
Clipboard.setString(copiableContent?.current.content || '')
|
Clipboard.setString(copiableContent?.current.content || '')
|
||||||
displayMessage({
|
displayMessage({
|
||||||
theme,
|
theme,
|
||||||
|
@ -48,7 +46,6 @@ const contextMenuShare = ({ copiableContent, actions, type, url }: Props) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (actions[index].id === 'share') {
|
if (actions[index].id === 'share') {
|
||||||
analytics('timeline_shared_headeractions_share_press')
|
|
||||||
switch (Platform.OS) {
|
switch (Platform.OS) {
|
||||||
case 'ios':
|
case 'ios':
|
||||||
Share.share({ url })
|
Share.share({ url })
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import apiInstance from '@api/instance'
|
import apiInstance from '@api/instance'
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
||||||
|
@ -107,17 +106,11 @@ const contextMenuStatus = ({ actions, status, queryKey, rootQueryKey }: Props) =
|
||||||
return // For Android
|
return // For Android
|
||||||
}
|
}
|
||||||
if (actions[index].id === 'status-delete') {
|
if (actions[index].id === 'status-delete') {
|
||||||
analytics('timeline_shared_headeractions_status_delete_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
Alert.alert(t('status.delete.alert.title'), t('status.delete.alert.message'), [
|
Alert.alert(t('status.delete.alert.title'), t('status.delete.alert.message'), [
|
||||||
{
|
{
|
||||||
text: t('status.delete.alert.buttons.confirm'),
|
text: t('status.delete.alert.buttons.confirm'),
|
||||||
style: 'destructive',
|
style: 'destructive',
|
||||||
onPress: async () => {
|
onPress: async () => {
|
||||||
analytics('timeline_shared_headeractions_status_delete_confirm', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'deleteItem',
|
type: 'deleteItem',
|
||||||
source: 'statuses',
|
source: 'statuses',
|
||||||
|
@ -133,17 +126,11 @@ const contextMenuStatus = ({ actions, status, queryKey, rootQueryKey }: Props) =
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
if (actions[index].id === 'status-delete-edit') {
|
if (actions[index].id === 'status-delete-edit') {
|
||||||
analytics('timeline_shared_headeractions_status_deleteedit_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
Alert.alert(t('status.deleteEdit.alert.title'), t('status.deleteEdit.alert.message'), [
|
Alert.alert(t('status.deleteEdit.alert.title'), t('status.deleteEdit.alert.message'), [
|
||||||
{
|
{
|
||||||
text: t('status.deleteEdit.alert.buttons.confirm'),
|
text: t('status.deleteEdit.alert.buttons.confirm'),
|
||||||
style: 'destructive',
|
style: 'destructive',
|
||||||
onPress: async () => {
|
onPress: async () => {
|
||||||
analytics('timeline_shared_headeractions_status_deleteedit_confirm', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
let replyToStatus: Mastodon.Status | undefined = undefined
|
let replyToStatus: Mastodon.Status | undefined = undefined
|
||||||
if (status.in_reply_to_id) {
|
if (status.in_reply_to_id) {
|
||||||
replyToStatus = await apiInstance<Mastodon.Status>({
|
replyToStatus = await apiInstance<Mastodon.Status>({
|
||||||
|
@ -174,9 +161,6 @@ const contextMenuStatus = ({ actions, status, queryKey, rootQueryKey }: Props) =
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
if (actions[index].id === 'status-mute') {
|
if (actions[index].id === 'status-mute') {
|
||||||
analytics('timeline_shared_headeractions_status_mute_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateStatusProperty',
|
type: 'updateStatusProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
|
@ -191,9 +175,6 @@ const contextMenuStatus = ({ actions, status, queryKey, rootQueryKey }: Props) =
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (actions[index].id === 'status-edit') {
|
if (actions[index].id === 'status-edit') {
|
||||||
analytics('timeline_shared_headeractions_status_edit_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
let replyToStatus: Mastodon.Status | undefined = undefined
|
let replyToStatus: Mastodon.Status | undefined = undefined
|
||||||
if (status.in_reply_to_id) {
|
if (status.in_reply_to_id) {
|
||||||
replyToStatus = await apiInstance<Mastodon.Status>({
|
replyToStatus = await apiInstance<Mastodon.Status>({
|
||||||
|
@ -224,9 +205,6 @@ const contextMenuStatus = ({ actions, status, queryKey, rootQueryKey }: Props) =
|
||||||
}
|
}
|
||||||
if (actions[index].id === 'status-pin') {
|
if (actions[index].id === 'status-pin') {
|
||||||
// Also note that reblogs cannot be pinned.
|
// Also note that reblogs cannot be pinned.
|
||||||
analytics('timeline_shared_headeractions_status_pin_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateStatusProperty',
|
type: 'updateStatusProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
import { Pressable } from 'react-native'
|
import { Pressable } from 'react-native'
|
||||||
import analytics from './analytics'
|
|
||||||
import CustomText from './Text'
|
import CustomText from './Text'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
|
@ -24,7 +23,6 @@ const ComponentHashtag: React.FC<Props> = ({
|
||||||
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||||
|
|
||||||
const onPress = useCallback(() => {
|
const onPress = useCallback(() => {
|
||||||
analytics('search_account_press', { page: origin })
|
|
||||||
navigation.push('Tab-Shared-Hashtag', { hashtag: hashtag.name })
|
navigation.push('Tab-Shared-Hashtag', { hashtag: hashtag.name })
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
|
|
@ -9,18 +9,10 @@ import * as WebBrowser from 'expo-web-browser'
|
||||||
import { debounce } from 'lodash'
|
import { debounce } from 'lodash'
|
||||||
import React, { RefObject, useCallback, useMemo, useState } from 'react'
|
import React, { RefObject, useCallback, useMemo, useState } from 'react'
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
import { Trans, useTranslation } from 'react-i18next'
|
||||||
import {
|
import { Alert, Image, KeyboardAvoidingView, Platform, TextInput, View } from 'react-native'
|
||||||
Alert,
|
|
||||||
Image,
|
|
||||||
KeyboardAvoidingView,
|
|
||||||
Platform,
|
|
||||||
TextInput,
|
|
||||||
View
|
|
||||||
} from 'react-native'
|
|
||||||
import { ScrollView } from 'react-native-gesture-handler'
|
import { ScrollView } from 'react-native-gesture-handler'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import { Placeholder } from 'rn-placeholder'
|
import { Placeholder } from 'rn-placeholder'
|
||||||
import analytics from './analytics'
|
|
||||||
import InstanceAuth from './Instance/Auth'
|
import InstanceAuth from './Instance/Auth'
|
||||||
import InstanceInfo from './Instance/Info'
|
import InstanceInfo from './Instance/Info'
|
||||||
import CustomText from './Text'
|
import CustomText from './Text'
|
||||||
|
@ -65,11 +57,7 @@ const ComponentInstance: React.FC<Props> = ({
|
||||||
|
|
||||||
const processUpdate = useCallback(() => {
|
const processUpdate = useCallback(() => {
|
||||||
if (domain) {
|
if (domain) {
|
||||||
analytics('instance_login')
|
if (instances && instances.filter(instance => instance.url === domain).length) {
|
||||||
if (
|
|
||||||
instances &&
|
|
||||||
instances.filter(instance => instance.url === domain).length
|
|
||||||
) {
|
|
||||||
Alert.alert(t('update.alert.title'), t('update.alert.message'), [
|
Alert.alert(t('update.alert.title'), t('update.alert.message'), [
|
||||||
{
|
{
|
||||||
text: t('update.alert.buttons.cancel'),
|
text: t('update.alert.buttons.cancel'),
|
||||||
|
@ -142,9 +130,7 @@ const ComponentInstance: React.FC<Props> = ({
|
||||||
borderBottomWidth: 1,
|
borderBottomWidth: 1,
|
||||||
...StyleConstants.FontStyle.M,
|
...StyleConstants.FontStyle.M,
|
||||||
color: colors.primaryDefault,
|
color: colors.primaryDefault,
|
||||||
borderBottomColor: instanceQuery.isError
|
borderBottomColor: instanceQuery.isError ? colors.red : colors.border
|
||||||
? colors.red
|
|
||||||
: colors.border
|
|
||||||
}}
|
}}
|
||||||
editable={false}
|
editable={false}
|
||||||
defaultValue='https://'
|
defaultValue='https://'
|
||||||
|
@ -156,9 +142,7 @@ const ComponentInstance: React.FC<Props> = ({
|
||||||
...StyleConstants.FontStyle.M,
|
...StyleConstants.FontStyle.M,
|
||||||
marginRight: StyleConstants.Spacing.M,
|
marginRight: StyleConstants.Spacing.M,
|
||||||
color: colors.primaryDefault,
|
color: colors.primaryDefault,
|
||||||
borderBottomColor: instanceQuery.isError
|
borderBottomColor: instanceQuery.isError ? colors.red : colors.border
|
||||||
? colors.red
|
|
||||||
: colors.border
|
|
||||||
}}
|
}}
|
||||||
onChangeText={onChangeText}
|
onChangeText={onChangeText}
|
||||||
autoCapitalize='none'
|
autoCapitalize='none'
|
||||||
|
@ -166,7 +150,6 @@ const ComponentInstance: React.FC<Props> = ({
|
||||||
keyboardType='url'
|
keyboardType='url'
|
||||||
textContentType='URL'
|
textContentType='URL'
|
||||||
onSubmitEditing={({ nativeEvent: { text } }) => {
|
onSubmitEditing={({ nativeEvent: { text } }) => {
|
||||||
analytics('instance_textinput_submit', { match: text === domain })
|
|
||||||
if (
|
if (
|
||||||
text === domain &&
|
text === domain &&
|
||||||
instanceQuery.isSuccess &&
|
instanceQuery.isSuccess &&
|
||||||
|
@ -182,11 +165,7 @@ const ComponentInstance: React.FC<Props> = ({
|
||||||
keyboardAppearance={mode}
|
keyboardAppearance={mode}
|
||||||
{...(scrollViewRef && {
|
{...(scrollViewRef && {
|
||||||
onFocus: () =>
|
onFocus: () =>
|
||||||
setTimeout(
|
setTimeout(() => scrollViewRef.current?.scrollTo({ y: 0, animated: true }), 150)
|
||||||
() =>
|
|
||||||
scrollViewRef.current?.scrollTo({ y: 0, animated: true }),
|
|
||||||
150
|
|
||||||
)
|
|
||||||
})}
|
})}
|
||||||
autoCorrect={false}
|
autoCorrect={false}
|
||||||
spellCheck={false}
|
spellCheck={false}
|
||||||
|
@ -211,27 +190,19 @@ const ComponentInstance: React.FC<Props> = ({
|
||||||
<InstanceInfo
|
<InstanceInfo
|
||||||
style={{ alignItems: 'flex-start' }}
|
style={{ alignItems: 'flex-start' }}
|
||||||
header={t('server.information.accounts')}
|
header={t('server.information.accounts')}
|
||||||
content={
|
content={instanceQuery.data?.stats?.user_count?.toString() || undefined}
|
||||||
instanceQuery.data?.stats?.user_count?.toString() || undefined
|
|
||||||
}
|
|
||||||
potentialWidth={4}
|
potentialWidth={4}
|
||||||
/>
|
/>
|
||||||
<InstanceInfo
|
<InstanceInfo
|
||||||
style={{ alignItems: 'center' }}
|
style={{ alignItems: 'center' }}
|
||||||
header={t('server.information.statuses')}
|
header={t('server.information.statuses')}
|
||||||
content={
|
content={instanceQuery.data?.stats?.status_count?.toString() || undefined}
|
||||||
instanceQuery.data?.stats?.status_count?.toString() ||
|
|
||||||
undefined
|
|
||||||
}
|
|
||||||
potentialWidth={4}
|
potentialWidth={4}
|
||||||
/>
|
/>
|
||||||
<InstanceInfo
|
<InstanceInfo
|
||||||
style={{ alignItems: 'flex-end' }}
|
style={{ alignItems: 'flex-end' }}
|
||||||
header={t('server.information.domains')}
|
header={t('server.information.domains')}
|
||||||
content={
|
content={instanceQuery.data?.stats?.domain_count?.toString() || undefined}
|
||||||
instanceQuery.data?.stats?.domain_count?.toString() ||
|
|
||||||
undefined
|
|
||||||
}
|
|
||||||
potentialWidth={4}
|
potentialWidth={4}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
@ -248,17 +219,11 @@ const ComponentInstance: React.FC<Props> = ({
|
||||||
size={StyleConstants.Font.Size.S}
|
size={StyleConstants.Font.Size.S}
|
||||||
color={colors.secondary}
|
color={colors.secondary}
|
||||||
style={{
|
style={{
|
||||||
marginTop:
|
marginTop: (StyleConstants.Font.LineHeight.S - StyleConstants.Font.Size.S) / 2,
|
||||||
(StyleConstants.Font.LineHeight.S -
|
|
||||||
StyleConstants.Font.Size.S) /
|
|
||||||
2,
|
|
||||||
marginRight: StyleConstants.Spacing.XS
|
marginRight: StyleConstants.Spacing.XS
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<CustomText
|
<CustomText fontStyle='S' style={{ flex: 1, color: colors.secondary }}>
|
||||||
fontStyle='S'
|
|
||||||
style={{ flex: 1, color: colors.secondary }}
|
|
||||||
>
|
|
||||||
{t('server.disclaimer.base')}
|
{t('server.disclaimer.base')}
|
||||||
</CustomText>
|
</CustomText>
|
||||||
</View>
|
</View>
|
||||||
|
@ -274,10 +239,7 @@ const ComponentInstance: React.FC<Props> = ({
|
||||||
size={StyleConstants.Font.Size.S}
|
size={StyleConstants.Font.Size.S}
|
||||||
color={colors.secondary}
|
color={colors.secondary}
|
||||||
style={{
|
style={{
|
||||||
marginTop:
|
marginTop: (StyleConstants.Font.LineHeight.S - StyleConstants.Font.Size.S) / 2,
|
||||||
(StyleConstants.Font.LineHeight.S -
|
|
||||||
StyleConstants.Font.Size.S) /
|
|
||||||
2,
|
|
||||||
marginRight: StyleConstants.Spacing.XS
|
marginRight: StyleConstants.Spacing.XS
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -292,22 +254,14 @@ const ComponentInstance: React.FC<Props> = ({
|
||||||
<CustomText
|
<CustomText
|
||||||
accessible
|
accessible
|
||||||
style={{ color: colors.blue }}
|
style={{ color: colors.blue }}
|
||||||
onPress={() => {
|
onPress={() => WebBrowser.openBrowserAsync('https://tooot.app/privacy-policy')}
|
||||||
analytics('view_privacy')
|
|
||||||
WebBrowser.openBrowserAsync(
|
|
||||||
'https://tooot.app/privacy-policy'
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
/>,
|
/>,
|
||||||
<CustomText
|
<CustomText
|
||||||
accessible
|
accessible
|
||||||
style={{ color: colors.blue }}
|
style={{ color: colors.blue }}
|
||||||
onPress={() => {
|
onPress={() =>
|
||||||
analytics('view_tos')
|
WebBrowser.openBrowserAsync('https://tooot.app/terms-of-service')
|
||||||
WebBrowser.openBrowserAsync(
|
}
|
||||||
'https://tooot.app/terms-of-service'
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import openLink from '@components/openLink'
|
import openLink from '@components/openLink'
|
||||||
import ParseEmojis from '@components/Parse/Emojis'
|
import ParseEmojis from '@components/Parse/Emojis'
|
||||||
|
@ -63,7 +62,6 @@ const renderNode = ({
|
||||||
lineHeight: adaptedLineheight
|
lineHeight: adaptedLineheight
|
||||||
}}
|
}}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('status_hashtag_press')
|
|
||||||
!disableDetails &&
|
!disableDetails &&
|
||||||
differentTag &&
|
differentTag &&
|
||||||
navigation.push('Tab-Shared-Hashtag', {
|
navigation.push('Tab-Shared-Hashtag', {
|
||||||
|
@ -89,7 +87,6 @@ const renderNode = ({
|
||||||
lineHeight: adaptedLineheight
|
lineHeight: adaptedLineheight
|
||||||
}}
|
}}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('status_mention_press')
|
|
||||||
accountIndex !== -1 &&
|
accountIndex !== -1 &&
|
||||||
!disableDetails &&
|
!disableDetails &&
|
||||||
differentAccount &&
|
differentAccount &&
|
||||||
|
@ -118,7 +115,6 @@ const renderNode = ({
|
||||||
lineHeight: adaptedLineheight
|
lineHeight: adaptedLineheight
|
||||||
}}
|
}}
|
||||||
onPress={async () => {
|
onPress={async () => {
|
||||||
analytics('status_link_press')
|
|
||||||
if (!disableDetails) {
|
if (!disableDetails) {
|
||||||
if (shouldBeTag) {
|
if (shouldBeTag) {
|
||||||
navigation.push('Tab-Shared-Hashtag', {
|
navigation.push('Tab-Shared-Hashtag', {
|
||||||
|
@ -255,7 +251,6 @@ const ParseHTML = React.memo(
|
||||||
<Pressable
|
<Pressable
|
||||||
accessibilityLabel={t('HTML.accessibilityHint')}
|
accessibilityLabel={t('HTML.accessibilityHint')}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('status_readmore', { totalLines, expanded })
|
|
||||||
layoutAnimation()
|
layoutAnimation()
|
||||||
setExpanded(!expanded)
|
setExpanded(!expanded)
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import haptics from '@components/haptics'
|
import haptics from '@components/haptics'
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
import {
|
import { QueryKeyRelationship, useRelationshipMutation } from '@utils/queryHooks/relationship'
|
||||||
QueryKeyRelationship,
|
|
||||||
useRelationshipMutation
|
|
||||||
} from '@utils/queryHooks/relationship'
|
|
||||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
|
@ -23,17 +19,12 @@ const RelationshipIncoming: React.FC<Props> = ({ id }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const queryKeyRelationship: QueryKeyRelationship = ['Relationship', { id }]
|
const queryKeyRelationship: QueryKeyRelationship = ['Relationship', { id }]
|
||||||
const queryKeyNotification: QueryKeyTimeline = [
|
const queryKeyNotification: QueryKeyTimeline = ['Timeline', { page: 'Notifications' }]
|
||||||
'Timeline',
|
|
||||||
{ page: 'Notifications' }
|
|
||||||
]
|
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const mutation = useRelationshipMutation({
|
const mutation = useRelationshipMutation({
|
||||||
onSuccess: res => {
|
onSuccess: res => {
|
||||||
haptics('Success')
|
haptics('Success')
|
||||||
queryClient.setQueryData<Mastodon.Relationship[]>(queryKeyRelationship, [
|
queryClient.setQueryData<Mastodon.Relationship[]>(queryKeyRelationship, [res])
|
||||||
res
|
|
||||||
])
|
|
||||||
queryClient.refetchQueries(queryKeyNotification)
|
queryClient.refetchQueries(queryKeyNotification)
|
||||||
},
|
},
|
||||||
onError: (err: any, { type }) => {
|
onError: (err: any, { type }) => {
|
||||||
|
@ -62,28 +53,26 @@ const RelationshipIncoming: React.FC<Props> = ({ id }) => {
|
||||||
type='icon'
|
type='icon'
|
||||||
content='X'
|
content='X'
|
||||||
loading={mutation.isLoading}
|
loading={mutation.isLoading}
|
||||||
onPress={() => {
|
onPress={() =>
|
||||||
analytics('relationship_incoming_press_reject')
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
id,
|
id,
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
payload: { action: 'reject' }
|
payload: { action: 'reject' }
|
||||||
})
|
})
|
||||||
}}
|
}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
type='icon'
|
type='icon'
|
||||||
content='Check'
|
content='Check'
|
||||||
loading={mutation.isLoading}
|
loading={mutation.isLoading}
|
||||||
onPress={() => {
|
onPress={() =>
|
||||||
analytics('relationship_incoming_press_authorize')
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
id,
|
id,
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
payload: { action: 'authorize' }
|
payload: { action: 'authorize' }
|
||||||
})
|
})
|
||||||
}}
|
}
|
||||||
style={styles.approve}
|
style={styles.approve}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import haptics from '@components/haptics'
|
import haptics from '@components/haptics'
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
|
@ -29,10 +28,7 @@ const RelationshipOutgoing = React.memo(
|
||||||
const mutation = useRelationshipMutation({
|
const mutation = useRelationshipMutation({
|
||||||
onSuccess: (res, { payload: { action } }) => {
|
onSuccess: (res, { payload: { action } }) => {
|
||||||
haptics('Success')
|
haptics('Success')
|
||||||
queryClient.setQueryData<Mastodon.Relationship[]>(
|
queryClient.setQueryData<Mastodon.Relationship[]>(queryKeyRelationship, [res])
|
||||||
queryKeyRelationship,
|
|
||||||
[res]
|
|
||||||
)
|
|
||||||
if (action === 'block') {
|
if (action === 'block') {
|
||||||
const queryKey: QueryKeyTimeline = ['Timeline', { page: 'Following' }]
|
const queryKey: QueryKeyTimeline = ['Timeline', { page: 'Following' }]
|
||||||
queryClient.invalidateQueries(queryKey)
|
queryClient.invalidateQueries(queryKey)
|
||||||
|
@ -64,17 +60,12 @@ const RelationshipOutgoing = React.memo(
|
||||||
onPress = () => {}
|
onPress = () => {}
|
||||||
} else {
|
} else {
|
||||||
if (query.data?.blocked_by) {
|
if (query.data?.blocked_by) {
|
||||||
analytics('relationship_outgoing_blocked_by')
|
|
||||||
content = t('button.blocked_by')
|
content = t('button.blocked_by')
|
||||||
onPress = () => {
|
onPress = () => {}
|
||||||
analytics('relationship_outgoing_blocked_by_press')
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (query.data?.blocking) {
|
if (query.data?.blocking) {
|
||||||
analytics('relationship_outgoing_blocking')
|
|
||||||
content = t('button.blocking')
|
content = t('button.blocking')
|
||||||
onPress = () => {
|
onPress = () => {
|
||||||
analytics('relationship_outgoing_blocking_press')
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
id,
|
id,
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
|
@ -86,10 +77,8 @@ const RelationshipOutgoing = React.memo(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (query.data?.following) {
|
if (query.data?.following) {
|
||||||
analytics('relationship_outgoing_following')
|
|
||||||
content = t('button.following')
|
content = t('button.following')
|
||||||
onPress = () => {
|
onPress = () => {
|
||||||
analytics('relationship_outgoing_following_press')
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
id,
|
id,
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
|
@ -101,10 +90,8 @@ const RelationshipOutgoing = React.memo(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (query.data?.requested) {
|
if (query.data?.requested) {
|
||||||
analytics('relationship_outgoing_requested')
|
|
||||||
content = t('button.requested')
|
content = t('button.requested')
|
||||||
onPress = () => {
|
onPress = () => {
|
||||||
analytics('relationship_outgoing_requested_press')
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
id,
|
id,
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
|
@ -115,10 +102,8 @@ const RelationshipOutgoing = React.memo(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
analytics('relationship_outgoing_default')
|
|
||||||
content = t('button.default')
|
content = t('button.default')
|
||||||
onPress = () => {
|
onPress = () => {
|
||||||
analytics('relationship_outgoing_default_press')
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
id,
|
id,
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import apiInstance from '@api/instance'
|
import apiInstance from '@api/instance'
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import GracefullyImage from '@components/GracefullyImage'
|
import GracefullyImage from '@components/GracefullyImage'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
import { StackNavigationProp } from '@react-navigation/stack'
|
import { StackNavigationProp } from '@react-navigation/stack'
|
||||||
|
@ -79,7 +78,6 @@ const TimelineConversation = React.memo(
|
||||||
const navigation =
|
const navigation =
|
||||||
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||||
const onPress = useCallback(() => {
|
const onPress = useCallback(() => {
|
||||||
analytics('timeline_conversation_press')
|
|
||||||
if (conversation.last_status) {
|
if (conversation.last_status) {
|
||||||
conversation.unread && mutate()
|
conversation.unread && mutate()
|
||||||
navigation.push('Tab-Shared-Toot', {
|
navigation.push('Tab-Shared-Toot', {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import TimelineActioned from '@components/Timeline/Shared/Actioned'
|
import TimelineActioned from '@components/Timeline/Shared/Actioned'
|
||||||
import TimelineActions from '@components/Timeline/Shared/Actions'
|
import TimelineActions from '@components/Timeline/Shared/Actions'
|
||||||
import TimelineAttachment from '@components/Timeline/Shared/Attachment'
|
import TimelineAttachment from '@components/Timeline/Shared/Attachment'
|
||||||
|
@ -17,7 +16,7 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import { uniqBy } from 'lodash'
|
import { uniqBy } from 'lodash'
|
||||||
import React, { useRef } from 'react'
|
import React, { useRef } from 'react'
|
||||||
import { Platform, Pressable, StyleProp, View, ViewStyle } from 'react-native'
|
import { Pressable, StyleProp, View, ViewStyle } from 'react-native'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import TimelineContextMenu from './Shared/ContextMenu'
|
import TimelineContextMenu from './Shared/ContextMenu'
|
||||||
import TimelineFeedback from './Shared/Feedback'
|
import TimelineFeedback from './Shared/Feedback'
|
||||||
|
@ -29,7 +28,6 @@ export interface Props {
|
||||||
item: Mastodon.Status & { _pinned?: boolean } // For account page, internal property
|
item: Mastodon.Status & { _pinned?: boolean } // For account page, internal property
|
||||||
queryKey?: QueryKeyTimeline
|
queryKey?: QueryKeyTimeline
|
||||||
rootQueryKey?: QueryKeyTimeline
|
rootQueryKey?: QueryKeyTimeline
|
||||||
origin?: string
|
|
||||||
highlighted?: boolean
|
highlighted?: boolean
|
||||||
disableDetails?: boolean
|
disableDetails?: boolean
|
||||||
disableOnPress?: boolean
|
disableOnPress?: boolean
|
||||||
|
@ -40,7 +38,6 @@ const TimelineDefault: React.FC<Props> = ({
|
||||||
item,
|
item,
|
||||||
queryKey,
|
queryKey,
|
||||||
rootQueryKey,
|
rootQueryKey,
|
||||||
origin,
|
|
||||||
highlighted = false,
|
highlighted = false,
|
||||||
disableDetails = false,
|
disableDetails = false,
|
||||||
disableOnPress = false
|
disableOnPress = false
|
||||||
|
@ -65,9 +62,6 @@ const TimelineDefault: React.FC<Props> = ({
|
||||||
|
|
||||||
const onPress = () => {
|
const onPress = () => {
|
||||||
if (highlighted) return
|
if (highlighted) return
|
||||||
analytics('timeline_default_press', {
|
|
||||||
page: queryKey ? queryKey[1].page : origin
|
|
||||||
})
|
|
||||||
navigation.push('Tab-Shared-Toot', {
|
navigation.push('Tab-Shared-Toot', {
|
||||||
toot: actualStatus,
|
toot: actualStatus,
|
||||||
rootQueryKey: queryKey
|
rootQueryKey: queryKey
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
|
@ -27,20 +26,11 @@ const TimelineEmpty = React.memo(
|
||||||
const children = () => {
|
const children = () => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 'loading':
|
case 'loading':
|
||||||
return (
|
return <Circle size={StyleConstants.Font.Size.L} color={colors.secondary} />
|
||||||
<Circle
|
|
||||||
size={StyleConstants.Font.Size.L}
|
|
||||||
color={colors.secondary}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
case 'error':
|
case 'error':
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Icon
|
<Icon name='Frown' size={StyleConstants.Font.Size.L} color={colors.primaryDefault} />
|
||||||
name='Frown'
|
|
||||||
size={StyleConstants.Font.Size.L}
|
|
||||||
color={colors.primaryDefault}
|
|
||||||
/>
|
|
||||||
<CustomText
|
<CustomText
|
||||||
fontStyle='M'
|
fontStyle='M'
|
||||||
style={{
|
style={{
|
||||||
|
@ -51,14 +41,7 @@ const TimelineEmpty = React.memo(
|
||||||
>
|
>
|
||||||
{t('empty.error.message')}
|
{t('empty.error.message')}
|
||||||
</CustomText>
|
</CustomText>
|
||||||
<Button
|
<Button type='text' content={t('empty.error.button')} onPress={() => refetch()} />
|
||||||
type='text'
|
|
||||||
content={t('empty.error.button')}
|
|
||||||
onPress={() => {
|
|
||||||
analytics('timeline_error_press_refetch')
|
|
||||||
refetch()
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
case 'success':
|
case 'success':
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import TimelineActioned from '@components/Timeline/Shared/Actioned'
|
import TimelineActioned from '@components/Timeline/Shared/Actioned'
|
||||||
import TimelineActions from '@components/Timeline/Shared/Actions'
|
import TimelineActions from '@components/Timeline/Shared/Actions'
|
||||||
import TimelineAttachment from '@components/Timeline/Shared/Attachment'
|
import TimelineAttachment from '@components/Timeline/Shared/Attachment'
|
||||||
|
@ -15,7 +14,7 @@ import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||||
import { getInstanceAccount } from '@utils/slices/instancesSlice'
|
import { getInstanceAccount } from '@utils/slices/instancesSlice'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import { isEqual, uniqBy } from 'lodash'
|
import { uniqBy } from 'lodash'
|
||||||
import React, { useCallback, useRef } from 'react'
|
import React, { useCallback, useRef } from 'react'
|
||||||
import { Platform, Pressable, View } from 'react-native'
|
import { Platform, Pressable, View } from 'react-native'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
|
@ -57,7 +56,6 @@ const TimelineNotifications: React.FC<Props> = ({
|
||||||
const actualAccount = notification.status ? notification.status.account : notification.account
|
const actualAccount = notification.status ? notification.status.account : notification.account
|
||||||
|
|
||||||
const onPress = useCallback(() => {
|
const onPress = useCallback(() => {
|
||||||
analytics('timeline_notification_press')
|
|
||||||
notification.status &&
|
notification.status &&
|
||||||
navigation.push('Tab-Shared-Toot', {
|
navigation.push('Tab-Shared-Toot', {
|
||||||
toot: notification.status,
|
toot: notification.status,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import { ParseEmojis } from '@components/Parse'
|
import { ParseEmojis } from '@components/Parse'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
|
@ -6,7 +5,7 @@ import { StackNavigationProp } from '@react-navigation/stack'
|
||||||
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { useCallback, useMemo } from 'react'
|
import React from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { Pressable, StyleSheet, View } from 'react-native'
|
import { Pressable, StyleSheet, View } from 'react-native'
|
||||||
|
|
||||||
|
@ -20,8 +19,7 @@ const TimelineActioned = React.memo(
|
||||||
({ account, action, notification = false }: Props) => {
|
({ account, action, notification = false }: Props) => {
|
||||||
const { t } = useTranslation('componentTimeline')
|
const { t } = useTranslation('componentTimeline')
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
const navigation =
|
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||||
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
|
||||||
const name = account?.display_name || account?.username
|
const name = account?.display_name || account?.username
|
||||||
const iconColor = colors.primaryDefault
|
const iconColor = colors.primaryDefault
|
||||||
|
|
||||||
|
@ -29,10 +27,7 @@ const TimelineActioned = React.memo(
|
||||||
<ParseEmojis content={content} emojis={account.emojis} size='S' />
|
<ParseEmojis content={content} emojis={account.emojis} size='S' />
|
||||||
)
|
)
|
||||||
|
|
||||||
const onPress = useCallback(() => {
|
const onPress = () => navigation.push('Tab-Shared-Account', { account })
|
||||||
analytics('timeline_shared_actioned_press', { action })
|
|
||||||
navigation.push('Tab-Shared-Account', { account })
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const children = () => {
|
const children = () => {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
|
@ -84,18 +83,16 @@ const TimelineActions: React.FC<Props> = ({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const onPressReply = useCallback(() => {
|
const onPressReply = useCallback(
|
||||||
analytics('timeline_shared_actions_reply_press', {
|
() =>
|
||||||
page: queryKey[1].page,
|
navigation.navigate('Screen-Compose', {
|
||||||
count: status.replies_count
|
type: 'reply',
|
||||||
})
|
incomingStatus: status,
|
||||||
navigation.navigate('Screen-Compose', {
|
accts,
|
||||||
type: 'reply',
|
queryKey
|
||||||
incomingStatus: status,
|
}),
|
||||||
accts,
|
[status.replies_count]
|
||||||
queryKey
|
)
|
||||||
})
|
|
||||||
}, [status.replies_count])
|
|
||||||
const { showActionSheetWithOptions } = useActionSheet()
|
const { showActionSheetWithOptions } = useActionSheet()
|
||||||
const onPressReblog = useCallback(() => {
|
const onPressReblog = useCallback(() => {
|
||||||
if (!status.reblogged) {
|
if (!status.reblogged) {
|
||||||
|
@ -112,11 +109,6 @@ const TimelineActions: React.FC<Props> = ({
|
||||||
(selectedIndex: number) => {
|
(selectedIndex: number) => {
|
||||||
switch (selectedIndex) {
|
switch (selectedIndex) {
|
||||||
case 0:
|
case 0:
|
||||||
analytics('timeline_shared_actions_reblog_public_press', {
|
|
||||||
page: queryKey[1].page,
|
|
||||||
count: status.reblogs_count,
|
|
||||||
current: status.reblogged
|
|
||||||
})
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateStatusProperty',
|
type: 'updateStatusProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
|
@ -133,11 +125,6 @@ const TimelineActions: React.FC<Props> = ({
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
analytics('timeline_shared_actions_reblog_unlisted_press', {
|
|
||||||
page: queryKey[1].page,
|
|
||||||
count: status.reblogs_count,
|
|
||||||
current: status.reblogged
|
|
||||||
})
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateStatusProperty',
|
type: 'updateStatusProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
|
@ -157,11 +144,6 @@ const TimelineActions: React.FC<Props> = ({
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
analytics('timeline_shared_actions_reblog_press', {
|
|
||||||
page: queryKey[1].page,
|
|
||||||
count: status.reblogs_count,
|
|
||||||
current: status.reblogged
|
|
||||||
})
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateStatusProperty',
|
type: 'updateStatusProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
|
@ -179,11 +161,6 @@ const TimelineActions: React.FC<Props> = ({
|
||||||
}
|
}
|
||||||
}, [status.reblogged, status.reblogs_count])
|
}, [status.reblogged, status.reblogs_count])
|
||||||
const onPressFavourite = useCallback(() => {
|
const onPressFavourite = useCallback(() => {
|
||||||
analytics('timeline_shared_actions_favourite_press', {
|
|
||||||
page: queryKey[1].page,
|
|
||||||
count: status.favourites_count,
|
|
||||||
current: status.favourited
|
|
||||||
})
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateStatusProperty',
|
type: 'updateStatusProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
|
@ -199,10 +176,6 @@ const TimelineActions: React.FC<Props> = ({
|
||||||
})
|
})
|
||||||
}, [status.favourited, status.favourites_count])
|
}, [status.favourited, status.favourites_count])
|
||||||
const onPressBookmark = useCallback(() => {
|
const onPressBookmark = useCallback(() => {
|
||||||
analytics('timeline_shared_actions_bookmark_press', {
|
|
||||||
page: queryKey[1].page,
|
|
||||||
current: status.bookmarked
|
|
||||||
})
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateStatusProperty',
|
type: 'updateStatusProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import haptics from '@components/haptics'
|
import haptics from '@components/haptics'
|
||||||
import AttachmentAudio from '@components/Timeline/Shared/Attachment/Audio'
|
import AttachmentAudio from '@components/Timeline/Shared/Attachment/Audio'
|
||||||
|
@ -195,7 +194,6 @@ const TimelineAttachment = React.memo(
|
||||||
content={t('shared.attachment.sensitive.button')}
|
content={t('shared.attachment.sensitive.button')}
|
||||||
overlay
|
overlay
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('timeline_shared_attachment_blurview_press_show')
|
|
||||||
layoutAnimation()
|
layoutAnimation()
|
||||||
setSensitiveShown(false)
|
setSensitiveShown(false)
|
||||||
haptics('Light')
|
haptics('Light')
|
||||||
|
@ -209,7 +207,6 @@ const TimelineAttachment = React.memo(
|
||||||
round
|
round
|
||||||
overlay
|
overlay
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('timeline_shared_attachment_blurview_press_hide')
|
|
||||||
setSensitiveShown(true)
|
setSensitiveShown(true)
|
||||||
haptics('Light')
|
haptics('Light')
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import GracefullyImage from '@components/GracefullyImage'
|
import GracefullyImage from '@components/GracefullyImage'
|
||||||
import { Slider } from '@sharcoux/slider'
|
import { Slider } from '@sharcoux/slider'
|
||||||
|
@ -25,7 +24,6 @@ const AttachmentAudio: React.FC<Props> = ({ total, index, sensitiveShown, audio
|
||||||
const [audioPlaying, setAudioPlaying] = useState(false)
|
const [audioPlaying, setAudioPlaying] = useState(false)
|
||||||
const [audioPosition, setAudioPosition] = useState(0)
|
const [audioPosition, setAudioPosition] = useState(0)
|
||||||
const playAudio = useCallback(async () => {
|
const playAudio = useCallback(async () => {
|
||||||
analytics('timeline_shared_attachment_audio_play_press', { id: audio.id })
|
|
||||||
if (!audioPlayer) {
|
if (!audioPlayer) {
|
||||||
const { sound } = await Audio.Sound.createAsync(
|
const { sound } = await Audio.Sound.createAsync(
|
||||||
{ uri: audio.url },
|
{ uri: audio.url },
|
||||||
|
@ -41,7 +39,6 @@ const AttachmentAudio: React.FC<Props> = ({ total, index, sensitiveShown, audio
|
||||||
}
|
}
|
||||||
}, [audioPlayer, audioPosition])
|
}, [audioPlayer, audioPosition])
|
||||||
const pauseAudio = useCallback(async () => {
|
const pauseAudio = useCallback(async () => {
|
||||||
analytics('timeline_shared_attachment_audio_pause_press', { id: audio.id })
|
|
||||||
audioPlayer!.pauseAsync()
|
audioPlayer!.pauseAsync()
|
||||||
setAudioPlaying(false)
|
setAudioPlaying(false)
|
||||||
}, [audioPlayer])
|
}, [audioPlayer])
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import GracefullyImage from '@components/GracefullyImage'
|
import GracefullyImage from '@components/GracefullyImage'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
@ -34,27 +33,17 @@ const AttachmentImage = ({
|
||||||
hidden={sensitiveShown}
|
hidden={sensitiveShown}
|
||||||
uri={{ original: image.preview_url, remote: image.remote_url }}
|
uri={{ original: image.preview_url, remote: image.remote_url }}
|
||||||
blurhash={image.blurhash}
|
blurhash={image.blurhash}
|
||||||
onPress={() => {
|
onPress={() => navigateToImagesViewer(image.id)}
|
||||||
analytics('timeline_shared_attachment_image_press', {
|
|
||||||
id: image.id
|
|
||||||
})
|
|
||||||
navigateToImagesViewer(image.id)
|
|
||||||
}}
|
|
||||||
style={{
|
style={{
|
||||||
aspectRatio:
|
aspectRatio:
|
||||||
total > 1 ||
|
total > 1 || !image.meta?.original?.width || !image.meta?.original?.height
|
||||||
!image.meta?.original?.width ||
|
|
||||||
!image.meta?.original?.height
|
|
||||||
? attachmentAspectRatio({ total, index })
|
? attachmentAspectRatio({ total, index })
|
||||||
: image.meta.original.height / image.meta.original.width > 1
|
: image.meta.original.height / image.meta.original.width > 1
|
||||||
? 1
|
? 1
|
||||||
: image.meta.original.width / image.meta.original.height
|
: image.meta.original.width / image.meta.original.height
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<AttachmentAltText
|
<AttachmentAltText sensitiveShown={sensitiveShown} text={image.description} />
|
||||||
sensitiveShown={sensitiveShown}
|
|
||||||
text={image.description}
|
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import openLink from '@components/openLink'
|
import openLink from '@components/openLink'
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
|
@ -18,12 +17,7 @@ export interface Props {
|
||||||
attachment: Mastodon.AttachmentUnknown
|
attachment: Mastodon.AttachmentUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
const AttachmentUnsupported: React.FC<Props> = ({
|
const AttachmentUnsupported: React.FC<Props> = ({ total, index, sensitiveShown, attachment }) => {
|
||||||
total,
|
|
||||||
index,
|
|
||||||
sensitiveShown,
|
|
||||||
attachment
|
|
||||||
}) => {
|
|
||||||
const { t } = useTranslation('componentTimeline')
|
const { t } = useTranslation('componentTimeline')
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
|
|
||||||
|
@ -55,9 +49,7 @@ const AttachmentUnsupported: React.FC<Props> = ({
|
||||||
style={{
|
style={{
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
marginBottom: StyleConstants.Spacing.S,
|
marginBottom: StyleConstants.Spacing.S,
|
||||||
color: attachment.blurhash
|
color: attachment.blurhash ? colors.backgroundDefault : colors.primaryDefault
|
||||||
? colors.backgroundDefault
|
|
||||||
: colors.primaryDefault
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{t('shared.attachment.unsupported.text')}
|
{t('shared.attachment.unsupported.text')}
|
||||||
|
@ -69,17 +61,13 @@ const AttachmentUnsupported: React.FC<Props> = ({
|
||||||
size='S'
|
size='S'
|
||||||
overlay
|
overlay
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('timeline_shared_attachment_unsupported_press')
|
|
||||||
attachment.remote_url && openLink(attachment.remote_url)
|
attachment.remote_url && openLink(attachment.remote_url)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
<AttachmentAltText
|
<AttachmentAltText sensitiveShown={sensitiveShown} text={attachment.description} />
|
||||||
sensitiveShown={sensitiveShown}
|
|
||||||
text={attachment.description}
|
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||||||
import { AppState, AppStateStatus, Pressable, View } from 'react-native'
|
import { AppState, AppStateStatus, Pressable, View } from 'react-native'
|
||||||
import { Blurhash } from 'react-native-blurhash'
|
import { Blurhash } from 'react-native-blurhash'
|
||||||
import attachmentAspectRatio from './aspectRatio'
|
import attachmentAspectRatio from './aspectRatio'
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import AttachmentAltText from './AltText'
|
import AttachmentAltText from './AltText'
|
||||||
import { Platform } from 'expo-modules-core'
|
import { Platform } from 'expo-modules-core'
|
||||||
|
|
||||||
|
@ -30,13 +29,6 @@ const AttachmentVideo: React.FC<Props> = ({
|
||||||
const [videoPosition, setVideoPosition] = useState<number>(0)
|
const [videoPosition, setVideoPosition] = useState<number>(0)
|
||||||
const [videoResizeMode, setVideoResizeMode] = useState<ResizeMode>(ResizeMode.COVER)
|
const [videoResizeMode, setVideoResizeMode] = useState<ResizeMode>(ResizeMode.COVER)
|
||||||
const playOnPress = useCallback(async () => {
|
const playOnPress = useCallback(async () => {
|
||||||
analytics('timeline_shared_attachment_video_length', {
|
|
||||||
length: video.meta?.length
|
|
||||||
})
|
|
||||||
analytics('timeline_shared_attachment_vide_play_press', {
|
|
||||||
id: video.id,
|
|
||||||
timestamp: Date.now()
|
|
||||||
})
|
|
||||||
setVideoLoading(true)
|
setVideoLoading(true)
|
||||||
if (!videoLoaded) {
|
if (!videoLoaded) {
|
||||||
await videoPlayer.current?.loadAsync({ uri: video.url })
|
await videoPlayer.current?.loadAsync({ uri: video.url })
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import GracefullyImage from '@components/GracefullyImage'
|
import GracefullyImage from '@components/GracefullyImage'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
import { StackNavigationProp } from '@react-navigation/stack'
|
import { StackNavigationProp } from '@react-navigation/stack'
|
||||||
|
@ -14,43 +13,37 @@ export interface Props {
|
||||||
highlighted: boolean
|
highlighted: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const TimelineAvatar = React.memo(
|
const TimelineAvatar = React.memo(({ queryKey, account, highlighted }: Props) => {
|
||||||
({ queryKey, account, highlighted }: Props) => {
|
const { t } = useTranslation('componentTimeline')
|
||||||
const { t } = useTranslation('componentTimeline')
|
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||||
const navigation =
|
// Need to fix go back root
|
||||||
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
const onPress = useCallback(() => {
|
||||||
// Need to fix go back root
|
queryKey && navigation.push('Tab-Shared-Account', { account })
|
||||||
const onPress = useCallback(() => {
|
}, [])
|
||||||
analytics('timeline_shared_avatar_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
queryKey && navigation.push('Tab-Shared-Account', { account })
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GracefullyImage
|
<GracefullyImage
|
||||||
{...(highlighted && {
|
{...(highlighted && {
|
||||||
accessibilityLabel: t('shared.avatar.accessibilityLabel', {
|
accessibilityLabel: t('shared.avatar.accessibilityLabel', {
|
||||||
name: account.display_name
|
name: account.display_name
|
||||||
}),
|
}),
|
||||||
accessibilityHint: t('shared.avatar.accessibilityHint', {
|
accessibilityHint: t('shared.avatar.accessibilityHint', {
|
||||||
name: account.display_name
|
name: account.display_name
|
||||||
})
|
})
|
||||||
})}
|
})}
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
uri={{ original: account?.avatar, static: account?.avatar_static }}
|
uri={{ original: account?.avatar, static: account?.avatar_static }}
|
||||||
dimension={{
|
dimension={{
|
||||||
width: StyleConstants.Avatar.M,
|
width: StyleConstants.Avatar.M,
|
||||||
height: StyleConstants.Avatar.M
|
height: StyleConstants.Avatar.M
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
borderRadius: StyleConstants.Avatar.M,
|
borderRadius: StyleConstants.Avatar.M,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
marginRight: StyleConstants.Spacing.S
|
marginRight: StyleConstants.Spacing.S
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
||||||
export default TimelineAvatar
|
export default TimelineAvatar
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import ComponentAccount from '@components/Account'
|
import ComponentAccount from '@components/Account'
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import GracefullyImage from '@components/GracefullyImage'
|
import GracefullyImage from '@components/GracefullyImage'
|
||||||
import openLink from '@components/openLink'
|
import openLink from '@components/openLink'
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
|
@ -130,10 +129,10 @@ const TimelineCard = React.memo(({ card }: Props) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (isStatus && foundStatus) {
|
if (isStatus && foundStatus) {
|
||||||
return <TimelineDefault item={foundStatus} disableDetails disableOnPress origin='card' />
|
return <TimelineDefault item={foundStatus} disableDetails disableOnPress />
|
||||||
}
|
}
|
||||||
if (isAccount && foundAccount) {
|
if (isAccount && foundAccount) {
|
||||||
return <ComponentAccount account={foundAccount} origin='card' />
|
return <ComponentAccount account={foundAccount} />
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -193,10 +192,7 @@ const TimelineCard = React.memo(({ card }: Props) => {
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
borderColor: colors.border
|
borderColor: colors.border
|
||||||
}}
|
}}
|
||||||
onPress={async () => {
|
onPress={async () => await openLink(card.url, navigation)}
|
||||||
analytics('timeline_shared_card_press')
|
|
||||||
await openLink(card.url, navigation)
|
|
||||||
}}
|
|
||||||
children={cardContent}
|
children={cardContent}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
import { StackNavigationProp } from '@react-navigation/stack'
|
import { StackNavigationProp } from '@react-navigation/stack'
|
||||||
|
@ -11,10 +10,7 @@ import { useTranslation } from 'react-i18next'
|
||||||
import { StyleSheet, View } from 'react-native'
|
import { StyleSheet, View } from 'react-native'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
status: Pick<
|
status: Pick<Mastodon.Status, 'id' | 'edited_at' | 'reblogs_count' | 'favourites_count'>
|
||||||
Mastodon.Status,
|
|
||||||
'id' | 'edited_at' | 'reblogs_count' | 'favourites_count'
|
|
||||||
>
|
|
||||||
highlighted: boolean
|
highlighted: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,8 +22,7 @@ const TimelineFeedback = React.memo(
|
||||||
|
|
||||||
const { t } = useTranslation('componentTimeline')
|
const { t } = useTranslation('componentTimeline')
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
const navigation =
|
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||||
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
|
||||||
|
|
||||||
const { data } = useStatusHistory({
|
const { data } = useStatusHistory({
|
||||||
id: status.id,
|
id: status.id,
|
||||||
|
@ -39,28 +34,20 @@ const TimelineFeedback = React.memo(
|
||||||
<View style={{ flexDirection: 'row' }}>
|
<View style={{ flexDirection: 'row' }}>
|
||||||
{status.reblogs_count > 0 ? (
|
{status.reblogs_count > 0 ? (
|
||||||
<CustomText
|
<CustomText
|
||||||
accessibilityLabel={t(
|
accessibilityLabel={t('shared.actionsUsers.reblogged_by.accessibilityLabel', {
|
||||||
'shared.actionsUsers.reblogged_by.accessibilityLabel',
|
count: status.reblogs_count
|
||||||
{
|
})}
|
||||||
count: status.reblogs_count
|
accessibilityHint={t('shared.actionsUsers.reblogged_by.accessibilityHint')}
|
||||||
}
|
|
||||||
)}
|
|
||||||
accessibilityHint={t(
|
|
||||||
'shared.actionsUsers.reblogged_by.accessibilityHint'
|
|
||||||
)}
|
|
||||||
accessibilityRole='button'
|
accessibilityRole='button'
|
||||||
style={[styles.text, { color: colors.blue }]}
|
style={[styles.text, { color: colors.blue }]}
|
||||||
onPress={() => {
|
onPress={() =>
|
||||||
analytics('timeline_shared_feedback_press_reblog', {
|
|
||||||
count: status.reblogs_count
|
|
||||||
})
|
|
||||||
navigation.push('Tab-Shared-Users', {
|
navigation.push('Tab-Shared-Users', {
|
||||||
reference: 'statuses',
|
reference: 'statuses',
|
||||||
id: status.id,
|
id: status.id,
|
||||||
type: 'reblogged_by',
|
type: 'reblogged_by',
|
||||||
count: status.reblogs_count
|
count: status.reblogs_count
|
||||||
})
|
})
|
||||||
}}
|
}
|
||||||
>
|
>
|
||||||
{t('shared.actionsUsers.reblogged_by.text', {
|
{t('shared.actionsUsers.reblogged_by.text', {
|
||||||
count: status.reblogs_count
|
count: status.reblogs_count
|
||||||
|
@ -69,28 +56,20 @@ const TimelineFeedback = React.memo(
|
||||||
) : null}
|
) : null}
|
||||||
{status.favourites_count > 0 ? (
|
{status.favourites_count > 0 ? (
|
||||||
<CustomText
|
<CustomText
|
||||||
accessibilityLabel={t(
|
accessibilityLabel={t('shared.actionsUsers.favourited_by.accessibilityLabel', {
|
||||||
'shared.actionsUsers.favourited_by.accessibilityLabel',
|
count: status.reblogs_count
|
||||||
{
|
})}
|
||||||
count: status.reblogs_count
|
accessibilityHint={t('shared.actionsUsers.favourited_by.accessibilityHint')}
|
||||||
}
|
|
||||||
)}
|
|
||||||
accessibilityHint={t(
|
|
||||||
'shared.actionsUsers.favourited_by.accessibilityHint'
|
|
||||||
)}
|
|
||||||
accessibilityRole='button'
|
accessibilityRole='button'
|
||||||
style={[styles.text, { color: colors.blue }]}
|
style={[styles.text, { color: colors.blue }]}
|
||||||
onPress={() => {
|
onPress={() =>
|
||||||
analytics('timeline_shared_feedback_press_favourite', {
|
|
||||||
count: status.favourites_count
|
|
||||||
})
|
|
||||||
navigation.push('Tab-Shared-Users', {
|
navigation.push('Tab-Shared-Users', {
|
||||||
reference: 'statuses',
|
reference: 'statuses',
|
||||||
id: status.id,
|
id: status.id,
|
||||||
type: 'favourited_by',
|
type: 'favourited_by',
|
||||||
count: status.favourites_count
|
count: status.favourites_count
|
||||||
})
|
})
|
||||||
}}
|
}
|
||||||
>
|
>
|
||||||
{t('shared.actionsUsers.favourited_by.text', {
|
{t('shared.actionsUsers.favourited_by.text', {
|
||||||
count: status.favourites_count
|
count: status.favourites_count
|
||||||
|
@ -101,23 +80,13 @@ const TimelineFeedback = React.memo(
|
||||||
<View>
|
<View>
|
||||||
{data && data.length > 1 ? (
|
{data && data.length > 1 ? (
|
||||||
<CustomText
|
<CustomText
|
||||||
accessibilityLabel={t(
|
accessibilityLabel={t('shared.actionsUsers.history.accessibilityLabel', {
|
||||||
'shared.actionsUsers.history.accessibilityLabel',
|
count: data.length - 1
|
||||||
{
|
})}
|
||||||
count: data.length - 1
|
accessibilityHint={t('shared.actionsUsers.history.accessibilityHint')}
|
||||||
}
|
|
||||||
)}
|
|
||||||
accessibilityHint={t(
|
|
||||||
'shared.actionsUsers.history.accessibilityHint'
|
|
||||||
)}
|
|
||||||
accessibilityRole='button'
|
accessibilityRole='button'
|
||||||
style={[styles.text, { marginRight: 0, color: colors.blue }]}
|
style={[styles.text, { marginRight: 0, color: colors.blue }]}
|
||||||
onPress={() => {
|
onPress={() => navigation.push('Tab-Shared-History', { id: status.id })}
|
||||||
analytics('timeline_shared_feedback_press_history', {
|
|
||||||
count: data.length - 1
|
|
||||||
})
|
|
||||||
navigation.push('Tab-Shared-History', { id: status.id })
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{t('shared.actionsUsers.history.text', {
|
{t('shared.actionsUsers.history.text', {
|
||||||
count: data.length - 1
|
count: data.length - 1
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
import { ParseEmojis } from '@components/Parse'
|
import { ParseEmojis } from '@components/Parse'
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
import {
|
import { QueryKeyTimeline, useTimelineMutation } from '@utils/queryHooks/timeline'
|
||||||
QueryKeyTimeline,
|
|
||||||
useTimelineMutation
|
|
||||||
} from '@utils/queryHooks/timeline'
|
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { useCallback, useMemo } from 'react'
|
import React from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { Pressable, View } from 'react-native'
|
import { Pressable, View } from 'react-native'
|
||||||
import { useQueryClient } from 'react-query'
|
import { useQueryClient } from 'react-query'
|
||||||
|
@ -71,27 +67,6 @@ const HeaderConversation = ({ queryKey, conversation }: Props) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const actionOnPress = useCallback(() => {
|
|
||||||
analytics('timeline_conversation_delete_press')
|
|
||||||
mutation.mutate({
|
|
||||||
type: 'deleteItem',
|
|
||||||
source: 'conversations',
|
|
||||||
queryKey,
|
|
||||||
id: conversation.id
|
|
||||||
})
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const actionChildren = useMemo(
|
|
||||||
() => (
|
|
||||||
<Icon
|
|
||||||
name='Trash'
|
|
||||||
color={colors.secondary}
|
|
||||||
size={StyleConstants.Font.Size.L}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{ flex: 1, flexDirection: 'row' }}>
|
<View style={{ flex: 1, flexDirection: 'row' }}>
|
||||||
<View style={{ flex: 3 }}>
|
<View style={{ flex: 3 }}>
|
||||||
|
@ -116,8 +91,15 @@ const HeaderConversation = ({ queryKey, conversation }: Props) => {
|
||||||
|
|
||||||
<Pressable
|
<Pressable
|
||||||
style={{ flex: 1, flexDirection: 'row', justifyContent: 'center' }}
|
style={{ flex: 1, flexDirection: 'row', justifyContent: 'center' }}
|
||||||
onPress={actionOnPress}
|
onPress={() =>
|
||||||
children={actionChildren}
|
mutation.mutate({
|
||||||
|
type: 'deleteItem',
|
||||||
|
source: 'conversations',
|
||||||
|
queryKey,
|
||||||
|
id: conversation.id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
children={<Icon name='Trash' color={colors.secondary} size={StyleConstants.Font.Size.L} />}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import openLink from '@components/openLink'
|
import openLink from '@components/openLink'
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
|
@ -20,9 +19,6 @@ const HeaderSharedApplication = React.memo(
|
||||||
fontStyle='S'
|
fontStyle='S'
|
||||||
accessibilityRole='link'
|
accessibilityRole='link'
|
||||||
onPress={async () => {
|
onPress={async () => {
|
||||||
analytics('timeline_shared_header_application_press', {
|
|
||||||
application
|
|
||||||
})
|
|
||||||
application.website && (await openLink(application.website))
|
application.website && (await openLink(application.website))
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import haptics from '@components/haptics'
|
import haptics from '@components/haptics'
|
||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
|
@ -40,9 +39,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||||
const { colors, theme } = useTheme()
|
const { colors, theme } = useTheme()
|
||||||
const { t, i18n } = useTranslation('componentTimeline')
|
const { t, i18n } = useTranslation('componentTimeline')
|
||||||
|
|
||||||
const [allOptions, setAllOptions] = useState(
|
const [allOptions, setAllOptions] = useState(new Array(poll.options.length).fill(false))
|
||||||
new Array(poll.options.length).fill(false)
|
|
||||||
)
|
|
||||||
|
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const mutation = useTimelineMutation({
|
const mutation = useTimelineMutation({
|
||||||
|
@ -86,8 +83,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||||
return (
|
return (
|
||||||
<View style={{ marginRight: StyleConstants.Spacing.S }}>
|
<View style={{ marginRight: StyleConstants.Spacing.S }}>
|
||||||
<Button
|
<Button
|
||||||
onPress={() => {
|
onPress={() =>
|
||||||
analytics('timeline_shared_vote_vote_press')
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateStatusProperty',
|
type: 'updateStatusProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
|
@ -101,7 +97,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||||
options: allOptions
|
options: allOptions
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}}
|
}
|
||||||
type='text'
|
type='text'
|
||||||
content={t('shared.poll.meta.button.vote')}
|
content={t('shared.poll.meta.button.vote')}
|
||||||
loading={mutation.isLoading}
|
loading={mutation.isLoading}
|
||||||
|
@ -113,8 +109,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||||
return (
|
return (
|
||||||
<View style={{ marginRight: StyleConstants.Spacing.S }}>
|
<View style={{ marginRight: StyleConstants.Spacing.S }}>
|
||||||
<Button
|
<Button
|
||||||
onPress={() => {
|
onPress={() =>
|
||||||
analytics('timeline_shared_vote_refresh_press')
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateStatusProperty',
|
type: 'updateStatusProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
|
@ -127,7 +122,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||||
type: 'refresh'
|
type: 'refresh'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}}
|
}
|
||||||
type='text'
|
type='text'
|
||||||
content={t('shared.poll.meta.button.refresh')}
|
content={t('shared.poll.meta.button.refresh')}
|
||||||
loading={mutation.isLoading}
|
loading={mutation.isLoading}
|
||||||
|
@ -136,14 +131,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [
|
}, [theme, i18n.language, poll.expired, poll.voted, allOptions, mutation.isLoading])
|
||||||
theme,
|
|
||||||
i18n.language,
|
|
||||||
poll.expired,
|
|
||||||
poll.voted,
|
|
||||||
allOptions,
|
|
||||||
mutation.isLoading
|
|
||||||
])
|
|
||||||
|
|
||||||
const isSelected = useCallback(
|
const isSelected = useCallback(
|
||||||
(index: number): string =>
|
(index: number): string =>
|
||||||
|
@ -154,20 +142,13 @@ const TimelinePoll: React.FC<Props> = ({
|
||||||
)
|
)
|
||||||
|
|
||||||
const pollBodyDisallow = useMemo(() => {
|
const pollBodyDisallow = useMemo(() => {
|
||||||
const maxValue = maxBy(
|
const maxValue = maxBy(poll.options, option => option.votes_count)?.votes_count
|
||||||
poll.options,
|
|
||||||
option => option.votes_count
|
|
||||||
)?.votes_count
|
|
||||||
return poll.options.map((option, index) => (
|
return poll.options.map((option, index) => (
|
||||||
<View
|
<View key={index} style={{ flex: 1, paddingVertical: StyleConstants.Spacing.S }}>
|
||||||
key={index}
|
|
||||||
style={{ flex: 1, paddingVertical: StyleConstants.Spacing.S }}
|
|
||||||
>
|
|
||||||
<View style={{ flex: 1, flexDirection: 'row' }}>
|
<View style={{ flex: 1, flexDirection: 'row' }}>
|
||||||
<Icon
|
<Icon
|
||||||
style={{
|
style={{
|
||||||
paddingTop:
|
paddingTop: StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
|
||||||
StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
|
|
||||||
marginRight: StyleConstants.Spacing.S
|
marginRight: StyleConstants.Spacing.S
|
||||||
}}
|
}}
|
||||||
name={
|
name={
|
||||||
|
@ -176,9 +157,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||||
}` as any
|
}` as any
|
||||||
}
|
}
|
||||||
size={StyleConstants.Font.Size.M}
|
size={StyleConstants.Font.Size.M}
|
||||||
color={
|
color={poll.own_votes?.includes(index) ? colors.blue : colors.disabled}
|
||||||
poll.own_votes?.includes(index) ? colors.blue : colors.disabled
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
<CustomText style={{ flex: 1 }}>
|
<CustomText style={{ flex: 1 }}>
|
||||||
<ParseEmojis content={option.title} emojis={poll.emojis} />
|
<ParseEmojis content={option.title} emojis={poll.emojis} />
|
||||||
|
@ -194,11 +173,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{poll.votes_count
|
{poll.votes_count
|
||||||
? Math.round(
|
? Math.round((option.votes_count / (poll.voters_count || poll.votes_count)) * 100)
|
||||||
(option.votes_count /
|
|
||||||
(poll.voters_count || poll.votes_count)) *
|
|
||||||
100
|
|
||||||
)
|
|
||||||
: 0}
|
: 0}
|
||||||
%
|
%
|
||||||
</CustomText>
|
</CustomText>
|
||||||
|
@ -213,11 +188,9 @@ const TimelinePoll: React.FC<Props> = ({
|
||||||
marginTop: StyleConstants.Spacing.XS,
|
marginTop: StyleConstants.Spacing.XS,
|
||||||
marginBottom: StyleConstants.Spacing.S,
|
marginBottom: StyleConstants.Spacing.S,
|
||||||
width: `${Math.round(
|
width: `${Math.round(
|
||||||
(option.votes_count / (poll.voters_count || poll.votes_count)) *
|
(option.votes_count / (poll.voters_count || poll.votes_count)) * 100
|
||||||
100
|
|
||||||
)}%`,
|
)}%`,
|
||||||
backgroundColor:
|
backgroundColor: option.votes_count === maxValue ? colors.blue : colors.disabled
|
||||||
option.votes_count === maxValue ? colors.blue : colors.disabled
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
@ -229,21 +202,15 @@ const TimelinePoll: React.FC<Props> = ({
|
||||||
key={index}
|
key={index}
|
||||||
style={{ flex: 1, paddingVertical: StyleConstants.Spacing.S }}
|
style={{ flex: 1, paddingVertical: StyleConstants.Spacing.S }}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('timeline_shared_vote_option_press')
|
|
||||||
!allOptions[index] && haptics('Light')
|
!allOptions[index] && haptics('Light')
|
||||||
if (poll.multiple) {
|
if (poll.multiple) {
|
||||||
setAllOptions(allOptions.map((o, i) => (i === index ? !o : o)))
|
setAllOptions(allOptions.map((o, i) => (i === index ? !o : o)))
|
||||||
} else {
|
} else {
|
||||||
{
|
{
|
||||||
const otherOptions =
|
const otherOptions = allOptions[index] === false ? false : undefined
|
||||||
allOptions[index] === false ? false : undefined
|
|
||||||
setAllOptions(
|
setAllOptions(
|
||||||
allOptions.map((o, i) =>
|
allOptions.map((o, i) =>
|
||||||
i === index
|
i === index ? !o : otherOptions !== undefined ? otherOptions : o
|
||||||
? !o
|
|
||||||
: otherOptions !== undefined
|
|
||||||
? otherOptions
|
|
||||||
: o
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -253,8 +220,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||||
<View style={{ flex: 1, flexDirection: 'row' }}>
|
<View style={{ flex: 1, flexDirection: 'row' }}>
|
||||||
<Icon
|
<Icon
|
||||||
style={{
|
style={{
|
||||||
paddingTop:
|
paddingTop: StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
|
||||||
StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
|
|
||||||
marginRight: StyleConstants.Spacing.S
|
marginRight: StyleConstants.Spacing.S
|
||||||
}}
|
}}
|
||||||
name={isSelected(index)}
|
name={isSelected(index)}
|
||||||
|
@ -271,13 +237,9 @@ const TimelinePoll: React.FC<Props> = ({
|
||||||
|
|
||||||
const pollVoteCounts = () => {
|
const pollVoteCounts = () => {
|
||||||
if (poll.voters_count !== null) {
|
if (poll.voters_count !== null) {
|
||||||
return (
|
return t('shared.poll.meta.count.voters', { count: poll.voters_count }) + ' • '
|
||||||
t('shared.poll.meta.count.voters', { count: poll.voters_count }) + ' • '
|
|
||||||
)
|
|
||||||
} else if (poll.votes_count !== null) {
|
} else if (poll.votes_count !== null) {
|
||||||
return (
|
return t('shared.poll.meta.count.votes', { count: poll.votes_count }) + ' • '
|
||||||
t('shared.poll.meta.count.votes', { count: poll.votes_count }) + ' • '
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,10 +270,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{pollButton}
|
{pollButton}
|
||||||
<CustomText
|
<CustomText fontStyle='S' style={{ flexShrink: 1, color: colors.secondary }}>
|
||||||
fontStyle='S'
|
|
||||||
style={{ flexShrink: 1, color: colors.secondary }}
|
|
||||||
>
|
|
||||||
{pollVoteCounts()}
|
{pollVoteCounts()}
|
||||||
{pollExpiration()}
|
{pollExpiration()}
|
||||||
</CustomText>
|
</CustomText>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import { ParseHTML } from '@components/Parse'
|
import { ParseHTML } from '@components/Parse'
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
import getLanguage from '@helpers/getLanguage'
|
import getLanguage from '@helpers/getLanguage'
|
||||||
|
@ -85,15 +84,9 @@ const TimelineTranslate = React.memo(
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
if (!isSuccess) {
|
if (!isSuccess) {
|
||||||
analytics('timeline_shared_translate_retry', {
|
|
||||||
language: detectedLanguage
|
|
||||||
})
|
|
||||||
refetch()
|
refetch()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
analytics('timeline_shared_translate', {
|
|
||||||
language: detectedLanguage
|
|
||||||
})
|
|
||||||
setEnabled(true)
|
setEnabled(true)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
import * as Analytics from 'expo-firebase-analytics'
|
|
||||||
|
|
||||||
const analytics = (event: string, params?: { [key: string]: any }) => {
|
|
||||||
Analytics.logEvent(event, params).catch(() => {})
|
|
||||||
}
|
|
||||||
|
|
||||||
export default analytics
|
|
|
@ -275,10 +275,6 @@
|
||||||
"contact": {
|
"contact": {
|
||||||
"heading": "Contact tooot"
|
"heading": "Contact tooot"
|
||||||
},
|
},
|
||||||
"analytics": {
|
|
||||||
"heading": "Help us improve",
|
|
||||||
"description": "Collecting only non-user relative usage"
|
|
||||||
},
|
|
||||||
"version": "Version v{{version}}",
|
"version": "Version v{{version}}",
|
||||||
"instanceVersion": "Mastodon version v{{version}}"
|
"instanceVersion": "Mastodon version v{{version}}"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import { MenuContainer, MenuHeader, MenuRow } from '@components/Menu'
|
import { MenuContainer, MenuHeader, MenuRow } from '@components/Menu'
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
import {
|
import {
|
||||||
|
@ -74,9 +73,6 @@ const ActionsAccount: React.FC<Props> = ({
|
||||||
<MenuHeader heading={t('shared.header.actions.account.heading')} />
|
<MenuHeader heading={t('shared.header.actions.account.heading')} />
|
||||||
<MenuRow
|
<MenuRow
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('timeline_shared_headeractions_account_mute_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
dismiss()
|
dismiss()
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateAccountProperty',
|
type: 'updateAccountProperty',
|
||||||
|
@ -92,9 +88,6 @@ const ActionsAccount: React.FC<Props> = ({
|
||||||
/>
|
/>
|
||||||
<MenuRow
|
<MenuRow
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('timeline_shared_headeractions_account_block_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
dismiss()
|
dismiss()
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateAccountProperty',
|
type: 'updateAccountProperty',
|
||||||
|
@ -110,9 +103,6 @@ const ActionsAccount: React.FC<Props> = ({
|
||||||
/>
|
/>
|
||||||
<MenuRow
|
<MenuRow
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('timeline_shared_headeractions_account_reports_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
dismiss()
|
dismiss()
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateAccountProperty',
|
type: 'updateAccountProperty',
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import MenuContainer from '@components/Menu/Container'
|
import MenuContainer from '@components/Menu/Container'
|
||||||
import MenuHeader from '@components/Menu/Header'
|
import MenuHeader from '@components/Menu/Header'
|
||||||
import MenuRow from '@components/Menu/Row'
|
import MenuRow from '@components/Menu/Row'
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
import {
|
import { QueryKeyTimeline, useTimelineMutation } from '@utils/queryHooks/timeline'
|
||||||
QueryKeyTimeline,
|
|
||||||
useTimelineMutation
|
|
||||||
} from '@utils/queryHooks/timeline'
|
|
||||||
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'
|
||||||
|
@ -20,12 +16,7 @@ export interface Props {
|
||||||
dismiss: () => void
|
dismiss: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const ActionsDomain: React.FC<Props> = ({
|
const ActionsDomain: React.FC<Props> = ({ queryKey, rootQueryKey, domain, dismiss }) => {
|
||||||
queryKey,
|
|
||||||
rootQueryKey,
|
|
||||||
domain,
|
|
||||||
dismiss
|
|
||||||
}) => {
|
|
||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
const { t } = useTranslation('componentTimeline')
|
const { t } = useTranslation('componentTimeline')
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
@ -47,10 +38,7 @@ const ActionsDomain: React.FC<Props> = ({
|
||||||
<MenuContainer>
|
<MenuContainer>
|
||||||
<MenuHeader heading={t(`shared.header.actions.domain.heading`)} />
|
<MenuHeader heading={t(`shared.header.actions.domain.heading`)} />
|
||||||
<MenuRow
|
<MenuRow
|
||||||
onPress={() => {
|
onPress={() =>
|
||||||
analytics('timeline_shared_headeractions_domain_block_press', {
|
|
||||||
page: queryKey[1].page
|
|
||||||
})
|
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
t('shared.header.actions.domain.alert.title', { domain }),
|
t('shared.header.actions.domain.alert.title', { domain }),
|
||||||
t('shared.header.actions.domain.alert.message'),
|
t('shared.header.actions.domain.alert.message'),
|
||||||
|
@ -63,12 +51,6 @@ const ActionsDomain: React.FC<Props> = ({
|
||||||
text: t('shared.header.actions.domain.alert.buttons.confirm'),
|
text: t('shared.header.actions.domain.alert.buttons.confirm'),
|
||||||
style: 'destructive',
|
style: 'destructive',
|
||||||
onPress: () => {
|
onPress: () => {
|
||||||
analytics(
|
|
||||||
'timeline_shared_headeractions_domain_block_confirm',
|
|
||||||
{
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
}
|
|
||||||
)
|
|
||||||
dismiss()
|
dismiss()
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'domainBlock',
|
type: 'domainBlock',
|
||||||
|
@ -79,7 +61,7 @@ const ActionsDomain: React.FC<Props> = ({
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
}}
|
}
|
||||||
iconFront='CloudOff'
|
iconFront='CloudOff'
|
||||||
title={t(`shared.header.actions.domain.block.button`, {
|
title={t(`shared.header.actions.domain.block.button`, {
|
||||||
domain
|
domain
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import MenuContainer from '@components/Menu/Container'
|
import MenuContainer from '@components/Menu/Container'
|
||||||
import MenuHeader from '@components/Menu/Header'
|
import MenuHeader from '@components/Menu/Header'
|
||||||
import MenuRow from '@components/Menu/Row'
|
import MenuRow from '@components/Menu/Row'
|
||||||
|
@ -22,7 +21,6 @@ const ActionsShare: React.FC<Props> = ({ type, url, dismiss }) => {
|
||||||
iconFront='Share2'
|
iconFront='Share2'
|
||||||
title={t(`shared.header.actions.share.${type}.button`)}
|
title={t(`shared.header.actions.share.${type}.button`)}
|
||||||
onPress={async () => {
|
onPress={async () => {
|
||||||
analytics('timeline_shared_headeractions_share_press')
|
|
||||||
switch (Platform.OS) {
|
switch (Platform.OS) {
|
||||||
case 'ios':
|
case 'ios':
|
||||||
await Share.share({
|
await Share.share({
|
||||||
|
|
|
@ -8,7 +8,6 @@ import {
|
||||||
QueryKeyTimeline,
|
QueryKeyTimeline,
|
||||||
useTimelineMutation
|
useTimelineMutation
|
||||||
} from '@utils/queryHooks/timeline'
|
} from '@utils/queryHooks/timeline'
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import apiInstance from '@api/instance'
|
import apiInstance from '@api/instance'
|
||||||
|
@ -69,9 +68,6 @@ const ActionsStatus: React.FC<Props> = ({
|
||||||
{canEditPost ? (
|
{canEditPost ? (
|
||||||
<MenuRow
|
<MenuRow
|
||||||
onPress={async () => {
|
onPress={async () => {
|
||||||
analytics('timeline_shared_headeractions_status_edit_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
let replyToStatus: Mastodon.Status | undefined = undefined
|
let replyToStatus: Mastodon.Status | undefined = undefined
|
||||||
if (status.in_reply_to_id) {
|
if (status.in_reply_to_id) {
|
||||||
replyToStatus = await apiInstance<Mastodon.Status>({
|
replyToStatus = await apiInstance<Mastodon.Status>({
|
||||||
|
@ -107,9 +103,6 @@ const ActionsStatus: React.FC<Props> = ({
|
||||||
) : null}
|
) : null}
|
||||||
<MenuRow
|
<MenuRow
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('timeline_shared_headeractions_status_delete_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
t('shared.header.actions.status.delete.alert.title'),
|
t('shared.header.actions.status.delete.alert.title'),
|
||||||
t('shared.header.actions.status.delete.alert.message'),
|
t('shared.header.actions.status.delete.alert.message'),
|
||||||
|
@ -126,12 +119,6 @@ const ActionsStatus: React.FC<Props> = ({
|
||||||
),
|
),
|
||||||
style: 'destructive',
|
style: 'destructive',
|
||||||
onPress: async () => {
|
onPress: async () => {
|
||||||
analytics(
|
|
||||||
'timeline_shared_headeractions_status_delete_confirm',
|
|
||||||
{
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
}
|
|
||||||
)
|
|
||||||
dismiss()
|
dismiss()
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'deleteItem',
|
type: 'deleteItem',
|
||||||
|
@ -150,9 +137,6 @@ const ActionsStatus: React.FC<Props> = ({
|
||||||
/>
|
/>
|
||||||
<MenuRow
|
<MenuRow
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('timeline_shared_headeractions_status_deleteedit_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
t('shared.header.actions.status.deleteEdit.alert.title'),
|
t('shared.header.actions.status.deleteEdit.alert.title'),
|
||||||
t('shared.header.actions.status.deleteEdit.alert.message'),
|
t('shared.header.actions.status.deleteEdit.alert.message'),
|
||||||
|
@ -169,12 +153,6 @@ const ActionsStatus: React.FC<Props> = ({
|
||||||
),
|
),
|
||||||
style: 'destructive',
|
style: 'destructive',
|
||||||
onPress: async () => {
|
onPress: async () => {
|
||||||
analytics(
|
|
||||||
'timeline_shared_headeractions_status_deleteedit_confirm',
|
|
||||||
{
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
}
|
|
||||||
)
|
|
||||||
let replyToStatus: Mastodon.Status | undefined = undefined
|
let replyToStatus: Mastodon.Status | undefined = undefined
|
||||||
if (status.in_reply_to_id) {
|
if (status.in_reply_to_id) {
|
||||||
replyToStatus = await apiInstance<Mastodon.Status>({
|
replyToStatus = await apiInstance<Mastodon.Status>({
|
||||||
|
@ -208,9 +186,6 @@ const ActionsStatus: React.FC<Props> = ({
|
||||||
/>
|
/>
|
||||||
<MenuRow
|
<MenuRow
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('timeline_shared_headeractions_status_mute_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
dismiss()
|
dismiss()
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateStatusProperty',
|
type: 'updateStatusProperty',
|
||||||
|
@ -236,9 +211,6 @@ const ActionsStatus: React.FC<Props> = ({
|
||||||
{(status.visibility === 'public' || status.visibility === 'unlisted') && (
|
{(status.visibility === 'public' || status.visibility === 'unlisted') && (
|
||||||
<MenuRow
|
<MenuRow
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('timeline_shared_headeractions_status_pin_press', {
|
|
||||||
page: queryKey && queryKey[1].page
|
|
||||||
})
|
|
||||||
dismiss()
|
dismiss()
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
type: 'updateStatusProperty',
|
type: 'updateStatusProperty',
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import haptics from '@components/haptics'
|
import haptics from '@components/haptics'
|
||||||
import { ParseHTML } from '@components/Parse'
|
import { ParseHTML } from '@components/Parse'
|
||||||
|
@ -7,10 +6,7 @@ import CustomText from '@components/Text'
|
||||||
import { BlurView } from '@react-native-community/blur'
|
import { BlurView } from '@react-native-community/blur'
|
||||||
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
||||||
import { RootStackScreenProps } from '@utils/navigation/navigators'
|
import { RootStackScreenProps } from '@utils/navigation/navigators'
|
||||||
import {
|
import { useAnnouncementMutation, useAnnouncementQuery } from '@utils/queryHooks/announcement'
|
||||||
useAnnouncementMutation,
|
|
||||||
useAnnouncementQuery
|
|
||||||
} from '@utils/queryHooks/announcement'
|
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { useCallback, useEffect, useState } from 'react'
|
import React, { useCallback, useEffect, useState } from 'react'
|
||||||
|
@ -29,9 +25,7 @@ import FastImage from 'react-native-fast-image'
|
||||||
import { FlatList, ScrollView } from 'react-native-gesture-handler'
|
import { FlatList, ScrollView } from 'react-native-gesture-handler'
|
||||||
import { SafeAreaView } from 'react-native-safe-area-context'
|
import { SafeAreaView } from 'react-native-safe-area-context'
|
||||||
|
|
||||||
const ScreenAnnouncements: React.FC<
|
const ScreenAnnouncements: React.FC<RootStackScreenProps<'Screen-Announcements'>> = ({
|
||||||
RootStackScreenProps<'Screen-Announcements'>
|
|
||||||
> = ({
|
|
||||||
route: {
|
route: {
|
||||||
params: { showAll = false }
|
params: { showAll = false }
|
||||||
},
|
},
|
||||||
|
@ -46,9 +40,7 @@ const ScreenAnnouncements: React.FC<
|
||||||
showAll,
|
showAll,
|
||||||
options: {
|
options: {
|
||||||
select: announcements =>
|
select: announcements =>
|
||||||
announcements.filter(announcement =>
|
announcements.filter(announcement => (showAll ? announcement : !announcement.read))
|
||||||
showAll ? announcement : !announcement.read
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const mutation = useAnnouncementMutation({
|
const mutation = useAnnouncementMutation({
|
||||||
|
@ -75,10 +67,7 @@ const ScreenAnnouncements: React.FC<
|
||||||
justifyContent: 'center'
|
justifyContent: 'center'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Pressable
|
<Pressable style={StyleSheet.absoluteFillObject} onPress={() => navigation.goBack()} />
|
||||||
style={StyleSheet.absoluteFillObject}
|
|
||||||
onPress={() => navigation.goBack()}
|
|
||||||
/>
|
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
flexShrink: 1,
|
flexShrink: 1,
|
||||||
|
@ -136,31 +125,22 @@ const ScreenAnnouncements: React.FC<
|
||||||
marginRight: StyleConstants.Spacing.M,
|
marginRight: StyleConstants.Spacing.M,
|
||||||
borderRadius: 6,
|
borderRadius: 6,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
borderColor: reaction.me
|
borderColor: reaction.me ? colors.disabled : colors.primaryDefault,
|
||||||
? colors.disabled
|
backgroundColor: reaction.me ? colors.disabled : colors.backgroundDefault
|
||||||
: colors.primaryDefault,
|
|
||||||
backgroundColor: reaction.me
|
|
||||||
? colors.disabled
|
|
||||||
: colors.backgroundDefault
|
|
||||||
}}
|
}}
|
||||||
onPress={() => {
|
onPress={() =>
|
||||||
analytics('announcement_reaction_press', {
|
|
||||||
current: reaction.me
|
|
||||||
})
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
type: 'reaction',
|
type: 'reaction',
|
||||||
name: reaction.name,
|
name: reaction.name,
|
||||||
me: reaction.me
|
me: reaction.me
|
||||||
})
|
})
|
||||||
}}
|
}
|
||||||
>
|
>
|
||||||
{reaction.url ? (
|
{reaction.url ? (
|
||||||
<FastImage
|
<FastImage
|
||||||
source={{
|
source={{
|
||||||
uri: reduceMotionEnabled
|
uri: reduceMotionEnabled ? reaction.static_url : reaction.url
|
||||||
? reaction.static_url
|
|
||||||
: reaction.url
|
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
width: StyleConstants.Font.LineHeight.M + 3,
|
width: StyleConstants.Font.LineHeight.M + 3,
|
||||||
|
@ -183,27 +163,14 @@ const ScreenAnnouncements: React.FC<
|
||||||
) : null}
|
) : null}
|
||||||
</Pressable>
|
</Pressable>
|
||||||
))}
|
))}
|
||||||
{/* <Pressable
|
|
||||||
style={[styles.reaction, { borderColor: colors.primaryDefault }]}
|
|
||||||
onPress={() => invisibleTextInputRef.current?.focus()}
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
name='Plus'
|
|
||||||
size={StyleConstants.Font.Size.M}
|
|
||||||
color={colors.primaryDefault}
|
|
||||||
/>
|
|
||||||
</Pressable> */}
|
|
||||||
</View>
|
</View>
|
||||||
) : null}
|
) : null}
|
||||||
<Button
|
<Button
|
||||||
type='text'
|
type='text'
|
||||||
content={
|
content={item.read ? t('content.button.read') : t('content.button.unread')}
|
||||||
item.read ? t('content.button.read') : t('content.button.unread')
|
|
||||||
}
|
|
||||||
loading={mutation.isLoading}
|
loading={mutation.isLoading}
|
||||||
disabled={item.read}
|
disabled={item.read}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('announcement_read_press')
|
|
||||||
!item.read &&
|
!item.read &&
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
|
@ -279,10 +246,8 @@ const ScreenAnnouncements: React.FC<
|
||||||
borderRadius: StyleConstants.Spacing.S,
|
borderRadius: StyleConstants.Spacing.S,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
borderColor: colors.primaryDefault,
|
borderColor: colors.primaryDefault,
|
||||||
backgroundColor:
|
backgroundColor: i === index ? colors.primaryDefault : undefined,
|
||||||
i === index ? colors.primaryDefault : undefined,
|
marginLeft: i === query.data.length ? 0 : StyleConstants.Spacing.S
|
||||||
marginLeft:
|
|
||||||
i === query.data.length ? 0 : StyleConstants.Spacing.S
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
@ -292,9 +257,7 @@ const ScreenAnnouncements: React.FC<
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
</BlurView>
|
</BlurView>
|
||||||
) : (
|
) : (
|
||||||
<SafeAreaView
|
<SafeAreaView style={{ flex: 1, backgroundColor: colors.backgroundDefault }}>
|
||||||
style={{ flex: 1, backgroundColor: colors.backgroundDefault }}
|
|
||||||
>
|
|
||||||
<FlatList
|
<FlatList
|
||||||
horizontal
|
horizontal
|
||||||
data={query.data}
|
data={query.data}
|
||||||
|
@ -323,10 +286,8 @@ const ScreenAnnouncements: React.FC<
|
||||||
borderRadius: StyleConstants.Spacing.S,
|
borderRadius: StyleConstants.Spacing.S,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
borderColor: colors.primaryDefault,
|
borderColor: colors.primaryDefault,
|
||||||
backgroundColor:
|
backgroundColor: i === index ? colors.primaryDefault : undefined,
|
||||||
i === index ? colors.primaryDefault : undefined,
|
marginLeft: i === query.data.length ? 0 : StyleConstants.Spacing.S
|
||||||
marginLeft:
|
|
||||||
i === query.data.length ? 0 : StyleConstants.Spacing.S
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import { ComponentEmojis } from '@components/Emojis'
|
import { ComponentEmojis } from '@components/Emojis'
|
||||||
import { EmojisState } from '@components/Emojis/helpers/EmojisContext'
|
import { EmojisState } from '@components/Emojis/helpers/EmojisContext'
|
||||||
import { HeaderLeft, HeaderRight } from '@components/Header'
|
import { HeaderLeft, HeaderRight } from '@components/Header'
|
||||||
|
@ -209,19 +208,15 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
|
||||||
type='text'
|
type='text'
|
||||||
content={t('heading.left.button')}
|
content={t('heading.left.button')}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('compose_header_back_press')
|
|
||||||
if (!composeState.dirty) {
|
if (!composeState.dirty) {
|
||||||
analytics('compose_header_back_empty')
|
|
||||||
navigation.goBack()
|
navigation.goBack()
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
analytics('compose_header_back_state_occupied')
|
|
||||||
Alert.alert(t('heading.left.alert.title'), undefined, [
|
Alert.alert(t('heading.left.alert.title'), undefined, [
|
||||||
{
|
{
|
||||||
text: t('heading.left.alert.buttons.delete'),
|
text: t('heading.left.alert.buttons.delete'),
|
||||||
style: 'destructive',
|
style: 'destructive',
|
||||||
onPress: () => {
|
onPress: () => {
|
||||||
analytics('compose_header_back_occupied_save')
|
|
||||||
removeDraft()
|
removeDraft()
|
||||||
navigation.goBack()
|
navigation.goBack()
|
||||||
}
|
}
|
||||||
|
@ -229,17 +224,13 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
|
||||||
{
|
{
|
||||||
text: t('heading.left.alert.buttons.save'),
|
text: t('heading.left.alert.buttons.save'),
|
||||||
onPress: () => {
|
onPress: () => {
|
||||||
analytics('compose_header_back_occupied_delete')
|
|
||||||
saveDraft()
|
saveDraft()
|
||||||
navigation.goBack()
|
navigation.goBack()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: t('heading.left.alert.buttons.cancel'),
|
text: t('heading.left.alert.buttons.cancel'),
|
||||||
style: 'cancel',
|
style: 'cancel'
|
||||||
onPress: () => {
|
|
||||||
analytics('compose_header_back_occupied_cancel')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
@ -272,7 +263,6 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
|
||||||
: t('heading.right.button.default')
|
: t('heading.right.button.default')
|
||||||
}
|
}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('compose_header_post_press')
|
|
||||||
composeDispatch({ type: 'posting', payload: true })
|
composeDispatch({ type: 'posting', payload: true })
|
||||||
|
|
||||||
composePost(params, composeState)
|
composePost(params, composeState)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import apiInstance from '@api/instance'
|
import apiInstance from '@api/instance'
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import haptics from '@components/haptics'
|
import haptics from '@components/haptics'
|
||||||
import { HeaderRight } from '@components/Header'
|
import { HeaderRight } from '@components/Header'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
|
@ -29,8 +28,6 @@ const ComposeEditAttachmentSubmit: React.FC<Props> = ({ index }) => {
|
||||||
content='Save'
|
content='Save'
|
||||||
loading={isSubmitting}
|
loading={isSubmitting}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('editattachment_confirm_press')
|
|
||||||
|
|
||||||
setIsSubmitting(true)
|
setIsSubmitting(true)
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
if (theAttachment.description) {
|
if (theAttachment.description) {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import { emojis } from '@components/Emojis'
|
import { emojis } from '@components/Emojis'
|
||||||
import EmojisContext from '@components/Emojis/helpers/EmojisContext'
|
import EmojisContext from '@components/Emojis/helpers/EmojisContext'
|
||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
|
@ -36,9 +35,6 @@ const ComposeActions: React.FC = () => {
|
||||||
if (composeState.poll.active) return
|
if (composeState.poll.active) return
|
||||||
|
|
||||||
if (composeState.attachments.uploads.length < instanceConfigurationStatusMaxAttachments) {
|
if (composeState.attachments.uploads.length < instanceConfigurationStatusMaxAttachments) {
|
||||||
analytics('compose_actions_attachment_press', {
|
|
||||||
count: composeState.attachments.uploads.length
|
|
||||||
})
|
|
||||||
return chooseAndUploadAttachment({
|
return chooseAndUploadAttachment({
|
||||||
composeDispatch,
|
composeDispatch,
|
||||||
showActionSheetWithOptions
|
showActionSheetWithOptions
|
||||||
|
@ -57,9 +53,6 @@ const ComposeActions: React.FC = () => {
|
||||||
}, [composeState.poll.active, composeState.attachments.uploads])
|
}, [composeState.poll.active, composeState.attachments.uploads])
|
||||||
const pollOnPress = () => {
|
const pollOnPress = () => {
|
||||||
if (!composeState.attachments.uploads.length) {
|
if (!composeState.attachments.uploads.length) {
|
||||||
analytics('compose_actions_poll_press', {
|
|
||||||
current: composeState.poll.active
|
|
||||||
})
|
|
||||||
layoutAnimation()
|
layoutAnimation()
|
||||||
composeDispatch({
|
composeDispatch({
|
||||||
type: 'poll',
|
type: 'poll',
|
||||||
|
@ -101,31 +94,15 @@ const ComposeActions: React.FC = () => {
|
||||||
buttonIndex => {
|
buttonIndex => {
|
||||||
switch (buttonIndex) {
|
switch (buttonIndex) {
|
||||||
case 0:
|
case 0:
|
||||||
analytics('compose_actions_visibility_press', {
|
|
||||||
current: composeState.visibility,
|
|
||||||
new: 'public'
|
|
||||||
})
|
|
||||||
composeDispatch({ type: 'visibility', payload: 'public' })
|
composeDispatch({ type: 'visibility', payload: 'public' })
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
analytics('compose_actions_visibility_press', {
|
|
||||||
current: composeState.visibility,
|
|
||||||
new: 'unlisted'
|
|
||||||
})
|
|
||||||
composeDispatch({ type: 'visibility', payload: 'unlisted' })
|
composeDispatch({ type: 'visibility', payload: 'unlisted' })
|
||||||
break
|
break
|
||||||
case 2:
|
case 2:
|
||||||
analytics('compose_actions_visibility_press', {
|
|
||||||
current: composeState.visibility,
|
|
||||||
new: 'private'
|
|
||||||
})
|
|
||||||
composeDispatch({ type: 'visibility', payload: 'private' })
|
composeDispatch({ type: 'visibility', payload: 'private' })
|
||||||
break
|
break
|
||||||
case 3:
|
case 3:
|
||||||
analytics('compose_actions_visibility_press', {
|
|
||||||
current: composeState.visibility,
|
|
||||||
new: 'direct'
|
|
||||||
})
|
|
||||||
composeDispatch({ type: 'visibility', payload: 'direct' })
|
composeDispatch({ type: 'visibility', payload: 'direct' })
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -135,9 +112,6 @@ const ComposeActions: React.FC = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const spoilerOnPress = () => {
|
const spoilerOnPress = () => {
|
||||||
analytics('compose_actions_spoiler_press', {
|
|
||||||
current: composeState.spoiler.active
|
|
||||||
})
|
|
||||||
if (composeState.spoiler.active) {
|
if (composeState.spoiler.active) {
|
||||||
composeState.textInputFocus.refs.text.current?.focus()
|
composeState.textInputFocus.refs.text.current?.focus()
|
||||||
}
|
}
|
||||||
|
@ -159,9 +133,6 @@ const ComposeActions: React.FC = () => {
|
||||||
}
|
}
|
||||||
}, [emojis.current?.length, emojisState.targetIndex])
|
}, [emojis.current?.length, emojisState.targetIndex])
|
||||||
const emojiOnPress = () => {
|
const emojiOnPress = () => {
|
||||||
analytics('compose_actions_emojis_press', {
|
|
||||||
current: emojisState.targetIndex !== -1
|
|
||||||
})
|
|
||||||
if (emojisState.targetIndex === -1) {
|
if (emojisState.targetIndex === -1) {
|
||||||
Keyboard.dismiss()
|
Keyboard.dismiss()
|
||||||
const focusedPropsIndex = emojisState.inputProps?.findIndex(props => props.isFocused.current)
|
const focusedPropsIndex = emojisState.inputProps?.findIndex(props => props.isFocused.current)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import haptics from '@components/haptics'
|
import haptics from '@components/haptics'
|
||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
|
@ -9,14 +8,7 @@ import { getInstanceConfigurationStatusMaxAttachments } from '@utils/slices/inst
|
||||||
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'
|
||||||
import React, {
|
import React, { RefObject, useCallback, useContext, useEffect, useMemo, useRef } from 'react'
|
||||||
RefObject,
|
|
||||||
useCallback,
|
|
||||||
useContext,
|
|
||||||
useEffect,
|
|
||||||
useMemo,
|
|
||||||
useRef
|
|
||||||
} from 'react'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { FlatList, Pressable, StyleSheet, View } from 'react-native'
|
import { FlatList, Pressable, StyleSheet, View } from 'react-native'
|
||||||
import { Circle } from 'react-native-animated-spinkit'
|
import { Circle } from 'react-native-animated-spinkit'
|
||||||
|
@ -39,41 +31,29 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
const navigation = useNavigation<any>()
|
const navigation = useNavigation<any>()
|
||||||
|
|
||||||
const maxAttachments = useSelector(
|
const maxAttachments = useSelector(getInstanceConfigurationStatusMaxAttachments, () => true)
|
||||||
getInstanceConfigurationStatusMaxAttachments,
|
|
||||||
() => true
|
|
||||||
)
|
|
||||||
|
|
||||||
const flatListRef = useRef<FlatList>(null)
|
const flatListRef = useRef<FlatList>(null)
|
||||||
|
|
||||||
const sensitiveOnPress = useCallback(() => {
|
const sensitiveOnPress = useCallback(
|
||||||
analytics('compose_attachment_sensitive_press', {
|
() =>
|
||||||
current: composeState.attachments.sensitive
|
composeDispatch({
|
||||||
})
|
type: 'attachments/sensitive',
|
||||||
composeDispatch({
|
payload: { sensitive: !composeState.attachments.sensitive }
|
||||||
type: 'attachments/sensitive',
|
}),
|
||||||
payload: { sensitive: !composeState.attachments.sensitive }
|
[composeState.attachments.sensitive]
|
||||||
})
|
)
|
||||||
}, [composeState.attachments.sensitive])
|
|
||||||
|
|
||||||
const calculateWidth = useCallback((item: ExtendedAttachment) => {
|
const calculateWidth = useCallback((item: ExtendedAttachment) => {
|
||||||
if (item.local) {
|
if (item.local) {
|
||||||
return (
|
return ((item.local.width || 100) / (item.local.height || 100)) * DEFAULT_HEIGHT
|
||||||
((item.local.width || 100) / (item.local.height || 100)) *
|
|
||||||
DEFAULT_HEIGHT
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
if (item.remote) {
|
if (item.remote) {
|
||||||
if (item.remote.meta.original.aspect) {
|
if (item.remote.meta.original.aspect) {
|
||||||
return item.remote.meta.original.aspect * DEFAULT_HEIGHT
|
return item.remote.meta.original.aspect * DEFAULT_HEIGHT
|
||||||
} else if (
|
} else if (item.remote.meta.original.width && item.remote.meta.original.height) {
|
||||||
item.remote.meta.original.width &&
|
|
||||||
item.remote.meta.original.height
|
|
||||||
) {
|
|
||||||
return (
|
return (
|
||||||
(item.remote.meta.original.width /
|
(item.remote.meta.original.width / item.remote.meta.original.height) * DEFAULT_HEIGHT
|
||||||
item.remote.meta.original.height) *
|
|
||||||
DEFAULT_HEIGHT
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
return DEFAULT_HEIGHT
|
return DEFAULT_HEIGHT
|
||||||
|
@ -85,19 +65,17 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const snapToOffsets = useMemo(() => {
|
const snapToOffsets = useMemo(() => {
|
||||||
const attachmentsOffsets = composeState.attachments.uploads.map(
|
const attachmentsOffsets = composeState.attachments.uploads.map((_, index) => {
|
||||||
(_, index) => {
|
let currentOffset = 0
|
||||||
let currentOffset = 0
|
Array.from(Array(index).keys()).map(
|
||||||
Array.from(Array(index).keys()).map(
|
i =>
|
||||||
i =>
|
(currentOffset =
|
||||||
(currentOffset =
|
currentOffset +
|
||||||
currentOffset +
|
calculateWidth(composeState.attachments.uploads[i]) +
|
||||||
calculateWidth(composeState.attachments.uploads[i]) +
|
StyleConstants.Spacing.Global.PagePadding)
|
||||||
StyleConstants.Spacing.Global.PagePadding)
|
)
|
||||||
)
|
return currentOffset
|
||||||
return currentOffset
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
return attachmentsOffsets.length < 4
|
return attachmentsOffsets.length < 4
|
||||||
? [
|
? [
|
||||||
...attachmentsOffsets,
|
...attachmentsOffsets,
|
||||||
|
@ -109,14 +87,9 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||||
}, [composeState.attachments.uploads.length])
|
}, [composeState.attachments.uploads.length])
|
||||||
let prevOffsets = useRef<number[]>()
|
let prevOffsets = useRef<number[]>()
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (snapToOffsets.length > (prevOffsets.current ? prevOffsets.current.length : 0)) {
|
||||||
snapToOffsets.length >
|
|
||||||
(prevOffsets.current ? prevOffsets.current.length : 0)
|
|
||||||
) {
|
|
||||||
flatListRef.current?.scrollToOffset({
|
flatListRef.current?.scrollToOffset({
|
||||||
offset:
|
offset: snapToOffsets[snapToOffsets.length - 2] + snapToOffsets[snapToOffsets.length - 1]
|
||||||
snapToOffsets[snapToOffsets.length - 2] +
|
|
||||||
snapToOffsets[snapToOffsets.length - 1]
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
prevOffsets.current = snapToOffsets
|
prevOffsets.current = snapToOffsets
|
||||||
|
@ -168,10 +141,7 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||||
backgroundColor: colors.backgroundOverlayInvert
|
backgroundColor: colors.backgroundOverlayInvert
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Circle
|
<Circle size={StyleConstants.Font.Size.L} color={colors.primaryOverlay} />
|
||||||
size={StyleConstants.Font.Size.L}
|
|
||||||
color={colors.primaryOverlay}
|
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
) : (
|
) : (
|
||||||
<View
|
<View
|
||||||
|
@ -184,17 +154,15 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
accessibilityLabel={t(
|
accessibilityLabel={t('content.root.footer.attachments.remove.accessibilityLabel', {
|
||||||
'content.root.footer.attachments.remove.accessibilityLabel',
|
attachment: index + 1
|
||||||
{ attachment: index + 1 }
|
})}
|
||||||
)}
|
|
||||||
type='icon'
|
type='icon'
|
||||||
content='X'
|
content='X'
|
||||||
spacing='M'
|
spacing='M'
|
||||||
round
|
round
|
||||||
overlay
|
overlay
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('compose_attachment_delete')
|
|
||||||
layoutAnimation()
|
layoutAnimation()
|
||||||
composeDispatch({
|
composeDispatch({
|
||||||
type: 'attachment/delete',
|
type: 'attachment/delete',
|
||||||
|
@ -204,17 +172,15 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
accessibilityLabel={t(
|
accessibilityLabel={t('content.root.footer.attachments.edit.accessibilityLabel', {
|
||||||
'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={() => {
|
||||||
analytics('compose_attachment_edit')
|
|
||||||
navigation.navigate('Screen-Compose-EditAttachment', {
|
navigation.navigate('Screen-Compose-EditAttachment', {
|
||||||
index
|
index
|
||||||
})
|
})
|
||||||
|
@ -232,9 +198,7 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||||
() => (
|
() => (
|
||||||
<Pressable
|
<Pressable
|
||||||
accessible
|
accessible
|
||||||
accessibilityLabel={t(
|
accessibilityLabel={t('content.root.footer.attachments.upload.accessibilityLabel')}
|
||||||
'content.root.footer.attachments.upload.accessibilityLabel'
|
|
||||||
)}
|
|
||||||
style={{
|
style={{
|
||||||
height: DEFAULT_HEIGHT,
|
height: DEFAULT_HEIGHT,
|
||||||
marginLeft: StyleConstants.Spacing.Global.PagePadding,
|
marginLeft: StyleConstants.Spacing.Global.PagePadding,
|
||||||
|
@ -244,7 +208,6 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||||
backgroundColor: colors.backgroundOverlayInvert
|
backgroundColor: colors.backgroundOverlayInvert
|
||||||
}}
|
}}
|
||||||
onPress={async () => {
|
onPress={async () => {
|
||||||
analytics('compose_attachment_add_container_press')
|
|
||||||
await chooseAndUploadAttachment({
|
await chooseAndUploadAttachment({
|
||||||
composeDispatch,
|
composeDispatch,
|
||||||
showActionSheetWithOptions
|
showActionSheetWithOptions
|
||||||
|
@ -258,7 +221,6 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||||
round
|
round
|
||||||
overlay
|
overlay
|
||||||
onPress={async () => {
|
onPress={async () => {
|
||||||
analytics('compose_attachment_add_button_press')
|
|
||||||
await chooseAndUploadAttachment({
|
await chooseAndUploadAttachment({
|
||||||
composeDispatch,
|
composeDispatch,
|
||||||
showActionSheetWithOptions
|
showActionSheetWithOptions
|
||||||
|
@ -266,16 +228,8 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top:
|
top: (DEFAULT_HEIGHT - StyleConstants.Spacing.M * 2 - StyleConstants.Font.Size.M) / 2,
|
||||||
(DEFAULT_HEIGHT -
|
left: (DEFAULT_HEIGHT - StyleConstants.Spacing.M * 2 - StyleConstants.Font.Size.M) / 2
|
||||||
StyleConstants.Spacing.M * 2 -
|
|
||||||
StyleConstants.Font.Size.M) /
|
|
||||||
2,
|
|
||||||
left:
|
|
||||||
(DEFAULT_HEIGHT -
|
|
||||||
StyleConstants.Spacing.M * 2 -
|
|
||||||
StyleConstants.Font.Size.M) /
|
|
||||||
2
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
|
@ -327,13 +281,9 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||||
keyboardShouldPersistTaps='always'
|
keyboardShouldPersistTaps='always'
|
||||||
showsHorizontalScrollIndicator={false}
|
showsHorizontalScrollIndicator={false}
|
||||||
data={composeState.attachments.uploads}
|
data={composeState.attachments.uploads}
|
||||||
keyExtractor={item =>
|
keyExtractor={item => item.local?.uri || item.remote?.url || Math.random().toString()}
|
||||||
item.local?.uri || item.remote?.url || Math.random().toString()
|
|
||||||
}
|
|
||||||
ListFooterComponent={
|
ListFooterComponent={
|
||||||
composeState.attachments.uploads.length < maxAttachments
|
composeState.attachments.uploads.length < maxAttachments ? listFooter : null
|
||||||
? listFooter
|
|
||||||
: null
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import { MenuRow } from '@components/Menu'
|
import { MenuRow } from '@components/Menu'
|
||||||
|
@ -134,7 +133,6 @@ const ComposePoll: React.FC = () => {
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('compose_poll_reduce_press')
|
|
||||||
total > 2 &&
|
total > 2 &&
|
||||||
composeDispatch({
|
composeDispatch({
|
||||||
type: 'poll',
|
type: 'poll',
|
||||||
|
@ -169,7 +167,6 @@ const ComposePoll: React.FC = () => {
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('compose_poll_increase_press')
|
|
||||||
total < MAX_OPTIONS &&
|
total < MAX_OPTIONS &&
|
||||||
composeDispatch({
|
composeDispatch({
|
||||||
type: 'poll',
|
type: 'poll',
|
||||||
|
@ -205,10 +202,6 @@ const ComposePoll: React.FC = () => {
|
||||||
},
|
},
|
||||||
index => {
|
index => {
|
||||||
if (index && index < 2) {
|
if (index && index < 2) {
|
||||||
analytics('compose_poll_expiration_press', {
|
|
||||||
current: multiple,
|
|
||||||
new: index === 1
|
|
||||||
})
|
|
||||||
composeDispatch({
|
composeDispatch({
|
||||||
type: 'poll',
|
type: 'poll',
|
||||||
payload: { multiple: index === 1 }
|
payload: { multiple: index === 1 }
|
||||||
|
@ -249,10 +242,6 @@ const ComposePoll: React.FC = () => {
|
||||||
},
|
},
|
||||||
index => {
|
index => {
|
||||||
if (index !== undefined && index < expirations.length) {
|
if (index !== undefined && index < expirations.length) {
|
||||||
analytics('compose_poll_expiration_press', {
|
|
||||||
current: expire,
|
|
||||||
new: expirations[index]
|
|
||||||
})
|
|
||||||
composeDispatch({
|
composeDispatch({
|
||||||
type: 'poll',
|
type: 'poll',
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import ComponentAccount from '@components/Account'
|
import ComponentAccount from '@components/Account'
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import haptics from '@components/haptics'
|
import haptics from '@components/haptics'
|
||||||
import ComponentHashtag from '@components/Hashtag'
|
import ComponentHashtag from '@components/Hashtag'
|
||||||
import React, { useContext, useEffect } from 'react'
|
import React, { useContext, useEffect } from 'react'
|
||||||
|
@ -18,9 +17,6 @@ const ComposeRootSuggestion: React.FC<Props> = ({ item }) => {
|
||||||
}, [composeState.text.raw.length])
|
}, [composeState.text.raw.length])
|
||||||
|
|
||||||
const onPress = () => {
|
const onPress = () => {
|
||||||
analytics('compose_suggestion_press', {
|
|
||||||
type: item.acct ? 'account' : 'hashtag'
|
|
||||||
})
|
|
||||||
const focusedInput = composeState.textInputFocus.current
|
const focusedInput = composeState.textInputFocus.current
|
||||||
const updatedText = (): string => {
|
const updatedText = (): string => {
|
||||||
const main = item.acct ? `@${item.acct}` : `#${item.name}`
|
const main = item.acct ? `@${item.acct}` : `#${item.name}`
|
||||||
|
@ -48,7 +44,7 @@ const ComposeRootSuggestion: React.FC<Props> = ({ item }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return item.acct ? (
|
return item.acct ? (
|
||||||
<ComponentAccount account={item} onPress={onPress} origin='suggestion' />
|
<ComponentAccount account={item} onPress={onPress} />
|
||||||
) : (
|
) : (
|
||||||
<ComponentHashtag hashtag={item} onPress={onPress} origin='suggestion' />
|
<ComponentHashtag hashtag={item} onPress={onPress} origin='suggestion' />
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import GracefullyImage from '@components/GracefullyImage'
|
import GracefullyImage from '@components/GracefullyImage'
|
||||||
import { HeaderCenter, HeaderLeft, HeaderRight } from '@components/Header'
|
import { HeaderCenter, HeaderLeft, HeaderRight } from '@components/Header'
|
||||||
import { useActionSheet } from '@expo/react-native-action-sheet'
|
import { useActionSheet } from '@expo/react-native-action-sheet'
|
||||||
|
@ -49,7 +48,6 @@ const ScreenImagesViewer = ({
|
||||||
|
|
||||||
const { showActionSheetWithOptions } = useActionSheet()
|
const { showActionSheetWithOptions } = useActionSheet()
|
||||||
const onPress = useCallback(() => {
|
const onPress = useCallback(() => {
|
||||||
analytics('imageviewer_more_press')
|
|
||||||
showActionSheetWithOptions(
|
showActionSheetWithOptions(
|
||||||
{
|
{
|
||||||
options: [
|
options: [
|
||||||
|
@ -63,11 +61,9 @@ const ScreenImagesViewer = ({
|
||||||
async buttonIndex => {
|
async buttonIndex => {
|
||||||
switch (buttonIndex) {
|
switch (buttonIndex) {
|
||||||
case 0:
|
case 0:
|
||||||
analytics('imageviewer_more_save_press')
|
|
||||||
saveImage({ theme, image: imageUrls[currentIndex] })
|
saveImage({ theme, image: imageUrls[currentIndex] })
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
analytics('imageviewer_more_share_press')
|
|
||||||
switch (Platform.OS) {
|
switch (Platform.OS) {
|
||||||
case 'ios':
|
case 'ios':
|
||||||
await Share.share({ url: imageUrls[currentIndex].url })
|
await Share.share({ url: imageUrls[currentIndex].url })
|
||||||
|
@ -179,7 +175,6 @@ const ScreenImagesViewer = ({
|
||||||
</View>
|
</View>
|
||||||
<LongPressGestureHandler
|
<LongPressGestureHandler
|
||||||
onEnded={() => {
|
onEnded={() => {
|
||||||
analytics('imageviewer_more_press')
|
|
||||||
showActionSheetWithOptions(
|
showActionSheetWithOptions(
|
||||||
{
|
{
|
||||||
options: [
|
options: [
|
||||||
|
@ -193,11 +188,9 @@ const ScreenImagesViewer = ({
|
||||||
async buttonIndex => {
|
async buttonIndex => {
|
||||||
switch (buttonIndex) {
|
switch (buttonIndex) {
|
||||||
case 0:
|
case 0:
|
||||||
analytics('imageviewer_more_save_press')
|
|
||||||
saveImage({ theme, image: imageUrls[currentIndex] })
|
saveImage({ theme, image: imageUrls[currentIndex] })
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
analytics('imageviewer_more_share_press')
|
|
||||||
switch (Platform.OS) {
|
switch (Platform.OS) {
|
||||||
case 'ios':
|
case 'ios':
|
||||||
await Share.share({ url: imageUrls[currentIndex].url })
|
await Share.share({ url: imageUrls[currentIndex].url })
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import { HeaderCenter, HeaderRight } from '@components/Header'
|
import { HeaderCenter, HeaderRight } from '@components/Header'
|
||||||
import Timeline from '@components/Timeline'
|
import Timeline from '@components/Timeline'
|
||||||
import TimelineDefault from '@components/Timeline/Default'
|
import TimelineDefault from '@components/Timeline/Default'
|
||||||
|
@ -76,13 +75,12 @@ const TabLocal = React.memo(
|
||||||
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={() => {
|
onPress={() =>
|
||||||
analytics('search_tap', { page: 'Local' })
|
|
||||||
navigation.navigate('Tab-Local', {
|
navigation.navigate('Tab-Local', {
|
||||||
screen: 'Tab-Shared-Search',
|
screen: 'Tab-Shared-Search',
|
||||||
params: { text: undefined }
|
params: { text: undefined }
|
||||||
})
|
})
|
||||||
}}
|
}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import { MenuContainer, MenuRow } from '@components/Menu'
|
import { MenuContainer, MenuRow } from '@components/Menu'
|
||||||
import { useActionSheet } from '@expo/react-native-action-sheet'
|
import { useActionSheet } from '@expo/react-native-action-sheet'
|
||||||
import { useAppDispatch } from '@root/store'
|
import { useAppDispatch } from '@root/store'
|
||||||
|
@ -44,18 +43,12 @@ const TabMeProfileRoot: React.FC<
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
const indexVisibilityMapping = [
|
const indexVisibilityMapping = ['public', 'unlisted', 'private'] as [
|
||||||
'public',
|
'public',
|
||||||
'unlisted',
|
'unlisted',
|
||||||
'private'
|
'private'
|
||||||
] as ['public', 'unlisted', 'private']
|
]
|
||||||
if (data?.source.privacy !== indexVisibilityMapping[buttonIndex]) {
|
if (data?.source.privacy !== indexVisibilityMapping[buttonIndex]) {
|
||||||
analytics('me_profile_visibility', {
|
|
||||||
current: t(
|
|
||||||
`me.profile.root.visibility.options.${data?.source.privacy}`
|
|
||||||
),
|
|
||||||
new: indexVisibilityMapping[buttonIndex]
|
|
||||||
})
|
|
||||||
mutateAsync({
|
mutateAsync({
|
||||||
theme,
|
theme,
|
||||||
messageRef,
|
messageRef,
|
||||||
|
@ -75,10 +68,6 @@ const TabMeProfileRoot: React.FC<
|
||||||
}, [theme, data?.source?.privacy])
|
}, [theme, data?.source?.privacy])
|
||||||
|
|
||||||
const onPressSensitive = useCallback(() => {
|
const onPressSensitive = useCallback(() => {
|
||||||
analytics('me_profile_sensitive', {
|
|
||||||
current: data?.source.sensitive,
|
|
||||||
new: data?.source.sensitive === undefined ? true : !data.source.sensitive
|
|
||||||
})
|
|
||||||
mutateAsync({
|
mutateAsync({
|
||||||
theme,
|
theme,
|
||||||
messageRef,
|
messageRef,
|
||||||
|
@ -93,10 +82,6 @@ const TabMeProfileRoot: React.FC<
|
||||||
}, [data?.source.sensitive])
|
}, [data?.source.sensitive])
|
||||||
|
|
||||||
const onPressLock = useCallback(() => {
|
const onPressLock = useCallback(() => {
|
||||||
analytics('me_profile_lock', {
|
|
||||||
current: data?.locked,
|
|
||||||
new: data?.locked === undefined ? true : !data.locked
|
|
||||||
})
|
|
||||||
mutateAsync({
|
mutateAsync({
|
||||||
theme,
|
theme,
|
||||||
messageRef,
|
messageRef,
|
||||||
|
@ -111,10 +96,6 @@ const TabMeProfileRoot: React.FC<
|
||||||
}, [theme, data?.locked])
|
}, [theme, data?.locked])
|
||||||
|
|
||||||
const onPressBot = useCallback(() => {
|
const onPressBot = useCallback(() => {
|
||||||
analytics('me_profile_bot', {
|
|
||||||
current: data?.bot,
|
|
||||||
new: data?.bot === undefined ? true : !data.bot
|
|
||||||
})
|
|
||||||
mutateAsync({
|
mutateAsync({
|
||||||
theme,
|
theme,
|
||||||
messageRef,
|
messageRef,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import { MenuContainer, MenuRow } from '@components/Menu'
|
import { MenuContainer, MenuRow } from '@components/Menu'
|
||||||
|
@ -28,10 +27,7 @@ import { useSelector } from 'react-redux'
|
||||||
const TabMePush: React.FC = () => {
|
const TabMePush: React.FC = () => {
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
const { t } = useTranslation('screenTabs')
|
const { t } = useTranslation('screenTabs')
|
||||||
const instanceAccount = useSelector(
|
const instanceAccount = useSelector(getInstanceAccount, (prev, next) => prev?.acct === next?.acct)
|
||||||
getInstanceAccount,
|
|
||||||
(prev, next) => prev?.acct === next?.acct
|
|
||||||
)
|
|
||||||
const instanceUri = useSelector(getInstanceUri)
|
const instanceUri = useSelector(getInstanceUri)
|
||||||
|
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
@ -70,15 +66,7 @@ const TabMePush: React.FC = () => {
|
||||||
const alerts = useMemo(() => {
|
const alerts = useMemo(() => {
|
||||||
return instancePush?.alerts
|
return instancePush?.alerts
|
||||||
? (
|
? (
|
||||||
[
|
['follow', 'follow_request', 'favourite', 'reblog', 'mention', 'poll', 'status'] as [
|
||||||
'follow',
|
|
||||||
'follow_request',
|
|
||||||
'favourite',
|
|
||||||
'reblog',
|
|
||||||
'mention',
|
|
||||||
'poll',
|
|
||||||
'status'
|
|
||||||
] as [
|
|
||||||
'follow',
|
'follow',
|
||||||
'follow_request',
|
'follow_request',
|
||||||
'favourite',
|
'favourite',
|
||||||
|
@ -91,15 +79,9 @@ const TabMePush: React.FC = () => {
|
||||||
<MenuRow
|
<MenuRow
|
||||||
key={alert}
|
key={alert}
|
||||||
title={t(`me.push.${alert}.heading`)}
|
title={t(`me.push.${alert}.heading`)}
|
||||||
switchDisabled={
|
switchDisabled={!pushEnabled || !instancePush.global.value || isLoading}
|
||||||
!pushEnabled || !instancePush.global.value || isLoading
|
|
||||||
}
|
|
||||||
switchValue={instancePush?.alerts[alert].value}
|
switchValue={instancePush?.alerts[alert].value}
|
||||||
switchOnValueChange={() => {
|
switchOnValueChange={() =>
|
||||||
analytics(`me_push_${alert}`, {
|
|
||||||
current: instancePush?.alerts[alert].value,
|
|
||||||
new: !instancePush?.alerts[alert].value
|
|
||||||
})
|
|
||||||
dispatch(
|
dispatch(
|
||||||
updateInstancePushAlert({
|
updateInstancePushAlert({
|
||||||
changed: alert,
|
changed: alert,
|
||||||
|
@ -112,7 +94,7 @@ const TabMePush: React.FC = () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}}
|
}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
: null
|
: null
|
||||||
|
@ -127,23 +109,18 @@ const TabMePush: React.FC = () => {
|
||||||
<Button
|
<Button
|
||||||
type='text'
|
type='text'
|
||||||
content={
|
content={
|
||||||
pushCanAskAgain
|
pushCanAskAgain ? t('me.push.enable.direct') : t('me.push.enable.settings')
|
||||||
? t('me.push.enable.direct')
|
|
||||||
: t('me.push.enable.settings')
|
|
||||||
}
|
}
|
||||||
style={{
|
style={{
|
||||||
marginTop: StyleConstants.Spacing.Global.PagePadding,
|
marginTop: StyleConstants.Spacing.Global.PagePadding,
|
||||||
marginHorizontal:
|
marginHorizontal: StyleConstants.Spacing.Global.PagePadding * 2
|
||||||
StyleConstants.Spacing.Global.PagePadding * 2
|
|
||||||
}}
|
}}
|
||||||
onPress={async () => {
|
onPress={async () => {
|
||||||
if (pushCanAskAgain) {
|
if (pushCanAskAgain) {
|
||||||
analytics('me_push_enabled_dialogue')
|
|
||||||
const result = await Notifications.requestPermissionsAsync()
|
const result = await Notifications.requestPermissionsAsync()
|
||||||
setPushEnabled(result.granted)
|
setPushEnabled(result.granted)
|
||||||
setPushCanAskAgain(result.canAskAgain)
|
setPushCanAskAgain(result.canAskAgain)
|
||||||
} else {
|
} else {
|
||||||
analytics('me_push_enabled_setting')
|
|
||||||
Linking.openSettings()
|
Linking.openSettings()
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
@ -158,16 +135,8 @@ const TabMePush: React.FC = () => {
|
||||||
description={t('me.push.global.description')}
|
description={t('me.push.global.description')}
|
||||||
loading={instancePush?.global.loading}
|
loading={instancePush?.global.loading}
|
||||||
switchDisabled={!pushEnabled || isLoading}
|
switchDisabled={!pushEnabled || isLoading}
|
||||||
switchValue={
|
switchValue={pushEnabled === false ? false : instancePush?.global.value}
|
||||||
pushEnabled === false ? false : instancePush?.global.value
|
switchOnValueChange={() => dispatch(updateInstancePush(!instancePush?.global.value))}
|
||||||
}
|
|
||||||
switchOnValueChange={() => {
|
|
||||||
analytics('me_push_global', {
|
|
||||||
current: instancePush?.global.value,
|
|
||||||
new: !instancePush?.global.value
|
|
||||||
})
|
|
||||||
dispatch(updateInstancePush(!instancePush?.global.value))
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</MenuContainer>
|
</MenuContainer>
|
||||||
<MenuContainer>
|
<MenuContainer>
|
||||||
|
@ -175,25 +144,16 @@ const TabMePush: React.FC = () => {
|
||||||
title={t('me.push.decode.heading')}
|
title={t('me.push.decode.heading')}
|
||||||
description={t('me.push.decode.description')}
|
description={t('me.push.decode.description')}
|
||||||
loading={instancePush?.decode.loading}
|
loading={instancePush?.decode.loading}
|
||||||
switchDisabled={
|
switchDisabled={!pushEnabled || !instancePush?.global.value || isLoading}
|
||||||
!pushEnabled || !instancePush?.global.value || isLoading
|
|
||||||
}
|
|
||||||
switchValue={instancePush?.decode.value}
|
switchValue={instancePush?.decode.value}
|
||||||
switchOnValueChange={() => {
|
switchOnValueChange={() =>
|
||||||
analytics('me_push_decode', {
|
|
||||||
current: instancePush?.decode.value,
|
|
||||||
new: !instancePush?.decode.value
|
|
||||||
})
|
|
||||||
dispatch(updateInstancePushDecode(!instancePush?.decode.value))
|
dispatch(updateInstancePushDecode(!instancePush?.decode.value))
|
||||||
}}
|
}
|
||||||
/>
|
/>
|
||||||
<MenuRow
|
<MenuRow
|
||||||
title={t('me.push.howitworks')}
|
title={t('me.push.howitworks')}
|
||||||
iconBack='ExternalLink'
|
iconBack='ExternalLink'
|
||||||
onPress={() => {
|
onPress={() => WebBrowser.openBrowserAsync('https://tooot.app/how-push-works')}
|
||||||
analytics('me_push_howitworks')
|
|
||||||
WebBrowser.openBrowserAsync('https://tooot.app/how-push-works')
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</MenuContainer>
|
</MenuContainer>
|
||||||
<MenuContainer>{alerts}</MenuContainer>
|
<MenuContainer>{alerts}</MenuContainer>
|
||||||
|
@ -207,11 +167,7 @@ const TabMePush: React.FC = () => {
|
||||||
alignItems: 'center'
|
alignItems: 'center'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon name='Frown' size={StyleConstants.Font.Size.L} color={colors.primaryDefault} />
|
||||||
name='Frown'
|
|
||||||
size={StyleConstants.Font.Size.L}
|
|
||||||
color={colors.primaryDefault}
|
|
||||||
/>
|
|
||||||
<CustomText fontStyle='M' style={{ color: colors.primaryDefault }}>
|
<CustomText fontStyle='M' style={{ color: colors.primaryDefault }}>
|
||||||
{t('me.push.notAvailable')}
|
{t('me.push.notAvailable')}
|
||||||
</CustomText>
|
</CustomText>
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
import { MenuContainer, MenuRow } from '@components/Menu'
|
import { MenuContainer } from '@components/Menu'
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
import { useAppDispatch } from '@root/store'
|
|
||||||
import { getInstanceVersion } from '@utils/slices/instancesSlice'
|
import { getInstanceVersion } from '@utils/slices/instancesSlice'
|
||||||
import {
|
|
||||||
changeAnalytics,
|
|
||||||
getSettingsAnalytics
|
|
||||||
} from '@utils/slices/settingsSlice'
|
|
||||||
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 Constants from 'expo-constants'
|
import Constants from 'expo-constants'
|
||||||
|
@ -14,25 +9,13 @@ import { useTranslation } from 'react-i18next'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
|
|
||||||
const SettingsAnalytics: React.FC = () => {
|
const SettingsAnalytics: React.FC = () => {
|
||||||
const dispatch = useAppDispatch()
|
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
const { t } = useTranslation('screenTabs')
|
const { t } = useTranslation('screenTabs')
|
||||||
|
|
||||||
const settingsAnalytics = useSelector(getSettingsAnalytics)
|
|
||||||
const instanceVersion = useSelector(getInstanceVersion, () => true)
|
const instanceVersion = useSelector(getInstanceVersion, () => true)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MenuContainer>
|
|
||||||
<MenuRow
|
|
||||||
title={t('me.settings.analytics.heading')}
|
|
||||||
description={t('me.settings.analytics.description')}
|
|
||||||
switchValue={settingsAnalytics}
|
|
||||||
switchOnValueChange={() =>
|
|
||||||
dispatch(changeAnalytics(!settingsAnalytics))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</MenuContainer>
|
|
||||||
<MenuContainer>
|
<MenuContainer>
|
||||||
<CustomText
|
<CustomText
|
||||||
fontStyle='S'
|
fontStyle='S'
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import haptics from '@components/haptics'
|
import haptics from '@components/haptics'
|
||||||
import { MenuContainer, MenuRow } from '@components/Menu'
|
import { MenuContainer, MenuRow } from '@components/Menu'
|
||||||
import { useActionSheet } from '@expo/react-native-action-sheet'
|
import { useActionSheet } from '@expo/react-native-action-sheet'
|
||||||
|
@ -77,26 +76,14 @@ const SettingsApp: React.FC = () => {
|
||||||
buttonIndex => {
|
buttonIndex => {
|
||||||
switch (buttonIndex) {
|
switch (buttonIndex) {
|
||||||
case 0:
|
case 0:
|
||||||
analytics('settings_appearance_press', {
|
|
||||||
current: settingsTheme,
|
|
||||||
new: 'auto'
|
|
||||||
})
|
|
||||||
haptics('Success')
|
haptics('Success')
|
||||||
dispatch(changeTheme('auto'))
|
dispatch(changeTheme('auto'))
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
analytics('settings_appearance_press', {
|
|
||||||
current: settingsTheme,
|
|
||||||
new: 'light'
|
|
||||||
})
|
|
||||||
haptics('Success')
|
haptics('Success')
|
||||||
dispatch(changeTheme('light'))
|
dispatch(changeTheme('light'))
|
||||||
break
|
break
|
||||||
case 2:
|
case 2:
|
||||||
analytics('settings_appearance_press', {
|
|
||||||
current: settingsTheme,
|
|
||||||
new: 'dark'
|
|
||||||
})
|
|
||||||
haptics('Success')
|
haptics('Success')
|
||||||
dispatch(changeTheme('dark'))
|
dispatch(changeTheme('dark'))
|
||||||
break
|
break
|
||||||
|
@ -123,18 +110,10 @@ const SettingsApp: React.FC = () => {
|
||||||
buttonIndex => {
|
buttonIndex => {
|
||||||
switch (buttonIndex) {
|
switch (buttonIndex) {
|
||||||
case 0:
|
case 0:
|
||||||
analytics('settings_darktheme_press', {
|
|
||||||
current: settingsDarkTheme,
|
|
||||||
new: 'lighter'
|
|
||||||
})
|
|
||||||
haptics('Success')
|
haptics('Success')
|
||||||
dispatch(changeDarkTheme('lighter'))
|
dispatch(changeDarkTheme('lighter'))
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
analytics('settings_darktheme_press', {
|
|
||||||
current: settingsDarkTheme,
|
|
||||||
new: 'darker'
|
|
||||||
})
|
|
||||||
haptics('Success')
|
haptics('Success')
|
||||||
dispatch(changeDarkTheme('darker'))
|
dispatch(changeDarkTheme('darker'))
|
||||||
break
|
break
|
||||||
|
@ -161,18 +140,10 @@ const SettingsApp: React.FC = () => {
|
||||||
buttonIndex => {
|
buttonIndex => {
|
||||||
switch (buttonIndex) {
|
switch (buttonIndex) {
|
||||||
case 0:
|
case 0:
|
||||||
analytics('settings_browser_press', {
|
|
||||||
current: settingsBrowser,
|
|
||||||
new: 'internal'
|
|
||||||
})
|
|
||||||
haptics('Success')
|
haptics('Success')
|
||||||
dispatch(changeBrowser('internal'))
|
dispatch(changeBrowser('internal'))
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
analytics('settings_browser_press', {
|
|
||||||
current: settingsBrowser,
|
|
||||||
new: 'external'
|
|
||||||
})
|
|
||||||
haptics('Success')
|
haptics('Success')
|
||||||
dispatch(changeBrowser('external'))
|
dispatch(changeBrowser('external'))
|
||||||
break
|
break
|
||||||
|
@ -185,13 +156,7 @@ const SettingsApp: React.FC = () => {
|
||||||
title={t('me.settings.staticEmoji.heading')}
|
title={t('me.settings.staticEmoji.heading')}
|
||||||
description={t('me.settings.staticEmoji.description')}
|
description={t('me.settings.staticEmoji.description')}
|
||||||
switchValue={settingsStaticEmoji}
|
switchValue={settingsStaticEmoji}
|
||||||
switchOnValueChange={() => {
|
switchOnValueChange={() => dispatch(changeStaticEmoji(!settingsStaticEmoji))}
|
||||||
analytics('settings_staticemoji_press', {
|
|
||||||
current: settingsStaticEmoji.toString(),
|
|
||||||
new: !settingsStaticEmoji.toString()
|
|
||||||
})
|
|
||||||
dispatch(changeStaticEmoji(!settingsStaticEmoji))
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</MenuContainer>
|
</MenuContainer>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import { MenuContainer, MenuRow } from '@components/Menu'
|
import { MenuContainer, MenuRow } from '@components/Menu'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
|
@ -33,29 +32,20 @@ const SettingsTooot: React.FC = () => {
|
||||||
<Icon name='MessageSquare' size={StyleConstants.Font.Size.M} color={colors.secondary} />
|
<Icon name='MessageSquare' size={StyleConstants.Font.Size.M} color={colors.secondary} />
|
||||||
}
|
}
|
||||||
iconBack='ChevronRight'
|
iconBack='ChevronRight'
|
||||||
onPress={() => {
|
onPress={() => Linking.openURL('https://feedback.tooot.app/feature-requests')}
|
||||||
analytics('settings_feedback_press')
|
|
||||||
Linking.openURL('https://feedback.tooot.app/feature-requests')
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<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='ChevronRight'
|
||||||
onPress={() => {
|
onPress={() => Linking.openURL('https://www.buymeacoffee.com/xmflsct')}
|
||||||
analytics('settings_support_press')
|
|
||||||
Linking.openURL('https://www.buymeacoffee.com/xmflsct')
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
{isDevelopment || isRelease ? (
|
{isDevelopment || isRelease ? (
|
||||||
<MenuRow
|
<MenuRow
|
||||||
title={t('me.settings.review.heading')}
|
title={t('me.settings.review.heading')}
|
||||||
content={<Icon name='Star' size={StyleConstants.Font.Size.M} color='#FF9500' />}
|
content={<Icon name='Star' size={StyleConstants.Font.Size.M} color='#FF9500' />}
|
||||||
iconBack='ChevronRight'
|
iconBack='ChevronRight'
|
||||||
onPress={() => {
|
onPress={() => StoreReview?.isAvailableAsync().then(() => StoreReview?.requestReview())}
|
||||||
analytics('settings_review_press')
|
|
||||||
StoreReview?.isAvailableAsync().then(() => StoreReview?.requestReview())
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<MenuRow
|
<MenuRow
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import haptics from '@components/haptics'
|
import haptics from '@components/haptics'
|
||||||
import { MenuContainer, MenuRow } from '@components/Menu'
|
import { MenuContainer, MenuRow } from '@components/Menu'
|
||||||
import { LOCALES } from '@root/i18n/locales'
|
import { LOCALES } from '@root/i18n/locales'
|
||||||
|
@ -21,10 +20,6 @@ const TabMeSettingsLanguage: React.FC<
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
const change = (lang: string) => {
|
const change = (lang: string) => {
|
||||||
analytics('settings_language_press', {
|
|
||||||
current: i18n.language,
|
|
||||||
new: lang
|
|
||||||
})
|
|
||||||
haptics('Success')
|
haptics('Success')
|
||||||
|
|
||||||
dispatch(changeLanguage(lang))
|
dispatch(changeLanguage(lang))
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import { HeaderCenter, HeaderRight } from '@components/Header'
|
import { HeaderCenter, HeaderRight } from '@components/Header'
|
||||||
import Timeline from '@components/Timeline'
|
import Timeline from '@components/Timeline'
|
||||||
import TimelineNotifications from '@components/Timeline/Notifications'
|
import TimelineNotifications from '@components/Timeline/Notifications'
|
||||||
|
@ -29,12 +28,11 @@ const TabNotifications = React.memo(
|
||||||
accessibilityLabel={t('notifications.filter.accessibilityLabel')}
|
accessibilityLabel={t('notifications.filter.accessibilityLabel')}
|
||||||
accessibilityHint={t('notifications.filter.accessibilityHint')}
|
accessibilityHint={t('notifications.filter.accessibilityHint')}
|
||||||
content='Filter'
|
content='Filter'
|
||||||
onPress={() => {
|
onPress={() =>
|
||||||
analytics('notificationsfilter_tap')
|
|
||||||
navigationRef.navigate('Screen-Actions', {
|
navigationRef.navigate('Screen-Actions', {
|
||||||
type: 'notifications_filter'
|
type: 'notifications_filter'
|
||||||
})
|
})
|
||||||
}}
|
}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import { HeaderRight } from '@components/Header'
|
import { HeaderRight } from '@components/Header'
|
||||||
import Timeline from '@components/Timeline'
|
import Timeline from '@components/Timeline'
|
||||||
import TimelineDefault from '@components/Timeline/Default'
|
import TimelineDefault from '@components/Timeline/Default'
|
||||||
|
@ -51,13 +50,12 @@ const TabPublic = React.memo(
|
||||||
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={() => {
|
onPress={() =>
|
||||||
analytics('search_tap', { page: pages[segment].key })
|
|
||||||
navigation.navigate('Tab-Public', {
|
navigation.navigate('Tab-Public', {
|
||||||
screen: 'Tab-Shared-Search',
|
screen: 'Tab-Shared-Search',
|
||||||
params: { text: undefined }
|
params: { text: undefined }
|
||||||
})
|
})
|
||||||
}}
|
}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import GracefullyImage from '@components/GracefullyImage'
|
import GracefullyImage from '@components/GracefullyImage'
|
||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
|
@ -8,13 +7,7 @@ import { useTimelineQuery } from '@utils/queryHooks/timeline'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { useCallback, useEffect } from 'react'
|
import React, { useCallback, useEffect } from 'react'
|
||||||
import {
|
import { Dimensions, ListRenderItem, Pressable, StyleSheet, View } from 'react-native'
|
||||||
Dimensions,
|
|
||||||
ListRenderItem,
|
|
||||||
Pressable,
|
|
||||||
StyleSheet,
|
|
||||||
View
|
|
||||||
} from 'react-native'
|
|
||||||
import { FlatList } from 'react-native-gesture-handler'
|
import { FlatList } from 'react-native-gesture-handler'
|
||||||
import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated'
|
import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated'
|
||||||
|
|
||||||
|
@ -24,16 +17,13 @@ export interface Props {
|
||||||
|
|
||||||
const AccountAttachments = React.memo(
|
const AccountAttachments = React.memo(
|
||||||
({ account }: Props) => {
|
({ account }: Props) => {
|
||||||
const navigation =
|
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||||
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
|
|
||||||
const DISPLAY_AMOUNT = 6
|
const DISPLAY_AMOUNT = 6
|
||||||
|
|
||||||
const width =
|
const width =
|
||||||
(Dimensions.get('screen').width -
|
(Dimensions.get('screen').width - StyleConstants.Spacing.Global.PagePadding * 2) / 4
|
||||||
StyleConstants.Spacing.Global.PagePadding * 2) /
|
|
||||||
4
|
|
||||||
|
|
||||||
const queryKeyParams = {
|
const queryKeyParams = {
|
||||||
page: 'Account_Attachments' as 'Account_Attachments',
|
page: 'Account_Attachments' as 'Account_Attachments',
|
||||||
|
@ -62,9 +52,7 @@ const AccountAttachments = React.memo(
|
||||||
return (
|
return (
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('account_attachment_more_press')
|
account && navigation.push('Tab-Shared-Attachments', { account })
|
||||||
account &&
|
|
||||||
navigation.push('Tab-Shared-Attachments', { account })
|
|
||||||
}}
|
}}
|
||||||
children={
|
children={
|
||||||
<View
|
<View
|
||||||
|
@ -91,21 +79,15 @@ const AccountAttachments = React.memo(
|
||||||
return (
|
return (
|
||||||
<GracefullyImage
|
<GracefullyImage
|
||||||
uri={{
|
uri={{
|
||||||
original:
|
original: item.media_attachments[0]?.preview_url || item.media_attachments[0]?.url,
|
||||||
item.media_attachments[0]?.preview_url ||
|
|
||||||
item.media_attachments[0]?.url,
|
|
||||||
remote: item.media_attachments[0]?.remote_url
|
remote: item.media_attachments[0]?.remote_url
|
||||||
}}
|
}}
|
||||||
blurhash={
|
blurhash={
|
||||||
item.media_attachments[0] &&
|
item.media_attachments[0] && (item.media_attachments[0].blurhash || undefined)
|
||||||
(item.media_attachments[0].blurhash || undefined)
|
|
||||||
}
|
}
|
||||||
dimension={{ width: width, height: width }}
|
dimension={{ width: width, height: width }}
|
||||||
style={{ marginLeft: StyleConstants.Spacing.Global.PagePadding }}
|
style={{ marginLeft: StyleConstants.Spacing.Global.PagePadding }}
|
||||||
onPress={() => {
|
onPress={() => navigation.push('Tab-Shared-Toot', { toot: item })}
|
||||||
analytics('account_attachment_item_press')
|
|
||||||
navigation.push('Tab-Shared-Toot', { toot: item })
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -116,9 +98,7 @@ const AccountAttachments = React.memo(
|
||||||
const styleContainer = useAnimatedStyle(() => {
|
const styleContainer = useAnimatedStyle(() => {
|
||||||
if (flattenData.length) {
|
if (flattenData.length) {
|
||||||
return {
|
return {
|
||||||
height: withTiming(
|
height: withTiming(width + StyleConstants.Spacing.Global.PagePadding * 2),
|
||||||
width + StyleConstants.Spacing.Global.PagePadding * 2
|
|
||||||
),
|
|
||||||
paddingVertical: StyleConstants.Spacing.Global.PagePadding,
|
paddingVertical: StyleConstants.Spacing.Global.PagePadding,
|
||||||
borderTopWidth: 1,
|
borderTopWidth: 1,
|
||||||
borderTopColor: colors.border
|
borderTopColor: colors.border
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import { RelationshipOutgoing } from '@components/Relationship'
|
import { RelationshipOutgoing } from '@components/Relationship'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
|
@ -25,13 +24,12 @@ const Conversation = ({ account }: { account: Mastodon.Account }) => {
|
||||||
type='icon'
|
type='icon'
|
||||||
content='Mail'
|
content='Mail'
|
||||||
style={styles.actionLeft}
|
style={styles.actionLeft}
|
||||||
onPress={() => {
|
onPress={() =>
|
||||||
analytics('account_DM_press')
|
|
||||||
navigation.navigate('Screen-Compose', {
|
navigation.navigate('Screen-Compose', {
|
||||||
type: 'conversation',
|
type: 'conversation',
|
||||||
accts: [account.acct]
|
accts: [account.acct]
|
||||||
})
|
})
|
||||||
}}
|
}
|
||||||
/>
|
/>
|
||||||
) : null
|
) : null
|
||||||
}
|
}
|
||||||
|
@ -51,10 +49,7 @@ const AccountInformationActions: React.FC<Props> = ({ account, myInfo }) => {
|
||||||
<Button
|
<Button
|
||||||
type='text'
|
type='text'
|
||||||
content={t('shared.account.moved')}
|
content={t('shared.account.moved')}
|
||||||
onPress={() => {
|
onPress={() => navigation.push('Tab-Shared-Account', { account: accountMoved })}
|
||||||
analytics('account_gotomoved_press')
|
|
||||||
navigation.push('Tab-Shared-Account', { account: accountMoved })
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
@ -74,9 +69,7 @@ const AccountInformationActions: React.FC<Props> = ({ account, myInfo }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const instanceAccount = useSelector(getInstanceAccount, () => true)
|
const instanceAccount = useSelector(getInstanceAccount, () => true)
|
||||||
const ownAccount =
|
const ownAccount = account?.id === instanceAccount?.id && account?.acct === instanceAccount?.acct
|
||||||
account?.id === instanceAccount?.id &&
|
|
||||||
account?.acct === instanceAccount?.acct
|
|
||||||
|
|
||||||
if (!ownAccount && account) {
|
if (!ownAccount && account) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import GracefullyImage from '@components/GracefullyImage'
|
import GracefullyImage from '@components/GracefullyImage'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
|
@ -25,7 +24,6 @@ const AccountInformationAvatar: React.FC<Props> = ({
|
||||||
<Pressable
|
<Pressable
|
||||||
disabled={!myInfo}
|
disabled={!myInfo}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('account_avatar_press')
|
|
||||||
myInfo && account && navigation.push('Tab-Shared-Account', { account })
|
myInfo && account && navigation.push('Tab-Shared-Account', { account })
|
||||||
}}
|
}}
|
||||||
style={styles.base}
|
style={styles.base}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
import { StackNavigationProp } from '@react-navigation/stack'
|
import { StackNavigationProp } from '@react-navigation/stack'
|
||||||
|
@ -33,7 +32,6 @@ const AccountInformationStats: React.FC<Props> = ({ account, myInfo }) => {
|
||||||
count: account.statuses_count || 0
|
count: account.statuses_count || 0
|
||||||
})}
|
})}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
analytics('account_stats_toots_press')
|
|
||||||
myInfo && account && navigation.push('Tab-Shared-Account', { account })
|
myInfo && account && navigation.push('Tab-Shared-Account', { account })
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -52,17 +50,14 @@ const AccountInformationStats: React.FC<Props> = ({ account, myInfo }) => {
|
||||||
children={t('shared.account.summary.following_count', {
|
children={t('shared.account.summary.following_count', {
|
||||||
count: account.following_count
|
count: account.following_count
|
||||||
})}
|
})}
|
||||||
onPress={() => {
|
onPress={() =>
|
||||||
analytics('account_stats_following_press', {
|
|
||||||
count: account.following_count
|
|
||||||
})
|
|
||||||
navigation.push('Tab-Shared-Users', {
|
navigation.push('Tab-Shared-Users', {
|
||||||
reference: 'accounts',
|
reference: 'accounts',
|
||||||
id: account.id,
|
id: account.id,
|
||||||
type: 'following',
|
type: 'following',
|
||||||
count: account.following_count
|
count: account.following_count
|
||||||
})
|
})
|
||||||
}}
|
}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<PlaceholderLine
|
<PlaceholderLine
|
||||||
|
@ -79,17 +74,14 @@ const AccountInformationStats: React.FC<Props> = ({ account, myInfo }) => {
|
||||||
children={t('shared.account.summary.followers_count', {
|
children={t('shared.account.summary.followers_count', {
|
||||||
count: account.followers_count
|
count: account.followers_count
|
||||||
})}
|
})}
|
||||||
onPress={() => {
|
onPress={() =>
|
||||||
analytics('account_stats_followers_press', {
|
|
||||||
count: account.followers_count
|
|
||||||
})
|
|
||||||
navigation.push('Tab-Shared-Users', {
|
navigation.push('Tab-Shared-Users', {
|
||||||
reference: 'accounts',
|
reference: 'accounts',
|
||||||
id: account.id,
|
id: account.id,
|
||||||
type: 'followers',
|
type: 'followers',
|
||||||
count: account.followers_count
|
count: account.followers_count
|
||||||
})
|
})
|
||||||
}}
|
}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<PlaceholderLine
|
<PlaceholderLine
|
||||||
|
|
|
@ -9,18 +9,10 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { useCallback, useMemo } from 'react'
|
import React, { useCallback, useMemo } from 'react'
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
import { Trans, useTranslation } from 'react-i18next'
|
||||||
import {
|
import { KeyboardAvoidingView, Platform, SectionList, StyleSheet, View } from 'react-native'
|
||||||
KeyboardAvoidingView,
|
|
||||||
Platform,
|
|
||||||
SectionList,
|
|
||||||
StyleSheet,
|
|
||||||
View
|
|
||||||
} from 'react-native'
|
|
||||||
import { Circle } from 'react-native-animated-spinkit'
|
import { Circle } from 'react-native-animated-spinkit'
|
||||||
|
|
||||||
const TabSharedSearch: React.FC<
|
const TabSharedSearch: React.FC<TabSharedStackScreenProps<'Tab-Shared-Search'>> = ({
|
||||||
TabSharedStackScreenProps<'Tab-Shared-Search'>
|
|
||||||
> = ({
|
|
||||||
route: {
|
route: {
|
||||||
params: { text }
|
params: { text }
|
||||||
}
|
}
|
||||||
|
@ -75,10 +67,7 @@ const TabSharedSearch: React.FC<
|
||||||
<View>
|
<View>
|
||||||
{status === 'loading' ? (
|
{status === 'loading' ? (
|
||||||
<View style={{ flex: 1, alignItems: 'center' }}>
|
<View style={{ flex: 1, alignItems: 'center' }}>
|
||||||
<Circle
|
<Circle size={StyleConstants.Font.Size.M * 1.25} color={colors.secondary} />
|
||||||
size={StyleConstants.Font.Size.M * 1.25}
|
|
||||||
color={colors.secondary}
|
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
@ -96,39 +85,25 @@ const TabSharedSearch: React.FC<
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</CustomText>
|
</CustomText>
|
||||||
<CustomText
|
<CustomText style={[styles.emptyAdvanced, { color: colors.primaryDefault }]}>
|
||||||
style={[styles.emptyAdvanced, { color: colors.primaryDefault }]}
|
|
||||||
>
|
|
||||||
{t('shared.search.empty.advanced.header')}
|
{t('shared.search.empty.advanced.header')}
|
||||||
</CustomText>
|
</CustomText>
|
||||||
<CustomText
|
<CustomText style={[styles.emptyAdvanced, { color: colors.primaryDefault }]}>
|
||||||
style={[styles.emptyAdvanced, { color: colors.primaryDefault }]}
|
<CustomText style={{ color: colors.secondary }}>@username@domain</CustomText>
|
||||||
>
|
|
||||||
<CustomText style={{ color: colors.secondary }}>
|
|
||||||
@username@domain
|
|
||||||
</CustomText>
|
|
||||||
{' '}
|
{' '}
|
||||||
{t('shared.search.empty.advanced.example.account')}
|
{t('shared.search.empty.advanced.example.account')}
|
||||||
</CustomText>
|
</CustomText>
|
||||||
<CustomText
|
<CustomText style={[styles.emptyAdvanced, { color: colors.primaryDefault }]}>
|
||||||
style={[styles.emptyAdvanced, { color: colors.primaryDefault }]}
|
<CustomText style={{ color: colors.secondary }}>#example</CustomText>
|
||||||
>
|
|
||||||
<CustomText style={{ color: colors.secondary }}>
|
|
||||||
#example
|
|
||||||
</CustomText>
|
|
||||||
{' '}
|
{' '}
|
||||||
{t('shared.search.empty.advanced.example.hashtag')}
|
{t('shared.search.empty.advanced.example.hashtag')}
|
||||||
</CustomText>
|
</CustomText>
|
||||||
<CustomText
|
<CustomText style={[styles.emptyAdvanced, { color: colors.primaryDefault }]}>
|
||||||
style={[styles.emptyAdvanced, { color: colors.primaryDefault }]}
|
|
||||||
>
|
|
||||||
<CustomText style={{ color: colors.secondary }}>URL</CustomText>
|
<CustomText style={{ color: colors.secondary }}>URL</CustomText>
|
||||||
{' '}
|
{' '}
|
||||||
{t('shared.search.empty.advanced.example.statusLink')}
|
{t('shared.search.empty.advanced.example.statusLink')}
|
||||||
</CustomText>
|
</CustomText>
|
||||||
<CustomText
|
<CustomText style={[styles.emptyAdvanced, { color: colors.primaryDefault }]}>
|
||||||
style={[styles.emptyAdvanced, { color: colors.primaryDefault }]}
|
|
||||||
>
|
|
||||||
<CustomText style={{ color: colors.secondary }}>URL</CustomText>
|
<CustomText style={{ color: colors.secondary }}>URL</CustomText>
|
||||||
{' '}
|
{' '}
|
||||||
{t('shared.search.empty.advanced.example.accountLink')}
|
{t('shared.search.empty.advanced.example.accountLink')}
|
||||||
|
@ -140,21 +115,18 @@ const TabSharedSearch: React.FC<
|
||||||
)
|
)
|
||||||
}, [status])
|
}, [status])
|
||||||
|
|
||||||
const listItem = useCallback(
|
const listItem = useCallback(({ item, section }: { item: any; section: any }) => {
|
||||||
({ item, section }: { item: any; section: any }) => {
|
switch (section.title) {
|
||||||
switch (section.title) {
|
case 'accounts':
|
||||||
case 'accounts':
|
return <ComponentAccount account={item} />
|
||||||
return <ComponentAccount account={item} origin='search' />
|
case 'hashtags':
|
||||||
case 'hashtags':
|
return <ComponentHashtag hashtag={item} origin='search' />
|
||||||
return <ComponentHashtag hashtag={item} origin='search' />
|
case 'statuses':
|
||||||
case 'statuses':
|
return <TimelineDefault item={item} disableDetails />
|
||||||
return <TimelineDefault item={item} disableDetails origin='search' />
|
default:
|
||||||
default:
|
return null
|
||||||
return null
|
}
|
||||||
}
|
}, [])
|
||||||
},
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<KeyboardAvoidingView
|
<KeyboardAvoidingView
|
||||||
|
@ -195,10 +167,7 @@ const TabSharedSearch: React.FC<
|
||||||
backgroundColor: colors.backgroundDefault
|
backgroundColor: colors.backgroundDefault
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CustomText
|
<CustomText fontStyle='S' style={{ textAlign: 'center', color: colors.secondary }}>
|
||||||
fontStyle='S'
|
|
||||||
style={{ textAlign: 'center', color: colors.secondary }}
|
|
||||||
>
|
|
||||||
<Trans
|
<Trans
|
||||||
i18nKey='screenTabs:shared.search.notFound'
|
i18nKey='screenTabs:shared.search.notFound'
|
||||||
values={{ searchTerm: text, type: translation }}
|
values={{ searchTerm: text, type: translation }}
|
||||||
|
|
|
@ -34,7 +34,7 @@ const TabSharedUsers = React.memo(
|
||||||
data={flattenData}
|
data={flattenData}
|
||||||
style={styles.flatList}
|
style={styles.flatList}
|
||||||
renderItem={({ item }) => (
|
renderItem={({ item }) => (
|
||||||
<ComponentAccount account={item} origin='relationship' />
|
<ComponentAccount account={item} />
|
||||||
)}
|
)}
|
||||||
onEndReached={onEndReached}
|
onEndReached={onEndReached}
|
||||||
onEndReachedThreshold={0.75}
|
onEndReachedThreshold={0.75}
|
||||||
|
|
|
@ -55,7 +55,7 @@ const settingsPersistConfig = {
|
||||||
key: 'settings',
|
key: 'settings',
|
||||||
prefix,
|
prefix,
|
||||||
storage: AsyncStorage,
|
storage: AsyncStorage,
|
||||||
version: 1,
|
version: 3,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
migrate: createMigrate(settingsMigration)
|
migrate: createMigrate(settingsMigration)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { SettingsV0 } from './v0'
|
import { SettingsV0 } from './v0'
|
||||||
import { SettingsV1 } from './v1'
|
import { SettingsV1 } from './v1'
|
||||||
import { SettingsV2 } from './v2'
|
import { SettingsV2 } from './v2'
|
||||||
|
import { SettingsV3 } from './v3'
|
||||||
|
|
||||||
const settingsMigration = {
|
const settingsMigration = {
|
||||||
1: (state: SettingsV0): SettingsV1 => {
|
1: (state: SettingsV0): SettingsV1 => {
|
||||||
|
@ -15,6 +16,10 @@ const settingsMigration = {
|
||||||
darkTheme: 'lighter',
|
darkTheme: 'lighter',
|
||||||
staticEmoji: false
|
staticEmoji: false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
3: (state: SettingsV2): SettingsV3 => {
|
||||||
|
const { analytics, ...rest } = state
|
||||||
|
return rest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
export type SettingsV3 = {
|
||||||
|
fontsize: -1 | 0 | 1 | 2 | 3
|
||||||
|
language: string
|
||||||
|
theme: 'light' | 'dark' | 'auto'
|
||||||
|
darkTheme: 'lighter' | 'darker'
|
||||||
|
browser: 'internal' | 'external'
|
||||||
|
staticEmoji: boolean
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
import analytics from '@components/analytics'
|
|
||||||
import features from '@helpers/features'
|
import features from '@helpers/features'
|
||||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||||
import { RootState } from '@root/store'
|
import { RootState } from '@root/store'
|
||||||
|
@ -184,8 +183,6 @@ const instancesSlice = createSlice({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
analytics('login')
|
|
||||||
})
|
})
|
||||||
.addCase(addInstance.rejected, (state, action) => {
|
.addCase(addInstance.rejected, (state, action) => {
|
||||||
console.error(state.instances)
|
console.error(state.instances)
|
||||||
|
@ -204,8 +201,6 @@ const instancesSlice = createSlice({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
state.instances.length && (state.instances[state.instances.length - 1].active = true)
|
state.instances.length && (state.instances[state.instances.length - 1].active = true)
|
||||||
|
|
||||||
analytics('logout')
|
|
||||||
})
|
})
|
||||||
.addCase(removeInstance.rejected, (state, action) => {
|
.addCase(removeInstance.rejected, (state, action) => {
|
||||||
console.error(state)
|
console.error(state)
|
||||||
|
|
|
@ -1,72 +1,43 @@
|
||||||
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit'
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||||
import { LOCALES } from '@root/i18n/locales'
|
import { LOCALES } from '@root/i18n/locales'
|
||||||
import { RootState } from '@root/store'
|
import { RootState } from '@root/store'
|
||||||
import { SettingsV2 } from '@utils/migrations/settings/v2'
|
import { SettingsV3 } from '@utils/migrations/settings/v3'
|
||||||
import * as Analytics from 'expo-firebase-analytics'
|
|
||||||
import * as Localization from 'expo-localization'
|
import * as Localization from 'expo-localization'
|
||||||
import { pickBy } from 'lodash'
|
import { pickBy } from 'lodash'
|
||||||
|
|
||||||
export const changeAnalytics = createAsyncThunk(
|
export type SettingsState = SettingsV3
|
||||||
'settings/changeAnalytics',
|
|
||||||
async (newValue: SettingsState['analytics']) => {
|
|
||||||
await Analytics.setAnalyticsCollectionEnabled(newValue)
|
|
||||||
return { newValue }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
export type SettingsState = SettingsV2
|
|
||||||
|
|
||||||
export const settingsInitialState = {
|
export const settingsInitialState = {
|
||||||
fontsize: 0,
|
fontsize: 0,
|
||||||
notification: {
|
notification: {
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
language: Object.keys(
|
language: Object.keys(pickBy(LOCALES, (_, key) => Localization.locale.startsWith(key)))
|
||||||
pickBy(LOCALES, (_, key) => Localization.locale.startsWith(key))
|
? Object.keys(pickBy(LOCALES, (_, key) => Localization.locale.startsWith(key)))[0]
|
||||||
)
|
|
||||||
? Object.keys(
|
|
||||||
pickBy(LOCALES, (_, key) => Localization.locale.startsWith(key))
|
|
||||||
)[0]
|
|
||||||
: 'en',
|
: 'en',
|
||||||
theme: 'auto',
|
theme: 'auto',
|
||||||
darkTheme: 'lighter',
|
darkTheme: 'lighter',
|
||||||
browser: 'internal',
|
browser: 'internal',
|
||||||
staticEmoji: false,
|
staticEmoji: false
|
||||||
analytics: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingsSlice = createSlice({
|
const settingsSlice = createSlice({
|
||||||
name: 'settings',
|
name: 'settings',
|
||||||
initialState: settingsInitialState as SettingsState,
|
initialState: settingsInitialState as SettingsState,
|
||||||
reducers: {
|
reducers: {
|
||||||
changeFontsize: (
|
changeFontsize: (state, action: PayloadAction<SettingsState['fontsize']>) => {
|
||||||
state,
|
|
||||||
action: PayloadAction<SettingsState['fontsize']>
|
|
||||||
) => {
|
|
||||||
state.fontsize = action.payload
|
state.fontsize = action.payload
|
||||||
},
|
},
|
||||||
changeLanguage: (
|
changeLanguage: (state, action: PayloadAction<NonNullable<SettingsState['language']>>) => {
|
||||||
state,
|
|
||||||
action: PayloadAction<NonNullable<SettingsState['language']>>
|
|
||||||
) => {
|
|
||||||
state.language = action.payload
|
state.language = action.payload
|
||||||
},
|
},
|
||||||
changeTheme: (
|
changeTheme: (state, action: PayloadAction<NonNullable<SettingsState['theme']>>) => {
|
||||||
state,
|
|
||||||
action: PayloadAction<NonNullable<SettingsState['theme']>>
|
|
||||||
) => {
|
|
||||||
state.theme = action.payload
|
state.theme = action.payload
|
||||||
},
|
},
|
||||||
changeDarkTheme: (
|
changeDarkTheme: (state, action: PayloadAction<NonNullable<SettingsState['darkTheme']>>) => {
|
||||||
state,
|
|
||||||
action: PayloadAction<NonNullable<SettingsState['darkTheme']>>
|
|
||||||
) => {
|
|
||||||
state.darkTheme = action.payload
|
state.darkTheme = action.payload
|
||||||
},
|
},
|
||||||
changeBrowser: (
|
changeBrowser: (state, action: PayloadAction<NonNullable<SettingsState['browser']>>) => {
|
||||||
state,
|
|
||||||
action: PayloadAction<NonNullable<SettingsState['browser']>>
|
|
||||||
) => {
|
|
||||||
state.browser = action.payload
|
state.browser = action.payload
|
||||||
},
|
},
|
||||||
changeStaticEmoji: (
|
changeStaticEmoji: (
|
||||||
|
@ -75,25 +46,15 @@ const settingsSlice = createSlice({
|
||||||
) => {
|
) => {
|
||||||
state.staticEmoji = action.payload
|
state.staticEmoji = action.payload
|
||||||
}
|
}
|
||||||
},
|
|
||||||
extraReducers: builder => {
|
|
||||||
builder.addCase(changeAnalytics.fulfilled, (state, action) => {
|
|
||||||
state.analytics = action.payload.newValue
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getSettingsFontsize = (state: RootState) =>
|
export const getSettingsFontsize = (state: RootState) => state.settings.fontsize || 0
|
||||||
state.settings.fontsize || 0
|
|
||||||
export const getSettingsLanguage = (state: RootState) => state.settings.language
|
export const getSettingsLanguage = (state: RootState) => state.settings.language
|
||||||
export const getSettingsTheme = (state: RootState) => state.settings.theme
|
export const getSettingsTheme = (state: RootState) => state.settings.theme
|
||||||
export const getSettingsDarkTheme = (state: RootState) =>
|
export const getSettingsDarkTheme = (state: RootState) => state.settings.darkTheme
|
||||||
state.settings.darkTheme
|
|
||||||
export const getSettingsBrowser = (state: RootState) => state.settings.browser
|
export const getSettingsBrowser = (state: RootState) => state.settings.browser
|
||||||
export const getSettingsStaticEmoji = (state: RootState) =>
|
export const getSettingsStaticEmoji = (state: RootState) => state.settings.staticEmoji
|
||||||
state.settings.staticEmoji
|
|
||||||
export const getSettingsAnalytics = (state: RootState) =>
|
|
||||||
state.settings.analytics
|
|
||||||
|
|
||||||
export const {
|
export const {
|
||||||
changeFontsize,
|
changeFontsize,
|
||||||
|
|
14
yarn.lock
14
yarn.lock
|
@ -5659,20 +5659,6 @@ expo-file-system@^15.1.1, expo-file-system@~15.1.0, expo-file-system@~15.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
uuid "^3.4.0"
|
uuid "^3.4.0"
|
||||||
|
|
||||||
expo-firebase-analytics@^8.0.0:
|
|
||||||
version "8.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/expo-firebase-analytics/-/expo-firebase-analytics-8.0.0.tgz#69b17bf48317d95a55f28cbd485e06d4800c134b"
|
|
||||||
integrity sha512-nWYa5vm2BX+qXrB0UQPMb0vh+QSGpx9G78TetRQAa+M+96j5Y0qUEsSKWkKvkICFF8ItnhNz2vdDNWZrMLefnw==
|
|
||||||
dependencies:
|
|
||||||
expo-firebase-core "~6.0.0"
|
|
||||||
|
|
||||||
expo-firebase-core@~6.0.0:
|
|
||||||
version "6.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/expo-firebase-core/-/expo-firebase-core-6.0.0.tgz#854fb72b6769f3c6d3caa5797c3f8d4effe9a564"
|
|
||||||
integrity sha512-ZMcvRxKuAjZ0V4+VCuYKQ9P3Br8nGUORCbG41ewyLnLXBwov85AdBx4/5lA7T5cX1oOmv2fKMnU3gqCR+s6Veg==
|
|
||||||
dependencies:
|
|
||||||
expo-constants "~14.0.0"
|
|
||||||
|
|
||||||
expo-font@~11.0.1:
|
expo-font@~11.0.1:
|
||||||
version "11.0.1"
|
version "11.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/expo-font/-/expo-font-11.0.1.tgz#0758ce4e505995d0193a33e3c4325b35bf1fb7f7"
|
resolved "https://registry.yarnpkg.com/expo-font/-/expo-font-11.0.1.tgz#0758ce4e505995d0193a33e3c4325b35bf1fb7f7"
|
||||||
|
|
Loading…
Reference in New Issue