diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml
deleted file mode 100644
index b20868ea..00000000
--- a/.github/workflows/development.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-name: Publish development
-on:
- push:
- branches:
- - '*-development'
-jobs:
- publish:
- runs-on: ubuntu-latest
- steps:
- - name: -- Step 1 -- Checkout code
- uses: actions/checkout@v2
- - name: -- Step 2 -- Setup node
- uses: actions/setup-node@v2
- with:
- node-version: 14.x
- - name: -- Step 3 -- Use Expo action
- uses: expo/expo-github-action@v5
- with:
- expo-version: 4.x
- expo-username: ${{ secrets.EXPO_USERNAME }}
- expo-token: ${{ secrets.EXPO_TOKEN }}
- - name: -- Step 4 -- Install dependencies
- run: yarn install
- - name: -- Step 5 -- Publish
- env:
- SENTRY_ORGANIZATION: ${{ secrets.SENTRY_ORGANIZATION }}
- SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
- SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
- SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
- SENTRY_DEPLOY_ENV: development
- run: expo publish --release-channel=${GITHUB_REF#refs/heads/}
diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml
index 1d253940..b72d6010 100644
--- a/.github/workflows/production.yml
+++ b/.github/workflows/production.yml
@@ -2,7 +2,7 @@ name: Publish production
on:
push:
branches:
- - '*-production'
+ - production
jobs:
publish:
runs-on: ubuntu-latest
diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml
index 247d475d..f83f4cbf 100644
--- a/.github/workflows/staging.yml
+++ b/.github/workflows/staging.yml
@@ -1,11 +1,11 @@
-name: Publish staging
+name: Build staging
on:
push:
branches:
- - '*-staging'
+ - staging
jobs:
- publish:
- runs-on: ubuntu-latest
+ build-ios:
+ runs-on: macos-latest
steps:
- name: -- Step 1 -- Checkout code
uses: actions/checkout@v2
@@ -13,19 +13,26 @@ jobs:
uses: actions/setup-node@v2
with:
node-version: 14.x
- - name: -- Step 3 -- Use Expo action
- uses: expo/expo-github-action@v5
- with:
- expo-version: 4.x
- expo-username: ${{ secrets.EXPO_USERNAME }}
- expo-token: ${{ secrets.EXPO_TOKEN }}
+ - name: -- Step 3 -- Setup ruby
+ uses: actions/setup-ruby@v1
- name: -- Step 4 -- Install dependencies
run: yarn install
- - name: -- Step 5 -- Publish
+ - name: -- Step 5 -- Install native dependencies
+ run: npx pod-install
+ - name: -- Step 6 -- Run fastlane
env:
+ TOOOT_ENVIRONMENT: staging
SENTRY_ORGANIZATION: ${{ secrets.SENTRY_ORGANIZATION }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
- SENTRY_DEPLOY_ENV: staging
- run: expo publish --release-channel=${GITHUB_REF#refs/heads/}
+ LC_ALL: en_US.UTF-8
+ LANG: en_US.UTF-8
+ FASTLANE_USER: ${{ secrets.FASTLANE_USER }}
+ MATCH_GIT_URL: ${{ secrets.MATCH_GIT_URL }}
+ MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }}
+ MATCH_GIT_PRIVATE_KEY: ${{ MATCH_GIT_PRIVATE_KEY }}
+ APP_STORE_CONNECT_API_KEY_KEY_ID: ${{ APP_STORE_CONNECT_API_KEY_KEY_ID }}
+ APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
+ APP_STORE_CONNECT_API_KEY_KEY: ${{ APP_STORE_CONNECT_API_KEY_KEY }}
+ run: yarn ios:build
diff --git a/Gemfile b/Gemfile
index adc90d98..2ccf2ecb 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,3 +1,5 @@
source "https://rubygems.org"
-gem "fastlane"
\ No newline at end of file
+gem "fastlane"
+plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
+eval_gemfile(plugins_path) if File.exist?(plugins_path)
diff --git a/Gemfile.lock b/Gemfile.lock
index d611c9d3..63efde57 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -85,6 +85,9 @@ GEM
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
+ fastlane-plugin-json (1.0.0)
+ fastlane-plugin-versioning (0.4.4)
+ fastlane-plugin-yarn (1.2)
gh_inspector (1.1.3)
google-api-client (0.38.0)
addressable (~> 2.5, >= 2.5.1)
@@ -196,6 +199,9 @@ PLATFORMS
DEPENDENCIES
fastlane
+ fastlane-plugin-json
+ fastlane-plugin-versioning
+ fastlane-plugin-yarn
BUNDLED WITH
1.17.2
diff --git a/VERSIONING.md b/VERSIONING.md
new file mode 100644
index 00000000..389dcb44
--- /dev/null
+++ b/VERSIONING.md
@@ -0,0 +1,30 @@
+## Major releases - App Store
+
+"Major releases" are artifacts published as `x.?.?`:
+ * An artifact must be released as `x.?.?` if native modules have been changed or updated, including upgrading Expo SDK version.
+ * A new app store version has to be submitted.
+ * Outdated versions in principle do not receive further OTA updates.
+
+## Minor releases - App Store and OTA
+
+"Minor releases" are artifacts published as `?.y.?`:
+ * An artifact can be released as `?.y.?` when there is no change nor update made to the native modules.
+ * A new app store version can be submitted for better first launch experience.
+ * All these versions that are not part of above mentioned outdates versions receive also OTA updates.
+
+## Patch releases - OTA
+
+"Patch releases" are artifacts published as `?.?.z`:
+ * An artifact must be release as `?.?.z` when there is no major change to the functionalities.
+ * No new app store version will be submitted.
+ * All these versions that are not part of above mentioned outdates versions receive also OTA updates.
+
+## OTA release channels
+
+ * `MAJOR-environment`. Environments include `production`, `staging` and `development`.
+
+## Major versions mapping to native module versions
+
+| Major version | Native module version |
+| :-----------: | :-------------------: |
+| `0` | `210201` |
\ No newline at end of file
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index eca08281..b8e1e673 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -21,13 +21,28 @@
-
+
-
+
@@ -42,6 +57,6 @@
-
+
-
\ No newline at end of file
+
diff --git a/android/app/src/main/res/drawable-night/splashscreen_image.png b/android/app/src/main/res/drawable-night/splashscreen_image.png
new file mode 100644
index 00000000..83ca55a4
Binary files /dev/null and b/android/app/src/main/res/drawable-night/splashscreen_image.png differ
diff --git a/android/app/src/main/res/values-night/colors.xml b/android/app/src/main/res/values-night/colors.xml
new file mode 100644
index 00000000..55096642
--- /dev/null
+++ b/android/app/src/main/res/values-night/colors.xml
@@ -0,0 +1,5 @@
+
+
+
+ #191919
+
diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml
index 88cd0a91..e2efbb44 100644
--- a/android/app/src/main/res/values/colors.xml
+++ b/android/app/src/main/res/values/colors.xml
@@ -1,6 +1,11 @@
-
+
+
#FFFFFF
#FAFAFA
#023c69
-
\ No newline at end of file
+
diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml
index ed009e7d..52c9e4cf 100644
--- a/android/app/src/main/res/values/styles.xml
+++ b/android/app/src/main/res/values/styles.xml
@@ -11,7 +11,8 @@
diff --git a/app.config.ts b/app.config.ts
index 8956ddcc..b99e6197 100644
--- a/app.config.ts
+++ b/app.config.ts
@@ -1,26 +1,20 @@
import { ExpoConfig } from '@expo/config'
+import { versions } from './package.json'
import 'dotenv/config'
+const toootVersion = `${versions.major}.${versions.minor}.${versions.patch}`
+
export default (): ExpoConfig => ({
name: 'tooot',
description: 'tooot for Mastodon',
slug: 'tooot',
+ version: toootVersion,
+ sdkVersion: versions.expo,
privacy: 'hidden',
- sdkVersion: '40.0.0',
- version: '0.8',
- platforms: ['ios', 'android'],
- orientation: 'portrait',
- userInterfaceStyle: 'automatic',
- icon: './assets/icon.png',
- splash: {
- backgroundColor: '#FAFAFA',
- image: './assets/splash.png'
- },
- scheme: 'tooot',
assetBundlePatterns: ['assets/*'],
extra: {
- sentryDSN: process.env.SENTRY_DSN,
- sentryEnv: process.env.SENTRY_DEPLOY_ENV
+ toootEnvironment: process.env.TOOOT_ENVIRONMENT,
+ sentryDSN: process.env.SENTRY_DSN
},
hooks: {
postPublish: [
@@ -31,7 +25,7 @@ export default (): ExpoConfig => ({
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_AUTH_TOKEN,
setCommits: process.env.GITHUB_SHA || undefined,
- deployEnv: process.env.SENTRY_DEPLOY_ENV
+ deployEnv: process.env.TOOOT_ENVIRONMENT
}
}
]
diff --git a/assets/icon.png b/assets/icon.png
deleted file mode 100644
index ab0e8cbc..00000000
Binary files a/assets/icon.png and /dev/null differ
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
index 0ecfa0e2..0cea5d18 100644
--- a/fastlane/Fastfile
+++ b/fastlane/Fastfile
@@ -1,79 +1,110 @@
-$ExpoSDK = '40.0.0'
-$NativeVersion = '210201' # Update when there is native module change
+fastlane_version "2.172.0"
-fastlane_version '2.172.0'
+ensure_env_vars(
+ env_vars: ["TOOOT_ENVIRONMENT"]
+)
+
+VERSIONS = read_json( json_path: "./package.json" )[:versions]
+ENVIRONMENT = ENV["TOOOT_ENVIRONMENT"]
+VERSION = "#{VERSIONS[:major]}.#{VERSIONS[:minor]}"
+RELEASE_CHANNEL = "#{VERSIONS[:major]}-#{ENVIRONMENT}"
+BUILD_NUMBER = Time.now.strftime("%y%m%d")
platform :ios do
- desc 'Build and deploy'
- private_lane :build do |options|
- branch = 'NATIVEVERSION-TYPE'.gsub('NATIVEVERSION', $NativeVersion).gsub('TYPE', options[:type])
- set_info_plist_value(
- path: './ios/tooot/Supporting/Expo.plist',
- key: 'EXUpdatesSDKVersion',
- value: $ExpoSDK
- )
- set_info_plist_value(
- path: './ios/tooot/Supporting/Expo.plist',
- key: 'EXUpdatesReleaseChannel',
- value: branch
- )
+ XCODEPROJ = "./ios/tooot.xcodeproj"
+ INFO_PLIST = "./ios/tooot/Info.plist"
+ EXPO_PLIST = "./ios/tooot/Supporting/Expo.plist"
- case options[:type]
- when 'staging', 'production'
- ensure_git_branch(
- branch: options[:type]
- )
- ensure_git_status_clean
- increment_build_number(
- build_number: $NativeVersion
- )
- app_store_connect_api_key(
- key_filepath: "appstore.p8"
- )
- end
-
- match(
- type: options[:type],
- readonly: true
- )
-
- case options[:type]
- when 'development'
- build_ios_app(
- scheme: 'tooot',
- silent: true,
- include_bitcode: true,
- workspace: './ios/tooot.xcworkspace',
- export_method: 'development'
- )
- install_on_device(
- skip_wifi: true
- )
- when 'staging'
- build_ios_app(
- scheme: 'tooot',
- workspace: './ios/tooot.xcworkspace'
- )
- upload_to_testflight(
- skip_submission: true,
- notify_external_testers: false
- )
+ desc "Prepare app store"
+ private_lane :prepare_appstore do
+ case ENVIRONMENT
+ when "staging", "production"
+ increment_build_number( xcodeproj: XCODEPROJ, build_number: BUILD_NUMBER )
+ app_store_connect_api_key
end
end
- desc 'Build development to phone'
- lane :development do
- build(type: 'development')
+ desc "Expo release"
+ private_lane :expo_release do
+ yarn( package_path: "./package.json", flags: "release", command: RELEASE_CHANNEL )
end
- desc 'Build staging to TestFlight'
- lane :staging do
- build(type: 'staging')
+ desc "Get certificates"
+ private_lane :get_certificates do |options|
+ if ENV['CI'] == true
+ match( type: options[:type], readonly: true, keychain_name: KEYCHAIN_NAME, keychain_password: KEYCHAIN_PASS )
+ else
+ match( type: options[:type], readonly: true )
+ end
end
- desc 'Build product to App Store'
- lane :production do
- build(type: 'production')
+ desc "Build and deploy"
+ lane :build do
+ BUILD_DIRECTORY = "./ios/build"
+ SHOULD_BUILD_NATIVE = false
+
+ case ENVIRONMENT
+ when "staging", "production"
+ PREVIOUS_VERSION = get_info_plist_value( path: INFO_PLIST, key: "CFBundleShortVersionString" )
+ if VERSION.to_f > PREVIOUS_VERSION.to_f
+ SHOULD_BUILD_NATIVE = true
+ set_info_plist_value( path: INFO_PLIST, key: "CFBundleShortVersionString", value: VERSION )
+ set_info_plist_value( path: EXPO_PLIST, key: "EXUpdatesSDKVersion", value: VERSIONS[:expo] )
+ set_info_plist_value( path: EXPO_PLIST, key: "EXUpdatesReleaseChannel", value: RELEASE_CHANNEL )
+ end
+ when "development"
+ SHOULD_BUILD_NATIVE = true
+ end
+
+ if SHOULD_BUILD_NATIVE == true
+ prepare_appstore
+
+ KEYCHAIN_NAME = "tooot"
+ KEYCHAIN_PASS = SecureRandom.base64
+ if ENV['CI'] == true
+ create_keychain(
+ name: KEYCHAIN_NAME,
+ password: KEYCHAIN_PASS,
+ default_keychain: true,
+ unlock: true,
+ timeout: 3600,
+ lock_when_sleeps: true
+ )
+ end
+
+ case ENVIRONMENT
+ when "development"
+ get_certificates( type: "development" )
+ build_ios_app(
+ export_method: "development",
+ output_directory: BUILD_DIRECTORY,
+ output_name: VERSION + "-" + BUILD_NUMBER
+ )
+ install_on_device( skip_wifi: true )
+ when "staging"
+ get_certificates( type: "appstore" )
+ build_ios_app(
+ export_method: "app-store",
+ output_directory: BUILD_DIRECTORY,
+ output_name: VERSION + "-" + BUILD_NUMBER
+ )
+ upload_to_testflight(
+ demo_account_required: true,
+ distribute_external: true,
+ groups: "内测用户",
+ changelog: "Ready for testing"
+ )
+ when "production"
+ get_certificates( type: "appstore" )
+ build_ios_app(
+ export_method: "app-store",
+ output_directory: BUILD_DIRECTORY,
+ output_name: VERSION + "-" + BUILD_NUMBER
+ )
+ end
+ end
+
+ expo_release
end
end
diff --git a/fastlane/Gymfile b/fastlane/Gymfile
new file mode 100644
index 00000000..a8f82852
--- /dev/null
+++ b/fastlane/Gymfile
@@ -0,0 +1,3 @@
+scheme "tooot"
+workspace "./ios/tooot.xcworkspace"
+clean true
\ No newline at end of file
diff --git a/fastlane/Matchfile b/fastlane/Matchfile
index 664483e0..7f6446f2 100644
--- a/fastlane/Matchfile
+++ b/fastlane/Matchfile
@@ -1,3 +1,2 @@
git_user_email("me@xmflsct.com")
-git_private_key("./github.key")
storage_mode("git")
diff --git a/fastlane/Pluginfile b/fastlane/Pluginfile
new file mode 100644
index 00000000..26c71a41
--- /dev/null
+++ b/fastlane/Pluginfile
@@ -0,0 +1,6 @@
+# Autogenerated by fastlane
+#
+# Ensure this file is checked in to source control!
+
+gem 'fastlane-plugin-yarn'
+gem 'fastlane-plugin-json'
diff --git a/fastlane/README.md b/fastlane/README.md
index 7476eb8e..bdf09fa7 100644
--- a/fastlane/README.md
+++ b/fastlane/README.md
@@ -16,21 +16,11 @@ or alternatively using `brew install fastlane`
# Available Actions
## iOS
-### ios development
+### ios build
```
-fastlane ios development
+fastlane ios build
```
-Build development to phone
-### ios staging
-```
-fastlane ios staging
-```
-Build staging to TestFlight
-### ios production
-```
-fastlane ios production
-```
-Build product to App Store
+Build and deploy
----
diff --git a/ios/tooot.xcodeproj/project.pbxproj b/ios/tooot.xcodeproj/project.pbxproj
index 89650a2d..b856caaa 100644
--- a/ios/tooot.xcodeproj/project.pbxproj
+++ b/ios/tooot.xcodeproj/project.pbxproj
@@ -12,6 +12,7 @@
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; };
+ 5E36538325C9B8BD009F93EE /* RootViewColor.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5E36538225C9B8BD009F93EE /* RootViewColor.xcassets */; };
6CB3B7B773184F6EB8040C3E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4C2DAF0391E246238BE2A4B4 /* InfoPlist.strings */; };
8BA74ECC129842FEA0CC08AF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F78D778B9BBC48D584012340 /* InfoPlist.strings */; };
96905EF65AED1B983A6B3ABC /* libPods-tooot.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58EEBF8E8E6FB1BC6CAF49B5 /* libPods-tooot.a */; };
@@ -30,6 +31,7 @@
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = tooot/main.m; sourceTree = ""; };
4C2DAF0391E246238BE2A4B4 /* InfoPlist.strings */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = text.plist.strings; name = InfoPlist.strings; path = /Users/zhzhe/Documents/GitHub/tooot/app/ios/tooot/Supporting/en.lproj/InfoPlist.strings; sourceTree = ""; };
58EEBF8E8E6FB1BC6CAF49B5 /* libPods-tooot.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-tooot.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5E36538225C9B8BD009F93EE /* RootViewColor.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = RootViewColor.xcassets; path = tooot/RootViewColor.xcassets; sourceTree = ""; };
6C2E3173556A471DD304B334 /* Pods-tooot.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-tooot.debug.xcconfig"; path = "Target Support Files/Pods-tooot/Pods-tooot.debug.xcconfig"; sourceTree = ""; };
7A4D352CD337FB3A3BF06240 /* Pods-tooot.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-tooot.release.xcconfig"; path = "Target Support Files/Pods-tooot/Pods-tooot.release.xcconfig"; sourceTree = ""; };
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = tooot/SplashScreen.storyboard; sourceTree = ""; };
@@ -72,6 +74,7 @@
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
13B07FB71A68108700A75B9A /* main.m */,
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */,
+ 5E36538225C9B8BD009F93EE /* RootViewColor.xcassets */,
B96B72E5384D44A7B240B27E /* GoogleService-Info.plist */,
);
name = tooot;
@@ -179,6 +182,7 @@
13B07F861A680F5B00A75B9A = {
DevelopmentTeam = 8EGBLQ2MA6;
LastSwiftMigration = 1120;
+ ProvisioningStyle = Automatic;
};
};
};
@@ -205,6 +209,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 5E36538325C9B8BD009F93EE /* RootViewColor.xcassets in Resources */,
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
@@ -325,7 +330,9 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = tooot/tooot.entitlements;
- CURRENT_PROJECT_VERSION = 1;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 2102022230;
DEVELOPMENT_TEAM = 8EGBLQ2MA6;
ENABLE_BITCODE = NO;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -343,6 +350,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.xmflsct.app.tooot;
PRODUCT_NAME = tooot;
+ PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
@@ -357,7 +365,9 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = tooot/tooot.entitlements;
- CURRENT_PROJECT_VERSION = 1;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 2102022230;
DEVELOPMENT_TEAM = 8EGBLQ2MA6;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
INFOPLIST_FILE = tooot/Info.plist;
@@ -370,6 +380,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.xmflsct.app.tooot;
PRODUCT_NAME = tooot;
+ PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
VERSIONING_SYSTEM = "apple-generic";
diff --git a/ios/tooot/AppDelegate.m b/ios/tooot/AppDelegate.m
index 6b7d0734..6b5d1c23 100644
--- a/ios/tooot/AppDelegate.m
+++ b/ios/tooot/AppDelegate.m
@@ -85,7 +85,7 @@ static void InitializeFlipper(UIApplication *application) {
{
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:self.launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"main" initialProperties:nil];
- rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
+ rootView.backgroundColor = [UIColor colorNamed:@"Background"];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
diff --git a/ios/tooot/Images.xcassets/SplashScreen.imageset/Contents.json b/ios/tooot/Images.xcassets/SplashScreen.imageset/Contents.json
index 40eb421f..63ffe583 100644
--- a/ios/tooot/Images.xcassets/SplashScreen.imageset/Contents.json
+++ b/ios/tooot/Images.xcassets/SplashScreen.imageset/Contents.json
@@ -5,11 +5,42 @@
"filename": "splashscreen.png",
"scale": "1x"
},
+ {
+ "appearances": [
+ {
+ "appearance": "luminosity",
+ "value": "dark"
+ }
+ ],
+ "idiom": "universal",
+ "filename": "dark_splashscreen.png",
+ "scale": "1x"
+ },
{
"idiom": "universal",
"scale": "2x"
},
{
+ "appearances": [
+ {
+ "appearance": "luminosity",
+ "value": "dark"
+ }
+ ],
+ "idiom": "universal",
+ "scale": "2x"
+ },
+ {
+ "idiom": "universal",
+ "scale": "3x"
+ },
+ {
+ "appearances": [
+ {
+ "appearance": "luminosity",
+ "value": "dark"
+ }
+ ],
"idiom": "universal",
"scale": "3x"
}
diff --git a/ios/tooot/Images.xcassets/SplashScreen.imageset/dark_splashscreen.png b/ios/tooot/Images.xcassets/SplashScreen.imageset/dark_splashscreen.png
new file mode 100644
index 00000000..83ca55a4
Binary files /dev/null and b/ios/tooot/Images.xcassets/SplashScreen.imageset/dark_splashscreen.png differ
diff --git a/ios/tooot/Images.xcassets/SplashScreenBackground.imageset/Contents.json b/ios/tooot/Images.xcassets/SplashScreenBackground.imageset/Contents.json
index c69ca4ab..847f2599 100644
--- a/ios/tooot/Images.xcassets/SplashScreenBackground.imageset/Contents.json
+++ b/ios/tooot/Images.xcassets/SplashScreenBackground.imageset/Contents.json
@@ -5,11 +5,42 @@
"filename": "background.png",
"scale": "1x"
},
+ {
+ "appearances": [
+ {
+ "appearance": "luminosity",
+ "value": "dark"
+ }
+ ],
+ "idiom": "universal",
+ "filename": "dark_background.png",
+ "scale": "1x"
+ },
{
"idiom": "universal",
"scale": "2x"
},
{
+ "appearances": [
+ {
+ "appearance": "luminosity",
+ "value": "dark"
+ }
+ ],
+ "idiom": "universal",
+ "scale": "2x"
+ },
+ {
+ "idiom": "universal",
+ "scale": "3x"
+ },
+ {
+ "appearances": [
+ {
+ "appearance": "luminosity",
+ "value": "dark"
+ }
+ ],
"idiom": "universal",
"scale": "3x"
}
diff --git a/ios/tooot/Images.xcassets/SplashScreenBackground.imageset/dark_background.png b/ios/tooot/Images.xcassets/SplashScreenBackground.imageset/dark_background.png
new file mode 100644
index 00000000..8b65011f
Binary files /dev/null and b/ios/tooot/Images.xcassets/SplashScreenBackground.imageset/dark_background.png differ
diff --git a/ios/tooot/Info.plist b/ios/tooot/Info.plist
index 73d0c046..6f194baf 100644
--- a/ios/tooot/Info.plist
+++ b/ios/tooot/Info.plist
@@ -1,95 +1,85 @@
-
- CFBundleDevelopmentRegion
- en
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- $(PRODUCT_NAME)
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- 0.1.0
- CFBundleSignature
- ????
- CFBundleVersion
- 0
- LSRequiresIPhoneOS
-
- NSAppTransportSecurity
-
- NSAllowsArbitraryLoads
-
- NSExceptionDomains
-
- localhost
-
- NSExceptionAllowsInsecureHTTPLoads
-
-
-
-
- NSLocationWhenInUseUsageDescription
-
- UILaunchStoryboardName
- SplashScreen
- UIRequiredDeviceCapabilities
-
- armv7
-
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
-
- UIViewControllerBasedStatusBarAppearance
-
- CFBundleAllowMixedLocalizations
-
- ITSAppUsesNonExemptEncryption
-
- UIUserInterfaceStyle
- Automatic
- CFBundleURLTypes
-
-
- CFBundleURLSchemes
-
- tooot
- com.xmflsct.app.tooot
-
-
-
- UIRequiresFullScreen
-
- CFBundleDisplayName
- tooot
- NSMicrophoneUsageDescription
- Allow $(PRODUCT_NAME) to access your microphone
- NSPhotoLibraryUsageDescription
- Give $(PRODUCT_NAME) permission to save photos
- NSPhotoLibraryAddUsageDescription
- Give $(PRODUCT_NAME) permission to save photos
- NSCameraUsageDescription
- Give $(PRODUCT_NAME) permission to access your camera
- NSMicrophoneUsageDescription
- Give $(PRODUCT_NAME) permission to use your microphone
- CFBundleURLTypes
-
-
- CFBundleURLName
- gizmos
- CFBundleURLSchemes
-
- tooot
-
-
-
-
-
\ No newline at end of file
+
+ CFBundleAllowMixedLocalizations
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleDisplayName
+ tooot
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 0.8
+ CFBundleSignature
+ ????
+ CFBundleURLTypes
+
+
+ CFBundleURLName
+ gizmos
+ CFBundleURLSchemes
+
+ tooot
+
+
+
+ CFBundleVersion
+ 2102022230
+ ITSAppUsesNonExemptEncryption
+
+ LSRequiresIPhoneOS
+
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
+
+ NSExceptionDomains
+
+ localhost
+
+ NSExceptionAllowsInsecureHTTPLoads
+
+
+
+
+ NSCameraUsageDescription
+ Give $(PRODUCT_NAME) permission to access your camera
+ NSLocationWhenInUseUsageDescription
+
+ NSMicrophoneUsageDescription
+ Give $(PRODUCT_NAME) permission to use your microphone
+ NSPhotoLibraryAddUsageDescription
+ Give $(PRODUCT_NAME) permission to save photos
+ NSPhotoLibraryUsageDescription
+ Give $(PRODUCT_NAME) permission to save photos
+ UILaunchStoryboardName
+ SplashScreen
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UIRequiresFullScreen
+
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+
+ UIUserInterfaceStyle
+ Automatic
+ UIViewControllerBasedStatusBarAppearance
+
+
+
diff --git a/ios/tooot/RootViewColor.xcassets/Background.colorset/Contents.json b/ios/tooot/RootViewColor.xcassets/Background.colorset/Contents.json
new file mode 100644
index 00000000..ff4bf220
--- /dev/null
+++ b/ios/tooot/RootViewColor.xcassets/Background.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "250",
+ "green" : "250",
+ "red" : "250"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "25",
+ "green" : "25",
+ "red" : "25"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ios/tooot/RootViewColor.xcassets/Contents.json b/ios/tooot/RootViewColor.xcassets/Contents.json
new file mode 100644
index 00000000..73c00596
--- /dev/null
+++ b/ios/tooot/RootViewColor.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ios/tooot/Supporting/Expo.plist b/ios/tooot/Supporting/Expo.plist
index 6ceadb31..78942c5a 100644
--- a/ios/tooot/Supporting/Expo.plist
+++ b/ios/tooot/Supporting/Expo.plist
@@ -9,7 +9,7 @@
EXUpdatesLaunchWaitMs
0
EXUpdatesReleaseChannel
- 210201-development
+ 0-staging
EXUpdatesSDKVersion
40.0.0
EXUpdatesURL
diff --git a/package.json b/package.json
index db36db3c..99be2fe2 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"start": "react-native start",
"android": "react-native run-android",
"ios": "react-native run-ios",
- "ios:development": "bundle exec fastlane ios development",
+ "ios:build": "bundle exec fastlane ios build",
"test": "jest --watchAll",
"release": "scripts/release.sh"
},
@@ -104,6 +104,12 @@
"typescript": "~4.1.3"
},
"private": true,
- "name": "app",
- "version": "1.0.0"
-}
+ "name": "tooot",
+ "versions": {
+ "native": "210201",
+ "major": 0,
+ "minor": 8,
+ "patch": 0,
+ "expo": "40.0.0"
+ }
+}
\ No newline at end of file
diff --git a/splashes/dark.png b/splashes/dark.png
new file mode 100644
index 00000000..83ca55a4
Binary files /dev/null and b/splashes/dark.png differ
diff --git a/assets/splash.png b/splashes/default.png
similarity index 100%
rename from assets/splash.png
rename to splashes/default.png
diff --git a/src/Screens.tsx b/src/Screens.tsx
index 095b6ad2..0708cfa9 100644
--- a/src/Screens.tsx
+++ b/src/Screens.tsx
@@ -114,14 +114,18 @@ const Index: React.FC = ({ localCorrupt }) => {
return (
<>
-
+
-
+
}
-const GracefullyImage: React.FC = ({
- sharedElement,
- hidden = false,
- uri,
- blurhash,
- dimension,
- onPress,
- style,
- imageStyle
-}) => {
- const { mode, theme } = useTheme()
- const [imageLoaded, setImageLoaded] = useState(false)
-
- const children = useCallback(() => {
- return (
- <>
- {sharedElement ? (
-
- setImageLoaded(true)}
- />
-
- ) : (
- setImageLoaded(true)}
- />
- )}
- {blurhash && (hidden || !imageLoaded) ? (
-
- ) : null}
- >
+const GracefullyImage = React.memo(
+ ({
+ sharedElement,
+ hidden = false,
+ uri,
+ blurhash,
+ dimension,
+ onPress,
+ style,
+ imageStyle
+ }: Props) => {
+ const { mode, theme } = useTheme()
+ const [previewLoaded, setPreviewLoaded] = useState(
+ uri.preview ? false : true
)
- }, [hidden, imageLoaded, mode, uri])
+ const [originalLoaded, setOriginalLoaded] = useState(false)
+ const [originalFailed, setOriginalFailed] = useState(false)
+ const [remoteLoaded, setRemoteLoaded] = useState(uri.remote ? false : true)
- return (
-
- )
-}
+ const sourceUri = useMemo(() => {
+ if (previewLoaded) {
+ if (originalFailed) {
+ return uri.remote
+ } else {
+ return uri.original
+ }
+ } else {
+ return uri.preview
+ }
+ }, [previewLoaded, originalLoaded, originalFailed, remoteLoaded])
+ const onLoad = useCallback(() => {
+ if (previewLoaded) {
+ if (originalFailed) {
+ return setRemoteLoaded(true)
+ } else {
+ return setOriginalLoaded(true)
+ }
+ } else {
+ return setPreviewLoaded(true)
+ }
+ }, [previewLoaded, originalLoaded, originalFailed, remoteLoaded])
+ const onError = useCallback(() => {
+ if (previewLoaded) {
+ if (originalFailed) {
+ return
+ } else {
+ return setOriginalFailed(true)
+ }
+ } else {
+ return
+ }
+ }, [previewLoaded, originalLoaded, originalFailed, remoteLoaded])
+
+ const children = useCallback(() => {
+ return (
+ <>
+ {sharedElement ? (
+
+
+
+ ) : (
+
+ )}
+ {blurhash &&
+ (hidden || !(previewLoaded || originalLoaded || remoteLoaded)) ? (
+
+ ) : null}
+ >
+ )
+ }, [hidden, previewLoaded, originalLoaded, remoteLoaded, mode, uri])
+
+ return (
+
+ )
+ },
+ (prev, next) => {
+ let skipUpdate = true
+ skipUpdate = prev.hidden === next.hidden
+ skipUpdate = prev.uri.original === next.uri.original
+ return false
+ }
+)
const styles = StyleSheet.create({
image: {
diff --git a/src/components/Timelines/Timeline/Shared/Actions.tsx b/src/components/Timelines/Timeline/Shared/Actions.tsx
index 960146e0..b4ee1ab9 100644
--- a/src/components/Timelines/Timeline/Shared/Actions.tsx
+++ b/src/components/Timelines/Timeline/Shared/Actions.tsx
@@ -202,6 +202,7 @@ const TimelineActions: React.FC = ({
: iconColorAction(status.reblogged)
}
size={StyleConstants.Font.Size.L}
+ strokeWidth={status.reblogged ? 3 : undefined}
/>
{status.reblogs_count > 0 && (
= ({
name='Heart'
color={iconColorAction(status.favourited)}
size={StyleConstants.Font.Size.L}
+ strokeWidth={status.favourited ? 3 : undefined}
/>
{status.favourites_count > 0 && (
= ({
name='Bookmark'
color={iconColorAction(status.bookmarked)}
size={StyleConstants.Font.Size.L}
+ strokeWidth={status.bookmarked ? 3 : undefined}
/>
),
[status.bookmarked]
diff --git a/src/components/Timelines/Timeline/Shared/Attachment.tsx b/src/components/Timelines/Timeline/Shared/Attachment.tsx
index d50db0c8..31fc16ef 100644
--- a/src/components/Timelines/Timeline/Shared/Attachment.tsx
+++ b/src/components/Timelines/Timeline/Shared/Attachment.tsx
@@ -114,7 +114,7 @@ const TimelineAttachment: React.FC = ({ status }) => {
return (
- {attachments}
+
{status.sensitive &&
(sensitiveShown ? (
diff --git a/src/components/Timelines/Timeline/Shared/Attachment/Audio.tsx b/src/components/Timelines/Timeline/Shared/Attachment/Audio.tsx
index 9feb5e1b..6474de40 100644
--- a/src/components/Timelines/Timeline/Shared/Attachment/Audio.tsx
+++ b/src/components/Timelines/Timeline/Shared/Attachment/Audio.tsx
@@ -1,3 +1,4 @@
+import analytics from '@components/analytics'
import Button from '@components/Button'
import GracefullyImage from '@components/GracefullyImage'
import { Slider } from '@sharcoux/slider'
@@ -8,7 +9,6 @@ import React, { useCallback, useState } from 'react'
import { StyleSheet, View } from 'react-native'
import { Blurhash } from 'react-native-blurhash'
import attachmentAspectRatio from './aspectRatio'
-import analytics from '@components/analytics'
export interface Props {
total: number
diff --git a/src/components/Timelines/Timeline/Shared/Card.tsx b/src/components/Timelines/Timeline/Shared/Card.tsx
index 3b5a3a6c..b58574b1 100644
--- a/src/components/Timelines/Timeline/Shared/Card.tsx
+++ b/src/components/Timelines/Timeline/Shared/Card.tsx
@@ -27,6 +27,7 @@ const TimelineCard: React.FC = ({ card }) => {
uri={{ original: card.image }}
blurhash={card.blurhash}
style={styles.left}
+ imageStyle={styles.image}
/>
)}
@@ -64,15 +65,13 @@ const styles = StyleSheet.create({
height: StyleConstants.Font.LineHeight.M * 5,
marginTop: StyleConstants.Spacing.M,
borderWidth: StyleSheet.hairlineWidth,
- borderRadius: 6
+ borderRadius: 6,
+ overflow: 'hidden'
},
left: {
- width: StyleConstants.Font.LineHeight.M * 5,
- height: StyleConstants.Font.LineHeight.M * 5
+ flexBasis: StyleConstants.Font.LineHeight.M * 5
},
image: {
- width: '100%',
- height: '100%',
borderTopLeftRadius: 6,
borderBottomLeftRadius: 6
},
diff --git a/src/screens/Actions.tsx b/src/screens/Actions.tsx
index 1cbec5c9..2865c22a 100644
--- a/src/screens/Actions.tsx
+++ b/src/screens/Actions.tsx
@@ -1,8 +1,11 @@
+import analytics from '@components/analytics'
+import Button from '@components/Button'
import { StackScreenProps } from '@react-navigation/stack'
import { getLocalAccount, getLocalUrl } from '@utils/slices/instancesSlice'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { useCallback, useEffect, useMemo } from 'react'
+import { useTranslation } from 'react-i18next'
import { Dimensions, StyleSheet, View } from 'react-native'
import {
PanGestureHandler,
@@ -32,6 +35,8 @@ export type ScreenAccountProp = StackScreenProps<
const ScreenActions = React.memo(
({ route: { params }, navigation }: ScreenAccountProp) => {
+ const { t } = useTranslation()
+
const localAccount = useSelector(getLocalAccount)
let sameAccount = false
switch (params.type) {
@@ -174,6 +179,15 @@ const ScreenActions = React.memo(
]}
/>
{actions}
+
diff --git a/src/screens/Tabs/Shared/Account/Header.tsx b/src/screens/Tabs/Shared/Account/Header.tsx
index d6dc3da2..91d3ca08 100644
--- a/src/screens/Tabs/Shared/Account/Header.tsx
+++ b/src/screens/Tabs/Shared/Account/Header.tsx
@@ -1,11 +1,7 @@
import { useTheme } from '@utils/styles/ThemeManager'
-import React, { useContext, useEffect } from 'react'
-import { Dimensions, Image } from 'react-native'
-import Animated, {
- useAnimatedStyle,
- useSharedValue,
- withTiming
-} from 'react-native-reanimated'
+import React, { useContext } from 'react'
+import { Dimensions } from 'react-native'
+import FastImage from 'react-native-fast-image'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import AccountContext from './utils/createContext'
@@ -15,39 +11,18 @@ export interface Props {
}
const AccountHeader: React.FC = ({ account, limitHeight = false }) => {
- const { accountState, accountDispatch } = useContext(AccountContext)
+ const { accountState } = useContext(AccountContext)
const { theme } = useTheme()
const topInset = useSafeAreaInsets().top
- const height = useSharedValue(
- Dimensions.get('screen').width * accountState.headerRatio + topInset
- )
- const styleHeight = useAnimatedStyle(() => {
- return {
- height: withTiming(height.value)
- }
- })
-
- useEffect(() => {
- if (
- account?.header &&
- !account.header.includes('/headers/original/missing.png')
- ) {
- Image.getSize(account.header, (width, height) => {
- // if (!limitHeight) {
- // accountDispatch({
- // type: 'headerRatio',
- // payload: height / width
- // })
- // }
- })
- }
- }, [account])
-
return (
-
)
}
diff --git a/src/screens/Tabs/Shared/Account/Information.tsx b/src/screens/Tabs/Shared/Account/Information.tsx
index c946c24b..3f1b2458 100644
--- a/src/screens/Tabs/Shared/Account/Information.tsx
+++ b/src/screens/Tabs/Shared/Account/Information.tsx
@@ -88,7 +88,9 @@ const styles = StyleSheet.create({
}
})
-export default React.memo(
- AccountInformation,
- (_, next) => next.account === undefined
-)
+export default React.memo(AccountInformation, (prev, next) => {
+ let skipUpdate = true
+ skipUpdate = prev.account?.id === next.account?.id
+ skipUpdate = prev.account?.acct === next.account?.acct
+ return skipUpdate
+})
diff --git a/src/screens/Tabs/Shared/Account/Information/Avatar.tsx b/src/screens/Tabs/Shared/Account/Information/Avatar.tsx
index 1c838913..828f0aff 100644
--- a/src/screens/Tabs/Shared/Account/Information/Avatar.tsx
+++ b/src/screens/Tabs/Shared/Account/Information/Avatar.tsx
@@ -3,7 +3,7 @@ import GracefullyImage from '@components/GracefullyImage'
import { useNavigation } from '@react-navigation/native'
import { StackNavigationProp } from '@react-navigation/stack'
import { StyleConstants } from '@utils/styles/constants'
-import React, { useMemo } from 'react'
+import React from 'react'
import { Pressable, StyleSheet } from 'react-native'
export interface Props {
@@ -15,35 +15,33 @@ const AccountInformationAvatar: React.FC = ({ account, myInfo }) => {
const navigation = useNavigation<
StackNavigationProp
>()
- const dimension = useMemo(
- () => ({
- width: StyleConstants.Avatar.L,
- height: StyleConstants.Avatar.L
- }),
- []
- )
return (
{
analytics('account_avatar_press')
- myInfo &&
- account &&
- navigation.push('Tab-Shared-Account', { account })
+ myInfo && account && navigation.push('Tab-Shared-Account', { account })
}}
+ style={styles.base}
>
)
}
const styles = StyleSheet.create({
- base: { borderRadius: 8, overflow: 'hidden' }
+ base: {
+ borderRadius: 8,
+ overflow: 'hidden',
+ width: StyleConstants.Avatar.L,
+ height: StyleConstants.Avatar.L
+ },
+ image: { flex: 1 }
})
export default AccountInformationAvatar
diff --git a/src/startup/sentry.ts b/src/startup/sentry.ts
index ff4f2430..38122a5c 100644
--- a/src/startup/sentry.ts
+++ b/src/startup/sentry.ts
@@ -1,18 +1,17 @@
import Constants from 'expo-constants'
+import * as Updates from 'expo-updates'
import * as Sentry from 'sentry-expo'
import log from './log'
const sentry = () => {
log('log', 'Sentry', 'initializing')
Sentry.init({
- environment: Constants.manifest.extra.sentryEnv,
dsn: Constants.manifest.extra.sentryDSN,
+ environment: Constants.manifest.extra.toootEnvironment,
enableInExpoDevelopment: false,
debug:
__DEV__ ||
- ['development'].some(channel =>
- Constants.manifest.releaseChannel?.includes(channel)
- )
+ ['development'].some(channel => Updates.releaseChannel.includes(channel))
})
}
diff --git a/src/utils/slices/contextsSlice.ts b/src/utils/slices/contextsSlice.ts
index 6556f948..5d38b6e0 100644
--- a/src/utils/slices/contextsSlice.ts
+++ b/src/utils/slices/contextsSlice.ts
@@ -1,6 +1,6 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import { RootState } from '@root/store'
-import Constants from 'expo-constants'
+import * as Updates from 'expo-updates'
import * as StoreReview from 'expo-store-review'
export const supportedLngs = ['zh-Hans', 'en']
@@ -38,7 +38,7 @@ const contextsSlice = createSlice({
initialState: contextsInitialState as ContextsState,
reducers: {
updateStoreReview: (state, action: PayloadAction<1>) => {
- if (Constants.manifest.releaseChannel?.includes('production')) {
+ if (Updates.releaseChannel.includes('production')) {
state.storeReview.current = state.storeReview.current + action.payload
if (state.storeReview.current === state.storeReview.context) {
StoreReview.isAvailableAsync().then(() => StoreReview.requestReview())
diff --git a/src/utils/slices/instancesSlice.ts b/src/utils/slices/instancesSlice.ts
index 53865185..f53e870f 100644
--- a/src/utils/slices/instancesSlice.ts
+++ b/src/utils/slices/instancesSlice.ts
@@ -175,15 +175,13 @@ const instancesSlice = createSlice({
name: 'instances',
initialState: instancesInitialState,
reducers: {
- localUpdateActiveIndex: (
- state,
- action: PayloadAction>
- ) => {
- if (action.payload < state.local.instances.length) {
- state.local.activeIndex = action.payload
- } else {
- throw new Error('Set index cannot be found')
- }
+ localUpdateActiveIndex: (state, action: PayloadAction) => {
+ state.local.activeIndex = state.local.instances.findIndex(
+ instance =>
+ instance.url === action.payload.url &&
+ instance.token === action.payload.token &&
+ instance.account.id === action.payload.account.id
+ )
},
localUpdateAccount: (
state,