mirror of
				https://github.com/tooot-app/app
				synced 2025-06-05 22:19:13 +02:00 
			
		
		
		
	Fixed #497
This commit is contained in:
		| @@ -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 | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								src/utils/migrations/settings/v3.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/utils/migrations/settings/v3.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -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" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user