diff --git a/.env.default b/.env.default index f67e0b178d..d4a1bb3479 100644 --- a/.env.default +++ b/.env.default @@ -1,4 +1,3 @@ -BOOST_NOTE_BASE_URL=https://note.boostio.co BOOST_HUB_BASE_URL=https://boosthub.io AMPLIFY_AUTH_IDENTITY_POOL_ID= diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000000..2cf9b310c9 --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,16 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties +/app/release diff --git a/android/app/.gitignore b/android/app/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/android/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000000..e8d49bedcf --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,49 @@ +plugins { + id 'com.android.application' + id 'kotlin-android' +} + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.boostio.boostnote2021" + minSdkVersion 19 + targetSdkVersion 30 + versionCode 2 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation 'androidx.core:core-ktx:1.3.1' + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation "androidx.browser:browser:1.3.0" + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:2.0.1' + testImplementation 'junit:junit:4.+' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' +} + +repositories { +} \ No newline at end of file diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/android/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/android/app/src/androidTest/java/com/boostio/boostnote/ExampleInstrumentedTest.kt b/android/app/src/androidTest/java/com/boostio/boostnote/ExampleInstrumentedTest.kt new file mode 100644 index 0000000000..3429d8163d --- /dev/null +++ b/android/app/src/androidTest/java/com/boostio/boostnote/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.boostio.boostnote + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.boostio.boostnote", appContext.packageName) + } +} \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..4f19f90248 --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/java/com/boostio/boostnote/MainActivity.kt b/android/app/src/main/java/com/boostio/boostnote/MainActivity.kt new file mode 100644 index 0000000000..7e6d9e4c2e --- /dev/null +++ b/android/app/src/main/java/com/boostio/boostnote/MainActivity.kt @@ -0,0 +1,163 @@ +//package com.boostio.boostnote +// +//import androidx.appcompat.app.AppCompatActivity +//import android.os.Bundle +// +//class MainActivity : AppCompatActivity() { +// override fun onCreate(savedInstanceState: Bundle?) { +// super.onCreate(savedInstanceState) +// setContentView(R.layout.activity_main) +// } +//} + +package com.boostio.boostnote2021 + +import android.app.AlertDialog +import android.content.Context +import android.content.DialogInterface +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.util.Log +import android.webkit.* +import android.webkit.WebView +//import androidx.annotation.RequiresApi +import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContextCompat.startActivity + + + +class MainActivity : AppCompatActivity() { + val ctx: AppCompatActivity = this + + val authStatePreferencesKey = "com.boostio.boostnote.authState" +// val mobileBaseUrl = "http://localhost:3005" + val mobileBaseUrl = "https://m.boostnote.io" + private var webviewReloadAlertDialog: AlertDialog? = null + + class WebAppInterface(private val mContext: MainActivity) { + + @JavascriptInterface + fun openUrl(url: String) { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + startActivity(mContext, intent, null); + } + @JavascriptInterface + fun openAuthUrl(url: String, state: String) { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + + val sharedPref = mContext.getPreferences(Context.MODE_PRIVATE) + with (sharedPref.edit()) { + putString(mContext.authStatePreferencesKey, state) + apply() + } + startActivity(mContext, intent, null); + } + } + + fun showReloadDialog(description: String?) { + if (this.webviewReloadAlertDialog != null) { + return + } + val builder = AlertDialog.Builder(this) + + builder.setMessage("Choose OK to reload the app") + .setTitle("""Error $description""") + .setPositiveButton("OK", DialogInterface.OnClickListener { _, _ -> + this.webviewReloadAlertDialog = null + val view = findViewById(R.id.webview); + view?.reload() + }) + .setCancelable(false) + + this.webviewReloadAlertDialog = builder.create() + this.webviewReloadAlertDialog!!.show() + } + + + override fun onCreate(savedInstanceState: Bundle?) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + WebView.setWebContentsDebuggingEnabled(true); + } + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main); + + val view = findViewById(R.id.webview); + val settings = view.settings; + settings.javaScriptEnabled = true; + settings.allowContentAccess = true; + settings.domStorageEnabled = true; + settings.userAgentString = settings.userAgentString + " BoostNote-Mobile-Android" + + view.webViewClient = object: WebViewClient() { +// override fun onReceivedError( +// view: WebView?, +// errorCode: Int, +// description: String?, +// failingUrl: String? +// ) { +// super.onReceivedError(view, errorCode, description, failingUrl) +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ return } +// +// this@MainActivity.showReloadDialog(description) +// } +// +// @RequiresApi(Build.VERSION_CODES.M) +// override fun onReceivedError( +// view: WebView?, +// request: WebResourceRequest?, +// error: WebResourceError? +// ) { +// super.onReceivedError(view, request, error) +// +// this@MainActivity.showReloadDialog(error?.description as String) +// } + } + view.webChromeClient = object : WebChromeClient() { + override fun onConsoleMessage(message: String, lineNumber: Int, sourceID: String) { + Log.d("WebView", "$message -- From line $lineNumber of $sourceID") + } + } + view.addJavascriptInterface(WebAppInterface(this), "Android") + + this.handleIntent(intent) + } + + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + + Log.d("Yolo","from new intent"); + this.handleIntent(intent) + } + + fun handleIntent(intent: Intent) { + if ( + !this.resolveAuthIntent(intent)) { + + val view = findViewById(R.id.webview); + view.loadUrl(this.mobileBaseUrl); + } + } + + fun resolveAuthIntent(intent: Intent):Boolean { + val sharedPref = this.getPreferences(Context.MODE_PRIVATE) ?: return false + val state = sharedPref.getString(authStatePreferencesKey, "") + + val data: Uri? = intent.data + + if (state === "") {return false } + if (data == null) {return false} + if (data.host != "boosthub") {return false} + if (data.path != "/login") {return false} + + val code = data.getQueryParameter("code") ?: return false + + val view = findViewById(R.id.webview); + view.loadUrl(this.mobileBaseUrl + "?state=" + state + "&code="+code); + return true + } + + + +} diff --git a/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000000..8d0cd6b5fc --- /dev/null +++ b/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,24 @@ + + + + + + + diff --git a/android/app/src/main/res/drawable/ic_launcher_background.xml b/android/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000000..d4b684b064 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/android/app/src/main/res/layout/activity_main.xml b/android/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000000..fdd03ae94b --- /dev/null +++ b/android/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000000..eca70cfe52 --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000000..eca70cfe52 --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100755 index 0000000000..dc7b4fbb70 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100755 index 0000000000..45975dd5e0 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100755 index 0000000000..386db99218 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100755 index 0000000000..bb7abba16d Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100755 index 0000000000..f0178507ad Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100755 index 0000000000..b5c5f013c5 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100755 index 0000000000..4556c57eb0 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100755 index 0000000000..2db96d4c48 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100755 index 0000000000..68b015659b Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100755 index 0000000000..c3ca84e7a3 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/values-night/themes.xml b/android/app/src/main/res/values-night/themes.xml new file mode 100644 index 0000000000..203e2191be --- /dev/null +++ b/android/app/src/main/res/values-night/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml new file mode 100644 index 0000000000..f8c6127d32 --- /dev/null +++ b/android/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml new file mode 100644 index 0000000000..7cddfc8b44 --- /dev/null +++ b/android/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Boost Note + \ 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 new file mode 100644 index 0000000000..797995d200 --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/android/app/src/main/res/values/themes.xml b/android/app/src/main/res/values/themes.xml new file mode 100644 index 0000000000..eebc2d049b --- /dev/null +++ b/android/app/src/main/res/values/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/android/app/src/test/java/com/boostio/boostnote/ExampleUnitTest.kt b/android/app/src/test/java/com/boostio/boostnote/ExampleUnitTest.kt new file mode 100644 index 0000000000..cba64f56dd --- /dev/null +++ b/android/app/src/test/java/com/boostio/boostnote/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.boostio.boostnote + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000000..3d258a9070 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,27 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + ext.kotlin_version = "1.5.20" + repositories { + google() + mavenCentral() + } + dependencies { + classpath "com.android.tools.build:gradle:4.2.2" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + google() + mavenCentral() + jcenter() // Warning: this repository is going to shut down soon + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} \ No newline at end of file diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000000..252175276f --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,19 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app"s APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Kotlin code style for this project: "official" or "obsolete": +kotlin.code.style=official \ No newline at end of file diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..f6b961fd5a Binary files /dev/null and b/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..8e20b040e0 --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Jul 12 06:54:57 JST 2021 +distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip +distributionPath=wrapper/dists +zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/android/gradlew b/android/gradlew new file mode 100755 index 0000000000..cccdd3d517 --- /dev/null +++ b/android/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/android/gradlew.bat b/android/gradlew.bat new file mode 100644 index 0000000000..e95643d6a2 --- /dev/null +++ b/android/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000000..eb38b39808 --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = "Boost Note" +include ':app' diff --git a/docs/development.md b/docs/development.md index aded056d3e..901b166f4a 100644 --- a/docs/development.md +++ b/docs/development.md @@ -2,7 +2,6 @@ ``` NODE_ENV=production -BOOST_NOTE_BASE_URL=https://note.boostio.co BOOST_HUB_BASE_URL= SSE_URL= diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000000..330d1674f3 --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,90 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## User settings +xcuserdata/ + +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) +*.xcscmblueprint +*.xccheckout + +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) +build/ +DerivedData/ +*.moved-aside +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 + +## Obj-C/Swift specific +*.hmap + +## App packaging +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +# *.xcodeproj +# +# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata +# hence it is not needed unless you have added a package configuration file to your project +# .swiftpm + +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ +# +# Add this line if you want to avoid checking in source code from the Xcode workspace +# *.xcworkspace + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build/ + +# Accio dependency management +Dependencies/ +.accio/ + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. +# Instead, use fastlane to re-generate the screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output + +# Code Injection +# +# After new code Injection tools there's a generated folder /iOSInjectionProject +# https://github.com/johnno1962/injectionforxcode + +iOSInjectionProject/ diff --git a/ios/BoostNoteMobile/BoostNoteMobile.xcodeproj/project.pbxproj b/ios/BoostNoteMobile/BoostNoteMobile.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..2f41df9540 --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobile.xcodeproj/project.pbxproj @@ -0,0 +1,852 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 08E6257A26996209003B4DCE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08E6257926996209003B4DCE /* AppDelegate.swift */; }; + 08E6257C26996209003B4DCE /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08E6257B26996209003B4DCE /* SceneDelegate.swift */; }; + 08E6257E26996209003B4DCE /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08E6257D26996209003B4DCE /* ViewController.swift */; }; + 08E6258126996209003B4DCE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 08E6257F26996209003B4DCE /* Main.storyboard */; }; + 08E625832699620B003B4DCE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 08E625822699620B003B4DCE /* Assets.xcassets */; }; + 08E625862699620B003B4DCE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 08E625842699620B003B4DCE /* LaunchScreen.storyboard */; }; + 08E625912699620B003B4DCE /* BoostNoteMobileTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08E625902699620B003B4DCE /* BoostNoteMobileTests.swift */; }; + 08E6259C2699620B003B4DCE /* BoostNoteMobileUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08E6259B2699620B003B4DCE /* BoostNoteMobileUITests.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 08E6258D2699620B003B4DCE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08E6256E26996209003B4DCE /* Project object */; + proxyType = 1; + remoteGlobalIDString = 08E6257526996209003B4DCE; + remoteInfo = BoostNoteMobile; + }; + 08E625982699620B003B4DCE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08E6256E26996209003B4DCE /* Project object */; + proxyType = 1; + remoteGlobalIDString = 08E6257526996209003B4DCE; + remoteInfo = BoostNoteMobile; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 08E6257626996209003B4DCE /* BoostNoteMobile.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BoostNoteMobile.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 08E6257926996209003B4DCE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 08E6257B26996209003B4DCE /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 08E6257D26996209003B4DCE /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 08E6258026996209003B4DCE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 08E625822699620B003B4DCE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 08E625852699620B003B4DCE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 08E625872699620B003B4DCE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 08E6258C2699620B003B4DCE /* BoostNoteMobileTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BoostNoteMobileTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 08E625902699620B003B4DCE /* BoostNoteMobileTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoostNoteMobileTests.swift; sourceTree = ""; }; + 08E625922699620B003B4DCE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 08E625972699620B003B4DCE /* BoostNoteMobileUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BoostNoteMobileUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 08E6259B2699620B003B4DCE /* BoostNoteMobileUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoostNoteMobileUITests.swift; sourceTree = ""; }; + 08E6259D2699620B003B4DCE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 08E6257326996209003B4DCE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 08E625892699620B003B4DCE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 08E625942699620B003B4DCE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 08E6256D26996209003B4DCE = { + isa = PBXGroup; + children = ( + 08E6257826996209003B4DCE /* BoostNoteMobile */, + 08E6258F2699620B003B4DCE /* BoostNoteMobileTests */, + 08E6259A2699620B003B4DCE /* BoostNoteMobileUITests */, + 08E6257726996209003B4DCE /* Products */, + ); + sourceTree = ""; + }; + 08E6257726996209003B4DCE /* Products */ = { + isa = PBXGroup; + children = ( + 08E6257626996209003B4DCE /* BoostNoteMobile.app */, + 08E6258C2699620B003B4DCE /* BoostNoteMobileTests.xctest */, + 08E625972699620B003B4DCE /* BoostNoteMobileUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 08E6257826996209003B4DCE /* BoostNoteMobile */ = { + isa = PBXGroup; + children = ( + 08E6257926996209003B4DCE /* AppDelegate.swift */, + 08E6257B26996209003B4DCE /* SceneDelegate.swift */, + 08E6257D26996209003B4DCE /* ViewController.swift */, + 08E6257F26996209003B4DCE /* Main.storyboard */, + 08E625822699620B003B4DCE /* Assets.xcassets */, + 08E625842699620B003B4DCE /* LaunchScreen.storyboard */, + 08E625872699620B003B4DCE /* Info.plist */, + ); + path = BoostNoteMobile; + sourceTree = ""; + }; + 08E6258F2699620B003B4DCE /* BoostNoteMobileTests */ = { + isa = PBXGroup; + children = ( + 08E625902699620B003B4DCE /* BoostNoteMobileTests.swift */, + 08E625922699620B003B4DCE /* Info.plist */, + ); + path = BoostNoteMobileTests; + sourceTree = ""; + }; + 08E6259A2699620B003B4DCE /* BoostNoteMobileUITests */ = { + isa = PBXGroup; + children = ( + 08E6259B2699620B003B4DCE /* BoostNoteMobileUITests.swift */, + 08E6259D2699620B003B4DCE /* Info.plist */, + ); + path = BoostNoteMobileUITests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 08E6257526996209003B4DCE /* BoostNoteMobile */ = { + isa = PBXNativeTarget; + buildConfigurationList = 08E625A02699620B003B4DCE /* Build configuration list for PBXNativeTarget "BoostNoteMobile" */; + buildPhases = ( + 08E6257226996209003B4DCE /* Sources */, + 08E6257326996209003B4DCE /* Frameworks */, + 08E6257426996209003B4DCE /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = BoostNoteMobile; + productName = BoostNoteMobile; + productReference = 08E6257626996209003B4DCE /* BoostNoteMobile.app */; + productType = "com.apple.product-type.application"; + }; + 08E6258B2699620B003B4DCE /* BoostNoteMobileTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 08E625A32699620B003B4DCE /* Build configuration list for PBXNativeTarget "BoostNoteMobileTests" */; + buildPhases = ( + 08E625882699620B003B4DCE /* Sources */, + 08E625892699620B003B4DCE /* Frameworks */, + 08E6258A2699620B003B4DCE /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 08E6258E2699620B003B4DCE /* PBXTargetDependency */, + ); + name = BoostNoteMobileTests; + productName = BoostNoteMobileTests; + productReference = 08E6258C2699620B003B4DCE /* BoostNoteMobileTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 08E625962699620B003B4DCE /* BoostNoteMobileUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 08E625A62699620B003B4DCE /* Build configuration list for PBXNativeTarget "BoostNoteMobileUITests" */; + buildPhases = ( + 08E625932699620B003B4DCE /* Sources */, + 08E625942699620B003B4DCE /* Frameworks */, + 08E625952699620B003B4DCE /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 08E625992699620B003B4DCE /* PBXTargetDependency */, + ); + name = BoostNoteMobileUITests; + productName = BoostNoteMobileUITests; + productReference = 08E625972699620B003B4DCE /* BoostNoteMobileUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 08E6256E26996209003B4DCE /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1250; + LastUpgradeCheck = 1250; + TargetAttributes = { + 08E6257526996209003B4DCE = { + CreatedOnToolsVersion = 12.5.1; + }; + 08E6258B2699620B003B4DCE = { + CreatedOnToolsVersion = 12.5.1; + TestTargetID = 08E6257526996209003B4DCE; + }; + 08E625962699620B003B4DCE = { + CreatedOnToolsVersion = 12.5.1; + TestTargetID = 08E6257526996209003B4DCE; + }; + }; + }; + buildConfigurationList = 08E6257126996209003B4DCE /* Build configuration list for PBXProject "BoostNoteMobile" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 08E6256D26996209003B4DCE; + productRefGroup = 08E6257726996209003B4DCE /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 08E6257526996209003B4DCE /* BoostNoteMobile */, + 08E6258B2699620B003B4DCE /* BoostNoteMobileTests */, + 08E625962699620B003B4DCE /* BoostNoteMobileUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 08E6257426996209003B4DCE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 08E625862699620B003B4DCE /* LaunchScreen.storyboard in Resources */, + 08E625832699620B003B4DCE /* Assets.xcassets in Resources */, + 08E6258126996209003B4DCE /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 08E6258A2699620B003B4DCE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 08E625952699620B003B4DCE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 08E6257226996209003B4DCE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 08E6257E26996209003B4DCE /* ViewController.swift in Sources */, + 08E6257A26996209003B4DCE /* AppDelegate.swift in Sources */, + 08E6257C26996209003B4DCE /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 08E625882699620B003B4DCE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 08E625912699620B003B4DCE /* BoostNoteMobileTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 08E625932699620B003B4DCE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 08E6259C2699620B003B4DCE /* BoostNoteMobileUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 08E6258E2699620B003B4DCE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 08E6257526996209003B4DCE /* BoostNoteMobile */; + targetProxy = 08E6258D2699620B003B4DCE /* PBXContainerItemProxy */; + }; + 08E625992699620B003B4DCE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 08E6257526996209003B4DCE /* BoostNoteMobile */; + targetProxy = 08E625982699620B003B4DCE /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 08E6257F26996209003B4DCE /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 08E6258026996209003B4DCE /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 08E625842699620B003B4DCE /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 08E625852699620B003B4DCE /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 089820D4269D359C0082E4CD /* Release (Staging) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.5; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = "Release (Staging)"; + }; + 089820D5269D359C0082E4CD /* Release (Staging) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 6; + DEVELOPMENT_TEAM = TG7C97ZRU2; + INFOPLIST_FILE = BoostNoteMobile/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.1; + PRODUCT_BUNDLE_IDENTIFIER = "com.boostio.boostnote-2021"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = "Release (Staging)"; + }; + 089820D6269D359C0082E4CD /* Release (Staging) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = TG7C97ZRU2; + INFOPLIST_FILE = BoostNoteMobileTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.5; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = boostio.BoostNoteMobileTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BoostNoteMobile.app/BoostNoteMobile"; + }; + name = "Release (Staging)"; + }; + 089820D7269D359C0082E4CD /* Release (Staging) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = TG7C97ZRU2; + INFOPLIST_FILE = BoostNoteMobileUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = boostio.BoostNoteMobileUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = BoostNoteMobile; + }; + name = "Release (Staging)"; + }; + 089820D8269D35B70082E4CD /* Debug (Local) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.5; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = "Debug (Local)"; + }; + 089820D9269D35B70082E4CD /* Debug (Local) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 6; + DEVELOPMENT_TEAM = TG7C97ZRU2; + INFOPLIST_FILE = BoostNoteMobile/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.1; + PRODUCT_BUNDLE_IDENTIFIER = "com.boostio.boostnote-2021"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = "Debug (Local)"; + }; + 089820DA269D35B70082E4CD /* Debug (Local) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = TG7C97ZRU2; + INFOPLIST_FILE = BoostNoteMobileTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.5; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = boostio.BoostNoteMobileTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BoostNoteMobile.app/BoostNoteMobile"; + }; + name = "Debug (Local)"; + }; + 089820DB269D35B70082E4CD /* Debug (Local) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = TG7C97ZRU2; + INFOPLIST_FILE = BoostNoteMobileUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = boostio.BoostNoteMobileUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = BoostNoteMobile; + }; + name = "Debug (Local)"; + }; + 08E6259E2699620B003B4DCE /* Debug (Staging) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.5; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = "Debug (Staging)"; + }; + 08E6259F2699620B003B4DCE /* Release (Production) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.5; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = "Release (Production)"; + }; + 08E625A12699620B003B4DCE /* Debug (Staging) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 6; + DEVELOPMENT_TEAM = TG7C97ZRU2; + INFOPLIST_FILE = BoostNoteMobile/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.1; + PRODUCT_BUNDLE_IDENTIFIER = "com.boostio.boostnote-2021"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = "Debug (Staging)"; + }; + 08E625A22699620B003B4DCE /* Release (Production) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 6; + DEVELOPMENT_TEAM = TG7C97ZRU2; + INFOPLIST_FILE = BoostNoteMobile/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.1; + PRODUCT_BUNDLE_IDENTIFIER = "com.boostio.boostnote-2021"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = "Release (Production)"; + }; + 08E625A42699620B003B4DCE /* Debug (Staging) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = TG7C97ZRU2; + INFOPLIST_FILE = BoostNoteMobileTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.5; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = boostio.BoostNoteMobileTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BoostNoteMobile.app/BoostNoteMobile"; + }; + name = "Debug (Staging)"; + }; + 08E625A52699620B003B4DCE /* Release (Production) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = TG7C97ZRU2; + INFOPLIST_FILE = BoostNoteMobileTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.5; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = boostio.BoostNoteMobileTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BoostNoteMobile.app/BoostNoteMobile"; + }; + name = "Release (Production)"; + }; + 08E625A72699620B003B4DCE /* Debug (Staging) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = TG7C97ZRU2; + INFOPLIST_FILE = BoostNoteMobileUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = boostio.BoostNoteMobileUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = BoostNoteMobile; + }; + name = "Debug (Staging)"; + }; + 08E625A82699620B003B4DCE /* Release (Production) */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = TG7C97ZRU2; + INFOPLIST_FILE = BoostNoteMobileUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = boostio.BoostNoteMobileUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = BoostNoteMobile; + }; + name = "Release (Production)"; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 08E6257126996209003B4DCE /* Build configuration list for PBXProject "BoostNoteMobile" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 08E6259E2699620B003B4DCE /* Debug (Staging) */, + 089820D8269D35B70082E4CD /* Debug (Local) */, + 08E6259F2699620B003B4DCE /* Release (Production) */, + 089820D4269D359C0082E4CD /* Release (Staging) */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Release (Production)"; + }; + 08E625A02699620B003B4DCE /* Build configuration list for PBXNativeTarget "BoostNoteMobile" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 08E625A12699620B003B4DCE /* Debug (Staging) */, + 089820D9269D35B70082E4CD /* Debug (Local) */, + 08E625A22699620B003B4DCE /* Release (Production) */, + 089820D5269D359C0082E4CD /* Release (Staging) */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Release (Production)"; + }; + 08E625A32699620B003B4DCE /* Build configuration list for PBXNativeTarget "BoostNoteMobileTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 08E625A42699620B003B4DCE /* Debug (Staging) */, + 089820DA269D35B70082E4CD /* Debug (Local) */, + 08E625A52699620B003B4DCE /* Release (Production) */, + 089820D6269D359C0082E4CD /* Release (Staging) */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Release (Production)"; + }; + 08E625A62699620B003B4DCE /* Build configuration list for PBXNativeTarget "BoostNoteMobileUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 08E625A72699620B003B4DCE /* Debug (Staging) */, + 089820DB269D35B70082E4CD /* Debug (Local) */, + 08E625A82699620B003B4DCE /* Release (Production) */, + 089820D7269D359C0082E4CD /* Release (Staging) */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Release (Production)"; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08E6256E26996209003B4DCE /* Project object */; +} diff --git a/ios/BoostNoteMobile/BoostNoteMobile.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/BoostNoteMobile/BoostNoteMobile.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..919434a625 --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobile.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/BoostNoteMobile/BoostNoteMobile.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/BoostNoteMobile/BoostNoteMobile.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000..18d981003d --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobile.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/BoostNoteMobile/BoostNoteMobile.xcodeproj/xcshareddata/xcschemes/BoostNoteMobile.xcscheme b/ios/BoostNoteMobile/BoostNoteMobile.xcodeproj/xcshareddata/xcschemes/BoostNoteMobile.xcscheme new file mode 100644 index 0000000000..91049c6a56 --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobile.xcodeproj/xcshareddata/xcschemes/BoostNoteMobile.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/BoostNoteMobile/BoostNoteMobile/AppDelegate.swift b/ios/BoostNoteMobile/BoostNoteMobile/AppDelegate.swift new file mode 100644 index 0000000000..79c48a3e02 --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobile/AppDelegate.swift @@ -0,0 +1,36 @@ +// +// AppDelegate.swift +// BoostNoteMobile +// +// Created by Junyoung Choi on 7/10/21. +// + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AccentColor.colorset/Contents.json b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000000..eb87897008 --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..8d8f4bb49a --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "ItunesArtwork@2x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000000..36314e5161 Binary files /dev/null and b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000000..0fc3e9791e Binary files /dev/null and b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000..e02ca4f1b3 Binary files /dev/null and b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000000..e6b814734f Binary files /dev/null and b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000..7e5f2b9886 Binary files /dev/null and b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000000..2a346c159d Binary files /dev/null and b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000000..0fc3e9791e Binary files /dev/null and b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000..d35efbfa35 Binary files /dev/null and b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000..e5b61bf74c Binary files /dev/null and b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000..e5b61bf74c Binary files /dev/null and b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000..39d6869b87 Binary files /dev/null and b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000..ae24e6dec8 Binary files /dev/null and b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000000..9a68d43803 Binary files /dev/null and b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000000..e7a2322458 Binary files /dev/null and b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png new file mode 100644 index 0000000000..7e7ec93d7d Binary files /dev/null and b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png differ diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/Contents.json b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/Contents.json new file mode 100644 index 0000000000..73c00596a7 --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobile/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Base.lproj/LaunchScreen.storyboard b/ios/BoostNoteMobile/BoostNoteMobile/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000000..865e9329f3 --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobile/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Base.lproj/Main.storyboard b/ios/BoostNoteMobile/BoostNoteMobile/Base.lproj/Main.storyboard new file mode 100644 index 0000000000..25a763858e --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobile/Base.lproj/Main.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/BoostNoteMobile/BoostNoteMobile/Info.plist b/ios/BoostNoteMobile/BoostNoteMobile/Info.plist new file mode 100644 index 0000000000..bfaea08a75 --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobile/Info.plist @@ -0,0 +1,75 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Boost Note + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + ITSAppUsesNonExemptEncryption + + LSApplicationCategoryType + + LSRequiresIPhoneOS + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/ios/BoostNoteMobile/BoostNoteMobile/SceneDelegate.swift b/ios/BoostNoteMobile/BoostNoteMobile/SceneDelegate.swift new file mode 100644 index 0000000000..1deb34dbb7 --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobile/SceneDelegate.swift @@ -0,0 +1,52 @@ +// +// SceneDelegate.swift +// BoostNoteMobile +// +// Created by Junyoung Choi on 7/10/21. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/ios/BoostNoteMobile/BoostNoteMobile/ViewController.swift b/ios/BoostNoteMobile/BoostNoteMobile/ViewController.swift new file mode 100644 index 0000000000..0fd7bcab18 --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobile/ViewController.swift @@ -0,0 +1,137 @@ +// +// ViewController.swift +// BoostNoteMobile +// +// Created by Junyoung Choi on 7/10/21. +// + +import UIKit +import WebKit +import SafariServices +import AuthenticationServices + + +class ViewController: UIViewController,WKNavigationDelegate, WKScriptMessageHandler, SFSafariViewControllerDelegate, ASWebAuthenticationPresentationContextProviding { + + var webView: WKWebView! + var safariViewController: SFSafariViewController? = nil + var session: ASWebAuthenticationSession? = nil + var mobileBaseUrl = "https://m.boostnote.io" + // var mobileBaseUrl = "http://localhost:3005" + + func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { + guard let body = message.body as? NSDictionary else { return } + guard let type = body.value(forKey: "type") as? String else {return } + + if (type == "open-auth-link") { + guard let state = body.value(forKey: "state") as? String else {return } + + guard let urlString = body.value(forKey: "url") as? String else { return } + + guard let url = URL(string: urlString) else { return } + + let scheme = "boostnote" + // Initialize the session. + session = ASWebAuthenticationSession(url: url, callbackURLScheme: scheme) + { callbackURL, error in + guard error == nil, let callbackURL = callbackURL else { + self.session = nil + return + } + + print(callbackURL, "URL") + self.session!.cancel() + self.session = nil + + let queryItems = URLComponents(string: callbackURL.absoluteString)?.queryItems + let code = queryItems?.filter({ $0.name == "code" }).first?.value + + let script = "window.dispatchEvent(new CustomEvent('native-mobile-auth', {detail: {state:'" + state + "', code: '" + (code ?? "") + "'}}))" + self.webView.evaluateJavaScript(script) { value, error in + return + } + } + session!.prefersEphemeralWebBrowserSession = true + session!.presentationContextProvider = self + session!.start() + } + if (type == "open-link") { + print("open popeneponeopen") + guard let urlString = body.value(forKey: "url") as? String else { return } + guard let url = URL(string: urlString) else { return } + + safariViewController = SFSafariViewController(url: url) + safariViewController!.delegate = self + present(safariViewController!, animated: true, completion: nil) + } + } + + func safariViewControllerDidFinish(_ controller: SFSafariViewController) { + print() + controller.dismiss(animated: true, completion: nil) + safariViewController = nil + } + + func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor { + return view.window! + } + + override func viewDidLoad() { + super.viewDidLoad() + + // 1 + loadUrl() + + // 2 + let refresh = UIBarButtonItem(barButtonSystemItem: .refresh, target: webView, action: #selector(webView.reload)) + toolbarItems = [refresh] + webView.navigationDelegate = self + + } + + private func loadUrl() { + let url = URL(string: mobileBaseUrl)! + webView.load(URLRequest(url: url)) + } + + override func loadView() { + let contentController = WKUserContentController() + contentController.add(self, name: "callback") + + let config = WKWebViewConfiguration() + config.userContentController = contentController + + webView = WKWebView(frame: self.accessibilityFrame, configuration: config) + webView.navigationDelegate = self + + let customUserAgent = webView.value(forKey: "userAgent") as! String + " BoostNote-Mobile-iOS" + webView.customUserAgent = customUserAgent + + webView.allowsLinkPreview = false + + view = webView + } + + func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { + title = webView.title + } + + // Handling error + func webView(_ webView: WKWebView, + didFailProvisionalNavigation navigation: WKNavigation!, + withError error: Error) { + let error = error as NSError + let alert = UIAlertController(title: "Error \(error.code)", message: "Choose OK to refresh", preferredStyle: .alert) + alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "Default action"), style: .default, handler: { _ in + + if webView.url != nil { + webView.reload() + } else { + self.loadUrl() + } + })) + + self.present(alert, animated: true, completion: nil) + } +} + diff --git a/ios/BoostNoteMobile/BoostNoteMobileTests/BoostNoteMobileTests.swift b/ios/BoostNoteMobile/BoostNoteMobileTests/BoostNoteMobileTests.swift new file mode 100644 index 0000000000..f35cc0c653 --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobileTests/BoostNoteMobileTests.swift @@ -0,0 +1,33 @@ +// +// BoostNoteMobileTests.swift +// BoostNoteMobileTests +// +// Created by Junyoung Choi on 7/10/21. +// + +import XCTest +@testable import BoostNoteMobile + +class BoostNoteMobileTests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() throws { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/ios/BoostNoteMobile/BoostNoteMobileTests/Info.plist b/ios/BoostNoteMobile/BoostNoteMobileTests/Info.plist new file mode 100644 index 0000000000..64d65ca495 --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobileTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/ios/BoostNoteMobile/BoostNoteMobileUITests/BoostNoteMobileUITests.swift b/ios/BoostNoteMobile/BoostNoteMobileUITests/BoostNoteMobileUITests.swift new file mode 100644 index 0000000000..af172df8bd --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobileUITests/BoostNoteMobileUITests.swift @@ -0,0 +1,42 @@ +// +// BoostNoteMobileUITests.swift +// BoostNoteMobileUITests +// +// Created by Junyoung Choi on 7/10/21. +// + +import XCTest + +class BoostNoteMobileUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testLaunchPerformance() throws { + if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } + } +} diff --git a/ios/BoostNoteMobile/BoostNoteMobileUITests/Info.plist b/ios/BoostNoteMobile/BoostNoteMobileUITests/Info.plist new file mode 100644 index 0000000000..64d65ca495 --- /dev/null +++ b/ios/BoostNoteMobile/BoostNoteMobileUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/mobile-static/favicon.ico b/mobile-static/favicon.ico new file mode 100644 index 0000000000..bdd6a298a7 Binary files /dev/null and b/mobile-static/favicon.ico differ diff --git a/mobile-static/images/initial/bookmarks1.png b/mobile-static/images/initial/bookmarks1.png new file mode 100644 index 0000000000..5fb592d8ba Binary files /dev/null and b/mobile-static/images/initial/bookmarks1.png differ diff --git a/mobile-static/images/initial/bookmarks2.png b/mobile-static/images/initial/bookmarks2.png new file mode 100644 index 0000000000..8f0f29b3e5 Binary files /dev/null and b/mobile-static/images/initial/bookmarks2.png differ diff --git a/mobile-static/images/initial/bookmarks3.png b/mobile-static/images/initial/bookmarks3.png new file mode 100644 index 0000000000..af81728ad1 Binary files /dev/null and b/mobile-static/images/initial/bookmarks3.png differ diff --git a/mobile-static/images/initial/coauthoring.gif b/mobile-static/images/initial/coauthoring.gif new file mode 100644 index 0000000000..84178970c6 Binary files /dev/null and b/mobile-static/images/initial/coauthoring.gif differ diff --git a/mobile-static/images/initial/coauthoring.jpg b/mobile-static/images/initial/coauthoring.jpg new file mode 100644 index 0000000000..f09a97e0f9 Binary files /dev/null and b/mobile-static/images/initial/coauthoring.jpg differ diff --git a/mobile-static/images/initial/comments1.jpg b/mobile-static/images/initial/comments1.jpg new file mode 100644 index 0000000000..d955f9c8ba Binary files /dev/null and b/mobile-static/images/initial/comments1.jpg differ diff --git a/mobile-static/images/initial/comments2.png b/mobile-static/images/initial/comments2.png new file mode 100644 index 0000000000..5949b350c3 Binary files /dev/null and b/mobile-static/images/initial/comments2.png differ diff --git a/mobile-static/images/initial/comments3.png b/mobile-static/images/initial/comments3.png new file mode 100644 index 0000000000..1cc4a71443 Binary files /dev/null and b/mobile-static/images/initial/comments3.png differ diff --git a/mobile-static/images/initial/comments4.png b/mobile-static/images/initial/comments4.png new file mode 100644 index 0000000000..283a1ef506 Binary files /dev/null and b/mobile-static/images/initial/comments4.png differ diff --git a/mobile-static/images/initial/comments5.png b/mobile-static/images/initial/comments5.png new file mode 100644 index 0000000000..c92f14d1e9 Binary files /dev/null and b/mobile-static/images/initial/comments5.png differ diff --git a/mobile-static/images/initial/comments6.png b/mobile-static/images/initial/comments6.png new file mode 100644 index 0000000000..66b5bfbdf9 Binary files /dev/null and b/mobile-static/images/initial/comments6.png differ diff --git a/mobile-static/images/initial/comments7.png b/mobile-static/images/initial/comments7.png new file mode 100644 index 0000000000..94a3c5441d Binary files /dev/null and b/mobile-static/images/initial/comments7.png differ diff --git a/mobile-static/images/initial/comments8.png b/mobile-static/images/initial/comments8.png new file mode 100644 index 0000000000..478d906795 Binary files /dev/null and b/mobile-static/images/initial/comments8.png differ diff --git a/mobile-static/images/initial/createTeam1.png b/mobile-static/images/initial/createTeam1.png new file mode 100644 index 0000000000..9a569d1bbd Binary files /dev/null and b/mobile-static/images/initial/createTeam1.png differ diff --git a/mobile-static/images/initial/createTeam2.png b/mobile-static/images/initial/createTeam2.png new file mode 100644 index 0000000000..9f7291ac81 Binary files /dev/null and b/mobile-static/images/initial/createTeam2.png differ diff --git a/mobile-static/images/initial/createTeam3.png b/mobile-static/images/initial/createTeam3.png new file mode 100644 index 0000000000..adc141954a Binary files /dev/null and b/mobile-static/images/initial/createTeam3.png differ diff --git a/mobile-static/images/initial/customizeWorkspace1.png b/mobile-static/images/initial/customizeWorkspace1.png new file mode 100644 index 0000000000..326298b3a5 Binary files /dev/null and b/mobile-static/images/initial/customizeWorkspace1.png differ diff --git a/mobile-static/images/initial/customizeWorkspace2.png b/mobile-static/images/initial/customizeWorkspace2.png new file mode 100644 index 0000000000..f8e771fa80 Binary files /dev/null and b/mobile-static/images/initial/customizeWorkspace2.png differ diff --git a/mobile-static/images/initial/customizeWorkspace3.png b/mobile-static/images/initial/customizeWorkspace3.png new file mode 100644 index 0000000000..2262a91827 Binary files /dev/null and b/mobile-static/images/initial/customizeWorkspace3.png differ diff --git a/mobile-static/images/initial/customizeWorkspace4.png b/mobile-static/images/initial/customizeWorkspace4.png new file mode 100644 index 0000000000..641dd3293b Binary files /dev/null and b/mobile-static/images/initial/customizeWorkspace4.png differ diff --git a/mobile-static/images/initial/customizeWorkspace5.png b/mobile-static/images/initial/customizeWorkspace5.png new file mode 100644 index 0000000000..f29dc4f125 Binary files /dev/null and b/mobile-static/images/initial/customizeWorkspace5.png differ diff --git a/mobile-static/images/initial/embedContents1.png b/mobile-static/images/initial/embedContents1.png new file mode 100644 index 0000000000..56d600ed15 Binary files /dev/null and b/mobile-static/images/initial/embedContents1.png differ diff --git a/mobile-static/images/initial/embedContents2.gif b/mobile-static/images/initial/embedContents2.gif new file mode 100644 index 0000000000..c8777f1bf3 Binary files /dev/null and b/mobile-static/images/initial/embedContents2.gif differ diff --git a/mobile-static/images/initial/embedContents3.gif b/mobile-static/images/initial/embedContents3.gif new file mode 100644 index 0000000000..4dfbfca0d1 Binary files /dev/null and b/mobile-static/images/initial/embedContents3.gif differ diff --git a/mobile-static/images/initial/embedContents4.gif b/mobile-static/images/initial/embedContents4.gif new file mode 100644 index 0000000000..6b00b7db65 Binary files /dev/null and b/mobile-static/images/initial/embedContents4.gif differ diff --git a/mobile-static/images/initial/embedContents5.gif b/mobile-static/images/initial/embedContents5.gif new file mode 100644 index 0000000000..b856763bce Binary files /dev/null and b/mobile-static/images/initial/embedContents5.gif differ diff --git a/mobile-static/images/initial/embedContents6.gif b/mobile-static/images/initial/embedContents6.gif new file mode 100644 index 0000000000..d265d2d372 Binary files /dev/null and b/mobile-static/images/initial/embedContents6.gif differ diff --git a/mobile-static/images/initial/embedDocuments1.png b/mobile-static/images/initial/embedDocuments1.png new file mode 100644 index 0000000000..1dc1a17bce Binary files /dev/null and b/mobile-static/images/initial/embedDocuments1.png differ diff --git a/mobile-static/images/initial/embedDocuments2.png b/mobile-static/images/initial/embedDocuments2.png new file mode 100644 index 0000000000..3259b79a1c Binary files /dev/null and b/mobile-static/images/initial/embedDocuments2.png differ diff --git a/mobile-static/images/initial/embedDocuments3.png b/mobile-static/images/initial/embedDocuments3.png new file mode 100644 index 0000000000..a08f7f7680 Binary files /dev/null and b/mobile-static/images/initial/embedDocuments3.png differ diff --git a/mobile-static/images/initial/idesearch.png b/mobile-static/images/initial/idesearch.png new file mode 100644 index 0000000000..95135bec59 Binary files /dev/null and b/mobile-static/images/initial/idesearch.png differ diff --git a/mobile-static/images/initial/inviteGuest1.png b/mobile-static/images/initial/inviteGuest1.png new file mode 100644 index 0000000000..593d578b77 Binary files /dev/null and b/mobile-static/images/initial/inviteGuest1.png differ diff --git a/mobile-static/images/initial/inviteGuest2.png b/mobile-static/images/initial/inviteGuest2.png new file mode 100644 index 0000000000..f70dce4bec Binary files /dev/null and b/mobile-static/images/initial/inviteGuest2.png differ diff --git a/mobile-static/images/initial/inviteGuest3.png b/mobile-static/images/initial/inviteGuest3.png new file mode 100644 index 0000000000..fd96288039 Binary files /dev/null and b/mobile-static/images/initial/inviteGuest3.png differ diff --git a/mobile-static/images/initial/inviteGuest4.png b/mobile-static/images/initial/inviteGuest4.png new file mode 100644 index 0000000000..61a8be574c Binary files /dev/null and b/mobile-static/images/initial/inviteGuest4.png differ diff --git a/mobile-static/images/initial/inviteGuest5.png b/mobile-static/images/initial/inviteGuest5.png new file mode 100644 index 0000000000..6fa951ce5d Binary files /dev/null and b/mobile-static/images/initial/inviteGuest5.png differ diff --git a/mobile-static/images/initial/inviteGuest6.png b/mobile-static/images/initial/inviteGuest6.png new file mode 100644 index 0000000000..ca3bb7da74 Binary files /dev/null and b/mobile-static/images/initial/inviteGuest6.png differ diff --git a/mobile-static/images/initial/invitemembers.png b/mobile-static/images/initial/invitemembers.png new file mode 100644 index 0000000000..8e577cc3cd Binary files /dev/null and b/mobile-static/images/initial/invitemembers.png differ diff --git a/mobile-static/images/initial/keymap.jpg b/mobile-static/images/initial/keymap.jpg new file mode 100644 index 0000000000..fb8ad0c143 Binary files /dev/null and b/mobile-static/images/initial/keymap.jpg differ diff --git a/mobile-static/images/initial/migration.png b/mobile-static/images/initial/migration.png new file mode 100644 index 0000000000..cb674c0e44 Binary files /dev/null and b/mobile-static/images/initial/migration.png differ diff --git a/mobile-static/images/initial/privateWorkspace1.png b/mobile-static/images/initial/privateWorkspace1.png new file mode 100644 index 0000000000..50497d9d99 Binary files /dev/null and b/mobile-static/images/initial/privateWorkspace1.png differ diff --git a/mobile-static/images/initial/privateWorkspace2.png b/mobile-static/images/initial/privateWorkspace2.png new file mode 100644 index 0000000000..9718c2436a Binary files /dev/null and b/mobile-static/images/initial/privateWorkspace2.png differ diff --git a/mobile-static/images/initial/publicAPI.png b/mobile-static/images/initial/publicAPI.png new file mode 100644 index 0000000000..de39ede5db Binary files /dev/null and b/mobile-static/images/initial/publicAPI.png differ diff --git a/mobile-static/images/initial/publicLink1.png b/mobile-static/images/initial/publicLink1.png new file mode 100644 index 0000000000..6d39b0721a Binary files /dev/null and b/mobile-static/images/initial/publicLink1.png differ diff --git a/mobile-static/images/initial/publicLink2.png b/mobile-static/images/initial/publicLink2.png new file mode 100644 index 0000000000..4c6fae66f2 Binary files /dev/null and b/mobile-static/images/initial/publicLink2.png differ diff --git a/mobile-static/images/initial/publicLink3.png b/mobile-static/images/initial/publicLink3.png new file mode 100644 index 0000000000..a25570102e Binary files /dev/null and b/mobile-static/images/initial/publicLink3.png differ diff --git a/mobile-static/images/initial/publicLink4.png b/mobile-static/images/initial/publicLink4.png new file mode 100644 index 0000000000..efe613d436 Binary files /dev/null and b/mobile-static/images/initial/publicLink4.png differ diff --git a/mobile-static/images/initial/shareoptions.png b/mobile-static/images/initial/shareoptions.png new file mode 100644 index 0000000000..60395251ff Binary files /dev/null and b/mobile-static/images/initial/shareoptions.png differ diff --git a/mobile-static/images/initial/smartFolder1.png b/mobile-static/images/initial/smartFolder1.png new file mode 100644 index 0000000000..0c0ed9114b Binary files /dev/null and b/mobile-static/images/initial/smartFolder1.png differ diff --git a/mobile-static/images/initial/smartFolder2.png b/mobile-static/images/initial/smartFolder2.png new file mode 100644 index 0000000000..e756e9da5e Binary files /dev/null and b/mobile-static/images/initial/smartFolder2.png differ diff --git a/mobile-static/images/initial/smartFolder3.png b/mobile-static/images/initial/smartFolder3.png new file mode 100644 index 0000000000..719e772f4f Binary files /dev/null and b/mobile-static/images/initial/smartFolder3.png differ diff --git a/mobile-static/images/initial/smartFolder4.png b/mobile-static/images/initial/smartFolder4.png new file mode 100644 index 0000000000..77525d30ac Binary files /dev/null and b/mobile-static/images/initial/smartFolder4.png differ diff --git a/mobile-static/images/initial/smartFolder5.png b/mobile-static/images/initial/smartFolder5.png new file mode 100644 index 0000000000..565901d132 Binary files /dev/null and b/mobile-static/images/initial/smartFolder5.png differ diff --git a/mobile-static/images/initial/smartFolder6.png b/mobile-static/images/initial/smartFolder6.png new file mode 100644 index 0000000000..b183a7eaee Binary files /dev/null and b/mobile-static/images/initial/smartFolder6.png differ diff --git a/mobile-static/images/initial/smartfolderexample.png b/mobile-static/images/initial/smartfolderexample.png new file mode 100644 index 0000000000..9193b89b6f Binary files /dev/null and b/mobile-static/images/initial/smartfolderexample.png differ diff --git a/mobile-static/images/initial/step1-1.png b/mobile-static/images/initial/step1-1.png new file mode 100644 index 0000000000..939dbd588c Binary files /dev/null and b/mobile-static/images/initial/step1-1.png differ diff --git a/mobile-static/images/initial/step1-2.png b/mobile-static/images/initial/step1-2.png new file mode 100644 index 0000000000..59b0d483d2 Binary files /dev/null and b/mobile-static/images/initial/step1-2.png differ diff --git a/mobile-static/images/initial/step1-3.png b/mobile-static/images/initial/step1-3.png new file mode 100644 index 0000000000..c6071ebc81 Binary files /dev/null and b/mobile-static/images/initial/step1-3.png differ diff --git a/mobile-static/images/initial/step1-4.png b/mobile-static/images/initial/step1-4.png new file mode 100644 index 0000000000..bc1be96305 Binary files /dev/null and b/mobile-static/images/initial/step1-4.png differ diff --git a/mobile-static/images/initial/step1-5.png b/mobile-static/images/initial/step1-5.png new file mode 100644 index 0000000000..066424a412 Binary files /dev/null and b/mobile-static/images/initial/step1-5.png differ diff --git a/mobile-static/images/initial/step1-6.png b/mobile-static/images/initial/step1-6.png new file mode 100644 index 0000000000..2ef169e3a7 Binary files /dev/null and b/mobile-static/images/initial/step1-6.png differ diff --git a/mobile-static/images/initial/step1-7.gif b/mobile-static/images/initial/step1-7.gif new file mode 100644 index 0000000000..6f4504939d Binary files /dev/null and b/mobile-static/images/initial/step1-7.gif differ diff --git a/mobile-static/images/initial/step2-1.png b/mobile-static/images/initial/step2-1.png new file mode 100644 index 0000000000..2ef169e3a7 Binary files /dev/null and b/mobile-static/images/initial/step2-1.png differ diff --git a/mobile-static/images/initial/step2-2.png b/mobile-static/images/initial/step2-2.png new file mode 100644 index 0000000000..066424a412 Binary files /dev/null and b/mobile-static/images/initial/step2-2.png differ diff --git a/mobile-static/images/initial/step3-1.png b/mobile-static/images/initial/step3-1.png new file mode 100644 index 0000000000..7ad0484ca3 Binary files /dev/null and b/mobile-static/images/initial/step3-1.png differ diff --git a/mobile-static/images/initial/step3-2.png b/mobile-static/images/initial/step3-2.png new file mode 100644 index 0000000000..1e3fa28024 Binary files /dev/null and b/mobile-static/images/initial/step3-2.png differ diff --git a/mobile-static/images/initial/step3-3.png b/mobile-static/images/initial/step3-3.png new file mode 100644 index 0000000000..cc6047897b Binary files /dev/null and b/mobile-static/images/initial/step3-3.png differ diff --git a/mobile-static/images/initial/step4-1.png b/mobile-static/images/initial/step4-1.png new file mode 100644 index 0000000000..7c130d3f67 Binary files /dev/null and b/mobile-static/images/initial/step4-1.png differ diff --git a/mobile-static/images/initial/step4-2.png b/mobile-static/images/initial/step4-2.png new file mode 100644 index 0000000000..b0950bf6c5 Binary files /dev/null and b/mobile-static/images/initial/step4-2.png differ diff --git a/mobile-static/images/initial/step4-3.png b/mobile-static/images/initial/step4-3.png new file mode 100644 index 0000000000..641dd3293b Binary files /dev/null and b/mobile-static/images/initial/step4-3.png differ diff --git a/mobile-static/images/initial/step4-4.png b/mobile-static/images/initial/step4-4.png new file mode 100644 index 0000000000..b0950bf6c5 Binary files /dev/null and b/mobile-static/images/initial/step4-4.png differ diff --git a/mobile-static/images/initial/step4-5.png b/mobile-static/images/initial/step4-5.png new file mode 100644 index 0000000000..946a4129da Binary files /dev/null and b/mobile-static/images/initial/step4-5.png differ diff --git a/mobile-static/images/initial/step5-1.png b/mobile-static/images/initial/step5-1.png new file mode 100644 index 0000000000..ad700a38be Binary files /dev/null and b/mobile-static/images/initial/step5-1.png differ diff --git a/mobile-static/images/initial/step5-2.png b/mobile-static/images/initial/step5-2.png new file mode 100644 index 0000000000..88eda5736e Binary files /dev/null and b/mobile-static/images/initial/step5-2.png differ diff --git a/mobile-static/images/initial/step5-3.png b/mobile-static/images/initial/step5-3.png new file mode 100644 index 0000000000..6ad3fce38a Binary files /dev/null and b/mobile-static/images/initial/step5-3.png differ diff --git a/mobile-static/images/initial/step6.gif b/mobile-static/images/initial/step6.gif new file mode 100644 index 0000000000..7c8b8b0502 Binary files /dev/null and b/mobile-static/images/initial/step6.gif differ diff --git a/mobile-static/images/initial/versionHistory1.png b/mobile-static/images/initial/versionHistory1.png new file mode 100644 index 0000000000..f4b24267fa Binary files /dev/null and b/mobile-static/images/initial/versionHistory1.png differ diff --git a/mobile-static/images/initial/versionHistory2.png b/mobile-static/images/initial/versionHistory2.png new file mode 100644 index 0000000000..977c083c5f Binary files /dev/null and b/mobile-static/images/initial/versionHistory2.png differ diff --git a/mobile-static/images/initial/zapierIntro.gif b/mobile-static/images/initial/zapierIntro.gif new file mode 100644 index 0000000000..7c8b8b0502 Binary files /dev/null and b/mobile-static/images/initial/zapierIntro.gif differ diff --git a/mobile-static/images/logo.png b/mobile-static/images/logo.png new file mode 100644 index 0000000000..69e43dfe33 Binary files /dev/null and b/mobile-static/images/logo.png differ diff --git a/mobile.html b/mobile.html new file mode 100644 index 0000000000..73db6d5bff --- /dev/null +++ b/mobile.html @@ -0,0 +1,16 @@ + + + + + + Boost Note + + + + + + + +
+ + diff --git a/package.json b/package.json index 3c054243f2..e367f864a6 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dev:cloud": "env-cmd cross-env NODE_ENV=development TARGET=electron TS_NODE_PROJECT=\"tsconfig-webpack.json\" webpack-dev-server --mode development --config webpack.cloud.config.ts", "dev:webpack": "env-cmd cross-env NODE_ENV=development TS_NODE_PROJECT=\"tsconfig-webpack.json\" webpack-dev-server --mode development", "dev:electron": "env-cmd cross-env NODE_ENV=development ts-node -P tsconfig-webpack.json scripts/dev-electron.ts", + "dev:mobile": "env-cmd cross-env NODE_ENV=development TS_NODE_PROJECT=\"tsconfig-webpack.json\" webpack-dev-server --mode development --config webpack.mobile.config.ts", "start": "electron electron/index.js", "lint": "eslint src/* --ext .ts,.tsx", "format": "prettier --write \"src/**/*\"", @@ -20,6 +21,7 @@ "build:electron-renderer": "rimraf electron/compiled && env-cmd cross-env TS_NODE_PROJECT=\"tsconfig-webpack.json\" TARGET=electron webpack --mode production", "build:electron-main": "rimraf electron/index.js && env-cmd ts-node -P tsconfig-webpack.json scripts/build-electron-main", "build:cloud": "rimraf compiled-cloud && env-cmd cross-env NODE_ENV=production TS_NODE_PROJECT=\"tsconfig-webpack.json\" webpack --mode production --config webpack.cloud.config.ts", + "build:mobile": "rimraf compiled-mobile && env-cmd cross-env NODE_ENV=production TS_NODE_PROJECT=\"tsconfig-webpack.json\" webpack --mode production --config webpack.mobile.config.ts", "meta": "node scripts/meta.js", "prepack": "rimraf dist && env-cmd npm run meta && electron-builder --dir", "pack": "rimraf dist && env-cmd npm run meta && env-cmd electron-builder", diff --git a/src/cloud/api/desktop/login.ts b/src/cloud/api/desktop/login.ts index 69100b8a4d..ba63fb9896 100644 --- a/src/cloud/api/desktop/login.ts +++ b/src/cloud/api/desktop/login.ts @@ -17,3 +17,15 @@ export async function createDesktopLoginRequest(state: string) { return data } + +export async function loginWithStateAndCode(state: string, code: string) { + const data = await callApi<{}>('api/desktop/login', { + method: 'post', + search: { + state, + code, + }, + }) + + return data +} diff --git a/src/cloud/components/App.tsx b/src/cloud/components/App.tsx index 61dbea4953..642f82e26e 100644 --- a/src/cloud/components/App.tsx +++ b/src/cloud/components/App.tsx @@ -22,6 +22,7 @@ const App = () => { useEffectOnce(() => { ;(async () => { await initAccessToken() + setAccessTokenInitialized(true) })() }) diff --git a/src/cloud/components/atoms/MarkdownView/index.tsx b/src/cloud/components/atoms/MarkdownView/index.tsx index 5a59cc1426..ad5f87cf93 100644 --- a/src/cloud/components/atoms/MarkdownView/index.tsx +++ b/src/cloud/components/atoms/MarkdownView/index.tsx @@ -44,6 +44,7 @@ import Icon from '../../../../shared/components/atoms/Icon' import styled from '../../../../shared/lib/styled' import throttle from 'lodash.throttle' import CodeFence from '../../../../shared/components/atoms/markdown/CodeFence' +import { agentType, sendPostMessage } from '../../../../mobile/lib/nativeMobile' import { TableOfContents } from '../../molecules/TableOfContents' const remarkAdmonitionOptions = { @@ -156,6 +157,25 @@ const MarkdownView = ({ Fragment: React.Fragment, components: { a: ({ href, children }: any) => { + if (agentType === 'ios-native' || agentType === 'android-native') { + return ( + { + event.preventDefault() + console.log(event, href) + sendPostMessage({ + type: 'open-link', + url: href, + }) + }} + rel='noopener noreferrer' + > + {children} + + ) + } + if ( (href || '') .toLocaleLowerCase() @@ -448,7 +468,7 @@ const StyledMarkdownPreview = styled.div` height: 20px; display: flex; align-items: flex-start; - color: ${({ theme }) => theme.colors.icon.default} + color: ${({ theme }) => theme.colors.icon.default}; font-size: ${({ theme }) => theme.sizes.fonts.md}px; &:hover { diff --git a/src/cloud/components/atoms/buttons/SignOutButton.tsx b/src/cloud/components/atoms/buttons/SignOutButton.tsx deleted file mode 100644 index bcd3cc3e41..0000000000 --- a/src/cloud/components/atoms/buttons/SignOutButton.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React, { useCallback, MouseEvent } from 'react' -import CustomLink from '../Link/CustomLink' -import { useTranslation } from 'react-i18next' -import { usingElectron, sendToHost } from '../../../lib/stores/electron' -import { boostHubBaseUrl } from '../../../lib/consts' - -interface SignOutButton { - redirectTo?: string -} - -const SignOutButton = ({ redirectTo }: SignOutButton) => { - const { t } = useTranslation() - - const signOutUrl = - redirectTo == null - ? '/api/oauth/signout' - : `/api/oauth/signout?redirectTo=${redirectTo}` - - const signOut = useCallback( - (event: MouseEvent) => { - event.preventDefault() - if (usingElectron) { - sendToHost('sign-out') - } else { - window.location.href = `${boostHubBaseUrl}${signOutUrl}` - } - }, - [signOutUrl] - ) - - return ( - - {t('general.signOut')} - - ) -} - -export default SignOutButton diff --git a/src/cloud/components/atoms/buttons/login/GithubLoginButton.tsx b/src/cloud/components/atoms/buttons/login/GithubLoginButton.tsx index a398973992..d8ef9d03e0 100644 --- a/src/cloud/components/atoms/buttons/login/GithubLoginButton.tsx +++ b/src/cloud/components/atoms/buttons/login/GithubLoginButton.tsx @@ -4,6 +4,7 @@ import styled from '../../../../lib/styled' import { stringify } from 'querystring' import IconMdi from '../../IconMdi' import { mdiGithub } from '@mdi/js' +import { boostHubBaseUrl } from '../../../../lib/consts' interface GithubLoginButtonProps { query?: any @@ -21,7 +22,7 @@ const GithubLoginButton = ({ setDisabled, }: GithubLoginButtonProps) => { const [sending, setSending] = useState(false) - const loginHref = `/api/oauth/github${ + const loginHref = `${boostHubBaseUrl}/api/oauth/github${ query != null ? `?${stringify(query)}` : '' }` @@ -46,7 +47,7 @@ export default GithubLoginButton const StyledGithubButton = styled.a` display: inline-block; text-decoration: none; - width: 400px; + width: 100%; height: 40px; line-height: 10px; text-align: center; diff --git a/src/cloud/components/atoms/buttons/login/GoogleLoginButton.tsx b/src/cloud/components/atoms/buttons/login/GoogleLoginButton.tsx index 61504d5a41..025bf88cbb 100644 --- a/src/cloud/components/atoms/buttons/login/GoogleLoginButton.tsx +++ b/src/cloud/components/atoms/buttons/login/GoogleLoginButton.tsx @@ -56,6 +56,7 @@ const GoogleLoginButton = ({ ) const errorHandler = (response: any) => { + console.log(response.error) if (response.error === 'popup_closed_by_user') { return } @@ -109,7 +110,7 @@ export default GoogleLoginButton const StyledGoogleButton = styled.button` text-decoration: none; - width: 400px; + width: 100%; height: 40px; line-height: 10px; cursor: pointer; diff --git a/src/cloud/components/molecules/Editor/EditorIndentationStatus.tsx b/src/cloud/components/molecules/Editor/EditorIndentationStatus.tsx index 2c6d63495b..185dd409ff 100644 --- a/src/cloud/components/molecules/Editor/EditorIndentationStatus.tsx +++ b/src/cloud/components/molecules/Editor/EditorIndentationStatus.tsx @@ -46,7 +46,6 @@ const EditorIndentationStatus = () => { return } if (isChildNode(menuRef.current, event.relatedTarget as Node)) { - menuRef.current.focus() return } setShowingIndentMenu(false) diff --git a/src/cloud/components/molecules/Editor/EditorKeyMapSelect.tsx b/src/cloud/components/molecules/Editor/EditorKeyMapSelect.tsx index bcfdbf0395..faa21ef14c 100644 --- a/src/cloud/components/molecules/Editor/EditorKeyMapSelect.tsx +++ b/src/cloud/components/molecules/Editor/EditorKeyMapSelect.tsx @@ -35,7 +35,6 @@ const EditorKeyMapSelect = () => { return } if (isChildNode(menuRef.current, event.relatedTarget as Node)) { - menuRef.current.focus() return } setShowingMenu(false) diff --git a/src/cloud/components/molecules/Editor/EditorThemeSelect.tsx b/src/cloud/components/molecules/Editor/EditorThemeSelect.tsx index 00bd7428f7..7803b152b9 100644 --- a/src/cloud/components/molecules/Editor/EditorThemeSelect.tsx +++ b/src/cloud/components/molecules/Editor/EditorThemeSelect.tsx @@ -49,7 +49,6 @@ const EditorThemeSelect = () => { return } if (isChildNode(menuRef.current, event.relatedTarget as Node)) { - menuRef.current.focus() return } setShowingMenu(false) diff --git a/src/cloud/components/molecules/OpenInviteSection.tsx b/src/cloud/components/molecules/OpenInviteSection.tsx index 6185b7f89e..d591aa2c69 100644 --- a/src/cloud/components/molecules/OpenInviteSection.tsx +++ b/src/cloud/components/molecules/OpenInviteSection.tsx @@ -226,12 +226,14 @@ const OpenInvitesSection = ({ userPermissions }: OpenInvitesSectionProps) => { }, }} /> + + - + - { @@ -105,7 +105,7 @@ const EmailForm = ({ ) : ( 'Continue with signin code' )} - + ) } @@ -119,14 +119,15 @@ const EmailForm = ({ placeholder='Email...' onChange={emailChangeHandler} /> - {sending ? : 'Continue with email'} - + ) } @@ -139,30 +140,26 @@ const StyledEmailForm = styled.form` color: #9da0a5; label { display: block; - margin: ${({ theme }) => theme.space.xxsmall}px auto; + margin: ${({ theme }) => theme.sizes.spaces.sm}px auto; text-align: left; - width: 400px; + width: 100%; } input { - padding: ${({ theme }) => theme.space.xsmall}px - ${({ theme }) => theme.space.small}px; + padding: ${({ theme }) => theme.sizes.spaces.sm}px + ${({ theme }) => theme.sizes.spaces.sm}px; border: none; border-radius: 2px; border: 1px solid #d2d3d6; ::placeholder { color: #45474b; } - width: 400px; + width: 100%; height: 40px; } .submit-email { - display: block; - padding: 0; - width: 400px; - font-size: ${({ theme }) => theme.fontSizes.small}px; - text-align: center; - margin: ${({ theme }) => theme.space.small}px auto !important; + width: 100%; + margin: ${({ theme }) => theme.sizes.spaces.sm}px 0; } a.submit-email.disabled { @@ -171,6 +168,6 @@ const StyledEmailForm = styled.form` } .text-center { - margin-top: ${({ theme }) => theme.space.small}px; + margin-top: ${({ theme }) => theme.sizes.spaces.sm}px; } ` diff --git a/src/cloud/components/molecules/SignInForm/index.tsx b/src/cloud/components/molecules/SignInForm/index.tsx index 36d8509e6d..a39330dadb 100644 --- a/src/cloud/components/molecules/SignInForm/index.tsx +++ b/src/cloud/components/molecules/SignInForm/index.tsx @@ -1,7 +1,7 @@ import React, { useState, useMemo } from 'react' import GoogleLoginButton from '../../atoms/buttons/login/GoogleLoginButton' import GithubLoginButton from '../../atoms/buttons/login/GithubLoginButton' -import styled from '../../../lib/styled' +import styled from '../../../../shared/lib/styled' import ErrorBlock from '../../atoms/ErrorBlock' import EmailForm from './EmailForm' import { useRouter } from '../../../lib/router' @@ -12,6 +12,8 @@ interface SignInFormProps { inviteId?: string openInviteSlug?: string disabled?: boolean + width?: string + mobile?: boolean } const SignInForm = ({ @@ -20,6 +22,8 @@ const SignInForm = ({ inviteId, disabled: preventAction = false, openInviteSlug, + width = '400px', + mobile, }: SignInFormProps) => { const [error, setError] = useState() const [disabled, setDisabled] = useState(false) @@ -42,12 +46,15 @@ const SignInForm = ({ if (openInviteSlug != null) { query.openInviteSlug = openInviteSlug } + if (mobile) { + query.mobile = 'true' + } return query - }, [redirectTo, isSignup, inviteId, openInviteSlug]) + }, [redirectTo, isSignup, inviteId, openInviteSlug, mobile]) return ( <> - + theme.sizes.spaces.xsm}px; hr { background-color: #d2d3d6; height: 1px; border: none; - margin: 32px auto !important; + margin: ${({ theme }) => theme.sizes.spaces.l}px auto; width: 400px; } ` diff --git a/src/cloud/components/organisms/EditorLayout/molecules/DocTagsList/TagsAutoCompleteInput.tsx b/src/cloud/components/organisms/EditorLayout/molecules/DocTagsList/TagsAutoCompleteInput.tsx index 2f3107f277..cdabe406c1 100644 --- a/src/cloud/components/organisms/EditorLayout/molecules/DocTagsList/TagsAutoCompleteInput.tsx +++ b/src/cloud/components/organisms/EditorLayout/molecules/DocTagsList/TagsAutoCompleteInput.tsx @@ -71,6 +71,7 @@ const TagsAutoCompleteInput = ({ team, doc }: TagsAutoCompleteInputProps) => { const onBlurHandler = (event: any) => { if ( + containerRef.current !== event.relatedTarget && !isChildNode( containerRef.current, event.relatedTarget as HTMLElement | null diff --git a/src/cloud/components/organisms/Modal/contents/styled.ts b/src/cloud/components/organisms/Modal/contents/styled.ts index 3bee120402..df32589a50 100644 --- a/src/cloud/components/organisms/Modal/contents/styled.ts +++ b/src/cloud/components/organisms/Modal/contents/styled.ts @@ -95,6 +95,10 @@ export const ModalLine = styled.div` justify-content: flex-end; } + &.justify-center { + justify-content: center; + } + &.scrollable { margin: 0; overflow: hidden auto; diff --git a/src/cloud/lib/consts.ts b/src/cloud/lib/consts.ts index e7da49f3eb..43f98a70e6 100644 --- a/src/cloud/lib/consts.ts +++ b/src/cloud/lib/consts.ts @@ -3,7 +3,7 @@ export const nodeEnv = process.env.NODE_ENV || 'development' export const intercomAppId = process.env.INTERCOM_APP_ID || 'elidid' export const boostHubBaseUrl = process.env.BOOST_HUB_BASE_URL || 'http://localhost:3001' -export const realtimeUrl = process.env.REALTIME_URL || 'http://localhost:3002' +export const realtimeUrl = process.env.REALTIME_URL || 'http://localhost:3003' export const sseUrl = process.env.SSE_URL || 'http://localhost:3002' export const stripePublishableKey = process.env.STRIPE_PUBLISHABLE_KEY || 'elidid' @@ -13,3 +13,5 @@ export const googleClientId = process.env.GOOGLE_CLIENT_ID || 'elidid' export const newUserStandardCouponId = process.env.COUPONS_NEW_USER_STANDARD export const newUserProCouponId = process.env.COUPONS_NEW_USER_PRO export const newSpaceCouponId = process.env.COUPONS_NEW_SPACE +export const mobileBaseUrl = + process.env.MOBILE_BASE_URL || 'http://localhost:3005' diff --git a/src/cloud/lib/date.ts b/src/cloud/lib/date.ts index da15f48550..0befc6d18a 100644 --- a/src/cloud/lib/date.ts +++ b/src/cloud/lib/date.ts @@ -65,6 +65,22 @@ export function getFormattedBoosthubDateTime(date: string, prefixed = false) { return `${prefixed ? 'on ' : ''}${format(converted, 'HH:mm, dd MMMM u')}` } } +export function getShortFormattedBoosthubDateTime(date: string) { + const converted = new Date(date) + const yesterday = new Date() + yesterday.setDate(yesterday.getDate() - 1) + + if (!isValid(converted)) { + return 'Invalid Date' + } + + switch (converted > yesterday) { + case true: + return `${formatDistanceToNowStrict(converted)} ago` + default: + return `${format(converted, 'dd MMM u')}` + } +} export function getUnixtimestamp(date: Date) { return date.getTime() / 1000 diff --git a/src/cloud/lib/localStorageKeys.ts b/src/cloud/lib/localStorageKeys.ts index b0593d4677..fb549712b6 100644 --- a/src/cloud/lib/localStorageKeys.ts +++ b/src/cloud/lib/localStorageKeys.ts @@ -2,4 +2,5 @@ export const preferencesKey = 'boosthub:preferences' export const searchKey = 'boosthub:search' export const searchHistoryKey = 'boosthub:search:history' export const sidebarCollapseKey = 'boosthub:sidebar' +export const mobilePreferencesKey = 'boosthub:mobile:preferences' export const teamStorageKey = 'boosthub:teamPreferences' diff --git a/src/cloud/lib/stores/electron.ts b/src/cloud/lib/stores/electron.ts index 65f52d6ceb..be52445dc1 100644 --- a/src/cloud/lib/stores/electron.ts +++ b/src/cloud/lib/stores/electron.ts @@ -18,7 +18,6 @@ import { import { useGlobalKeyDownHandler, isWithGeneralCtrlKey } from '../keyboard' import { IpcRendererEvent } from 'electron' import { useEffectOnce } from 'react-use' -import { nodeEnv } from '../consts' import ltSemver from 'semver/functions/lt' export function sendToHost(channel: string, ...args: any[]) { @@ -97,9 +96,6 @@ export function initAccessToken(): Promise { } export function getAccessToken(): string | null { - if (nodeEnv === 'production' && usingLegacyElectron) { - return null - } if (accessTokenHasBeenInitialized) { return accessToken } diff --git a/src/cloud/lib/utils/events.ts b/src/cloud/lib/utils/events.ts index cc98165e93..7893ea3dfd 100644 --- a/src/cloud/lib/utils/events.ts +++ b/src/cloud/lib/utils/events.ts @@ -3,21 +3,21 @@ import React, { ChangeEventHandler, EventHandler } from 'react' export type SelectChangeEventHandler = ChangeEventHandler export type ButtonClickEventHandler = EventHandler -function createCustomEventEmitter( +export function createCustomEventEmitter( name: string ): { dispatch: () => void listen: (handler: (event: CustomEvent) => void) => void unlisten: (handler: (event: CustomEvent) => void) => void } -function createCustomEventEmitter( +export function createCustomEventEmitter( name: string ): { dispatch: (detail: D) => void listen: (handler: (event: CustomEvent) => void) => void unlisten: (handler: (event: CustomEvent) => void) => void } -function createCustomEventEmitter(name: string) { +export function createCustomEventEmitter(name: string) { return { dispatch(detail: D) { window.dispatchEvent(new CustomEvent(name, { detail })) diff --git a/src/mobile/components/App.tsx b/src/mobile/components/App.tsx new file mode 100644 index 0000000000..5aad4e3a38 --- /dev/null +++ b/src/mobile/components/App.tsx @@ -0,0 +1,66 @@ +import React, { useState } from 'react' +import Router from './Router' +import { RouterProvider } from '../../cloud/lib/router' +import { GlobalDataProvider } from '../../cloud/lib/stores/globalData' + +import { RealtimeConnProvider } from '../../cloud/lib/stores/realtimeConn' +import { V2ToastProvider } from '../../shared/lib/stores/toast' +import { useEffectOnce } from 'react-use' +import { initAccessToken } from '../../cloud/lib/stores/electron' +import '../../cloud/lib/i18n' +import '../lib/nativeMobile' + +const App = () => { + const [accessTokenInitialized, setAccessTokenInitialized] = useState(false) + + useEffectOnce(() => { + ;(async () => { + await initAccessToken() + setAccessTokenInitialized(true) + })() + }) + if (!accessTokenInitialized) { + return
Fetching access token...
+ } + + return ( + <> + + + + + + + + + + + + + + {/*