mirror of https://github.com/tooot-app/app
Merge branch 'main' into release
This commit is contained in:
commit
24c099b427
|
@ -20,7 +20,7 @@ jobs:
|
|||
- run: bundle install
|
||||
- run: yarn app:build ios
|
||||
env:
|
||||
DEVELOPER_DIR: /Applications/Xcode_14.3.app/Contents/Developer
|
||||
DEVELOPER_DIR: /Applications/Xcode_14.3.1.app/Contents/Developer
|
||||
ENVIRONMENT: ${{ steps.branch.outputs.current_branch }}
|
||||
SENTRY_ENVIRONMENT: ${{ steps.branch.outputs.current_branch }}
|
||||
LC_ALL: en_US.UTF-8
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
diff --git a/src/android.js b/src/android.js
|
||||
index fbf09855771f985c5edfc53c22cf6cfe828f45f9..7751d456e08e2dc4c78601fc9430fdbf1373e0d4 100644
|
||||
--- a/src/android.js
|
||||
+++ b/src/android.js
|
||||
@@ -16,7 +16,7 @@ import TextAncestor from 'react-native/Libraries/Text/TextAncestor';
|
||||
import TextInputState from 'react-native/Libraries/Components/TextInput/TextInputState';
|
||||
import invariant from 'invariant';
|
||||
import nullthrows from 'nullthrows';
|
||||
-import setAndForwardRef from 'react-native/Libraries/Utilities/setAndForwardRef';
|
||||
+import setAndForwardRef from './setAndForwardRef';
|
||||
|
||||
import usePressability from 'react-native/Libraries/Pressability/usePressability';
|
||||
|
||||
diff --git a/src/ios.tsx b/src/ios.tsx
|
||||
index b9ed28bbf9fca6fb44c27096e771d8d2b65b858f..588a75c82b2ee1123d3e48acb984bcbc8b293cc8 100644
|
||||
--- a/src/ios.tsx
|
||||
+++ b/src/ios.tsx
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from 'react-native';
|
||||
import TextInputState from 'react-native/Libraries/Components/TextInput/TextInputState';
|
||||
import TextAncestor from 'react-native/Libraries/Text/TextAncestor';
|
||||
-import setAndForwardRef from 'react-native/Libraries/Utilities/setAndForwardRef';
|
||||
+import setAndForwardRef from './setAndForwardRef';
|
||||
import { getTextInputExtraProps } from './extra_props';
|
||||
|
||||
import type {
|
||||
diff --git a/src/setAndForwardRef.js b/src/setAndForwardRef.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ad7777e271b945c7123953f7578a8d1208ca9e48
|
||||
--- /dev/null
|
||||
+++ b/src/setAndForwardRef.js
|
||||
@@ -0,0 +1,17 @@
|
||||
+function setAndForwardRef({ getForwardedRef, setLocalRef }) {
|
||||
+ return function forwardRef(ref) {
|
||||
+ const forwardedRef = getForwardedRef();
|
||||
+
|
||||
+ setLocalRef(ref);
|
||||
+
|
||||
+ // Forward to user ref prop (if one has been specified)
|
||||
+ if (typeof forwardedRef === 'function') {
|
||||
+ // Handle function-based refs. String-based refs are handled as functions.
|
||||
+ forwardedRef(ref);
|
||||
+ } else if (typeof forwardedRef === 'object' && forwardedRef != null) {
|
||||
+ // Handle createRef-based refs
|
||||
+ forwardedRef.current = ref;
|
||||
+ }
|
||||
+ };
|
||||
+}
|
||||
+export default setAndForwardRef;
|
||||
\ No newline at end of file
|
|
@ -0,0 +1,74 @@
|
|||
diff --git a/Libraries/Utilities/setAndForwardRef.js b/Libraries/Utilities/setAndForwardRef.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e67b530b9a933b68e219e2b8cec2a66dc8f51323
|
||||
--- /dev/null
|
||||
+++ b/Libraries/Utilities/setAndForwardRef.js
|
||||
@@ -0,0 +1,68 @@
|
||||
+/**
|
||||
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
+ *
|
||||
+ * This source code is licensed under the MIT license found in the
|
||||
+ * LICENSE file in the root directory of this source tree.
|
||||
+ *
|
||||
+ * @format
|
||||
+ * @flow
|
||||
+ */
|
||||
+
|
||||
+'use strict'
|
||||
+
|
||||
+import type { ElementRef, Ref } from 'react'
|
||||
+
|
||||
+type Args = $ReadOnly<{|
|
||||
+ getForwardedRef: () => ?Ref<any>,
|
||||
+ setLocalRef: (ref: ElementRef<any>) => mixed
|
||||
+|}>
|
||||
+
|
||||
+/**
|
||||
+ * This is a helper function for when a component needs to be able to forward a ref
|
||||
+ * to a child component, but still needs to have access to that component as part of
|
||||
+ * its implementation.
|
||||
+ *
|
||||
+ * Its main use case is in wrappers for native components.
|
||||
+ *
|
||||
+ * Usage:
|
||||
+ *
|
||||
+ * class MyView extends React.Component {
|
||||
+ * _nativeRef = null;
|
||||
+ *
|
||||
+ * _setNativeRef = setAndForwardRef({
|
||||
+ * getForwardedRef: () => this.props.forwardedRef,
|
||||
+ * setLocalRef: ref => {
|
||||
+ * this._nativeRef = ref;
|
||||
+ * },
|
||||
+ * });
|
||||
+ *
|
||||
+ * render() {
|
||||
+ * return <View ref={this._setNativeRef} />;
|
||||
+ * }
|
||||
+ * }
|
||||
+ *
|
||||
+ * const MyViewWithRef = React.forwardRef((props, ref) => (
|
||||
+ * <MyView {...props} forwardedRef={ref} />
|
||||
+ * ));
|
||||
+ *
|
||||
+ * module.exports = MyViewWithRef;
|
||||
+ */
|
||||
+
|
||||
+function setAndForwardRef({ getForwardedRef, setLocalRef }: Args): (ref: ElementRef<any>) => void {
|
||||
+ return function forwardRef(ref: ElementRef<any>) {
|
||||
+ const forwardedRef = getForwardedRef()
|
||||
+
|
||||
+ setLocalRef(ref)
|
||||
+
|
||||
+ // Forward to user ref prop (if one has been specified)
|
||||
+ if (typeof forwardedRef === 'function') {
|
||||
+ // Handle function-based refs. String-based refs are handled as functions.
|
||||
+ forwardedRef(ref)
|
||||
+ } else if (typeof forwardedRef === 'object' && forwardedRef != null) {
|
||||
+ // Handle createRef-based refs
|
||||
+ forwardedRef.current = ref
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+module.exports = setAndForwardRef
|
2
Gemfile
2
Gemfile
|
@ -1,6 +1,6 @@
|
|||
source "https://rubygems.org"
|
||||
|
||||
gem "fastlane"
|
||||
gem 'cocoapods'
|
||||
gem 'cocoapods', '~> 1.12'
|
||||
plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
|
||||
eval_gemfile(plugins_path) if File.exist?(plugins_path)
|
||||
|
|
38
Gemfile.lock
38
Gemfile.lock
|
@ -8,7 +8,7 @@ GEM
|
|||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
addressable (2.8.1)
|
||||
addressable (2.8.4)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
algoliasearch (1.27.5)
|
||||
httpclient (~> 2.8, >= 2.8.3)
|
||||
|
@ -16,20 +16,20 @@ GEM
|
|||
artifactory (3.0.15)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.2.0)
|
||||
aws-partitions (1.722.0)
|
||||
aws-sdk-core (3.170.0)
|
||||
aws-partitions (1.785.0)
|
||||
aws-sdk-core (3.178.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.651.0)
|
||||
aws-sigv4 (~> 1.5)
|
||||
jmespath (~> 1, >= 1.6.1)
|
||||
aws-sdk-kms (1.63.0)
|
||||
aws-sdk-core (~> 3, >= 3.165.0)
|
||||
aws-sdk-kms (1.71.0)
|
||||
aws-sdk-core (~> 3, >= 3.177.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.119.1)
|
||||
aws-sdk-core (~> 3, >= 3.165.0)
|
||||
aws-sdk-s3 (1.129.0)
|
||||
aws-sdk-core (~> 3, >= 3.177.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.4)
|
||||
aws-sigv4 (1.5.2)
|
||||
aws-sigv4 (~> 1.6)
|
||||
aws-sigv4 (1.6.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
babosa (1.0.4)
|
||||
claide (1.1.0)
|
||||
|
@ -76,7 +76,7 @@ GEM
|
|||
highline (~> 2.0.0)
|
||||
concurrent-ruby (1.2.2)
|
||||
declarative (0.0.20)
|
||||
digest-crc (0.6.4)
|
||||
digest-crc (0.6.5)
|
||||
rake (>= 12.0.0, < 14.0.0)
|
||||
domain_name (0.5.20190701)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
|
@ -85,7 +85,7 @@ GEM
|
|||
escape (0.0.4)
|
||||
ethon (0.16.0)
|
||||
ffi (>= 1.15.0)
|
||||
excon (0.99.0)
|
||||
excon (0.100.0)
|
||||
faraday (1.10.3)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
|
@ -114,8 +114,8 @@ GEM
|
|||
faraday-retry (1.0.3)
|
||||
faraday_middleware (1.2.0)
|
||||
faraday (~> 1.0)
|
||||
fastimage (2.2.6)
|
||||
fastlane (2.212.1)
|
||||
fastimage (2.2.7)
|
||||
fastlane (2.213.0)
|
||||
CFPropertyList (>= 2.3, < 4.0.0)
|
||||
addressable (>= 2.8, < 3.0.0)
|
||||
artifactory (~> 3.0)
|
||||
|
@ -139,7 +139,7 @@ GEM
|
|||
json (< 3.0.0)
|
||||
jwt (>= 2.1.0, < 3)
|
||||
mini_magick (>= 4.9.4, < 5.0.0)
|
||||
multipart-post (~> 2.0.0)
|
||||
multipart-post (>= 2.0.0, < 3.0.0)
|
||||
naturally (~> 2.2)
|
||||
optparse (~> 0.1.1)
|
||||
plist (>= 3.1.0, < 4.0.0)
|
||||
|
@ -163,7 +163,7 @@ GEM
|
|||
fourflusher (2.3.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
google-apis-androidpublisher_v3 (0.35.0)
|
||||
google-apis-androidpublisher_v3 (0.45.0)
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-apis-core (0.11.0)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
|
@ -194,7 +194,7 @@ GEM
|
|||
google-cloud-core (~> 1.6)
|
||||
googleauth (>= 0.16.2, < 2.a)
|
||||
mini_mime (~> 1.0)
|
||||
googleauth (1.3.0)
|
||||
googleauth (1.6.0)
|
||||
faraday (>= 0.17.3, < 3.a)
|
||||
jwt (>= 1.4, < 3.0)
|
||||
memoist (~> 0.16)
|
||||
|
@ -209,14 +209,14 @@ GEM
|
|||
concurrent-ruby (~> 1.0)
|
||||
jmespath (1.6.2)
|
||||
json (2.6.3)
|
||||
jwt (2.7.0)
|
||||
jwt (2.7.1)
|
||||
memoist (0.16.2)
|
||||
mini_magick (4.12.0)
|
||||
mini_mime (1.1.2)
|
||||
minitest (5.18.0)
|
||||
molinillo (0.8.0)
|
||||
multi_json (1.15.0)
|
||||
multipart-post (2.0.0)
|
||||
multipart-post (2.3.0)
|
||||
nanaimo (0.3.0)
|
||||
nap (1.1.0)
|
||||
naturally (2.2.1)
|
||||
|
@ -280,7 +280,7 @@ PLATFORMS
|
|||
arm64-darwin-22
|
||||
|
||||
DEPENDENCIES
|
||||
cocoapods
|
||||
cocoapods (~> 1.12)
|
||||
fastlane
|
||||
fastlane-plugin-json
|
||||
fastlane-plugin-sentry
|
||||
|
|
|
@ -2,8 +2,6 @@ apply plugin: "com.android.application"
|
|||
apply plugin: "com.facebook.react"
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
|
||||
import com.android.build.OutputFile
|
||||
|
||||
/**
|
||||
* This is the configuration block to customize your React Native Android app.
|
||||
* By default you don't need to apply any configuration, just uncomment the lines you need.
|
||||
|
@ -15,8 +13,8 @@ react {
|
|||
// root = file("../")
|
||||
// The folder where the react-native NPM package is. Default is ../node_modules/react-native
|
||||
// reactNativeDir = file("../node_modules/react-native")
|
||||
// The folder where the react-native Codegen package is. Default is ../node_modules/react-native-codegen
|
||||
// codegenDir = file("../node_modules/react-native-codegen")
|
||||
// The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen
|
||||
// codegenDir = file("../node_modules/@react-native/codegen")
|
||||
// The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
|
||||
// cliFile = file("../node_modules/react-native/cli.js")
|
||||
/* Variants */
|
||||
|
@ -51,14 +49,6 @@ react {
|
|||
// hermesFlags = ["-O", "-output-source-map"]
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this to true to create four separate APKs instead of one,
|
||||
* one for each native architecture. This is useful if you don't
|
||||
* use App Bundles (https://developer.android.com/guide/app-bundle/)
|
||||
* and want to have separate APKs to upload to the Play Store.
|
||||
*/
|
||||
def enableSeparateBuildPerCPUArchitecture = false
|
||||
|
||||
/**
|
||||
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
|
||||
*/
|
||||
|
@ -77,16 +67,6 @@ def enableProguardInReleaseBuilds = false
|
|||
*/
|
||||
def jscFlavor = 'org.webkit:android-jsc:+'
|
||||
|
||||
/**
|
||||
* Private function to get the list of Native Architectures you want to build.
|
||||
* This reads the value from reactNativeArchitectures in your gradle.properties
|
||||
* file and works together with the --active-arch-only flag of react-native run-android.
|
||||
*/
|
||||
def reactNativeArchitectures() {
|
||||
def value = project.getProperties().get("reactNativeArchitectures")
|
||||
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
||||
}
|
||||
|
||||
android {
|
||||
ndkVersion rootProject.ext.ndkVersion
|
||||
|
||||
|
@ -105,14 +85,6 @@ android {
|
|||
versionCode 50
|
||||
versionName "0.2"
|
||||
}
|
||||
splits {
|
||||
abi {
|
||||
reset()
|
||||
enable enableSeparateBuildPerCPUArchitecture
|
||||
universalApk false // If true, also generate a universal APK
|
||||
include (*reactNativeArchitectures())
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file('debug.keystore')
|
||||
|
@ -133,28 +105,9 @@ android {
|
|||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||
}
|
||||
}
|
||||
|
||||
// applicationVariants are e.g. debug, release
|
||||
applicationVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
// For each separate APK per architecture, set a unique version code as described here:
|
||||
// https://developer.android.com/studio/build/configure-apk-splits.html
|
||||
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
|
||||
def abi = output.getFilter(OutputFile.ABI)
|
||||
if (abi != null) { // null for the universal-debug, universal-release variants
|
||||
output.versionCodeOverride =
|
||||
defaultConfig.versionCode * 1000 + versionCodes.get(abi)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.3.0") {
|
||||
force = true
|
||||
}
|
||||
|
||||
def isGifEnabled = (findProperty('expo.gif.enabled') ?: "") == "true";
|
||||
def isWebpEnabled = (findProperty('expo.webp.enabled') ?: "") == "true";
|
||||
def isWebpAnimatedEnabled = (findProperty('expo.webp.animated') ?: "") == "true";
|
||||
|
@ -182,7 +135,6 @@ dependencies {
|
|||
|
||||
// The version of react-native is set by the React Native Gradle Plugin
|
||||
implementation("com.facebook.react:react-android")
|
||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
|
||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
|
||||
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.squareup.okhttp3', module:'okhttp'
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
package com.xmflsct.app.tooot;
|
||||
import expo.modules.ReactActivityDelegateWrapper;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.facebook.react.ReactActivity;
|
||||
|
@ -30,13 +31,10 @@ public class MainActivity extends ReactActivity {
|
|||
*/
|
||||
@Override
|
||||
protected ReactActivityDelegate createReactActivityDelegate() {
|
||||
return new DefaultReactActivityDelegate(
|
||||
return new ReactActivityDelegateWrapper(this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, new DefaultReactActivityDelegate(
|
||||
this,
|
||||
getMainComponentName(),
|
||||
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
|
||||
DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled
|
||||
// If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18).
|
||||
DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled
|
||||
);
|
||||
DefaultNewArchitectureEntryPoint.getFabricEnabled()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.util.List;
|
|||
public class MainApplication extends Application implements ReactApplication {
|
||||
private final ReactNativeHost mReactNativeHost = new ReactNativeHostWrapper(
|
||||
this,
|
||||
new DefaultReactNativeHost(this) {
|
||||
new ReactNativeHostWrapper(this, new DefaultReactNativeHost(this) {
|
||||
@Override
|
||||
public boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
|
@ -48,7 +48,7 @@ public class MainApplication extends Application implements ReactApplication {
|
|||
protected Boolean isHermesEnabled() {
|
||||
return BuildConfig.IS_HERMES_ENABLED;
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
@Override
|
||||
public ReactNativeHost getReactNativeHost() {
|
||||
|
@ -65,5 +65,12 @@ public class MainApplication extends Application implements ReactApplication {
|
|||
DefaultNewArchitectureEntryPoint.load();
|
||||
}
|
||||
// ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
ApplicationLifecycleDispatcher.onApplicationCreate(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ buildscript {
|
|||
compileSdkVersion = 33
|
||||
targetSdkVersion = 33
|
||||
kotlinVersion = '1.8.21'
|
||||
frescoVersion = '2.5.0'
|
||||
|
||||
// We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
|
||||
ndkVersion = "23.1.7779620"
|
||||
|
@ -17,7 +18,7 @@ buildscript {
|
|||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:7.4.1")
|
||||
classpath("com.android.tools.build:gradle")
|
||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||
classpath 'com.google.gms:google-services:4.3.14'
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ android.useAndroidX=true
|
|||
android.enableJetifier=true
|
||||
|
||||
# Version of flipper SDK to use with React Native
|
||||
FLIPPER_VERSION=0.176.1
|
||||
FLIPPER_VERSION=0.182.0
|
||||
|
||||
# Use this property to specify which architecture you want to build.
|
||||
# You can also override it from the CLI using
|
||||
|
|
Binary file not shown.
|
@ -1,5 +1,6 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-all.zip
|
||||
networkTimeout=10000
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -17,14 +17,56 @@
|
|||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
|
@ -37,6 +79,7 @@ do
|
|||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
|
@ -73,6 +116,7 @@ esac
|
|||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
|
@ -122,7 +166,9 @@ fi
|
|||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
|
@ -152,11 +198,19 @@ fi
|
|||
# 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.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
|
@ -183,4 +237,4 @@ eval "set -- $(
|
|||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
exec "$JAVACMD" "$@"
|
|
@ -14,7 +14,7 @@
|
|||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
|
@ -25,7 +25,7 @@
|
|||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
|
@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
@ -69,20 +69,23 @@ goto fail
|
|||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
:omega
|
|
@ -1,11 +1,10 @@
|
|||
rootProject.name = 'tooot'
|
||||
|
||||
apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute().text.trim(), "../scripts/autolinking.gradle");
|
||||
apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle");
|
||||
useExpoModules()
|
||||
|
||||
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute().text.trim(), "../native_modules.gradle");
|
||||
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
|
||||
applyNativeModulesSettingsGradle(settings)
|
||||
|
||||
include ':app'
|
||||
|
||||
includeBuild('../node_modules/react-native-gradle-plugin')
|
||||
includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json')"].execute(null, rootDir).text.trim()).getParentFile())
|
||||
|
|
|
@ -1,26 +1,27 @@
|
|||
module.exports = function (api) {
|
||||
api.cache(false)
|
||||
|
||||
const plugins = [
|
||||
'@babel/plugin-proposal-optional-chaining',
|
||||
[
|
||||
'module-resolver',
|
||||
{
|
||||
root: ['./'],
|
||||
alias: {
|
||||
'@components': './src/components',
|
||||
'@i18n': './src/i18n',
|
||||
'@screens': './src/screens',
|
||||
'@utils': './src/utils'
|
||||
return {
|
||||
presets: ['babel-preset-expo'],
|
||||
plugins: [
|
||||
'@babel/plugin-proposal-optional-chaining',
|
||||
[
|
||||
'module-resolver',
|
||||
{
|
||||
root: ['./'],
|
||||
alias: {
|
||||
'@components': './src/components',
|
||||
'@i18n': './src/i18n',
|
||||
'@screens': './src/screens',
|
||||
'@utils': './src/utils'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
'react-native-reanimated/plugin'
|
||||
]
|
||||
|
||||
if (process.env.NODE_ENV === 'production' || process.env.BABEL_ENV === 'production') {
|
||||
plugins.push('transform-remove-console')
|
||||
]
|
||||
].concat(
|
||||
process.env.NODE_ENV === 'production' || process.env.BABEL_ENV === 'production'
|
||||
? ['transform-remove-console']
|
||||
: [],
|
||||
['react-native-reanimated/plugin']
|
||||
)
|
||||
}
|
||||
|
||||
return { presets: ['babel-preset-expo'], plugins }
|
||||
}
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
Enjoy toooting! This version includes following improvements and fixes:
|
||||
- Fixed functionality version check (e.g. cannot edit own toots)
|
||||
- Supports mute duration
|
||||
- Long press to copy toot
|
||||
- Button to fetch latest on load
|
|
@ -1,2 +1,5 @@
|
|||
tooot-ing愉快!此版本包括以下改进和修复:
|
||||
- 修复版本功能检查(如无法编辑嘟文)
|
||||
- 新增neodb.social演出卡片
|
||||
- 支持选择隐藏用户时限
|
||||
- 长按复制嘟文
|
||||
- 新增获取最新嘟文按钮
|
12
ios/Podfile
12
ios/Podfile
|
@ -1,6 +1,11 @@
|
|||
require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
|
||||
require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods")
|
||||
require File.join(File.dirname(`node --print "require.resolve('@react-native-community/cli-platform-ios/package.json')"`), "native_modules")
|
||||
|
||||
# Resolve react_native_pods.rb with node to allow for hoisting
|
||||
require Pod::Executable.execute_command('node', ['-p',
|
||||
'require.resolve(
|
||||
"react-native/scripts/react_native_pods.rb",
|
||||
{paths: [process.argv[1]]},
|
||||
)', __dir__]).strip
|
||||
|
||||
platform :ios, '13.0'
|
||||
prepare_react_native_project!
|
||||
|
@ -33,8 +38,7 @@ target 'tooot' do
|
|||
post_install do |installer|
|
||||
react_native_post_install(
|
||||
installer,
|
||||
# Set `mac_catalyst_enabled` to `true` in order to apply patches
|
||||
# necessary for Mac Catalyst builds
|
||||
config[:reactNativePath],
|
||||
:mac_catalyst_enabled => false
|
||||
)
|
||||
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
|
|
753
ios/Podfile.lock
753
ios/Podfile.lock
File diff suppressed because it is too large
Load Diff
|
@ -225,6 +225,7 @@
|
|||
buildPhases = (
|
||||
08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */,
|
||||
FD10A7F022414F080027D42C /* Start Packager */,
|
||||
395686AEA3960C8699AE1CAD /* [Expo] Configure project */,
|
||||
13B07F871A680F5B00A75B9A /* Sources */,
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
|
@ -385,6 +386,25 @@
|
|||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
395686AEA3960C8699AE1CAD /* [Expo] Configure project */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[Expo] Configure project";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-tooot/expo-configure-project.sh\"\n";
|
||||
};
|
||||
49D30A53634620EF2A5C6692 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -697,6 +717,8 @@
|
|||
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift\"\"";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
OTHER_CPLUSPLUSFLAGS = "$(inherited)";
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
|
@ -753,6 +775,8 @@
|
|||
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift\"\"";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
OTHER_CPLUSPLUSFLAGS = "$(inherited)";
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
|
|
|
@ -22,16 +22,6 @@
|
|||
#endif
|
||||
}
|
||||
|
||||
/// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
|
||||
///
|
||||
/// @see: https://reactjs.org/blog/2022/03/29/react-v18.html
|
||||
/// @note: This requires to be rendering on Fabric (i.e. on the New Architecture).
|
||||
/// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`.
|
||||
- (BOOL)concurrentRootEnabled
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Linking API
|
||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
NSString *urlString = url.absoluteString;
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
module.exports = {
|
||||
transformer: { inlineRequires: true }
|
||||
}
|
||||
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config')
|
||||
|
||||
/**
|
||||
* Metro configuration
|
||||
* https://facebook.github.io/metro/docs/configuration
|
||||
*
|
||||
* @type {import('metro-config').MetroConfig}
|
||||
*/
|
||||
const config = {};
|
||||
|
||||
module.exports = mergeConfig(getDefaultConfig(__dirname), config)
|
||||
|
|
121
package.json
121
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "tooot",
|
||||
"version": "4.9.6",
|
||||
"version": "4.10.0",
|
||||
"description": "tooot for Mastodon",
|
||||
"author": "xmflsct <me@xmflsct.com>",
|
||||
"license": "GPL-3.0-or-later",
|
||||
|
@ -19,95 +19,96 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@expo/react-native-action-sheet": "^4.0.1",
|
||||
"@formatjs/intl-datetimeformat": "^6.8.0",
|
||||
"@formatjs/intl-getcanonicallocales": "^2.2.0",
|
||||
"@formatjs/intl-locale": "^3.3.0",
|
||||
"@formatjs/intl-numberformat": "^8.5.0",
|
||||
"@formatjs/intl-pluralrules": "^5.2.2",
|
||||
"@formatjs/intl-relativetimeformat": "^11.2.2",
|
||||
"@formatjs/intl-datetimeformat": "^6.10.0",
|
||||
"@formatjs/intl-getcanonicallocales": "^2.2.1",
|
||||
"@formatjs/intl-locale": "^3.3.2",
|
||||
"@formatjs/intl-numberformat": "^8.7.0",
|
||||
"@formatjs/intl-pluralrules": "^5.2.4",
|
||||
"@formatjs/intl-relativetimeformat": "^11.2.4",
|
||||
"@mattermost/react-native-paste-input": "^0.6.2",
|
||||
"@neverdull-agency/expo-unlimited-secure-store": "^1.0.10",
|
||||
"@react-native-async-storage/async-storage": "~1.17.11",
|
||||
"@react-native-camera-roll/camera-roll": "^5.4.0",
|
||||
"@react-native-camera-roll/camera-roll": "^5.7.2",
|
||||
"@react-native-clipboard/clipboard": "^1.11.2",
|
||||
"@react-native-community/blur": "^4.3.2",
|
||||
"@react-native-community/netinfo": "9.3.10",
|
||||
"@react-native-firebase/app": "^17.5.0",
|
||||
"@react-native-menu/menu": "^0.7.3",
|
||||
"@react-native-segmented-control/segmented-control": "^2.4.1",
|
||||
"@react-navigation/bottom-tabs": "^6.5.7",
|
||||
"@react-navigation/native": "^6.1.6",
|
||||
"@react-navigation/native-stack": "^6.9.12",
|
||||
"@react-navigation/stack": "^6.3.16",
|
||||
"@sentry/react-native": "5.5.0",
|
||||
"@sharcoux/slider": "^6.1.2",
|
||||
"@tanstack/react-query": "^4.29.7",
|
||||
"@react-native-community/netinfo": "^9.4.1",
|
||||
"@react-native-firebase/app": "^18.1.0",
|
||||
"@react-native-menu/menu": "^0.8.0",
|
||||
"@react-native-segmented-control/segmented-control": "^2.4.2",
|
||||
"@react-navigation/bottom-tabs": "^6.5.8",
|
||||
"@react-navigation/native": "^6.1.7",
|
||||
"@react-navigation/native-stack": "^6.9.13",
|
||||
"@react-navigation/stack": "^6.3.17",
|
||||
"@sentry/react-native": "^5.7.1",
|
||||
"@sharcoux/slider": "^7.0.1",
|
||||
"@tanstack/react-query": "^4.29.19",
|
||||
"axios": "^1.4.0",
|
||||
"diff": "^5.1.0",
|
||||
"expo": "48.0.17",
|
||||
"expo-auth-session": "^4.1.0",
|
||||
"expo-av": "^13.3.0",
|
||||
"expo-constants": "^14.3.0",
|
||||
"expo-crypto": "^12.3.0",
|
||||
"expo-file-system": "^15.3.0",
|
||||
"expo-haptics": "^12.3.0",
|
||||
"expo-image": "^1.2.3",
|
||||
"expo-linking": "^4.1.0",
|
||||
"expo-localization": "^14.2.0",
|
||||
"expo-notifications": "^0.18.1",
|
||||
"expo-screen-capture": "5.1.1",
|
||||
"expo-screen-orientation": "^5.2.0",
|
||||
"expo-secure-store": "^12.1.1",
|
||||
"expo-splash-screen": "^0.18.2",
|
||||
"expo-store-review": "^6.3.0",
|
||||
"expo-video-thumbnails": "^7.3.0",
|
||||
"expo-web-browser": "~12.1.1",
|
||||
"expo": "^49.0.3",
|
||||
"expo-auth-session": "^5.0.2",
|
||||
"expo-av": "^13.4.1",
|
||||
"expo-constants": "^14.4.2",
|
||||
"expo-crypto": "^12.4.1",
|
||||
"expo-file-system": "^15.4.2",
|
||||
"expo-haptics": "^12.4.0",
|
||||
"expo-image": "^1.3.2",
|
||||
"expo-linking": "^5.0.2",
|
||||
"expo-localization": "^14.3.0",
|
||||
"expo-notifications": "^0.20.1",
|
||||
"expo-screen-capture": "^5.3.0",
|
||||
"expo-screen-orientation": "^6.0.3",
|
||||
"expo-secure-store": "^12.3.1",
|
||||
"expo-splash-screen": "^0.20.4",
|
||||
"expo-store-review": "^6.4.0",
|
||||
"expo-video-thumbnails": "^7.4.0",
|
||||
"expo-web-browser": "^12.3.2",
|
||||
"htmlparser2": "^9.0.0",
|
||||
"i18next": "^22.5.0",
|
||||
"i18next": "^23.2.11",
|
||||
"linkify-it": "^4.0.1",
|
||||
"lodash": "^4.17.21",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-i18next": "^12.3.1",
|
||||
"react-intl": "^6.4.2",
|
||||
"react-native": "^0.71.8",
|
||||
"react-i18next": "^13.0.2",
|
||||
"react-intl": "^6.4.4",
|
||||
"react-native": "^0.72.3",
|
||||
"react-native-flash-message": "^0.4.1",
|
||||
"react-native-gesture-handler": "~2.10.1",
|
||||
"react-native-image-picker": "^5.3.1",
|
||||
"react-native-gesture-handler": "~2.12.0",
|
||||
"react-native-image-picker": "^5.6.0",
|
||||
"react-native-ios-context-menu": "^1.15.3",
|
||||
"react-native-language-detection": "^0.2.2",
|
||||
"react-native-mmkv": "~2.8.0",
|
||||
"react-native-mmkv": "^2.10.1",
|
||||
"react-native-pager-view": "^6.2.0",
|
||||
"react-native-quick-base64": "^2.0.6",
|
||||
"react-native-reanimated": "^3.1.0",
|
||||
"react-native-reanimated": "^3.3.0",
|
||||
"react-native-reanimated-zoom": "^0.3.3",
|
||||
"react-native-safe-area-context": "^4.5.3",
|
||||
"react-native-screens": "^3.20.0",
|
||||
"react-native-safe-area-context": "^4.7.1",
|
||||
"react-native-screens": "^3.22.1",
|
||||
"react-native-share-menu": "^6.0.0",
|
||||
"react-native-svg": "^13.9.0",
|
||||
"react-native-svg": "^13.10.0",
|
||||
"react-native-swipe-list-view": "^3.2.9",
|
||||
"react-native-tab-view": "^3.5.1",
|
||||
"react-native-tab-view": "^3.5.2",
|
||||
"rn-placeholder": "^3.0.3",
|
||||
"zeego": "^1.6.1"
|
||||
"zeego": "^1.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.21.8",
|
||||
"@babel/core": "^7.22.8",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.21.0",
|
||||
"@babel/preset-typescript": "^7.21.5",
|
||||
"@expo/config": "^8.0.4",
|
||||
"@babel/preset-typescript": "^7.22.5",
|
||||
"@expo/config": "^8.1.2",
|
||||
"@react-native/metro-config": "^0.72.9",
|
||||
"@types/diff": "^5.0.3",
|
||||
"@types/linkify-it": "^3.0.2",
|
||||
"@types/lodash": "^4.14.194",
|
||||
"@types/react": "^18.2.6",
|
||||
"@types/react-dom": "^18.2.4",
|
||||
"@types/lodash": "^4.14.195",
|
||||
"@types/react": "^18.2.14",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"@types/react-native-share-menu": "^5.0.2",
|
||||
"babel-plugin-module-resolver": "^5.0.0",
|
||||
"babel-plugin-transform-remove-console": "^6.9.4",
|
||||
"chalk": "^4.1.2",
|
||||
"deprecated-react-native-prop-types": "^4.1.0",
|
||||
"dotenv": "^16.0.3",
|
||||
"dotenv": "^16.3.1",
|
||||
"react-native-clean-project": "^4.0.1",
|
||||
"typescript": "^5.0.4"
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"packageManager": "yarn@3.3.1",
|
||||
"resolutions": {
|
||||
|
@ -115,6 +116,8 @@
|
|||
"react-native-share-menu@^6.0.0": "patch:react-native-share-menu@npm%3A6.0.0#./.yarn/patches/react-native-share-menu-npm-6.0.0-f1094c3204.patch",
|
||||
"@types/react-native-share-menu@^5.0.2": "patch:@types/react-native-share-menu@npm%3A5.0.2#./.yarn/patches/@types-react-native-share-menu-npm-5.0.2-373df17ecc.patch",
|
||||
"react-native-ios-context-menu@^1.15.1": "patch:react-native-ios-context-menu@npm%3A1.15.1#./.yarn/patches/react-native-ios-context-menu-npm-1.15.1-0034bfa5ba.patch",
|
||||
"react-native-reanimated-zoom@^0.3.3": "patch:react-native-reanimated-zoom@npm%3A0.3.3#./.yarn/patches/react-native-reanimated-zoom-npm-0.3.3-bbb8d84109.patch"
|
||||
"react-native-reanimated-zoom@^0.3.3": "patch:react-native-reanimated-zoom@npm%3A0.3.3#./.yarn/patches/react-native-reanimated-zoom-npm-0.3.3-bbb8d84109.patch",
|
||||
"react-native@^0.72.0": "patch:react-native@npm%3A0.72.0#./.yarn/patches/react-native-npm-0.72.0-66f5fd62b3.patch",
|
||||
"@mattermost/react-native-paste-input@^0.6.2": "patch:@mattermost/react-native-paste-input@npm%3A0.6.2#./.yarn/patches/@mattermost-react-native-paste-input-npm-0.6.2-e109419dfb.patch"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ export type Props = {
|
|||
loading?: boolean
|
||||
disabled?: boolean
|
||||
destructive?: boolean
|
||||
destructiveColor?: string
|
||||
|
||||
onPress: () => void
|
||||
} & ({ type?: undefined; content: IconName } | { type: 'text'; content: string })
|
||||
|
@ -34,6 +35,7 @@ const HeaderRight: React.FC<Props> = ({
|
|||
loading,
|
||||
disabled,
|
||||
destructive = false,
|
||||
destructiveColor,
|
||||
onPress
|
||||
}) => {
|
||||
const { colors } = useTheme()
|
||||
|
@ -57,7 +59,7 @@ const HeaderRight: React.FC<Props> = ({
|
|||
color: disabled
|
||||
? colors.secondary
|
||||
: destructive
|
||||
? colors.red
|
||||
? destructiveColor || colors.red
|
||||
: colors.primaryDefault,
|
||||
opacity: loading ? 0 : 1
|
||||
}}
|
||||
|
|
|
@ -16,18 +16,19 @@ export type Props = {
|
|||
export const CardNeodb: React.FC<Props> = ({ card }) => {
|
||||
const { colors } = useTheme()
|
||||
|
||||
const segments = Linking.parse(card.url).path?.split('/')
|
||||
if (!segments || !['movie', 'book', 'tv', 'game', 'album', 'podcast'].includes(segments[0]))
|
||||
const path = Linking.parse(card.url).path
|
||||
if (!path) return null
|
||||
|
||||
const segments = path?.split('/')
|
||||
if (
|
||||
!segments ||
|
||||
!['movie', 'book', 'tv', 'game', 'album', 'podcast', 'performance'].includes(segments[0])
|
||||
)
|
||||
return null
|
||||
|
||||
const [headingLines, setHeadingLines] = useState(3)
|
||||
|
||||
const { data } = useNeodbQuery({
|
||||
path:
|
||||
segments[0] === 'tv' && segments[1] === 'season'
|
||||
? `${segments[0]}${segments[1]}/${segments[2]}`
|
||||
: `${segments[0]}/${segments[1]}`
|
||||
})
|
||||
const { data } = useNeodbQuery({ path })
|
||||
|
||||
if (!data) return null
|
||||
|
||||
|
@ -44,7 +45,13 @@ export const CardNeodb: React.FC<Props> = ({ card }) => {
|
|||
>
|
||||
{data.cover_image_url ? (
|
||||
<GracefullyImage
|
||||
sources={{ default: { uri: data.cover_image_url } }}
|
||||
sources={{
|
||||
default: {
|
||||
uri: data.cover_image_url.startsWith('/')
|
||||
? `https://neodb.social${data.cover_image_url}`
|
||||
: data.cover_image_url
|
||||
}
|
||||
}}
|
||||
dimension={{
|
||||
width: StyleConstants.Font.LineHeight.M * 4,
|
||||
height: StyleConstants.Font.LineHeight.M * 5
|
||||
|
@ -162,6 +169,27 @@ export const CardNeodb: React.FC<Props> = ({ card }) => {
|
|||
return (
|
||||
<Content heading={[data.title]} details={[data.hosts.join(' '), data.genre.join(' ')]} />
|
||||
)
|
||||
case 'performance':
|
||||
if (segments[1] === 'production') {
|
||||
return (
|
||||
<Content
|
||||
heading={[data.display_title]}
|
||||
details={[
|
||||
data.opening_date,
|
||||
data.director.join(' '),
|
||||
data.playwright.join(' '),
|
||||
data.composer.join(' ')
|
||||
]}
|
||||
/>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<Content
|
||||
heading={[data.title, data.orig_title]}
|
||||
details={[data.genre.join(' '), data.playwright.join(' '), data.director.join(' ')]}
|
||||
/>
|
||||
)
|
||||
}
|
||||
default:
|
||||
return null
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ const TimelineContent: React.FC<Props> = ({ notificationOwnToot = false, setSpoi
|
|||
adaptiveSize
|
||||
numberOfLines={999}
|
||||
color={suppressSpoiler ? colors.disabled : undefined}
|
||||
selectable
|
||||
/>
|
||||
{inThread ? (
|
||||
<CustomText
|
||||
|
@ -62,6 +63,7 @@ const TimelineContent: React.FC<Props> = ({ notificationOwnToot = false, setSpoi
|
|||
}
|
||||
expandHint={t('shared.content.expandHint')}
|
||||
setSpoilerExpanded={setSpoilerExpanded}
|
||||
selectable
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
|
@ -70,6 +72,7 @@ const TimelineContent: React.FC<Props> = ({ notificationOwnToot = false, setSpoi
|
|||
size={highlighted ? 'L' : 'M'}
|
||||
adaptiveSize
|
||||
numberOfLines={highlighted || inThread ? 999 : notificationOwnToot ? 2 : undefined}
|
||||
selectable
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import Icon from '@components/Icon'
|
||||
import ComponentSeparator from '@components/Separator'
|
||||
import CustomText from '@components/Text'
|
||||
import TimelineDefault from '@components/Timeline/Default'
|
||||
|
@ -10,12 +11,20 @@ import {
|
|||
setAccountStorage,
|
||||
useGlobalStorageListener
|
||||
} from '@utils/storage/actions'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { throttle } from 'lodash'
|
||||
import React, { RefObject, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { FlatList, FlatListProps, Platform, RefreshControl } from 'react-native'
|
||||
import {
|
||||
FlatList,
|
||||
FlatListProps,
|
||||
Platform,
|
||||
Pressable,
|
||||
RefreshControl,
|
||||
StyleProp,
|
||||
ViewStyle
|
||||
} from 'react-native'
|
||||
import Animated, {
|
||||
Easing,
|
||||
runOnJS,
|
||||
|
@ -127,6 +136,27 @@ const Timeline: React.FC<Props> = ({
|
|||
transform: [{ translateY: fetchedNoticeTop.value }]
|
||||
}))
|
||||
|
||||
const refetchedNoticeBottom = useDerivedValue(() => {
|
||||
if (firstLoad.value) {
|
||||
return withSequence(
|
||||
withTiming(0),
|
||||
withDelay(
|
||||
3000,
|
||||
withTiming(fetchedNoticeHeight.value + 32, { easing: Easing.out(Easing.ease) })
|
||||
)
|
||||
)
|
||||
} else {
|
||||
return fetchedNoticeHeight.value + 32
|
||||
}
|
||||
}, [])
|
||||
const refetchedNoticeAnimate = useAnimatedStyle(() => ({
|
||||
transform: [
|
||||
{
|
||||
translateY: refetchedNoticeBottom.value
|
||||
}
|
||||
]
|
||||
}))
|
||||
|
||||
const scrollY = useSharedValue(0)
|
||||
const fetchingType = useSharedValue<0 | 1 | 2>(0)
|
||||
|
||||
|
@ -169,10 +199,9 @@ const Timeline: React.FC<Props> = ({
|
|||
throttle(() => {
|
||||
if (readMarker) {
|
||||
const currentMarker = getAccountStorage.string(readMarker) || '0'
|
||||
// setAccountStorage([{ key: readMarker, value: '108425743226508521' }])
|
||||
if (latestMarker.current > currentMarker) {
|
||||
setAccountStorage([{ key: readMarker, value: latestMarker.current }])
|
||||
} else {
|
||||
// setAccountStorage([{ key: readMarker, value: '105250709762254246' }])
|
||||
}
|
||||
}
|
||||
}, 1000 * 15),
|
||||
|
@ -242,6 +271,18 @@ const Timeline: React.FC<Props> = ({
|
|||
flRef.current?.scrollToOffset({ offset: 0, animated: false })
|
||||
)
|
||||
|
||||
const noticeDefaults: StyleProp<Animated.AnimateStyle<StyleProp<ViewStyle>>> = {
|
||||
position: 'absolute',
|
||||
alignSelf: 'center',
|
||||
borderRadius: 99,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: colors.backgroundDefault,
|
||||
shadowColor: colors.primaryDefault,
|
||||
shadowOffset: { width: 0, height: 0 },
|
||||
shadowOpacity: theme === 'light' ? 0.16 : 0.24
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TimelineRefresh
|
||||
|
@ -286,42 +327,78 @@ const Timeline: React.FC<Props> = ({
|
|||
{...customProps}
|
||||
/>
|
||||
{!disableRefresh ? (
|
||||
<Animated.View
|
||||
style={[
|
||||
{
|
||||
position: 'absolute',
|
||||
alignSelf: 'center',
|
||||
top: -fetchedNoticeHeight.value - 16,
|
||||
paddingVertical: StyleConstants.Spacing.S,
|
||||
paddingHorizontal: StyleConstants.Spacing.M,
|
||||
backgroundColor: colors.backgroundDefault,
|
||||
shadowColor: colors.primaryDefault,
|
||||
shadowOffset: { width: 0, height: 0 },
|
||||
shadowOpacity: theme === 'light' ? 0.16 : 0.24,
|
||||
borderRadius: 99,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
fetchedNoticeAnimate
|
||||
]}
|
||||
onLayout={({
|
||||
nativeEvent: {
|
||||
layout: { height }
|
||||
}
|
||||
}) => (fetchedNoticeHeight.value = height)}
|
||||
>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{ color: colors.primaryDefault }}
|
||||
children={
|
||||
fetchedCount !== null
|
||||
? fetchedCount > 0
|
||||
? t('refresh.fetched.found', { count: fetchedCount })
|
||||
: t('refresh.fetched.none')
|
||||
: t('refresh.fetching')
|
||||
}
|
||||
/>
|
||||
</Animated.View>
|
||||
<>
|
||||
<Animated.View
|
||||
style={[
|
||||
{
|
||||
top: -fetchedNoticeHeight.value - 16,
|
||||
paddingVertical: StyleConstants.Spacing.S,
|
||||
paddingHorizontal: StyleConstants.Spacing.M,
|
||||
...noticeDefaults
|
||||
},
|
||||
fetchedNoticeAnimate
|
||||
]}
|
||||
onLayout={({
|
||||
nativeEvent: {
|
||||
layout: { height }
|
||||
}
|
||||
}) => (fetchedNoticeHeight.value = height)}
|
||||
>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{ color: colors.primaryDefault }}
|
||||
children={
|
||||
fetchedCount !== null
|
||||
? fetchedCount > 0
|
||||
? t('refresh.fetched.found', { count: fetchedCount })
|
||||
: t('refresh.fetched.none')
|
||||
: t('refresh.fetching')
|
||||
}
|
||||
/>
|
||||
</Animated.View>
|
||||
{readMarker ? (
|
||||
<Animated.View
|
||||
style={[
|
||||
{
|
||||
bottom: 16,
|
||||
borderColor: colors.primaryDefault,
|
||||
borderWidth: 0.5,
|
||||
...noticeDefaults
|
||||
},
|
||||
refetchedNoticeAnimate
|
||||
]}
|
||||
>
|
||||
<Pressable
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: StyleConstants.Spacing.S,
|
||||
paddingVertical: StyleConstants.Spacing.S,
|
||||
paddingHorizontal: StyleConstants.Spacing.M
|
||||
}}
|
||||
onPress={async () => {
|
||||
if (readMarker) {
|
||||
setAccountStorage([{ key: readMarker, value: undefined }])
|
||||
}
|
||||
flRef.current?.scrollToOffset({ offset: 0 })
|
||||
await refetch()
|
||||
}}
|
||||
>
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{ color: colors.primaryDefault }}
|
||||
children={t('refresh.refetch')}
|
||||
/>
|
||||
<Icon
|
||||
name='log-in'
|
||||
color={colors.primaryDefault}
|
||||
size={StyleConstants.Font.Size.M}
|
||||
style={{ transform: [{ rotate: '-90deg' }] }}
|
||||
/>
|
||||
</Pressable>
|
||||
</Animated.View>
|
||||
) : null}
|
||||
</>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
|
|
|
@ -4,6 +4,7 @@ import { useNavigation } from '@react-navigation/native'
|
|||
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
import apiInstance from '@utils/api/instance'
|
||||
import { featureCheck } from '@utils/helpers/featureCheck'
|
||||
import { checkIsMyAccount } from '@utils/helpers/isMyAccount'
|
||||
import { TabSharedStackParamList, useNavState } from '@utils/navigation/navigators'
|
||||
import { useAccountQuery } from '@utils/queryHooks/account'
|
||||
|
@ -203,13 +204,22 @@ const menuAccount = ({
|
|||
type: 'item',
|
||||
key: 'account-mute',
|
||||
props: {
|
||||
onSelect: () =>
|
||||
actualAccount &&
|
||||
timelineMutation.mutate({
|
||||
type: 'updateAccountProperty',
|
||||
id: actualAccount.id,
|
||||
payload: { property: 'mute', currentValue: data?.muting }
|
||||
}),
|
||||
onSelect: () => {
|
||||
if (actualAccount) {
|
||||
if (data?.muting !== true) {
|
||||
if (featureCheck('mute_duration')) {
|
||||
navigation.navigate('Tab-Shared-Mute', { account: actualAccount })
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
timelineMutation.mutate({
|
||||
type: 'updateAccountProperty',
|
||||
id: actualAccount.id,
|
||||
payload: { property: 'mute', currentValue: data?.muting }
|
||||
})
|
||||
}
|
||||
},
|
||||
disabled: Platform.OS !== 'android' ? !data || !isFetched : false,
|
||||
destructive: false,
|
||||
hidden: false
|
||||
|
|
|
@ -390,8 +390,8 @@
|
|||
"accessibilityHint": "Вы можаце ігнараваць, блакіраваць або абагуліць гэтага карыстальніка"
|
||||
},
|
||||
"followed_by": " падпісаны на вас",
|
||||
"privateNote": "",
|
||||
"moved": "",
|
||||
"privateNote": "Задаць прыватную нататку",
|
||||
"moved": "Карыстальнік перанесены",
|
||||
"created_at": "Далучыўся: {{date}}",
|
||||
"summary": {
|
||||
"statuses_count": "{{count}} допісаў"
|
||||
|
@ -412,11 +412,25 @@
|
|||
},
|
||||
"filter": {
|
||||
"name": "Дадаць у фільтр",
|
||||
"existed": ""
|
||||
"existed": "Існаваў у гэтых фільтрах"
|
||||
},
|
||||
"history": {
|
||||
"name": "Гісторыя рэдагавання"
|
||||
},
|
||||
"mute": {
|
||||
"name": "",
|
||||
"mute": "",
|
||||
"description": "",
|
||||
"notification": "",
|
||||
"duration": {
|
||||
"heading": "",
|
||||
"0": "Бестэрмінова",
|
||||
"1800": "30 хвілін",
|
||||
"3600": "1 гадзіна",
|
||||
"86400": "1 дзень",
|
||||
"604800": "1 тыдзень"
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "Паскардзіцца на {{acct}}",
|
||||
"report": "Скарга",
|
||||
|
@ -468,7 +482,7 @@
|
|||
"name": "Абмеркаванні",
|
||||
"remoteFetch": {
|
||||
"title": "Змяшчае аддаленае змесціва",
|
||||
"message": ""
|
||||
"message": "Федэратыўны кантэнт не заўсёды даступны на лакальным серверы. Гэты кантэнт атрымліваецца з аддаленага сервера і мае пазнаку. Вы можаце ўзаемадзейнічаць з гэтым кантэнтам як звычайна."
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "Edita l'historial"
|
||||
},
|
||||
"mute": {
|
||||
"name": "Silencia {{acct}}",
|
||||
"mute": "Silencia",
|
||||
"description": "Amaga publicacions i mencions d'aquest usuari, però encara podrà veure les teves publicacions i seguir-te.",
|
||||
"notification": "També amaga notificacions d'aquest usuari",
|
||||
"duration": {
|
||||
"heading": "D'una durada",
|
||||
"0": "Indefinida",
|
||||
"1800": "30 minuts",
|
||||
"3600": "1 hora",
|
||||
"86400": "1 dia",
|
||||
"604800": "1 setmana"
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "Denúncia a {{acct}}",
|
||||
"report": "Denúncia",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": ""
|
||||
},
|
||||
"mute": {
|
||||
"name": "",
|
||||
"mute": "",
|
||||
"description": "",
|
||||
"notification": "",
|
||||
"duration": {
|
||||
"heading": "",
|
||||
"0": "",
|
||||
"1800": "",
|
||||
"3600": "",
|
||||
"86400": "",
|
||||
"604800": ""
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "",
|
||||
"report": "",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "Bearbeitungsverlauf"
|
||||
},
|
||||
"mute": {
|
||||
"name": "@{{acct}} stummschalten",
|
||||
"mute": "Stummschalten",
|
||||
"description": "Verstecke Tröts des Users und solche, in denen das Konto erwähnt wird. Die Person wird weiterhin deine Beiträge lesen und dir folgen können.",
|
||||
"notification": "Benachrichtigungen dieses Profils ebenfalls ausblenden",
|
||||
"duration": {
|
||||
"heading": "Für die Dauer",
|
||||
"0": "Dauerhaft",
|
||||
"1800": "30 Minuten",
|
||||
"3600": "1 Stunde",
|
||||
"86400": "1 Tag",
|
||||
"604800": "1 Woche"
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "{{acct}} melden",
|
||||
"report": "Melden",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "Ιστορικό επεξεργασίας"
|
||||
},
|
||||
"mute": {
|
||||
"name": "",
|
||||
"mute": "",
|
||||
"description": "",
|
||||
"notification": "",
|
||||
"duration": {
|
||||
"heading": "",
|
||||
"0": "",
|
||||
"1800": "",
|
||||
"3600": "",
|
||||
"86400": "",
|
||||
"604800": ""
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "Αναφορά {{acct}}",
|
||||
"report": "Αναφορά",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "Edit History"
|
||||
},
|
||||
"mute": {
|
||||
"name": "Mute {{acct}}",
|
||||
"mute": "Mute",
|
||||
"description": "Hide posts from this user and posts mentioning them, but it will still allow them to see your posts and follow you.",
|
||||
"notification": "Also hide notifications from this user",
|
||||
"duration": {
|
||||
"heading": "For duration",
|
||||
"0": "Indefinitely",
|
||||
"1800": "30 minutes",
|
||||
"3600": "1 hour",
|
||||
"86400": "1 day",
|
||||
"604800": "1 week"
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "Report {{acct}}",
|
||||
"report": "Report",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "Historial de ediciones"
|
||||
},
|
||||
"mute": {
|
||||
"name": "Silenciar a {{acct}}",
|
||||
"mute": "Silenciar",
|
||||
"description": "Oculta publicaciones y menciones a este usuario, pero podrá ver tus publicaciones y seguirte.",
|
||||
"notification": "También oculta notificaciones de este usuario",
|
||||
"duration": {
|
||||
"heading": "Durante",
|
||||
"0": "Indefinidamente",
|
||||
"1800": "30 minutos",
|
||||
"3600": "1 hora",
|
||||
"86400": "1 día",
|
||||
"604800": "1 semana"
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "Denuncia {{acct}}",
|
||||
"report": "Denuncia",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": ""
|
||||
},
|
||||
"mute": {
|
||||
"name": "Mututu {{acct}}",
|
||||
"mute": "Mututu",
|
||||
"description": "Ezkutatu erabiltzaile honen argitalpenak berari aipatzen dieten argitalpenak, hala ere, berak zure argitalpenak irakurri ahal izango ditu eta zuri jarraitu ere.",
|
||||
"notification": "Baita ere, ezkutatu erabiltzaile honen jakinarazpenak",
|
||||
"duration": {
|
||||
"heading": "Iraupena",
|
||||
"0": "Mugagabe",
|
||||
"1800": "30 minutu",
|
||||
"3600": "Ordu 1",
|
||||
"86400": "Egun 1",
|
||||
"604800": "Aste 1"
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "",
|
||||
"report": "",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "Modifier l'historique"
|
||||
},
|
||||
"mute": {
|
||||
"name": "",
|
||||
"mute": "",
|
||||
"description": "",
|
||||
"notification": "",
|
||||
"duration": {
|
||||
"heading": "",
|
||||
"0": "",
|
||||
"1800": "",
|
||||
"3600": "",
|
||||
"86400": "",
|
||||
"604800": ""
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "",
|
||||
"report": "",
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
"cancel": "Annulla",
|
||||
"discard": "Scarta",
|
||||
"continue": "Continua",
|
||||
"create": "",
|
||||
"delete": "",
|
||||
"done": "",
|
||||
"create": "Crea",
|
||||
"delete": "Elimina",
|
||||
"done": "Fatto",
|
||||
"confirm": "Ho capito",
|
||||
"add": ""
|
||||
"add": "Aggiungi"
|
||||
},
|
||||
"customEmoji": {
|
||||
"accessibilityLabel": "Emoji personalizzata {{emoji}}"
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"server": {
|
||||
"textInput": {
|
||||
"placeholder": ""
|
||||
"placeholder": "Dominio dell'istanza"
|
||||
},
|
||||
"whitelisted": "",
|
||||
"whitelisted": "Questa potrebbe essere un'istanza nella whitelist nella quale tooot non può accedere ai dati di essa prima di fare il log-in.",
|
||||
"button": "Accedi",
|
||||
"information": {
|
||||
"name": "Nome",
|
||||
"description": ""
|
||||
"description": "Descrizione"
|
||||
},
|
||||
"disclaimer": {
|
||||
"base": "Per accedere, verrà aperta una pagina del browser di sistema. I dati di accesso del tuo account sono protetti."
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
"refresh": {
|
||||
"fetchPreviousPage": "Più recenti da qui",
|
||||
"refetch": "Al più recente",
|
||||
"fetching": "",
|
||||
"fetching": "Recupero nuovi toot ...",
|
||||
"fetched": {
|
||||
"none": "",
|
||||
"found": ""
|
||||
"none": "Nessun nuovo toot",
|
||||
"found": "{{count}} toot recuperati"
|
||||
}
|
||||
},
|
||||
"shared": {
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "Cronologia delle modifiche"
|
||||
},
|
||||
"mute": {
|
||||
"name": "",
|
||||
"mute": "",
|
||||
"description": "",
|
||||
"notification": "",
|
||||
"duration": {
|
||||
"heading": "",
|
||||
"0": "",
|
||||
"1800": "",
|
||||
"3600": "",
|
||||
"86400": "",
|
||||
"604800": ""
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "",
|
||||
"report": "",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "編集履歴"
|
||||
},
|
||||
"mute": {
|
||||
"name": "",
|
||||
"mute": "",
|
||||
"description": "",
|
||||
"notification": "",
|
||||
"duration": {
|
||||
"heading": "",
|
||||
"0": "",
|
||||
"1800": "",
|
||||
"3600": "",
|
||||
"86400": "",
|
||||
"604800": ""
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "{{acct}} の違反報告",
|
||||
"report": "報告",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "수정 이력"
|
||||
},
|
||||
"mute": {
|
||||
"name": "",
|
||||
"mute": "",
|
||||
"description": "",
|
||||
"notification": "",
|
||||
"duration": {
|
||||
"heading": "",
|
||||
"0": "",
|
||||
"1800": "",
|
||||
"3600": "",
|
||||
"86400": "",
|
||||
"604800": ""
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "@{{acct}} 신고",
|
||||
"report": "신고",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "Geschiedenis bewerken"
|
||||
},
|
||||
"mute": {
|
||||
"name": "",
|
||||
"mute": "",
|
||||
"description": "",
|
||||
"notification": "",
|
||||
"duration": {
|
||||
"heading": "Voor duur",
|
||||
"0": "Onbepaalde tijd",
|
||||
"1800": "30 minuten",
|
||||
"3600": "1 uur",
|
||||
"86400": "1 dag",
|
||||
"604800": "1 week"
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "Rapporteer {{acct}}",
|
||||
"report": "Rapporteer",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "Rediger historikk"
|
||||
},
|
||||
"mute": {
|
||||
"name": "Demp {{acct}}",
|
||||
"mute": "Demp",
|
||||
"description": "Skjul innlegg fra denne brukeren og innleggene som nevner brukeren, men det vil fortsatt la brukeren se dine innlegg og følge deg.",
|
||||
"notification": "Skjul varsler også for denne brukeren",
|
||||
"duration": {
|
||||
"heading": "For varighet",
|
||||
"0": "På ubestemt tid",
|
||||
"1800": "30 minutter",
|
||||
"3600": "Én time",
|
||||
"86400": "Én dag",
|
||||
"604800": "én uke"
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "Rapporter {{acct}}",
|
||||
"report": "Rapporter",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "Historia edycji"
|
||||
},
|
||||
"mute": {
|
||||
"name": "",
|
||||
"mute": "",
|
||||
"description": "",
|
||||
"notification": "",
|
||||
"duration": {
|
||||
"heading": "",
|
||||
"0": "",
|
||||
"1800": "",
|
||||
"3600": "",
|
||||
"86400": "",
|
||||
"604800": ""
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "Zgłoś {{acct}}",
|
||||
"report": "Zgłoś",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "Histórico de Edição"
|
||||
},
|
||||
"mute": {
|
||||
"name": "",
|
||||
"mute": "",
|
||||
"description": "",
|
||||
"notification": "",
|
||||
"duration": {
|
||||
"heading": "",
|
||||
"0": "",
|
||||
"1800": "",
|
||||
"3600": "",
|
||||
"86400": "",
|
||||
"604800": ""
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "Denuncia {{acct}}",
|
||||
"report": "Denunciar",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": ""
|
||||
},
|
||||
"mute": {
|
||||
"name": "",
|
||||
"mute": "",
|
||||
"description": "",
|
||||
"notification": "",
|
||||
"duration": {
|
||||
"heading": "",
|
||||
"0": "",
|
||||
"1800": "",
|
||||
"3600": "",
|
||||
"86400": "",
|
||||
"604800": ""
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "",
|
||||
"report": "",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "Redigeringshistorik"
|
||||
},
|
||||
"mute": {
|
||||
"name": "",
|
||||
"mute": "",
|
||||
"description": "",
|
||||
"notification": "",
|
||||
"duration": {
|
||||
"heading": "",
|
||||
"0": "",
|
||||
"1800": "",
|
||||
"3600": "",
|
||||
"86400": "",
|
||||
"604800": ""
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "Rapportera {{acct}}",
|
||||
"report": "Rapport",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "Редагувати історію"
|
||||
},
|
||||
"mute": {
|
||||
"name": "Ігнорувати {{acct}}",
|
||||
"mute": "Ігнорувати",
|
||||
"description": "Сховає дописи від цього користувача і дописи зі згадками про них, проте вони все одно матимуть змогу бачити ваші дописи та слідкувати за вами.",
|
||||
"notification": "Також сховати сповіщення цього користувача",
|
||||
"duration": {
|
||||
"heading": "На час",
|
||||
"0": "Безтерміново",
|
||||
"1800": "30 хвилин",
|
||||
"3600": "1 годину",
|
||||
"86400": "1 день",
|
||||
"604800": "1 тиждень"
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "Скарга на {{acct}}",
|
||||
"report": "Скарга",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "Lịch sử chỉnh sửa"
|
||||
},
|
||||
"mute": {
|
||||
"name": "",
|
||||
"mute": "",
|
||||
"description": "",
|
||||
"notification": "",
|
||||
"duration": {
|
||||
"heading": "",
|
||||
"0": "",
|
||||
"1800": "",
|
||||
"3600": "",
|
||||
"86400": "",
|
||||
"604800": ""
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "Báo cáo @{{acct}}",
|
||||
"report": "Báo cáo",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "编辑历史"
|
||||
},
|
||||
"mute": {
|
||||
"name": "隐藏{{acct}}",
|
||||
"mute": "隐藏",
|
||||
"description": "此用户的嘟文及提到此用户的嘟文都会隐藏,但他们仍可以看到你的嘟文,也可以关注你。",
|
||||
"notification": "同时隐藏来自此用户的通知",
|
||||
"duration": {
|
||||
"heading": "时限",
|
||||
"0": "无限期",
|
||||
"1800": "30分钟",
|
||||
"3600": "一小时",
|
||||
"86400": "一天",
|
||||
"604800": "一周"
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "举报 {{acct}}",
|
||||
"report": "举报",
|
||||
|
|
|
@ -417,6 +417,20 @@
|
|||
"history": {
|
||||
"name": "編輯歷史"
|
||||
},
|
||||
"mute": {
|
||||
"name": "禁音{{acct}}",
|
||||
"mute": "禁音",
|
||||
"description": "該使用者的嘟文及提到該使用者的嘟文都會被隱藏,但他們仍然可以看到你的嘟文,也可以關注你。",
|
||||
"notification": "同時隱藏來自該使用者的通知",
|
||||
"duration": {
|
||||
"heading": "時限",
|
||||
"0": "無限期",
|
||||
"1800": "30分鐘",
|
||||
"3600": "一小時",
|
||||
"86400": "一天",
|
||||
"604800": "一週"
|
||||
}
|
||||
},
|
||||
"report": {
|
||||
"name": "檢舉 {{acct}}",
|
||||
"report": "檢舉",
|
||||
|
|
|
@ -374,7 +374,10 @@ const Explore = ({ route: { key: page } }: { route: { key: 'Explore' } }) => {
|
|||
<DropdownMenu.ItemTitle children={item.title} />
|
||||
<DropdownMenu.ItemSubtitle children={item.domain} />
|
||||
{index === remotes?.findIndex(r => r.domain === remoteActive) ? (
|
||||
<DropdownMenu.ItemIcon ios={{ name: 'trash' }} />
|
||||
<DropdownMenu.ItemIcon
|
||||
ios={{ name: 'trash' }}
|
||||
androidIconName='ic_menu_delete'
|
||||
/>
|
||||
) : null}
|
||||
</DropdownMenu.CheckboxItem>
|
||||
))}
|
||||
|
@ -391,7 +394,7 @@ const Explore = ({ route: { key: page } }: { route: { key: 'Explore' } }) => {
|
|||
<DropdownMenu.ItemTitle
|
||||
children={t('screenTabs:tabs.public.exploring.followRemote')}
|
||||
/>
|
||||
<DropdownMenu.ItemIcon ios={{ name: 'plus' }} />
|
||||
<DropdownMenu.ItemIcon ios={{ name: 'plus' }} androidIconName='ic_menu_add' />
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Group>
|
||||
</DropdownMenu.Content>
|
||||
|
|
|
@ -71,7 +71,7 @@ const AccountInformationActions: React.FC = () => {
|
|||
round
|
||||
type='icon'
|
||||
content='at-sign'
|
||||
style={{ flex: 1, marginRight: StyleConstants.Spacing.S }}
|
||||
style={{ marginRight: StyleConstants.Spacing.S }}
|
||||
onPress={() => {}}
|
||||
/>
|
||||
</DropdownMenu.Trigger>
|
||||
|
@ -129,7 +129,7 @@ const styles = StyleSheet.create({
|
|||
base: {
|
||||
alignSelf: 'flex-end',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'stretch'
|
||||
alignItems: 'center'
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
import ComponentAccount from '@components/Account'
|
||||
import { HeaderLeft, HeaderRight } from '@components/Header'
|
||||
import Icon from '@components/Icon'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import { ModalScrollView } from '@components/ModalScrollView'
|
||||
import Selections from '@components/Selections'
|
||||
import CustomText from '@components/Text'
|
||||
import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
|
||||
import { useTimelineMutation } from '@utils/queryHooks/timeline'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Pressable, View } from 'react-native'
|
||||
|
||||
const TabSharedMute: React.FC<TabSharedStackScreenProps<'Tab-Shared-Report'>> = ({
|
||||
navigation,
|
||||
route: {
|
||||
params: { account }
|
||||
}
|
||||
}) => {
|
||||
const { colors, theme } = useTheme()
|
||||
const { t } = useTranslation(['common', 'screenTabs'])
|
||||
|
||||
const { mutateAsync, isLoading } = useTimelineMutation({
|
||||
onSuccess: () =>
|
||||
displayMessage({
|
||||
type: 'success',
|
||||
message: t('common:message.success.message', {
|
||||
function: t('componentContextMenu:account.mute.action', {
|
||||
defaultValue: 'false',
|
||||
context: 'false'
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
const [durations, setDurations] = useState<{ selected: boolean; content: string }[]>(
|
||||
(['0', '1800', '3600', '86400', '604800'] as ['0', '1800', '3600', '86400', '604800']).map(
|
||||
duration => ({
|
||||
selected: duration === '0',
|
||||
content: t(`screenTabs:shared.mute.duration.${duration}`)
|
||||
})
|
||||
)
|
||||
)
|
||||
const [notification, setNotification] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
navigation.setOptions({
|
||||
title: t('screenTabs:shared.mute.name', { acct: `@${account.acct}` }),
|
||||
headerLeft: () => (
|
||||
<HeaderLeft
|
||||
type='text'
|
||||
content={t('common:buttons.cancel')}
|
||||
onPress={() => navigation.goBack()}
|
||||
/>
|
||||
),
|
||||
headerRight: () => (
|
||||
<HeaderRight
|
||||
type='text'
|
||||
content={t('screenTabs:shared.mute.mute')}
|
||||
destructive
|
||||
destructiveColor={colors.yellow}
|
||||
onPress={async () => {
|
||||
await mutateAsync({
|
||||
type: 'updateAccountProperty',
|
||||
id: account.id,
|
||||
payload: { property: 'mute', currentValue: false }
|
||||
})
|
||||
navigation.pop(1)
|
||||
}}
|
||||
loading={isLoading}
|
||||
/>
|
||||
)
|
||||
})
|
||||
}, [theme, isLoading, durations, notification, account.id])
|
||||
|
||||
return (
|
||||
<ModalScrollView>
|
||||
<View
|
||||
style={{
|
||||
margin: StyleConstants.Spacing.Global.PagePadding,
|
||||
borderWidth: 1,
|
||||
borderColor: colors.yellow,
|
||||
borderRadius: StyleConstants.BorderRadius
|
||||
}}
|
||||
>
|
||||
<ComponentAccount account={account} props={{}} />
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding
|
||||
}}
|
||||
>
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{ color: colors.primaryDefault, marginBottom: StyleConstants.Spacing.M }}
|
||||
>
|
||||
{t('screenTabs:shared.mute.description')}
|
||||
</CustomText>
|
||||
|
||||
<Selections
|
||||
title={t('screenTabs:shared.mute.duration.heading')}
|
||||
options={durations}
|
||||
setOptions={setDurations}
|
||||
/>
|
||||
|
||||
<Pressable
|
||||
style={{ flex: 1, flexDirection: 'row', marginTop: StyleConstants.Spacing.M }}
|
||||
onPress={() => setNotification(!notification)}
|
||||
>
|
||||
<Icon
|
||||
style={{
|
||||
marginTop: (StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M) / 2,
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
}}
|
||||
name={notification ? 'check-square' : 'square'}
|
||||
size={StyleConstants.Font.Size.M}
|
||||
color={colors.primaryDefault}
|
||||
/>
|
||||
<CustomText fontStyle='M' style={{ color: colors.primaryDefault }}>
|
||||
{t('screenTabs:shared.mute.notification')}
|
||||
</CustomText>
|
||||
</Pressable>
|
||||
</View>
|
||||
</ModalScrollView>
|
||||
)
|
||||
}
|
||||
|
||||
export default TabSharedMute
|
|
@ -21,7 +21,6 @@ const TabSharedReport: React.FC<TabSharedStackScreenProps<'Tab-Shared-Report'>>
|
|||
params: { account, status }
|
||||
}
|
||||
}) => {
|
||||
console.log('account', account.id)
|
||||
const { colors } = useTheme()
|
||||
const { t } = useTranslation(['common', 'screenTabs'])
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import TabSharedToot from '@screens/Tabs/Shared/Toot'
|
|||
import TabSharedUsers from '@screens/Tabs/Shared/Users'
|
||||
import React from 'react'
|
||||
import TabSharedFilter from './Filter'
|
||||
import TabSharedMute from './Mute'
|
||||
|
||||
const TabShared = ({ Stack }: { Stack: any }) => {
|
||||
return (
|
||||
|
@ -44,6 +45,12 @@ const TabShared = ({ Stack }: { Stack: any }) => {
|
|||
name='Tab-Shared-History'
|
||||
component={TabSharedHistory}
|
||||
/>
|
||||
<Stack.Screen
|
||||
key='Tab-Shared-Mute'
|
||||
name='Tab-Shared-Mute'
|
||||
component={TabSharedMute}
|
||||
options={{ presentation: 'modal' }}
|
||||
/>
|
||||
<Stack.Screen
|
||||
key='Tab-Shared-Report'
|
||||
name='Tab-Shared-Report'
|
||||
|
|
|
@ -4,6 +4,7 @@ type Features =
|
|||
| 'account_follow_notify'
|
||||
| 'notification_type_status'
|
||||
| 'account_return_suspended'
|
||||
| 'mute_duration'
|
||||
| 'edit_post'
|
||||
| 'deprecate_auth_follow'
|
||||
| 'notification_type_update'
|
||||
|
@ -20,6 +21,7 @@ const features: { feature: Features; version: number }[] = [
|
|||
{ feature: 'account_follow_notify', version: 3.3 },
|
||||
{ feature: 'notification_type_status', version: 3.3 },
|
||||
{ feature: 'account_return_suspended', version: 3.3 },
|
||||
{ feature: 'mute_duration', version: 3.3 },
|
||||
{ feature: 'edit_post', version: 3.5 },
|
||||
{ feature: 'deprecate_auth_follow', version: 3.5 },
|
||||
{ feature: 'notification_type_update', version: 3.5 },
|
||||
|
|
|
@ -104,6 +104,9 @@ export type TabSharedStackParamList = {
|
|||
| { source: 'hashtag'; tag_name: Mastodon.Tag['name'] }
|
||||
'Tab-Shared-Hashtag': { tag_name: Mastodon.Tag['name']; queryKey?: QueryKeyTimeline }
|
||||
'Tab-Shared-History': { status: Mastodon.Status; detectedLanguage: string }
|
||||
'Tab-Shared-Mute': {
|
||||
account: Pick<Mastodon.Account, 'id' | 'acct' | 'username' | 'url'>
|
||||
}
|
||||
'Tab-Shared-Report': {
|
||||
account: Pick<Mastodon.Account, 'id' | 'acct' | 'username' | 'url'>
|
||||
status?: Pick<Mastodon.Status, 'id' | '_remote' | 'uri'>
|
||||
|
|
|
@ -25,10 +25,7 @@ const useAppsQuery = (
|
|||
|
||||
type MutationVarsApps = { domain: string; scopes: string[] }
|
||||
|
||||
export const redirectUri = AuthSession.makeRedirectUri({
|
||||
native: 'tooot://instance-auth',
|
||||
useProxy: false
|
||||
})
|
||||
export const redirectUri = AuthSession.makeRedirectUri({ native: 'tooot://instance-auth' })
|
||||
const mutationFunctionApps = async ({ domain, scopes }: MutationVarsApps) => {
|
||||
return apiGeneral<Mastodon.Apps>({
|
||||
method: 'post',
|
||||
|
@ -49,4 +46,5 @@ const useAppsMutation = (
|
|||
return useMutation(mutationFunctionApps, options)
|
||||
}
|
||||
|
||||
export { useAppsQuery, useAppsMutation }
|
||||
export { useAppsMutation, useAppsQuery }
|
||||
|
||||
|
|
Loading…
Reference in New Issue