Merge branch 'release/3.6.10' into master

This commit is contained in:
Antonella Sgarlatta
2021-06-09 15:41:18 -03:00
37 changed files with 1657 additions and 1387 deletions

11
.github/codeql/codeql-config.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
name: "Custom CodeQL Config"
queries:
- uses: security-and-quality
- uses: ./.github/codeql/custom-queries/javascript
paths:
- src
paths-ignore:
- node_modules

View File

@@ -0,0 +1,4 @@
name: custom-javascript-queries
version: 0.0.0
libraryPathDependencies:
- codeql-javascript

68
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,68 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ develop ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ develop ]
schedule:
- cron: '16 21 * * 4'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql/codeql-config.yml
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

4
.gitignore vendored
View File

@@ -68,4 +68,6 @@ ios-release.bundle.map
/ios/StandardNotes.xcodeproj/project.xcworkspace
# HProf
/android/*.hprof
/android/*.hprof
codeqldb

2
.prettierignore Normal file
View File

@@ -0,0 +1,2 @@
.github
codeqldb

View File

@@ -1,3 +1,6 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
"typescript.tsdk": "node_modules/typescript/lib",
"prettier.requireConfig": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
}

View File

@@ -6,21 +6,21 @@ GEM
public_suffix (>= 2.0.2, < 5.0)
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.1.0)
aws-partitions (1.422.0)
aws-sdk-core (3.111.2)
aws-eventstream (1.1.1)
aws-partitions (1.451.0)
aws-sdk-core (3.114.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.41.0)
aws-sdk-core (~> 3, >= 3.109.0)
aws-sdk-kms (1.43.0)
aws-sdk-core (~> 3, >= 3.112.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.87.0)
aws-sdk-core (~> 3, >= 3.109.0)
aws-sdk-s3 (1.94.1)
aws-sdk-core (~> 3, >= 3.112.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.2)
aws-sigv4 (1.2.3)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.0.3)
@@ -29,26 +29,29 @@ GEM
commander-fastlane (4.4.6)
highline (~> 1.7.2)
declarative (0.0.20)
declarative-option (0.1.0)
digest-crc (0.6.3)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.6)
emoji_regex (3.2.1)
excon (0.79.0)
faraday (1.3.0)
emoji_regex (3.2.2)
excon (0.81.0)
faraday (1.4.1)
faraday-excon (~> 1.1)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.1)
multipart-post (>= 1.2, < 3)
ruby2_keywords
ruby2_keywords (>= 0.0.4)
faraday-cookie_jar (0.0.7)
faraday (>= 0.8.0)
http-cookie (~> 1.0.0)
faraday-excon (1.1.0)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.1.0)
faraday_middleware (1.0.0)
faraday (~> 1.0)
fastimage (2.2.2)
fastlane (2.172.0)
fastimage (2.2.3)
fastlane (2.181.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0)
artifactory (~> 3.0)
@@ -72,6 +75,7 @@ GEM
jwt (>= 2.1.0, < 3)
mini_magick (>= 4.9.4, < 5.0.0)
multipart-post (~> 2.0.0)
naturally (~> 2.2)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 2.0.0, < 3.0.0)
security (= 0.1.3)
@@ -100,7 +104,7 @@ GEM
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
signet (~> 0.12)
google-apis-core (0.2.1)
google-apis-core (0.3.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (~> 0.14)
httpclient (>= 2.8.1, < 3.0)
@@ -110,17 +114,17 @@ GEM
rexml
signet (~> 0.14)
webrick
google-apis-iamcredentials_v1 (0.1.0)
google-apis-iamcredentials_v1 (0.3.0)
google-apis-core (~> 0.1)
google-apis-storage_v1 (0.1.0)
google-apis-storage_v1 (0.3.0)
google-apis-core (~> 0.1)
google-cloud-core (1.5.0)
google-cloud-core (1.6.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.4.0)
google-cloud-env (1.5.0)
faraday (>= 0.17.3, < 2.0)
google-cloud-errors (1.0.1)
google-cloud-storage (1.30.0)
google-cloud-errors (1.1.0)
google-cloud-storage (1.31.0)
addressable (~> 2.5)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
@@ -128,7 +132,7 @@ GEM
google-cloud-core (~> 1.2)
googleauth (~> 0.9)
mini_mime (~> 1.0)
googleauth (0.15.0)
googleauth (0.16.2)
faraday (>= 0.17.3, < 2.0)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
@@ -141,10 +145,10 @@ GEM
httpclient (2.8.3)
jmespath (1.4.0)
json (2.5.1)
jwt (2.2.2)
jwt (2.2.3)
memoist (0.16.2)
mini_magick (4.11.0)
mini_mime (1.0.2)
mini_mime (1.1.0)
multi_json (1.15.0)
multipart-post (2.0.0)
nanaimo (0.3.0)
@@ -154,17 +158,17 @@ GEM
public_suffix (4.0.6)
rake (13.0.3)
rchardet (1.8.0)
representable (3.0.4)
representable (3.1.1)
declarative (< 0.1.0)
declarative-option (< 0.2.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rexml (3.2.4)
rexml (3.2.5)
rouge (2.0.7)
ruby2_keywords (0.0.4)
rubyzip (2.3.0)
security (0.1.3)
signet (0.14.1)
signet (0.15.0)
addressable (~> 2.3)
faraday (>= 0.17.3, < 2.0)
jwt (>= 1.5, < 3.0)
@@ -176,6 +180,7 @@ GEM
terminal-notifier (2.0.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
trailblazer-option (0.1.1)
tty-cursor (0.7.1)
tty-screen (0.8.1)
tty-spinner (0.9.3)

View File

@@ -22,13 +22,12 @@ public class MainActivity extends ReactActivity {
super(activity, mainComponentName);
}
@Override
protected Bundle getLaunchOptions() {
String packageName = this.getContext().getPackageName();
Bundle props = new Bundle();
SharedPreferences settings = this.getContext().getSharedPreferences("react-native", Context.MODE_PRIVATE);
String bugsnagOptOut = settings.getString("bugsnagoptout", "false");
String bugsnagOptOut = settings.getString("bugsnagoptout", "true");
props.putBoolean("bugsnagOptOut", bugsnagOptOut.equals("true"));
if (packageName.equals("com.standardnotes.dev")) {
props.putString("env", "dev");

View File

@@ -3,6 +3,7 @@ package com.standardnotes;
import android.app.Application;
import android.app.Activity;
import android.content.Context;
import android.webkit.WebView;
import com.bugsnag.android.BreadcrumbType;
import com.bugsnag.android.Configuration;
@@ -65,6 +66,12 @@ public class MainApplication extends Application implements ReactApplication {
public void onCreate() {
super.onCreate();
// Enable Remote debugging for WebViews
String packageName = getApplicationContext().getPackageName();
if (packageName.equals("com.standardnotes.dev")) {
WebView.setWebContentsDebuggingEnabled(true);
}
rebuildOkHtttp();
Configuration config = Configuration.load(this);
@@ -79,7 +86,7 @@ public class MainApplication extends Application implements ReactApplication {
}});
SharedPreferences settings = getApplicationContext().getSharedPreferences("react-native", Context.MODE_PRIVATE);
String bugsnagOptOut = settings.getString("bugsnagoptout", "false");
String bugsnagOptOut = settings.getString("bugsnagoptout", "true");
if (!bugsnagOptOut.equals("true")) {
Bugsnag.start(this, config);

View File

@@ -1,4 +1,4 @@
fastlane_version "2.158.0"
fastlane_version "2.181.0"
platform :ios do
def sign_ios(type = 'appstore')

View File

@@ -15,10 +15,18 @@ pod 'TrustKit', '1.6.5'
target 'StandardNotes' do
config = use_native_modules!
use_react_native!(:path => config["reactNativePath"])
use_react_native!(
:path => config["reactNativePath"],
:hermes_enabled => false,
)
end
target "StandardNotesDev" do
config = use_native_modules!
use_react_native!(:path => config["reactNativePath"])
use_react_native!(
:path => config["reactNativePath"],
# Enabling hermes breaks fastlane build (at time of commit)
:hermes_enabled => false,
)
end

View File

@@ -3,190 +3,208 @@ PODS:
- BugsnagReactNative (7.5.6):
- React
- DoubleConversion (1.1.6)
- FBLazyVector (0.63.4)
- FBReactNativeSpec (0.63.4):
- Folly (= 2020.01.13.00)
- RCTRequired (= 0.63.4)
- RCTTypeSafety (= 0.63.4)
- React-Core (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- Folly (2020.01.13.00):
- boost-for-react-native
- DoubleConversion
- Folly/Default (= 2020.01.13.00)
- glog
- Folly/Default (2020.01.13.00):
- boost-for-react-native
- DoubleConversion
- glog
- FBLazyVector (0.64.1)
- FBReactNativeSpec (0.64.1):
- RCT-Folly (= 2020.01.13.00)
- RCTRequired (= 0.64.1)
- RCTTypeSafety (= 0.64.1)
- React-Core (= 0.64.1)
- React-jsi (= 0.64.1)
- ReactCommon/turbomodule/core (= 0.64.1)
- glog (0.3.5)
- RCTRequired (0.63.4)
- RCTTypeSafety (0.63.4):
- FBLazyVector (= 0.63.4)
- Folly (= 2020.01.13.00)
- RCTRequired (= 0.63.4)
- React-Core (= 0.63.4)
- React (0.63.4):
- React-Core (= 0.63.4)
- React-Core/DevSupport (= 0.63.4)
- React-Core/RCTWebSocket (= 0.63.4)
- React-RCTActionSheet (= 0.63.4)
- React-RCTAnimation (= 0.63.4)
- React-RCTBlob (= 0.63.4)
- React-RCTImage (= 0.63.4)
- React-RCTLinking (= 0.63.4)
- React-RCTNetwork (= 0.63.4)
- React-RCTSettings (= 0.63.4)
- React-RCTText (= 0.63.4)
- React-RCTVibration (= 0.63.4)
- React-callinvoker (0.63.4)
- React-Core (0.63.4):
- Folly (= 2020.01.13.00)
- RCT-Folly (2020.01.13.00):
- boost-for-react-native
- DoubleConversion
- glog
- React-Core/Default (= 0.63.4)
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- RCT-Folly/Default (= 2020.01.13.00)
- RCT-Folly/Default (2020.01.13.00):
- boost-for-react-native
- DoubleConversion
- glog
- RCTRequired (0.64.1)
- RCTTypeSafety (0.64.1):
- FBLazyVector (= 0.64.1)
- RCT-Folly (= 2020.01.13.00)
- RCTRequired (= 0.64.1)
- React-Core (= 0.64.1)
- React (0.64.1):
- React-Core (= 0.64.1)
- React-Core/DevSupport (= 0.64.1)
- React-Core/RCTWebSocket (= 0.64.1)
- React-RCTActionSheet (= 0.64.1)
- React-RCTAnimation (= 0.64.1)
- React-RCTBlob (= 0.64.1)
- React-RCTImage (= 0.64.1)
- React-RCTLinking (= 0.64.1)
- React-RCTNetwork (= 0.64.1)
- React-RCTSettings (= 0.64.1)
- React-RCTText (= 0.64.1)
- React-RCTVibration (= 0.64.1)
- React-callinvoker (0.64.1)
- React-Core (0.64.1):
- glog
- RCT-Folly (= 2020.01.13.00)
- React-Core/Default (= 0.64.1)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-jsiexecutor (= 0.64.1)
- React-perflogger (= 0.64.1)
- Yoga
- React-Core/CoreModulesHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- React-Core/CoreModulesHeaders (0.64.1):
- glog
- RCT-Folly (= 2020.01.13.00)
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-jsiexecutor (= 0.64.1)
- React-perflogger (= 0.64.1)
- Yoga
- React-Core/Default (0.63.4):
- Folly (= 2020.01.13.00)
- React-Core/Default (0.64.1):
- glog
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- RCT-Folly (= 2020.01.13.00)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-jsiexecutor (= 0.64.1)
- React-perflogger (= 0.64.1)
- Yoga
- React-Core/DevSupport (0.63.4):
- Folly (= 2020.01.13.00)
- React-Core/DevSupport (0.64.1):
- glog
- React-Core/Default (= 0.63.4)
- React-Core/RCTWebSocket (= 0.63.4)
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-jsinspector (= 0.63.4)
- RCT-Folly (= 2020.01.13.00)
- React-Core/Default (= 0.64.1)
- React-Core/RCTWebSocket (= 0.64.1)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-jsiexecutor (= 0.64.1)
- React-jsinspector (= 0.64.1)
- React-perflogger (= 0.64.1)
- Yoga
- React-Core/RCTActionSheetHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- React-Core/RCTActionSheetHeaders (0.64.1):
- glog
- RCT-Folly (= 2020.01.13.00)
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-jsiexecutor (= 0.64.1)
- React-perflogger (= 0.64.1)
- Yoga
- React-Core/RCTAnimationHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- React-Core/RCTAnimationHeaders (0.64.1):
- glog
- RCT-Folly (= 2020.01.13.00)
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-jsiexecutor (= 0.64.1)
- React-perflogger (= 0.64.1)
- Yoga
- React-Core/RCTBlobHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- React-Core/RCTBlobHeaders (0.64.1):
- glog
- RCT-Folly (= 2020.01.13.00)
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-jsiexecutor (= 0.64.1)
- React-perflogger (= 0.64.1)
- Yoga
- React-Core/RCTImageHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- React-Core/RCTImageHeaders (0.64.1):
- glog
- RCT-Folly (= 2020.01.13.00)
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-jsiexecutor (= 0.64.1)
- React-perflogger (= 0.64.1)
- Yoga
- React-Core/RCTLinkingHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- React-Core/RCTLinkingHeaders (0.64.1):
- glog
- RCT-Folly (= 2020.01.13.00)
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-jsiexecutor (= 0.64.1)
- React-perflogger (= 0.64.1)
- Yoga
- React-Core/RCTNetworkHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- React-Core/RCTNetworkHeaders (0.64.1):
- glog
- RCT-Folly (= 2020.01.13.00)
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-jsiexecutor (= 0.64.1)
- React-perflogger (= 0.64.1)
- Yoga
- React-Core/RCTSettingsHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- React-Core/RCTSettingsHeaders (0.64.1):
- glog
- RCT-Folly (= 2020.01.13.00)
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-jsiexecutor (= 0.64.1)
- React-perflogger (= 0.64.1)
- Yoga
- React-Core/RCTTextHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- React-Core/RCTTextHeaders (0.64.1):
- glog
- RCT-Folly (= 2020.01.13.00)
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-jsiexecutor (= 0.64.1)
- React-perflogger (= 0.64.1)
- Yoga
- React-Core/RCTVibrationHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- React-Core/RCTVibrationHeaders (0.64.1):
- glog
- RCT-Folly (= 2020.01.13.00)
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-jsiexecutor (= 0.64.1)
- React-perflogger (= 0.64.1)
- Yoga
- React-Core/RCTWebSocket (0.63.4):
- Folly (= 2020.01.13.00)
- React-Core/RCTWebSocket (0.64.1):
- glog
- React-Core/Default (= 0.63.4)
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- RCT-Folly (= 2020.01.13.00)
- React-Core/Default (= 0.64.1)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-jsiexecutor (= 0.64.1)
- React-perflogger (= 0.64.1)
- Yoga
- React-CoreModules (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.4)
- React-Core/CoreModulesHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- React-RCTImage (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-cxxreact (0.63.4):
- React-CoreModules (0.64.1):
- FBReactNativeSpec (= 0.64.1)
- RCT-Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.64.1)
- React-Core/CoreModulesHeaders (= 0.64.1)
- React-jsi (= 0.64.1)
- React-RCTImage (= 0.64.1)
- ReactCommon/turbomodule/core (= 0.64.1)
- React-cxxreact (0.64.1):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
- Folly (= 2020.01.13.00)
- glog
- React-callinvoker (= 0.63.4)
- React-jsinspector (= 0.63.4)
- React-jsi (0.63.4):
- RCT-Folly (= 2020.01.13.00)
- React-callinvoker (= 0.64.1)
- React-jsi (= 0.64.1)
- React-jsinspector (= 0.64.1)
- React-perflogger (= 0.64.1)
- React-runtimeexecutor (= 0.64.1)
- React-jsi (0.64.1):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
- Folly (= 2020.01.13.00)
- glog
- React-jsi/Default (= 0.63.4)
- React-jsi/Default (0.63.4):
- RCT-Folly (= 2020.01.13.00)
- React-jsi/Default (= 0.64.1)
- React-jsi/Default (0.64.1):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
- Folly (= 2020.01.13.00)
- glog
- React-jsiexecutor (0.63.4):
- RCT-Folly (= 2020.01.13.00)
- React-jsiexecutor (0.64.1):
- DoubleConversion
- Folly (= 2020.01.13.00)
- glog
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsinspector (0.63.4)
- RCT-Folly (= 2020.01.13.00)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-perflogger (= 0.64.1)
- React-jsinspector (0.64.1)
- react-native-aes (1.3.9):
- React-Core
- react-native-fingerprint-scanner (5.0.0):
@@ -203,66 +221,70 @@ PODS:
- React-Core
- react-native-webview (11.0.3):
- React-Core
- React-RCTActionSheet (0.63.4):
- React-Core/RCTActionSheetHeaders (= 0.63.4)
- React-RCTAnimation (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.4)
- React-Core/RCTAnimationHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTBlob (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- Folly (= 2020.01.13.00)
- React-Core/RCTBlobHeaders (= 0.63.4)
- React-Core/RCTWebSocket (= 0.63.4)
- React-jsi (= 0.63.4)
- React-RCTNetwork (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTImage (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.4)
- React-Core/RCTImageHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- React-RCTNetwork (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTLinking (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- React-Core/RCTLinkingHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTNetwork (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.4)
- React-Core/RCTNetworkHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTSettings (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.4)
- React-Core/RCTSettingsHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTText (0.63.4):
- React-Core/RCTTextHeaders (= 0.63.4)
- React-RCTVibration (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- Folly (= 2020.01.13.00)
- React-Core/RCTVibrationHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- ReactCommon/turbomodule/core (0.63.4):
- React-perflogger (0.64.1)
- React-RCTActionSheet (0.64.1):
- React-Core/RCTActionSheetHeaders (= 0.64.1)
- React-RCTAnimation (0.64.1):
- FBReactNativeSpec (= 0.64.1)
- RCT-Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.64.1)
- React-Core/RCTAnimationHeaders (= 0.64.1)
- React-jsi (= 0.64.1)
- ReactCommon/turbomodule/core (= 0.64.1)
- React-RCTBlob (0.64.1):
- FBReactNativeSpec (= 0.64.1)
- RCT-Folly (= 2020.01.13.00)
- React-Core/RCTBlobHeaders (= 0.64.1)
- React-Core/RCTWebSocket (= 0.64.1)
- React-jsi (= 0.64.1)
- React-RCTNetwork (= 0.64.1)
- ReactCommon/turbomodule/core (= 0.64.1)
- React-RCTImage (0.64.1):
- FBReactNativeSpec (= 0.64.1)
- RCT-Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.64.1)
- React-Core/RCTImageHeaders (= 0.64.1)
- React-jsi (= 0.64.1)
- React-RCTNetwork (= 0.64.1)
- ReactCommon/turbomodule/core (= 0.64.1)
- React-RCTLinking (0.64.1):
- FBReactNativeSpec (= 0.64.1)
- React-Core/RCTLinkingHeaders (= 0.64.1)
- React-jsi (= 0.64.1)
- ReactCommon/turbomodule/core (= 0.64.1)
- React-RCTNetwork (0.64.1):
- FBReactNativeSpec (= 0.64.1)
- RCT-Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.64.1)
- React-Core/RCTNetworkHeaders (= 0.64.1)
- React-jsi (= 0.64.1)
- ReactCommon/turbomodule/core (= 0.64.1)
- React-RCTSettings (0.64.1):
- FBReactNativeSpec (= 0.64.1)
- RCT-Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.64.1)
- React-Core/RCTSettingsHeaders (= 0.64.1)
- React-jsi (= 0.64.1)
- ReactCommon/turbomodule/core (= 0.64.1)
- React-RCTText (0.64.1):
- React-Core/RCTTextHeaders (= 0.64.1)
- React-RCTVibration (0.64.1):
- FBReactNativeSpec (= 0.64.1)
- RCT-Folly (= 2020.01.13.00)
- React-Core/RCTVibrationHeaders (= 0.64.1)
- React-jsi (= 0.64.1)
- ReactCommon/turbomodule/core (= 0.64.1)
- React-runtimeexecutor (0.64.1):
- React-jsi (= 0.64.1)
- ReactCommon/turbomodule/core (0.64.1):
- DoubleConversion
- Folly (= 2020.01.13.00)
- glog
- React-callinvoker (= 0.63.4)
- React-Core (= 0.63.4)
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- RCT-Folly (= 2020.01.13.00)
- React-callinvoker (= 0.64.1)
- React-Core (= 0.64.1)
- React-cxxreact (= 0.64.1)
- React-jsi (= 0.64.1)
- React-perflogger (= 0.64.1)
- ReactNativeAlternateIcons (0.3.0):
- React
- RNCAsyncStorage (1.12.1):
@@ -302,9 +324,9 @@ DEPENDENCIES:
- "BugsnagReactNative (from `../node_modules/@bugsnag/react-native`)"
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
- FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`)
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
- React (from `../node_modules/react-native/`)
@@ -325,6 +347,7 @@ DEPENDENCIES:
- react-native-sodium (from `../node_modules/react-native-sodium`)
- react-native-version-info (from `../node_modules/react-native-version-info`)
- react-native-webview (from `../node_modules/react-native-webview`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
- React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
@@ -334,6 +357,7 @@ DEPENDENCIES:
- React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
- React-RCTText (from `../node_modules/react-native/Libraries/Text`)
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- ReactNativeAlternateIcons (from `../node_modules/react-native-alternate-icons`)
- "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)"
@@ -367,11 +391,11 @@ EXTERNAL SOURCES:
FBLazyVector:
:path: "../node_modules/react-native/Libraries/FBLazyVector"
FBReactNativeSpec:
:path: "../node_modules/react-native/Libraries/FBReactNativeSpec"
Folly:
:podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec"
:path: "../node_modules/react-native/React/FBReactNativeSpec"
glog:
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
RCT-Folly:
:podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
RCTRequired:
:path: "../node_modules/react-native/Libraries/RCTRequired"
RCTTypeSafety:
@@ -408,6 +432,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-version-info"
react-native-webview:
:path: "../node_modules/react-native-webview"
React-perflogger:
:path: "../node_modules/react-native/ReactCommon/reactperflogger"
React-RCTActionSheet:
:path: "../node_modules/react-native/Libraries/ActionSheetIOS"
React-RCTAnimation:
@@ -426,6 +452,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/Libraries/Text"
React-RCTVibration:
:path: "../node_modules/react-native/Libraries/Vibration"
React-runtimeexecutor:
:path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
ReactCommon:
:path: "../node_modules/react-native/ReactCommon"
ReactNativeAlternateIcons:
@@ -467,20 +495,20 @@ SPEC CHECKSUMS:
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
BugsnagReactNative: 1ac1129bdf95273df07cfe4d89750dc3d9d888a3
DoubleConversion: cde416483dac037923206447da6e1454df403714
FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
FBLazyVector: 7b423f9e248eae65987838148c36eec1dbfe0b53
FBReactNativeSpec: 016334cbf24e61c86998bb3d8550a3742040247d
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
RCTRequired: 082f10cd3f905d6c124597fd1c14f6f2655ff65e
RCTTypeSafety: 8c9c544ecbf20337d069e4ae7fd9a377aadf504b
React: b0a957a2c44da4113b0c4c9853d8387f8e64e615
React-callinvoker: c3f44dd3cb195b6aa46621fff95ded79d59043fe
React-Core: d3b2a1ac9a2c13c3bcde712d9281fc1c8a5b315b
React-CoreModules: 0581ff36cb797da0943d424f69e7098e43e9be60
React-cxxreact: c1480d4fda5720086c90df537ee7d285d4c57ac3
React-jsi: a0418934cf48f25b485631deb27c64dc40fb4c31
React-jsiexecutor: 93bd528844ad21dc07aab1c67cb10abae6df6949
React-jsinspector: 58aef7155bc9a9683f5b60b35eccea8722a4f53a
RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c
RCTRequired: ec2ebc96b7bfba3ca5c32740f5a0c6a014a274d2
RCTTypeSafety: 22567f31e67c3e088c7ac23ea46ab6d4779c0ea5
React: a241e3dbb1e91d06332f1dbd2b3ab26e1a4c4b9d
React-callinvoker: da4d1c6141696a00163960906bc8a55b985e4ce4
React-Core: 46ba164c437d7dac607b470c83c8308b05799748
React-CoreModules: 217bd14904491c7b9940ff8b34a3fe08013c2f14
React-cxxreact: 0090588ae6660c4615d3629fdd5c768d0983add4
React-jsi: 5de8204706bd872b78ea646aee5d2561ca1214b6
React-jsiexecutor: 124e8f99992490d0d13e0649d950d3e1aae06fe9
React-jsinspector: 500a59626037be5b3b3d89c5151bc3baa9abf1a9
react-native-aes: a13199300208e4eda1df14506a276415561e02bd
react-native-fingerprint-scanner: be63e626b31fb951780a5fac5328b065a61a3d6e
react-native-mail: 5fe7239a5b5c1e858d425501c03d1ab977434122
@@ -489,16 +517,18 @@ SPEC CHECKSUMS:
react-native-sodium: 6cc4c4c1ea331f9f2b478076e983e09827a7b23f
react-native-version-info: 36490da17d2c6b5cc21321c70e433784dee7ed0b
react-native-webview: 21fdfbdd5a2268195ca013174f8f656f3509de50
React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336
React-RCTAnimation: 1bde3ecc0c104c55df246eda516e0deb03c4e49b
React-RCTBlob: a97d378b527740cc667e03ebfa183a75231ab0f0
React-RCTImage: c1b1f2d3f43a4a528c8946d6092384b5c880d2f0
React-RCTLinking: 35ae4ab9dc0410d1fcbdce4d7623194a27214fb2
React-RCTNetwork: 29ec2696f8d8cfff7331fac83d3e893c95ef43ae
React-RCTSettings: 60f0691bba2074ef394f95d4c2265ec284e0a46a
React-RCTText: 5c51df3f08cb9dedc6e790161195d12bac06101c
React-RCTVibration: ae4f914cfe8de7d4de95ae1ea6cc8f6315d73d9d
ReactCommon: 73d79c7039f473b76db6ff7c6b159c478acbbb3b
React-perflogger: aad6d4b4a267936b3667260d1f649b6f6069a675
React-RCTActionSheet: fc376be462c9c8d6ad82c0905442fd77f82a9d2a
React-RCTAnimation: ba0a1c3a2738be224a08092fa7f1b444ab77d309
React-RCTBlob: f758d4403fc5828a326dc69e27b41e1a92f34947
React-RCTImage: ce57088705f4a8d03f6594b066a59c29143ba73e
React-RCTLinking: 852a3a95c65fa63f657a4b4e2d3d83a815e00a7c
React-RCTNetwork: 9d7ccb8a08d522d71700b4fb677d9fa28cccd118
React-RCTSettings: d8aaf4389ff06114dee8c42ef5f0f2915946011e
React-RCTText: 809c12ed6b261796ba056c04fcd20d8b90bcc81d
React-RCTVibration: 4b99a7f5c6c0abbc5256410cc5425fb8531986e1
React-runtimeexecutor: ff951a0c241bfaefc4940a3f1f1a229e7cb32fa6
ReactCommon: bedc99ed4dae329c4fcf128d0c31b9115e5365ca
ReactNativeAlternateIcons: b2a8a729d9d9756ed0652c352694f190407f297f
RNCAsyncStorage: b03032fdbdb725bea0bd9e5ec5a7272865ae7398
RNCMaskedView: 5a8ec07677aa885546a0d98da336457e2bea557f
@@ -516,8 +546,8 @@ SPEC CHECKSUMS:
sn-textview: 0211237b3e0edeeb23aed2a9c47b78af35a81e95
SNReactNative: b5e9e529c175c13f3a618e27c76cf3071213d5e1
TrustKit: 073855e3adecd317417bda4ac9e9ac54a2e3b9f2
Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6
Yoga: a7de31c64fe738607e7a3803e3f591a4b1df7393
PODFILE CHECKSUM: 5f6066efbcc06032bd833f9e21b5c400c0a572eb
PODFILE CHECKSUM: 3f737e1e00a82037a88b8818c81a7c17327450dc
COCOAPODS: 1.10.1

View File

@@ -88,12 +88,16 @@
</dict>
</dict>
</dict>
<key>NSCameraUsageDescription</key>
<string>Camera is optionally used to upload images and scan QR codes using the TokenVault extension.</string>
<key>NSFaceIDUsageDescription</key>
<string>Face ID is required to unlock your notes.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Not used by application; required in configuration because API exists in build dependencies.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Not used by application; required in configuration because API exists in build dependencies.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Photo library is optionally used to select files to upload or QR code images from your photo library.</string>
<key>UIAppFonts</key>
<array>
<string>AntDesign.ttf</string>

View File

@@ -66,12 +66,16 @@
</dict>
</dict>
</dict>
<key>NSCameraUsageDescription</key>
<string>Camera is required to scan QR codes with the TokenVault extension.</string>
<key>NSFaceIDUsageDescription</key>
<string>Face ID is required to unlock your notes.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Not used by application; required in configuration because API exists in build dependencies.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Not used by application; required in configuration because API exists in build dependencies.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Photo library is required to select QR code images from your photo library.</string>
<key>UIAppFonts</key>
<array>
<string>AntDesign.ttf</string>

View File

@@ -1,7 +1,7 @@
{
"name": "StandardNotes",
"version": "3.6.9",
"user-version": "3.6.9",
"version": "3.6.10",
"user-version": "3.6.10",
"private": true,
"license": "AGPL-3.0-or-later",
"scripts": {
@@ -26,11 +26,11 @@
"@react-navigation/native": "^5.9.3",
"@react-navigation/stack": "^5.14.3",
"@standardnotes/sncrypto-common": "1.2.9",
"@standardnotes/snjs": "2.4.2",
"@standardnotes/snjs": "2.5.0",
"js-base64": "^3.5.2",
"moment": "^2.29.1",
"react": "16.13.1",
"react-native": "0.63.4",
"react": "17.0.1",
"react-native": "0.64.1",
"react-native-aes-crypto": "standardnotes/react-native-aes#6430299",
"react-native-alternate-icons": "standardnotes/react-native-alternate-icons#1d335d",
"react-native-default-preference": "^1.4.3",
@@ -86,6 +86,7 @@
"postinstall-postinstall": "^2.1.0",
"prettier": "^2.2.1",
"prettier-plugin-organize-imports": "^1.1.1",
"react-native-document-picker": "^5.0.4",
"react-test-renderer": "16.13.1",
"replace-in-file": "^6.1.0",
"typescript": "^3.9.4"

View File

@@ -60,7 +60,10 @@ export class MobileApplication extends SNApplication {
],
VersionInfo.bundleIdentifier?.includes('dev')
? 'https://syncing-server-dev.standardnotes.org/'
: 'https://sync.standardnotes.org'
: 'https://sync.standardnotes.org',
VersionInfo.bundleIdentifier?.includes('dev')
? 'https://api-dev.standardnotes.com/'
: 'https://api.standardnotes.com'
);
this.Uuid = Math.random().toString();
this.editorGroup = new EditorGroup(this);
@@ -138,7 +141,7 @@ export class MobileApplication extends SNApplication {
return this.MobileServices.backupsService;
}
public getPrefsService() {
public getLocalPreferences() {
return this.MobileServices.prefsService;
}

View File

@@ -30,6 +30,7 @@ import FlagSecure from 'react-native-flag-secure-android';
import { hide, show } from 'react-native-privacy-snapshot';
import VersionInfo from 'react-native-version-info';
import { MobileApplication } from './application';
import { associateComponentWithNote } from './component_manager';
import { Editor } from './editor';
import { PrefKey } from './preferences_manager';
@@ -102,6 +103,7 @@ export class ApplicationState extends ApplicationService {
keyboardDidHideListener?: EmitterSubscription;
keyboardHeight?: number;
appEventObersever: any;
selectedTagRestored = false;
selectedTag: SNTag = this.application.getSmartTags()[0];
userPreferences?: SNUserPrefs;
tabletMode: boolean = false;
@@ -152,24 +154,33 @@ export class ApplicationState extends ApplicationService {
this.keyboardDidHideListener = undefined;
}
restoreSelectedTag() {
if (this.selectedTagRestored) {
return;
}
const savedTagUuid: string | undefined = this.prefService.getValue(
PrefKey.SelectedTagUuid,
undefined
);
if (isNullOrUndefined(savedTagUuid)) {
this.selectedTagRestored = true;
return;
}
const savedTag =
(this.application.findItem(savedTagUuid) as SNTag) ||
this.application.getSmartTags().find(tag => tag.uuid === savedTagUuid);
if (savedTag) {
this.setSelectedTag(savedTag, false);
this.selectedTagRestored = true;
}
}
async onAppStart() {
this.removePreferencesLoadedListener = this.prefService.addPreferencesLoadedObserver(
() => {
this.notifyOfStateChange(AppStateType.PreferencesChanged);
const savedTagUuid: string | undefined = this.prefService.getValue(
PrefKey.SelectedTagUuid,
undefined
);
const savedTag = !isNullOrUndefined(savedTagUuid)
? (this.application.findItem(savedTagUuid) as SNTag) ||
this.application
.getSmartTags()
.find(tag => tag.uuid === savedTagUuid)
: undefined;
if (savedTag) {
this.setSelectedTag(savedTag, false);
}
}
);
@@ -269,19 +280,28 @@ export class ApplicationState extends ApplicationService {
* editor's note with an empty one.
*/
async createEditor(title?: string) {
const activeEditor = this.getActiveEditor();
let activeEditor = this.getActiveEditor();
if (!activeEditor || this.multiEditorEnabled) {
this.application.editorGroup.createEditor(undefined, title);
await this.application.editorGroup.createEditor(undefined, title);
activeEditor = this.getActiveEditor();
} else {
await activeEditor.reset(title);
}
const defaultEditor = this.application.componentManager.getDefaultEditor();
if (defaultEditor) {
await associateComponentWithNote(
this.application,
defaultEditor,
activeEditor.note!
);
}
}
async openEditor(noteUuid: string) {
const note = this.application.findItem(noteUuid) as SNNote;
const activeEditor = this.getActiveEditor();
if (!activeEditor || this.multiEditorEnabled) {
this.application.editorGroup.createEditor(noteUuid);
await this.application.editorGroup.createEditor(noteUuid);
} else {
activeEditor.setNote(note);
}
@@ -386,11 +406,21 @@ export class ApplicationState extends ApplicationService {
private handleApplicationEvents() {
this.appEventObersever = this.application.addEventObserver(
async eventName => {
if (eventName === ApplicationEvent.Started) {
this.locked = true;
} else if (eventName === ApplicationEvent.Launched) {
this.locked = false;
this.notifyLockStateObservers(LockStateType.Unlocked);
switch (eventName) {
case ApplicationEvent.LocalDataIncrementalLoad:
case ApplicationEvent.LocalDataLoaded: {
this.restoreSelectedTag();
break;
}
case ApplicationEvent.Started: {
this.locked = true;
break;
}
case ApplicationEvent.Launched: {
this.locked = false;
this.notifyLockStateObservers(LockStateType.Unlocked);
break;
}
}
}
);
@@ -399,8 +429,8 @@ export class ApplicationState extends ApplicationService {
/**
* Set selected @SNTag
*/
public setSelectedTag(tag: SNTag, saveSelection: boolean) {
if (this.selectedTag === tag) {
public setSelectedTag(tag: SNTag, saveSelection: boolean = true) {
if (this.selectedTag.uuid === tag.uuid) {
return;
}
const previousTag = this.selectedTag;
@@ -408,7 +438,7 @@ export class ApplicationState extends ApplicationService {
if (saveSelection) {
this.application
.getPrefsService()
.getLocalPreferences()
.setUserPrefValue(PrefKey.SelectedTagUuid, tag.uuid);
}
@@ -681,7 +711,7 @@ export class ApplicationState extends ApplicationService {
}
private get prefService() {
return this.application.getPrefsService();
return this.application.getLocalPreferences();
}
public getEnvironment() {

View File

@@ -1,7 +1,6 @@
import {
addIfUnique,
ComponentArea,
isNullOrUndefined,
removeFromArray,
SNComponent,
UuidString,
@@ -69,14 +68,8 @@ export class ComponentGroup {
}
}
activeComponentForArea(area: ComponentArea) {
return !isNullOrUndefined(this.activeComponentsForArea(area))
? this.activeComponentsForArea(area)[0]
: undefined;
}
activeComponentsForArea(area: ComponentArea) {
return this.allActiveComponents()?.filter(c => c.area === area);
activeComponentForArea(area: ComponentArea): SNComponent | undefined {
return this.allActiveComponents()?.filter(c => c.area === area)?.[0];
}
allComponentsForArea(area: ComponentArea) {

View File

@@ -1,8 +1,11 @@
import {
ComponentMutator,
PermissionDialog,
SNAlertService,
SNApplication,
SNComponent,
SNComponentManager,
SNNote,
} from '@standardnotes/snjs';
import { objectToCss } from '@Style/css_parser';
import { MobileTheme } from '@Style/theme_service';
@@ -49,3 +52,14 @@ export class ComponentManager extends SNComponentManager {
}
}
}
export async function associateComponentWithNote(
application: SNApplication,
component: SNComponent,
note: SNNote
) {
return application.changeItem<ComponentMutator>(component.uuid, mutator => {
mutator.removeDisassociatedItemId(note.uuid);
mutator.associateWithItem(note.uuid);
});
}

View File

@@ -14,20 +14,12 @@ export type EditorNoteValueChangeObserver = (
export class Editor {
public note?: SNNote;
private application?: MobileApplication;
private noteChangeObservers: EditorNoteChangeObserver[] = [];
private noteValueChangeObservers: EditorNoteValueChangeObserver[] = [];
private removeStreamObserver?: () => void;
public isTemplateNote = false;
constructor(
application: MobileApplication,
noteUuid?: string,
noteTitle?: string
) {
this.application = application;
this.init(noteUuid, noteTitle);
}
constructor(private application: MobileApplication) {}
async init(noteUuid?: string, noteTitle?: string) {
if (noteUuid) {
@@ -51,7 +43,7 @@ export class Editor {
this.removeStreamObserver = undefined;
this.noteChangeObservers.length = 0;
this.noteValueChangeObservers.length = 0;
this.application = undefined;
(this.application as unknown) = undefined;
}
private handleNoteStream(notes: SNNote[], source?: PayloadSource) {

View File

@@ -20,9 +20,10 @@ export class EditorGroup {
}
}
createEditor(noteUuid?: string, noteTitle?: string) {
async createEditor(noteUuid?: string, noteTitle?: string) {
if (this.application) {
const editor = new Editor(this.application, noteUuid, noteTitle);
const editor = new Editor(this.application);
await editor.init(noteUuid, noteTitle);
this.editors.push(editor);
this.notifyObservers();
}

View File

@@ -289,9 +289,16 @@ export class MobileDeviceInterface extends DeviceInterface {
async getBugsnagOptedOut() {
try {
return (await DefaultPreference.get(BUGSNAG_OPT_OUT_KEY)) === 'true';
/**
* Checking the absense of the 'bugsnagoptout' preference.
* If the value is absent, then error reporting is opt-in by default.
*/
const bugsnagOptedOut =
(await DefaultPreference.get(BUGSNAG_OPT_OUT_KEY)) ?? 'true';
return bugsnagOptedOut === 'true';
} catch {
return false;
return true;
}
}

View File

@@ -157,10 +157,8 @@ export const useSyncStatus = () => {
const [refreshing, setRefreshing] = React.useState(false);
const setStatus = useCallback(
(status?: string, color?: string) => {
application
?.getStatusManager()
.setMessage(SCREEN_NOTES, status ?? '', color);
(status = '') => {
application?.getStatusManager().setMessage(SCREEN_NOTES, status);
},
[application]
);
@@ -172,11 +170,16 @@ export const useSyncStatus = () => {
application!.isEncryptionAvailable() &&
application!.getStorageEncryptionPolicy() ===
StorageEncryptionPolicies.Default;
if (stats.localDataDone) {
if (
stats.localDataCurrent === 0 ||
stats.localDataTotal === 0 ||
stats.localDataDone
) {
setStatus();
return;
}
const notesString = `${stats.localDataCurrent}/${stats.localDataTotal} items...`;
const notesString = `${stats.localDataCurrent}/${stats.localDataTotal} items`;
const loadingStatus = encryption
? `Decrypting ${notesString}`
: `Loading ${notesString}`;
@@ -212,10 +215,12 @@ export const useSyncStatus = () => {
setStatus(
`Syncing ${stats.uploadCompletionCount}/${stats.uploadTotalCount} items...`
);
} else if (!syncStatus.syncInProgress) {
} else if (syncStatus.syncInProgress && !completedInitialSync) {
setStatus('Syncing…');
} else {
setStatus();
}
}, [application, setStatus]);
}, [application, completedInitialSync, setStatus]);
useEffect(() => {
const unsubscribeAppEvents = application?.addEventObserver(
@@ -231,23 +236,14 @@ export const useSyncStatus = () => {
setDecrypting(false);
setLoading(false);
updateLocalDataStatus();
} else if (eventName === ApplicationEvent.WillSync) {
if (application.hasAccount() && !completedInitialSync) {
setStatus('Syncing...');
}
} else if (eventName === ApplicationEvent.CompletedFullSync) {
if (
!completedInitialSync ||
!application?.getAppState().isInTabletMode
) {
setStatus();
}
if (!completedInitialSync) {
if (completedInitialSync) {
setRefreshing(false);
} else {
setCompletedInitialSync(true);
setLoading(false);
} else {
setRefreshing(false);
}
updateSyncStatus();
} else if (eventName === ApplicationEvent.LocalDatabaseReadError) {
application!.alertService!.alert(
'Unable to load local storage. Please restart the app and try again.'
@@ -337,7 +333,7 @@ export const useDeleteNoteWithPrivileges = (
async (permanently: boolean) => {
if (note?.locked) {
application?.alertService.alert(
"This note is locked. If you'd like to delete it, unlock it, and try again."
"This note has editing disabled. If you'd like to delete it, enable editing on it, and try again."
);
return;
}

View File

@@ -84,7 +84,7 @@ export const ComponentView = ({
useEffect(() => {
const warnUnsupportedEditors = async () => {
const doNotShowAgainUnsupportedEditors = application
?.getPrefsService()
?.getLocalPreferences()
.getValue(PrefKey.DoNotShowAgainUnsupportedEditors, false);
if (!doNotShowAgainUnsupportedEditors) {
const confirmed = await application?.alertService?.confirm(
@@ -96,7 +96,7 @@ export const ComponentView = ({
);
if (confirmed) {
application
?.getPrefsService()
?.getLocalPreferences()
.setUserPrefValue(PrefKey.DoNotShowAgainUnsupportedEditors, true);
}
}

View File

@@ -231,6 +231,12 @@ export class Compose extends React.Component<{}, State> {
if (this.editor) {
this.context?.editorGroup?.closeEditor(this.editor);
}
if (this.state.editorComponent) {
this.context?.componentGroup?.deactivateComponent(
this.state.editorComponent,
false
);
}
this.context?.getStatusManager()?.setMessage(SCREEN_COMPOSE, '');
if (this.saveTimeout) {
@@ -407,7 +413,7 @@ export class Compose extends React.Component<{}, State> {
onContentChange = (text: string) => {
if (Platform.OS === 'android' && this.note?.locked) {
this.context?.alertService?.alert(
'This note is locked. Please unlock this note to make changes.'
'This note has editing disabled. Please enable editing on this note to make changes.'
);
return;
}
@@ -433,7 +439,7 @@ export class Compose extends React.Component<{}, State> {
size={16}
color={theme.stylekitBackgroundColor}
/>
<LockedText>Note Locked</LockedText>
<LockedText>Note Editing Disabled</LockedText>
</LockedContainer>
)}
{this.state.webViewError && (

View File

@@ -11,7 +11,7 @@ import { useCustomActionSheet } from '@Style/custom_action_sheet';
import { ELIPSIS } from '@Style/icons';
import { ThemeService } from '@Style/theme_service';
import React, { useCallback, useContext, useLayoutEffect } from 'react';
import { YellowBox } from 'react-native';
import { LogBox } from 'react-native';
import { HeaderButtons, Item } from 'react-navigation-header-buttons';
import {
Container,
@@ -21,7 +21,7 @@ import {
TitleContainer,
} from './NoteHistoryPreview.styled';
YellowBox.ignoreWarnings([
LogBox.ignoreLogs([
'Non-serializable values were found in the navigation state',
]);

View File

@@ -123,7 +123,9 @@ export const NoteCell = ({
callback: () => {
if (note.locked) {
application?.alertService.alert(
"This note is locked. If you'd like to archive it, unlock it, and try again."
`This note has editing disabled. If you'd like to ${
note.archived ? 'unarchive' : 'archive'
} it, enable editing on it, and try again.`
);
return;
}
@@ -135,7 +137,7 @@ export const NoteCell = ({
});
options.push({
text: note.locked ? 'Unlock' : 'Lock',
text: note.locked ? 'Enable editing' : 'Prevent editing',
key: 'lock',
callback: () =>
changeNote(mutator => {
@@ -168,7 +170,7 @@ export const NoteCell = ({
},
},
{
text: 'Delete Permanently',
text: 'Delete permanently',
key: 'delete-forever',
destructive: true,
callback: async () => deleteNote(true),

View File

@@ -49,7 +49,7 @@ export const NoteCellFlags = ({
if (note.locked) {
flags.push({
text: 'Locked',
text: 'Editing Disabled',
color: theme.stylekitNeutralColor,
});
}

View File

@@ -60,18 +60,20 @@ export const Notes = React.memo(
// State
const [sortBy, setSortBy] = useState<CollectionSort>(() =>
application!
.getPrefsService()
.getLocalPreferences()
.getValue(PrefKey.SortNotesBy, CollectionSort.CreatedAt)
);
const [sortReverse, setSortReverse] = useState<boolean>(() =>
application!.getPrefsService().getValue(PrefKey.SortNotesReverse, false)
application!
.getLocalPreferences()
.getValue(PrefKey.SortNotesReverse, false)
);
const [hideDates, setHideDates] = useState<boolean>(() =>
application!.getPrefsService().getValue(PrefKey.NotesHideDate, false)
application!.getLocalPreferences().getValue(PrefKey.NotesHideDate, false)
);
const [hidePreviews, setHidePreviews] = useState<boolean>(() =>
application!
.getPrefsService()
.getLocalPreferences()
.getValue(PrefKey.NotesHideNotePreview, false)
);
const [notes, setNotes] = useState<SNNote[]>([]);
@@ -485,18 +487,18 @@ export const Notes = React.memo(
const reloadPreferences = useCallback(async () => {
const newSortBy = application
?.getPrefsService()
?.getLocalPreferences()
.getValue(PrefKey.SortNotesBy, CollectionSort.CreatedAt);
let displayOptionsChanged = false;
const newSortReverse = application
?.getPrefsService()
?.getLocalPreferences()
.getValue(PrefKey.SortNotesReverse, false);
const newHidePreview = application!
.getPrefsService()
.getLocalPreferences()
.getValue(PrefKey.NotesHideNotePreview, false);
const newHideDate = application!
.getPrefsService()
.getLocalPreferences()
.getValue(PrefKey.NotesHideDate, false);
if (sortBy !== newSortBy) {

View File

@@ -28,7 +28,7 @@ type Props = {
export const CompanySection = (props: Props) => {
const application = useContext(ApplicationContext);
const [bugsnagOptOut, setBugsnagOptOut] = useState(false);
const [bugsnagOptOut, setBugsnagOptOut] = useState(true);
const storeName = Platform.OS === 'android' ? 'Play Store' : 'App Store';
const openUrl = (action: keyof typeof URLS) => {

View File

@@ -12,6 +12,8 @@ import { SCREEN_MANAGE_SESSIONS, SCREEN_SETTINGS } from '@Screens/screens';
import { ButtonType } from '@standardnotes/snjs';
import moment from 'moment';
import React, { useCallback, useContext, useMemo, useState } from 'react';
import DocumentPicker from 'react-native-document-picker';
import RNFS from 'react-native-fs';
type Props = {
title: string;
@@ -27,9 +29,12 @@ export const OptionsSection = ({ title, encryptionAvailable }: Props) => {
>();
// State
const [importing, setImporting] = useState(false);
const [exporting, setExporting] = useState(false);
const [lastExportDate, setLastExportDate] = useState<Date | undefined>(() =>
application?.getPrefsService().getValue(PrefKey.LastExportDate, undefined)
application
?.getLocalPreferences()
.getValue(PrefKey.LastExportDate, undefined)
);
const lastExportData = useMemo(() => {
@@ -93,7 +98,7 @@ export const OptionsSection = ({ title, encryptionAvailable }: Props) => {
const exportDate = new Date();
setLastExportDate(exportDate);
application
?.getPrefsService()
?.getLocalPreferences()
.setUserPrefValue(PrefKey.LastExportDate, exportDate);
}
setExporting(false);
@@ -101,6 +106,65 @@ export const OptionsSection = ({ title, encryptionAvailable }: Props) => {
[application]
);
const readImportFile = async (fileUri: string): Promise<any> => {
return RNFS.readFile(fileUri)
.then(result => JSON.parse(result))
.catch(() => {
application!.alertService!.alert(
'Unable to open file. Ensure it is a proper JSON file and try again.'
);
});
};
const performImport = async (data: any) => {
const result = await application!.importData(data);
if (!result) {
return;
} else if ('error' in result) {
application!.alertService!.alert(result.error);
} else if (result.errorCount) {
application!.alertService!.alert(
`Import complete. ${result.errorCount} items were not imported because ` +
'there was an error decrypting them. Make sure the password is correct and try again.'
);
} else {
application!.alertService!.alert(
'Your data has been successfully imported.'
);
}
};
const onImportPress = async () => {
try {
const selectedFile = await DocumentPicker.pick({
type: [DocumentPicker.types.plainText],
});
const data = await readImportFile(selectedFile.uri);
if (!data) {
return;
}
setImporting(true);
if (data.version || data.auth_params || data.keyParams) {
const version =
data.version || data.keyParams?.version || data.auth_params?.version;
if (
application!.protocolService.supportedVersions().includes(version)
) {
await performImport(data);
} else {
application!.alertService.alert(
'This backup file was created using an unsupported version of the application ' +
'and cannot be imported here. Please update your application and try again.'
);
}
} else {
await performImport(data);
}
} finally {
setImporting(false);
}
};
const onExportPress = useCallback(
async (option: { key: string }) => {
let encrypted = option.key === 'encrypted';
@@ -152,9 +216,16 @@ export const OptionsSection = ({ title, encryptionAvailable }: Props) => {
</>
)}
<ButtonCell
testID="importData"
first={!signedIn}
leftAligned
title={importing ? 'Processing...' : 'Import Data'}
onPress={onImportPress}
/>
<SectionedOptionsTableCell
testID="exportData"
first={!signedIn}
leftAligned
options={exportOptions}
title={exporting ? 'Processing...' : 'Export Data'}

View File

@@ -13,17 +13,19 @@ export const PreferencesSection = () => {
// State
const [sortBy, setSortBy] = useState<CollectionSort>(() =>
application!
.getPrefsService()
.getLocalPreferences()
.getValue(PrefKey.SortNotesBy, CollectionSort.CreatedAt)
);
const [sortReverse, setSortReverse] = useState<boolean>(() =>
application!.getPrefsService().getValue(PrefKey.SortNotesReverse, false)
application!.getLocalPreferences().getValue(PrefKey.SortNotesReverse, false)
);
const [hideDates, setHideDates] = useState<boolean>(() =>
application!.getPrefsService().getValue(PrefKey.NotesHideDate, false)
application!.getLocalPreferences().getValue(PrefKey.NotesHideDate, false)
);
const [hidePreviews, setHidePreviews] = useState<boolean>(() =>
application!.getPrefsService().getValue(PrefKey.NotesHideNotePreview, false)
application!
.getLocalPreferences()
.getValue(PrefKey.NotesHideNotePreview, false)
);
const sortOptions = useMemo(() => {
@@ -36,24 +38,26 @@ export const PreferencesSection = () => {
const toggleReverseSort = () => {
application
?.getPrefsService()
?.getLocalPreferences()
.setUserPrefValue(PrefKey.SortNotesReverse, !sortReverse);
setSortReverse(value => !value);
};
const changeSortOption = (key: CollectionSort) => {
application?.getPrefsService().setUserPrefValue(PrefKey.SortNotesBy, key);
application
?.getLocalPreferences()
.setUserPrefValue(PrefKey.SortNotesBy, key);
setSortBy(key);
};
const toggleNotesPreviewHidden = () => {
application
?.getPrefsService()
?.getLocalPreferences()
.setUserPrefValue(PrefKey.NotesHideNotePreview, !hidePreviews);
setHidePreviews(value => !value);
};
const toggleNotesDateHidden = () => {
application
?.getPrefsService()
?.getLocalPreferences()
.setUserPrefValue(PrefKey.NotesHideDate, !hideDates);
setHideDates(value => !value);
};

View File

@@ -1,5 +1,6 @@
import { Platform, SafeAreaView, ScrollView, StatusBar } from 'react-native';
import styled, { css } from 'styled-components/native';
import { useMemo } from 'react';
import { Platform, SafeAreaView, StatusBar, StyleSheet } from 'react-native';
import styled, { css, DefaultTheme } from 'styled-components/native';
// We want top color to be different from bottom color of safe area.
// See https://stackoverflow.com/questions/47725607/react-native-safeareaview-background-color-how-to-assign-two-different-backgro
@@ -16,8 +17,18 @@ export const MainSafeAreaView = styled(SafeAreaView)`
background-color: ${({ theme }) => theme.stylekitBackgroundColor};
color: ${({ theme }) => theme.stylekitForegroundColor};
`;
export const SideMenuSectionContainer = styled(ScrollView)`
padding: 15px;
flex: 1;
background-color: ${({ theme }) => theme.stylekitBackgroundColor};
`;
/** Styled doesn't support FlatList types */
export const useStyles = (theme: DefaultTheme) => {
return useMemo(
() =>
StyleSheet.create({
sections: {
padding: 15,
flex: 1,
backgroundColor: theme.stylekitBackgroundColor,
},
}),
[theme.stylekitBackgroundColor]
);
};

View File

@@ -23,13 +23,14 @@ import React, {
} from 'react';
import { Platform } from 'react-native';
import FAB from 'react-native-fab';
import { FlatList } from 'react-native-gesture-handler';
import DrawerLayout from 'react-native-gesture-handler/DrawerLayout';
import Icon from 'react-native-vector-icons/Ionicons';
import { ThemeContext } from 'styled-components/native';
import {
FirstSafeAreaView,
MainSafeAreaView,
SideMenuSectionContainer,
useStyles,
} from './MainSideMenu.styled';
import { SideMenuHero } from './SideMenuHero';
import { SideMenuOption, SideMenuSection } from './SideMenuSection';
@@ -51,6 +52,7 @@ export const MainSideMenu = React.memo(({ drawerRef }: Props) => {
application!.getAppState().getSelectedTag()
);
const [themes, setThemes] = useState<SNTheme[]>([]);
const styles = useStyles(theme);
useEffect(() => {
const removeTagChangeObserver = application!
@@ -239,15 +241,18 @@ export const MainSideMenu = React.memo(({ drawerRef }: Props) => {
onThemeSelect,
]);
const onTagSelect = async (tag: SNTag) => {
if (tag.conflictOf) {
application!.changeAndSaveItem(tag.uuid, mutator => {
mutator.conflictOf = undefined;
});
}
application!.getAppState().setSelectedTag(tag, true);
drawerRef?.closeDrawer();
};
const onTagSelect = useCallback(
async (tag: SNTag) => {
if (tag.conflictOf) {
application!.changeAndSaveItem(tag.uuid, mutator => {
mutator.conflictOf = undefined;
});
}
application?.getAppState().setSelectedTag(tag, true);
drawerRef?.closeDrawer();
},
[application, drawerRef]
);
const openSettings = () => {
drawerRef?.closeDrawer();
@@ -271,6 +276,10 @@ export const MainSideMenu = React.memo(({ drawerRef }: Props) => {
}
};
const selectedTags = useMemo(() => (selectedTag ? [selectedTag] : []), [
selectedTag,
]);
return (
<Fragment>
<FirstSafeAreaView />
@@ -280,33 +289,46 @@ export const MainSideMenu = React.memo(({ drawerRef }: Props) => {
onPress={openSettings}
onOutOfSyncPress={outOfSyncPressed}
/>
<SideMenuSectionContainer>
<SideMenuSection
title="Themes"
key="themes-section"
options={themeOptions}
collapsed={true}
/>
<SideMenuSection title="Views" key="views-section">
<TagSelectionList
key="views-section-list"
contentType={ContentType.SmartTag}
onTagSelect={onTagSelect}
selectedTags={selectedTag ? [selectedTag] : []}
/>
</SideMenuSection>
<SideMenuSection title="Tags" key="tags-section">
<TagSelectionList
key="tags-section-list"
hasBottomPadding={Platform.OS === 'android'}
emptyPlaceholder={'No tags. Create one from the note composer.'}
contentType={ContentType.Tag}
onTagSelect={onTagSelect}
selectedTags={selectedTag ? [selectedTag] : []}
/>
</SideMenuSection>
</SideMenuSectionContainer>
<FlatList
style={styles.sections}
data={['themes-section', 'views-section', 'tags-section'].map(
key => ({
key,
themeOptions,
onTagSelect,
selectedTags,
})
)}
renderItem={({ item, index }) => {
return index === 0 ? (
<SideMenuSection
title="Themes"
options={item.themeOptions}
collapsed={true}
/>
) : index === 1 ? (
<SideMenuSection title="Views">
<TagSelectionList
contentType={ContentType.SmartTag}
onTagSelect={item.onTagSelect}
selectedTags={item.selectedTags}
/>
</SideMenuSection>
) : index === 2 ? (
<SideMenuSection title="Tags">
<TagSelectionList
hasBottomPadding={Platform.OS === 'android'}
emptyPlaceholder={
'No tags. Create one from the note composer.'
}
contentType={ContentType.Tag}
onTagSelect={item.onTagSelect}
selectedTags={item.selectedTags}
/>
</SideMenuSection>
) : null;
}}
/>
<FAB
buttonColor={theme.stylekitInfoColor}
iconTextColor={theme.stylekitInfoContrastColor}

View File

@@ -1,6 +1,8 @@
import { useMemo } from 'react';
import { StyleSheet } from 'react-native';
import { ScrollView } from 'react-native-gesture-handler';
import { SafeAreaView } from 'react-native-safe-area-context';
import styled from 'styled-components/native';
import styled, { DefaultTheme } from 'styled-components/native';
export const SafeAreaContainer = styled(SafeAreaView)`
flex: 1;
@@ -12,3 +14,16 @@ export const StyledList = styled(ScrollView)`
padding: 15px;
background-color: ${({ theme }) => theme.stylekitBackgroundColor};
`;
export const useStyles = (theme: DefaultTheme) => {
return useMemo(
() =>
StyleSheet.create({
sections: {
padding: 15,
backgroundColor: theme.stylekitBackgroundColor,
},
}),
[theme.stylekitBackgroundColor]
);
};

View File

@@ -1,3 +1,4 @@
import { associateComponentWithNote } from '@Lib/component_manager';
import { Editor } from '@Lib/editor';
import {
useChangeNote,
@@ -46,10 +47,11 @@ import React, {
} from 'react';
import { Platform, Share } from 'react-native';
import FAB from 'react-native-fab';
import { FlatList } from 'react-native-gesture-handler';
import DrawerLayout from 'react-native-gesture-handler/DrawerLayout';
import Icon from 'react-native-vector-icons/Ionicons';
import { ThemeContext } from 'styled-components/native';
import { SafeAreaContainer, StyledList } from './NoteSideMenu.styled';
import { SafeAreaContainer, useStyles } from './NoteSideMenu.styled';
import { SideMenuOption, SideMenuSection } from './SideMenuSection';
import { TagSelectionList } from './TagSelectionList';
@@ -64,6 +66,32 @@ type Props = {
drawerOpen: boolean;
};
function useEditorComponents(): SNComponent[] {
const application = useContext(ApplicationContext);
const [components, setComponents] = useState<SNComponent[]>([]);
useEffect(() => {
if (!application) {
return;
}
const removeComponentsObserver = application.streamItems(
ContentType.Component,
() => {
const displayComponents = sortAlphabetically(
application.componentManager.componentsForArea(ComponentArea.Editor)
);
setComponents(displayComponents);
}
);
return () => {
if (application) {
removeComponentsObserver();
}
};
}, [application]);
return components;
}
export const NoteSideMenu = React.memo((props: Props) => {
// Context
const theme = useContext(ThemeContext);
@@ -72,12 +100,13 @@ export const NoteSideMenu = React.memo((props: Props) => {
AppStackNavigationProp<typeof SCREEN_COMPOSE>['navigation']
>();
const { showActionSheet } = useCustomActionSheet();
const styles = useStyles(theme);
// State
const [editor, setEditor] = useState<Editor | undefined>(undefined);
const [note, setNote] = useState<SNNote | undefined>(undefined);
const [selectedTags, setSelectedTags] = useState<SNTag[]>([]);
const [components, setComponents] = useState<SNComponent[]>([]);
const components = useEditorComponents();
const [changeNote] = useChangeNote(note, editor);
const [protectOrUnprotectNote] = useProtectOrUnprotectNote(note, editor);
@@ -168,29 +197,6 @@ export const NoteSideMenu = React.memo((props: Props) => {
};
}, [editor, note?.uuid, props.drawerOpen, reloadTags]);
useEffect(() => {
let isMounted = true;
const removeComponentsObserver = application?.streamItems(
ContentType.Component,
async () => {
if (!note) {
return;
}
const displayComponents = sortAlphabetically(
application!.componentManager!.componentsForArea(ComponentArea.Editor)
);
if (isMounted && props.drawerOpen) {
setComponents(displayComponents);
}
}
);
return () => {
isMounted = false;
removeComponentsObserver && removeComponentsObserver();
};
}, [application, note, props.drawerOpen]);
useEffect(() => {
let isMounted = true;
const removeTagsObserver = application?.streamItems(ContentType.Tag, () => {
@@ -220,31 +226,21 @@ export const NoteSideMenu = React.memo((props: Props) => {
[application, note]
);
const associateComponentWithCurrentNote = useCallback(
async (component: SNComponent) => {
if (note) {
return application?.changeItem(component.uuid, m => {
const mutator = m as ComponentMutator;
mutator.removeDisassociatedItemId(note.uuid);
mutator.associateWithItem(note.uuid);
});
}
},
[application, note]
);
const onEditorPress = useCallback(
async (selectedComponent?: SNComponent) => {
if (!note || !application) {
return;
}
if (note?.locked) {
application?.alertService.alert(
"This note is locked. If you'd like to edit its options, unlock it, and try again."
"This note has editing disabled. If you'd like to edit its options, enable editing on it, and try again."
);
return;
}
if (editor?.isTemplateNote) {
await editor?.insertTemplatedNote();
}
const activeEditorComponent = application?.componentManager!.editorForNote(
const activeEditorComponent = application.componentManager!.editorForNote(
note!
);
props.drawerRef?.closeDrawer();
@@ -273,14 +269,13 @@ export const NoteSideMenu = React.memo((props: Props) => {
noteMutator.prefersPlainEditor = false;
});
}
await associateComponentWithCurrentNote(selectedComponent);
await associateComponentWithNote(application, selectedComponent, note);
}
/** Dirtying can happen above */
application?.sync();
},
[
application,
associateComponentWithCurrentNote,
disassociateComponentWithCurrentNote,
editor,
note,
@@ -355,11 +350,11 @@ export const NoteSideMenu = React.memo((props: Props) => {
[application, showActionSheet]
);
const editorComponents = useMemo(() => {
if (!note) {
const editors = useMemo(() => {
if (!note || !application) {
return [];
}
const componentEditor = application?.componentManager!.editorForNote(note);
const componentEditor = application.componentManager.editorForNote(note);
const options: SideMenuOption[] = [
{
text: 'Plain Editor',
@@ -378,7 +373,7 @@ export const NoteSideMenu = React.memo((props: Props) => {
text: component.name,
subtext: component.isMobileDefault ? 'Mobile Default' : undefined,
key: component.uuid || component.name,
selected: component === componentEditor,
selected: component.uuid === componentEditor?.uuid,
onSelect: () => {
onEditorPress(component);
},
@@ -405,14 +400,7 @@ export const NoteSideMenu = React.memo((props: Props) => {
});
}
return options;
}, [
note,
application?.componentManager,
application?.deviceInterface,
components,
onEditorPress,
onEdtiorLongPress,
]);
}, [note, application, components, onEditorPress, onEdtiorLongPress]);
useFocusEffect(
useCallback(() => {
@@ -447,7 +435,7 @@ export const NoteSideMenu = React.memo((props: Props) => {
const archiveEvent = () => {
if (note.locked) {
application?.alertService.alert(
"This note is locked. If you'd like to archive it, unlock it, and try again."
`This note has editing disabled. If you'd like to ${archiveOption.toLowerCase()} it, enable editing on it, and try again.`
);
return;
}
@@ -457,7 +445,7 @@ export const NoteSideMenu = React.memo((props: Props) => {
leaveEditor();
};
const lockOption = note.locked ? 'Unlock' : 'Lock';
const lockOption = note.locked ? 'Enable editing' : 'Prevent editing';
const lockEvent = () =>
changeNote(mutator => {
mutator.locked = !note.locked;
@@ -532,7 +520,7 @@ export const NoteSideMenu = React.memo((props: Props) => {
},
},
{
text: 'Delete Permanently',
text: 'Delete permanently',
textClass: 'danger' as 'danger',
key: 'delete-forever',
onSelect: async () => deleteNote(true),
@@ -604,31 +592,41 @@ export const NoteSideMenu = React.memo((props: Props) => {
return (
<SafeAreaContainer edges={['top', 'bottom', 'right']}>
<StyledList>
<SideMenuSection
title="Options"
key="options-section"
options={noteOptions}
/>
<SideMenuSection
title="Editors"
key="editors-section"
options={editorComponents}
collapsed={true}
/>
<SideMenuSection title="Tags" key="tags-section">
<TagSelectionList
key="tags-section-list"
hasBottomPadding={Platform.OS === 'android'}
contentType={ContentType.Tag}
onTagSelect={onTagSelect}
selectedTags={selectedTags}
emptyPlaceholder={
'Create a new tag using the tag button in the bottom right corner.'
}
/>
</SideMenuSection>
</StyledList>
<FlatList
style={styles.sections}
data={['options-section', 'editors-section', 'tags-section'].map(
key => ({
key,
noteOptions,
editorComponents: editors,
onTagSelect,
selectedTags,
})
)}
renderItem={({ item, index }) =>
index === 0 ? (
<SideMenuSection title="Options" options={item.noteOptions} />
) : index === 1 ? (
<SideMenuSection
title="Editors"
options={item.editorComponents}
collapsed={true}
/>
) : index === 2 ? (
<SideMenuSection title="Tags">
<TagSelectionList
hasBottomPadding={Platform.OS === 'android'}
contentType={ContentType.Tag}
onTagSelect={item.onTagSelect}
selectedTags={item.selectedTags}
emptyPlaceholder={
'Create a new tag using the tag button in the bottom right corner.'
}
/>
</SideMenuSection>
) : null
}
/>
<FAB
buttonColor={theme.stylekitInfoColor}

1741
yarn.lock
View File

File diff suppressed because it is too large Load Diff