mirror of
https://github.com/inaturalist/iNaturalistReactNative.git
synced 2025-12-23 22:18:36 -05:00
Update to react-native 0.74 (3rd attempt) (#2937)
* Upgrade to RN0.74 with upgrade helper * Bump minor version * Remove yarn files * RN 0.74.7 * Update .flowconfig * Update Gemfile.lock * Update project.pbxproj * Update PrivacyInfo.xcprivacy * Refactor uri into constant * Only use filename for name Because using the full uri does no longer work like this. * Check for uri being null * Update metro.config.js * Rubocop autocorrect * Update package-lock.json * Update react-native-vision-camera+4.0.5.patch * Update Podfile.lock
This commit is contained in:
@@ -28,6 +28,9 @@ node_modules/react-native/Libraries/polyfills/.*
|
||||
.*/node_modules/@react-native/community-cli-plugin/dist/commands/bundle/index.js.flow
|
||||
.*/node_modules/@react-native/community-cli-plugin/dist/commands/bundle/buildBundle.js.flow
|
||||
.*/node_modules/metro/src/lib/JsonReporter.js.flow
|
||||
.*/node_modules/hermes-estree/dist/generated/predicates.js.flow
|
||||
.*/node_modules/react-native/Libraries/StyleSheet/StyleSheetTypes.js
|
||||
.*/node_modules/react-native/Libraries/Types/ReactDevToolsTypes.js
|
||||
|
||||
[untyped]
|
||||
.*/node_modules/@react-native-community/cli/.*/.*
|
||||
|
||||
12
.gitignore
vendored
12
.gitignore
vendored
@@ -21,7 +21,7 @@ DerivedData
|
||||
*.ipa
|
||||
*.xcuserstate
|
||||
# Might be used to customize further the path to node that xcode uses, see .xcode.env for our version controlled file
|
||||
ios/.xcode.env.local
|
||||
**/.xcode.env.local
|
||||
|
||||
# Android/IntelliJ
|
||||
#
|
||||
@@ -47,7 +47,7 @@ yarn-error.log
|
||||
*.jsbundle
|
||||
|
||||
# Ruby / CocoaPods
|
||||
/ios/Pods/
|
||||
**/Pods/
|
||||
/vendor/bundle/
|
||||
|
||||
# Temporary files created by Metro to check the health of the file watcher
|
||||
@@ -59,6 +59,14 @@ yarn-error.log
|
||||
# Jest Coverage
|
||||
/coverage
|
||||
|
||||
# Yarn
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
||||
# Secrets file
|
||||
.env*
|
||||
|
||||
|
||||
1
Gemfile
1
Gemfile
@@ -8,6 +8,7 @@ ruby ">= 2.6.10"
|
||||
# bound in the template on Cocoapods with next React Native release.
|
||||
gem "activesupport", ">= 6.1.7.5", "< 7.1.0"
|
||||
gem "cocoapods", ">= 1.13", "< 1.15"
|
||||
gem "concurrent-ruby", "<= 1.3.4"
|
||||
gem "xcodeproj", "< 1.26.0"
|
||||
|
||||
gem "fastlane"
|
||||
|
||||
@@ -315,6 +315,7 @@ PLATFORMS
|
||||
DEPENDENCIES
|
||||
activesupport (>= 6.1.7.5, < 7.1.0)
|
||||
cocoapods (>= 1.13, < 1.15)
|
||||
concurrent-ruby (<= 1.3.4)
|
||||
fastlane
|
||||
fastlane-sirp!
|
||||
nokogiri
|
||||
|
||||
@@ -162,7 +162,6 @@ dependencies {
|
||||
|
||||
// The version of react-native is set by the React Native Gradle Plugin
|
||||
implementation("com.facebook.react:react-android")
|
||||
implementation("com.facebook.react:flipper-integration")
|
||||
|
||||
// This is required for getAttributes() to work in Detox on Android:
|
||||
// https://github.com/wix/Detox/issues/3147
|
||||
|
||||
@@ -9,7 +9,6 @@ import com.facebook.react.ReactPackage
|
||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
|
||||
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
|
||||
import com.facebook.react.defaults.DefaultReactNativeHost
|
||||
import com.facebook.react.flipper.ReactNativeFlipper
|
||||
import com.facebook.soloader.SoLoader
|
||||
|
||||
class MainApplication : Application(), ReactApplication {
|
||||
@@ -31,7 +30,7 @@ class MainApplication : Application(), ReactApplication {
|
||||
}
|
||||
|
||||
override val reactHost: ReactHost
|
||||
get() = getDefaultReactHost(this.applicationContext, reactNativeHost)
|
||||
get() = getDefaultReactHost(applicationContext, reactNativeHost)
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
@@ -40,6 +39,5 @@ class MainApplication : Application(), ReactApplication {
|
||||
// If you opted-in for the New Architecture, we load the native entry point for this app.
|
||||
load()
|
||||
}
|
||||
ReactNativeFlipper.initializeFlipper(this, reactNativeHost.reactInstanceManager)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material"
|
||||
android:insetRight="@dimen/abc_edit_text_inset_horizontal_material"
|
||||
android:insetTop="@dimen/abc_edit_text_inset_top_material"
|
||||
android:insetBottom="@dimen/abc_edit_text_inset_bottom_material">
|
||||
android:insetBottom="@dimen/abc_edit_text_inset_bottom_material"
|
||||
>
|
||||
|
||||
<selector>
|
||||
<!--
|
||||
|
||||
@@ -8,8 +8,8 @@ buildscript {
|
||||
minSdkVersion = 23
|
||||
compileSdkVersion = 34
|
||||
targetSdkVersion = 34
|
||||
ndkVersion = "25.1.8937393"
|
||||
kotlinVersion = "1.8.0"
|
||||
ndkVersion = "26.1.10909125"
|
||||
kotlinVersion = "1.9.22"
|
||||
// This specifies which tensorflow-lite version to use for our vision-plugin.
|
||||
tensorflowVersion = "2.14.0"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
14
android/gradlew
vendored
14
android/gradlew
vendored
@@ -145,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
@@ -153,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
@@ -202,11 +202,11 @@ fi
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
|
||||
20
android/gradlew.bat
vendored
20
android/gradlew.bat
vendored
@@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
@@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
|
||||
17
ios/Podfile
17
ios/Podfile
@@ -43,17 +43,6 @@ setup_permissions(
|
||||
]
|
||||
)
|
||||
|
||||
# If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
|
||||
# because `react-native-flipper` depends on (FlipperKit,...) that will be excluded
|
||||
#
|
||||
# To fix this you can also exclude `react-native-flipper` using a `react-native.config.js`
|
||||
# ```js
|
||||
# module.exports = {
|
||||
# dependencies: {
|
||||
# ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
|
||||
# ```
|
||||
# flipper_config = ENV["NO_FLIPPER"] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled
|
||||
|
||||
linkage = ENV.fetch( "USE_FRAMEWORKS", nil )
|
||||
unless linkage.nil?
|
||||
Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
|
||||
@@ -65,11 +54,6 @@ target "iNaturalistReactNative" do
|
||||
|
||||
use_react_native!(
|
||||
path: config[:reactNativePath],
|
||||
# Enables Flipper.
|
||||
#
|
||||
# Note that if you have use_frameworks! enabled, Flipper will not work and
|
||||
# you should disable the next line.
|
||||
# :flipper_configuration => flipper_config,
|
||||
# An absolute path to your application root.
|
||||
app_path: "#{Pod::Config.instance.installation_root}/.."
|
||||
)
|
||||
@@ -101,6 +85,7 @@ target "iNaturalistReactNative" do
|
||||
installer,
|
||||
config[:reactNativePath],
|
||||
mac_catalyst_enabled: false
|
||||
# :ccache_enabled => true
|
||||
)
|
||||
# Add these lines for Xcode 14 builds
|
||||
installer.generated_projects.each do | project |
|
||||
|
||||
1095
ios/Podfile.lock
1095
ios/Podfile.lock
File diff suppressed because it is too large
Load Diff
@@ -39,5 +39,9 @@
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array/>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -429,7 +429,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
|
||||
shellScript = "set -e\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
|
||||
};
|
||||
075F7EA7751B87EC3B297227 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
@@ -892,6 +892,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CC = "";
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++20";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
@@ -919,6 +920,7 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CXX = "";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
|
||||
@@ -939,6 +941,8 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
|
||||
LD = "";
|
||||
LDPLUSPLUS = "";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
/usr/lib/swift,
|
||||
"$(inherited)",
|
||||
@@ -957,6 +961,7 @@
|
||||
"-DFOLLY_MOBILE=1",
|
||||
"-DFOLLY_USE_LIBCPP=1",
|
||||
"-DFOLLY_CFG_NO_COROUTINES=1",
|
||||
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
|
||||
);
|
||||
OTHER_LDFLAGS = "$(inherited)";
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
@@ -970,6 +975,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CC = "";
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++20";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
@@ -997,6 +1003,7 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CXX = "";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
|
||||
@@ -1013,6 +1020,8 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
|
||||
LD = "";
|
||||
LDPLUSPLUS = "";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
/usr/lib/swift,
|
||||
"$(inherited)",
|
||||
@@ -1030,6 +1039,7 @@
|
||||
"-DFOLLY_MOBILE=1",
|
||||
"-DFOLLY_USE_LIBCPP=1",
|
||||
"-DFOLLY_CFG_NO_COROUTINES=1",
|
||||
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
|
||||
);
|
||||
OTHER_LDFLAGS = "$(inherited)";
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
|
||||
@@ -38,10 +38,10 @@
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
return [self getBundleURL];
|
||||
return [self bundleURL];
|
||||
}
|
||||
|
||||
- (NSURL *)getBundleURL
|
||||
- (NSURL *)bundleURL
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
/**
|
||||
* Metro configuration for React Native
|
||||
* https://github.com/facebook/react-native
|
||||
* https://reactnative.dev/docs/metro
|
||||
* with added config for react-native-svg-transformer
|
||||
* https://www.npmjs.com/package/react-native-svg-transformer?activeTab
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
const { getDefaultConfig, mergeConfig } = require( "@react-native/metro-config" );
|
||||
|
||||
const {
|
||||
|
||||
2392
package-lock.json
generated
2392
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -86,7 +86,7 @@
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-i18next": "^14.1.0",
|
||||
"react-native": "0.73.11",
|
||||
"react-native": "0.74.7",
|
||||
"react-native-animated-dots-carousel": "^2.0.0",
|
||||
"react-native-audio-recorder-player": "^3.6.7",
|
||||
"react-native-bouncy-checkbox": "^3.0.7",
|
||||
@@ -143,9 +143,10 @@
|
||||
"@babel/runtime": "^7.24.4",
|
||||
"@faker-js/faker": "^8.4.1",
|
||||
"@fluent/syntax": "^0.19.0",
|
||||
"@react-native/babel-preset": "0.73.21",
|
||||
"@react-native/metro-config": "0.73.5",
|
||||
"@react-native/typescript-config": "0.73.1",
|
||||
"@react-native/babel-preset": "0.74.89",
|
||||
"@react-native/eslint-config": "0.74.89",
|
||||
"@react-native/metro-config": "0.74.89",
|
||||
"@react-native/typescript-config": "0.74.89",
|
||||
"@tanstack/eslint-plugin-query": "^5.28.11",
|
||||
"@testing-library/jest-native": "^5.4.3",
|
||||
"@testing-library/react-native": "^12.4.5",
|
||||
@@ -201,7 +202,6 @@
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"packageManager": "yarn@3.6.4",
|
||||
"lint-staged": {
|
||||
"*.{js,jsx,ts,tsx}": [
|
||||
"eslint --cache --fix --max-warnings=0 --cache-location .eslintcache"
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
diff --git a/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/frameprocessors/VisionCameraProxy.kt b/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/frameprocessors/VisionCameraProxy.kt
|
||||
index d697bef..8de418b 100644
|
||||
--- a/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/frameprocessors/VisionCameraProxy.kt
|
||||
+++ b/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/frameprocessors/VisionCameraProxy.kt
|
||||
@@ -7,12 +7,14 @@ import com.facebook.jni.HybridData
|
||||
import com.facebook.proguard.annotations.DoNotStrip
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.bridge.UiThreadUtil
|
||||
+import com.facebook.react.common.annotations.FrameworkAPI
|
||||
import com.facebook.react.turbomodule.core.CallInvokerHolderImpl
|
||||
import com.facebook.react.uimanager.UIManagerHelper
|
||||
import com.mrousavy.camera.core.ViewNotFoundError
|
||||
import com.mrousavy.camera.react.CameraView
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
+@OptIn(FrameworkAPI::class)
|
||||
@Suppress("KotlinJniMissingFunction") // we use fbjni.
|
||||
class VisionCameraProxy(private val reactContext: ReactApplicationContext) {
|
||||
companion object {
|
||||
diff --git a/node_modules/react-native-vision-camera/ios/Core/MetadataProvider.swift b/node_modules/react-native-vision-camera/ios/Core/MetadataProvider.swift
|
||||
index 4855d31..ece8024 100644
|
||||
--- a/node_modules/react-native-vision-camera/ios/Core/MetadataProvider.swift
|
||||
|
||||
@@ -30,10 +30,11 @@ class ObservationPhoto extends Realm.Object {
|
||||
}
|
||||
|
||||
static mapPhotoForUpload( observationID, photo ) {
|
||||
const uri = Photo.getLocalPhotoUri( photo.localFilePath );
|
||||
return {
|
||||
file: new FileUpload( {
|
||||
uri: Photo.getLocalPhotoUri( photo.localFilePath ),
|
||||
name: Photo.getLocalPhotoUri( photo.localFilePath ),
|
||||
uri,
|
||||
name: uri?.split( "/" ).pop( ),
|
||||
type: "image/jpeg"
|
||||
} )
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user