diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..58f2723a
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,12 @@
+# These are supported funding model platforms
+
+github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
+patreon: bijoyskochar
+open_collective: # Replace with a single Open Collective username
+ko_fi: bijoyskochar
+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: bijoyskochar
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
diff --git a/app/build.gradle b/app/build.gradle
index 54230293..1f33484f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -10,11 +10,11 @@ android {
defaultConfig {
applicationId "com.bijoysingh.quicknote"
- minSdkVersion 17
+ minSdkVersion 21
targetSdkVersion 28
- versionCode 125
- versionName '6.9.7'
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ versionCode 156
+ versionName '7.5.4'
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 291b20a6..b6ea897a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,5 +1,6 @@
@@ -15,20 +16,12 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
- android:theme="@style/AppTheme">
-
-
-
-
+ android:theme="@style/AppTheme"
+ tools:ignore="GoogleAppIndexingWarning">
@@ -40,81 +33,6 @@
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/java/com/bijoysingh/quicknote/MaterialNotes.kt b/app/src/main/java/com/bijoysingh/quicknote/MaterialNotes.kt
index d9d43e54..0da8f077 100644
--- a/app/src/main/java/com/bijoysingh/quicknote/MaterialNotes.kt
+++ b/app/src/main/java/com/bijoysingh/quicknote/MaterialNotes.kt
@@ -1,16 +1,17 @@
package com.bijoysingh.quicknote
import com.maubis.scarlet.base.config.ApplicationBase
-import com.maubis.scarlet.base.config.CoreConfig
import com.maubis.scarlet.base.config.MaterialNoteConfig
import com.maubis.scarlet.base.export.support.ExternalFolderSync
+import com.maubis.scarlet.base.support.utils.Flavor
class MaterialNotes : ApplicationBase() {
override fun onCreate() {
super.onCreate()
- CoreConfig.instance = MaterialNoteConfig(this)
- CoreConfig.instance.themeController().setup(this)
+ sAppFlavor = Flavor.NONE
+
+ ApplicationBase.instance = MaterialNoteConfig(this)
ExternalFolderSync.setup(this)
}
}
\ No newline at end of file
diff --git a/base/build.gradle b/base/build.gradle
index 233f9ac3..e05df6f9 100644
--- a/base/build.gradle
+++ b/base/build.gradle
@@ -17,7 +17,13 @@ android {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ kapt {
+ arguments {
+ arg("room.schemaLocation", "$projectDir/schemas")
+ }
+ }
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ resValue "string", "file_provider_name", "com.maubis.scarlet.pro.base.support.GenericFileProvider"
}
buildTypes {
@@ -35,50 +41,48 @@ android {
dependencies {
api project(':markdown')
- api "com.android.support:recyclerview-v7:$android_support_version"
- api "com.android.support:cardview-v7:$android_support_version"
- api "com.android.support:support-v4:$android_support_version"
- api "com.android.support:design:$android_support_version"
- api "com.android.support:appcompat-v7:$android_support_version"
- api 'com.android.support.constraint:constraint-layout:1.1.3'
+ api 'androidx.recyclerview:recyclerview:1.1.0'
+ api 'androidx.cardview:cardview:1.0.0'
+ api 'androidx.legacy:legacy-support-v4:1.0.0'
+ api 'androidx.appcompat:appcompat:1.1.0'
+ api 'androidx.constraintlayout:constraintlayout:1.1.3'
+
+ api 'com.google.android.material:material:1.0.0'
api 'com.google.code.gson:gson:2.8.5'
- api 'com.github.ajalt.reprint:core:3.2.0@aar'
- api "com.github.bijoysingh:android-basics:5.0.0"
- api "com.github.bijoysingh:ui-basics:0.7.0"
+ api "com.github.bijoysingh:android-basics:5.1.0-x"
+ api "com.github.bijoysingh:ui-basics:1.0.0-x"
api 'com.github.bijoysingh:floating-bubble:3.0.0'
api 'com.evernote:android-job:1.2.6'
implementation 'com.google.android:flexbox:0.3.2'
- def room_version = "1.1.1"
- implementation "android.arch.persistence.room:runtime:$room_version"
- implementation "android.arch.persistence.room:testing:$room_version"
- annotationProcessor "android.arch.persistence.room:compiler:$room_version"
- kapt "android.arch.persistence.room:compiler:$room_version"
+ api 'androidx.room:room-runtime:2.2.2'
+ api 'androidx.room:room-testing:2.2.2'
+ kapt 'androidx.room:room-compiler:2.2.2'
+
+ def biometric_version = "1.0.0"
+ implementation "androidx.biometric:biometric:$biometric_version"
- implementation 'com.github.ajalt.reprint:core:3.2.0@aar'
implementation 'com.github.jkwiecien:EasyImage:1.3.1'
api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
api 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1'
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1"
- def litho_version = "0.21.0"
- implementation "com.facebook.litho:litho-core:$litho_version"
- implementation "com.facebook.litho:litho-widget:$litho_version"
- implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+ def litho_version = "0.31.0"
+ api "com.facebook.litho:litho-core:$litho_version"
+ api "com.facebook.litho:litho-widget:$litho_version"
compileOnly "com.facebook.litho:litho-annotations:$litho_version"
kapt "com.facebook.litho:litho-processor:$litho_version"
+ api 'com.facebook.soloader:soloader:0.5.1'
- implementation 'com.facebook.soloader:soloader:0.5.1'
-
- androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
+ androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
exclude group: 'com.android.support', module: 'support-annotations'
})
- testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.1'
}
apply plugin: 'kotlin-android-extensions'
\ No newline at end of file
diff --git a/base/proguard-rules.pro b/base/proguard-rules.pro
index f1b42451..edf0b1d3 100644
--- a/base/proguard-rules.pro
+++ b/base/proguard-rules.pro
@@ -19,3 +19,15 @@
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
+
+-dontwarn android.text.StaticLayout
+-dontwarn android.view.DisplayList
+-dontwarn android.view.RenderNode
+-dontwarn android.view.DisplayListCanvas
+-dontwarn android.view.HardwareCanvas
+
+-dontwarn com.facebook.fbui.**
+-dontwarn com.facebook.litho.**
+
+-dontwarn com.github.bijoysingh.starter.server.**
+-keep class com.facebook.yoga.** { *; }
diff --git a/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/10.json b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/10.json
new file mode 100644
index 00000000..c2d7aaec
--- /dev/null
+++ b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/10.json
@@ -0,0 +1,190 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 10,
+ "identityHash": "772aa0db40c8d5c7379af2f0657435e9",
+ "entities": [
+ {
+ "tableName": "note",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `description` TEXT, `displayTimestamp` TEXT, `timestamp` INTEGER, `color` INTEGER, `state` TEXT, `locked` INTEGER NOT NULL, `tags` TEXT, `updateTimestamp` INTEGER NOT NULL, `pinned` INTEGER NOT NULL, `uuid` TEXT, `meta` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "displayTimestamp",
+ "columnName": "displayTimestamp",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "locked",
+ "columnName": "locked",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "tags",
+ "columnName": "tags",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "updateTimestamp",
+ "columnName": "updateTimestamp",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "pinned",
+ "columnName": "pinned",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "meta",
+ "columnName": "meta",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_note_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_note_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "tag",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `uuid` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_tag_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_tag_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "widget",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`widgetId` INTEGER NOT NULL, `noteUUID` TEXT, PRIMARY KEY(`widgetId`))",
+ "fields": [
+ {
+ "fieldPath": "widgetId",
+ "columnName": "widgetId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "noteUUID",
+ "columnName": "noteUUID",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "widgetId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [
+ {
+ "name": "index_widget_widgetId",
+ "unique": false,
+ "columnNames": [
+ "widgetId"
+ ],
+ "createSql": "CREATE INDEX `index_widget_widgetId` ON `${TABLE_NAME}` (`widgetId`)"
+ }
+ ],
+ "foreignKeys": []
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"772aa0db40c8d5c7379af2f0657435e9\")"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/11.json b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/11.json
new file mode 100644
index 00000000..2bf7b579
--- /dev/null
+++ b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/11.json
@@ -0,0 +1,196 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 11,
+ "identityHash": "2b7771cb918cb46288978c977be868f2",
+ "entities": [
+ {
+ "tableName": "note",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `description` TEXT, `displayTimestamp` TEXT, `timestamp` INTEGER, `color` INTEGER, `state` TEXT, `locked` INTEGER NOT NULL, `tags` TEXT, `updateTimestamp` INTEGER NOT NULL, `pinned` INTEGER NOT NULL, `uuid` TEXT, `meta` TEXT, `disableBackup` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "displayTimestamp",
+ "columnName": "displayTimestamp",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "locked",
+ "columnName": "locked",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "tags",
+ "columnName": "tags",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "updateTimestamp",
+ "columnName": "updateTimestamp",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "pinned",
+ "columnName": "pinned",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "meta",
+ "columnName": "meta",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "disableBackup",
+ "columnName": "disableBackup",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_note_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_note_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "tag",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `uuid` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_tag_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_tag_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "widget",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`widgetId` INTEGER NOT NULL, `noteUUID` TEXT, PRIMARY KEY(`widgetId`))",
+ "fields": [
+ {
+ "fieldPath": "widgetId",
+ "columnName": "widgetId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "noteUUID",
+ "columnName": "noteUUID",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "widgetId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [
+ {
+ "name": "index_widget_widgetId",
+ "unique": false,
+ "columnNames": [
+ "widgetId"
+ ],
+ "createSql": "CREATE INDEX `index_widget_widgetId` ON `${TABLE_NAME}` (`widgetId`)"
+ }
+ ],
+ "foreignKeys": []
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"2b7771cb918cb46288978c977be868f2\")"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/12.json b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/12.json
new file mode 100644
index 00000000..10c0d8c8
--- /dev/null
+++ b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/12.json
@@ -0,0 +1,255 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 12,
+ "identityHash": "4fa11b193441aaf148468c857eec12ba",
+ "entities": [
+ {
+ "tableName": "note",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `description` TEXT, `displayTimestamp` TEXT, `timestamp` INTEGER, `color` INTEGER, `state` TEXT, `locked` INTEGER NOT NULL, `tags` TEXT, `updateTimestamp` INTEGER NOT NULL, `pinned` INTEGER NOT NULL, `uuid` TEXT, `meta` TEXT, `disableBackup` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "displayTimestamp",
+ "columnName": "displayTimestamp",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "locked",
+ "columnName": "locked",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "tags",
+ "columnName": "tags",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "updateTimestamp",
+ "columnName": "updateTimestamp",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "pinned",
+ "columnName": "pinned",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "meta",
+ "columnName": "meta",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "disableBackup",
+ "columnName": "disableBackup",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_note_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_note_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "tag",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `uuid` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_tag_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_tag_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "widget",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`widgetId` INTEGER NOT NULL, `noteUUID` TEXT, PRIMARY KEY(`widgetId`))",
+ "fields": [
+ {
+ "fieldPath": "widgetId",
+ "columnName": "widgetId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "noteUUID",
+ "columnName": "noteUUID",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "widgetId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [
+ {
+ "name": "index_widget_widgetId",
+ "unique": false,
+ "columnNames": [
+ "widgetId"
+ ],
+ "createSql": "CREATE INDEX `index_widget_widgetId` ON `${TABLE_NAME}` (`widgetId`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "folder",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `timestamp` INTEGER, `updateTimestamp` INTEGER NOT NULL, `color` INTEGER, `uuid` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "updateTimestamp",
+ "columnName": "updateTimestamp",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_folder_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_folder_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"4fa11b193441aaf148468c857eec12ba\")"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/14.json b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/14.json
new file mode 100644
index 00000000..f2cb56ee
--- /dev/null
+++ b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/14.json
@@ -0,0 +1,262 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 14,
+ "identityHash": "27a1b0ae4247b917be454c0e96798974",
+ "entities": [
+ {
+ "tableName": "note",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `description` TEXT, `displayTimestamp` TEXT, `timestamp` INTEGER, `color` INTEGER, `state` TEXT, `locked` INTEGER NOT NULL, `tags` TEXT, `updateTimestamp` INTEGER NOT NULL, `pinned` INTEGER NOT NULL, `uuid` TEXT, `meta` TEXT, `disableBackup` INTEGER NOT NULL, `folder` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "displayTimestamp",
+ "columnName": "displayTimestamp",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "locked",
+ "columnName": "locked",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "tags",
+ "columnName": "tags",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "updateTimestamp",
+ "columnName": "updateTimestamp",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "pinned",
+ "columnName": "pinned",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "meta",
+ "columnName": "meta",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "disableBackup",
+ "columnName": "disableBackup",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "folder",
+ "columnName": "folder",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_note_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_note_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "tag",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `uuid` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_tag_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_tag_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "widget",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`widgetId` INTEGER NOT NULL, `noteUUID` TEXT, PRIMARY KEY(`widgetId`))",
+ "fields": [
+ {
+ "fieldPath": "widgetId",
+ "columnName": "widgetId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "noteUUID",
+ "columnName": "noteUUID",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "widgetId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [
+ {
+ "name": "index_widget_widgetId",
+ "unique": false,
+ "columnNames": [
+ "widgetId"
+ ],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_widget_widgetId` ON `${TABLE_NAME}` (`widgetId`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "folder",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `timestamp` INTEGER, `updateTimestamp` INTEGER NOT NULL, `color` INTEGER, `uuid` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "updateTimestamp",
+ "columnName": "updateTimestamp",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_folder_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_folder_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ }
+ ],
+ "views": [],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '27a1b0ae4247b917be454c0e96798974')"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/2.json b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/2.json
new file mode 100644
index 00000000..3a33850e
--- /dev/null
+++ b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/2.json
@@ -0,0 +1,72 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 2,
+ "identityHash": "42138d9525b661262cd3c159b26e8bd1",
+ "entities": [
+ {
+ "tableName": "note",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `description` TEXT, `displayTimestamp` TEXT, `timestamp` INTEGER, `color` INTEGER)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "displayTimestamp",
+ "columnName": "displayTimestamp",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_note_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_note_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"42138d9525b661262cd3c159b26e8bd1\")"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/3.json b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/3.json
new file mode 100644
index 00000000..285b323b
--- /dev/null
+++ b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/3.json
@@ -0,0 +1,78 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 3,
+ "identityHash": "ebac89e10d42fee5041902845b3c4e50",
+ "entities": [
+ {
+ "tableName": "note",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `description` TEXT, `displayTimestamp` TEXT, `timestamp` INTEGER, `color` INTEGER, `state` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "displayTimestamp",
+ "columnName": "displayTimestamp",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_note_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_note_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"ebac89e10d42fee5041902845b3c4e50\")"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/4.json b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/4.json
new file mode 100644
index 00000000..f14c8fac
--- /dev/null
+++ b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/4.json
@@ -0,0 +1,84 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 4,
+ "identityHash": "ff9b7d3c13995d9bab939e5f605b7ca0",
+ "entities": [
+ {
+ "tableName": "note",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `description` TEXT, `displayTimestamp` TEXT, `timestamp` INTEGER, `color` INTEGER, `state` TEXT, `locked` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "displayTimestamp",
+ "columnName": "displayTimestamp",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "locked",
+ "columnName": "locked",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_note_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_note_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"ff9b7d3c13995d9bab939e5f605b7ca0\")"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/5.json b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/5.json
new file mode 100644
index 00000000..a168b5be
--- /dev/null
+++ b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/5.json
@@ -0,0 +1,125 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 5,
+ "identityHash": "ab6ec3e8f6d33797ac91c9254e63e906",
+ "entities": [
+ {
+ "tableName": "note",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `description` TEXT, `displayTimestamp` TEXT, `timestamp` INTEGER, `color` INTEGER, `state` TEXT, `locked` INTEGER NOT NULL, `tags` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "displayTimestamp",
+ "columnName": "displayTimestamp",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "locked",
+ "columnName": "locked",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "tags",
+ "columnName": "tags",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_note_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_note_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "tag",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_tag_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_tag_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"ab6ec3e8f6d33797ac91c9254e63e906\")"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/6.json b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/6.json
new file mode 100644
index 00000000..dab4bcd3
--- /dev/null
+++ b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/6.json
@@ -0,0 +1,137 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 6,
+ "identityHash": "44eaaecfdc7e16dab14a93e8938abb28",
+ "entities": [
+ {
+ "tableName": "note",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `description` TEXT, `displayTimestamp` TEXT, `timestamp` INTEGER, `color` INTEGER, `state` TEXT, `locked` INTEGER NOT NULL, `tags` TEXT, `updateTimestamp` INTEGER NOT NULL, `pinned` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "displayTimestamp",
+ "columnName": "displayTimestamp",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "locked",
+ "columnName": "locked",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "tags",
+ "columnName": "tags",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "updateTimestamp",
+ "columnName": "updateTimestamp",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "pinned",
+ "columnName": "pinned",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_note_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_note_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "tag",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_tag_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_tag_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"44eaaecfdc7e16dab14a93e8938abb28\")"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/7.json b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/7.json
new file mode 100644
index 00000000..e52a464a
--- /dev/null
+++ b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/7.json
@@ -0,0 +1,143 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 7,
+ "identityHash": "f142faa3ea6ca754af78d915e2aaf1ca",
+ "entities": [
+ {
+ "tableName": "note",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `description` TEXT, `displayTimestamp` TEXT, `timestamp` INTEGER, `color` INTEGER, `state` TEXT, `locked` INTEGER NOT NULL, `tags` TEXT, `updateTimestamp` INTEGER NOT NULL, `pinned` INTEGER NOT NULL, `uuid` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "displayTimestamp",
+ "columnName": "displayTimestamp",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "locked",
+ "columnName": "locked",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "tags",
+ "columnName": "tags",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "updateTimestamp",
+ "columnName": "updateTimestamp",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "pinned",
+ "columnName": "pinned",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_note_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_note_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "tag",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_tag_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_tag_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"f142faa3ea6ca754af78d915e2aaf1ca\")"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/8.json b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/8.json
new file mode 100644
index 00000000..cadcc778
--- /dev/null
+++ b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/8.json
@@ -0,0 +1,149 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 8,
+ "identityHash": "aef5fdefabc56501799ced8a278ae77f",
+ "entities": [
+ {
+ "tableName": "note",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `description` TEXT, `displayTimestamp` TEXT, `timestamp` INTEGER, `color` INTEGER, `state` TEXT, `locked` INTEGER NOT NULL, `tags` TEXT, `updateTimestamp` INTEGER NOT NULL, `pinned` INTEGER NOT NULL, `uuid` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "displayTimestamp",
+ "columnName": "displayTimestamp",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "locked",
+ "columnName": "locked",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "tags",
+ "columnName": "tags",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "updateTimestamp",
+ "columnName": "updateTimestamp",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "pinned",
+ "columnName": "pinned",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_note_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_note_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "tag",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `uuid` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_tag_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_tag_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"aef5fdefabc56501799ced8a278ae77f\")"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/9.json b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/9.json
new file mode 100644
index 00000000..0976510c
--- /dev/null
+++ b/base/schemas/com.maubis.scarlet.base.database.room.AppDatabase/9.json
@@ -0,0 +1,184 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 9,
+ "identityHash": "134846fcabba01b20eb0b0b4afd63dae",
+ "entities": [
+ {
+ "tableName": "note",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `description` TEXT, `displayTimestamp` TEXT, `timestamp` INTEGER, `color` INTEGER, `state` TEXT, `locked` INTEGER NOT NULL, `tags` TEXT, `updateTimestamp` INTEGER NOT NULL, `pinned` INTEGER NOT NULL, `uuid` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "displayTimestamp",
+ "columnName": "displayTimestamp",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "locked",
+ "columnName": "locked",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "tags",
+ "columnName": "tags",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "updateTimestamp",
+ "columnName": "updateTimestamp",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "pinned",
+ "columnName": "pinned",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_note_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_note_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "tag",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `uuid` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "title",
+ "columnName": "title",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_tag_uid",
+ "unique": false,
+ "columnNames": [
+ "uid"
+ ],
+ "createSql": "CREATE INDEX `index_tag_uid` ON `${TABLE_NAME}` (`uid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "widget",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`widgetId` INTEGER NOT NULL, `noteUUID` TEXT, PRIMARY KEY(`widgetId`))",
+ "fields": [
+ {
+ "fieldPath": "widgetId",
+ "columnName": "widgetId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "noteUUID",
+ "columnName": "noteUUID",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "widgetId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [
+ {
+ "name": "index_widget_widgetId",
+ "unique": false,
+ "columnNames": [
+ "widgetId"
+ ],
+ "createSql": "CREATE INDEX `index_widget_widgetId` ON `${TABLE_NAME}` (`widgetId`)"
+ }
+ ],
+ "foreignKeys": []
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"134846fcabba01b20eb0b0b4afd63dae\")"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/base/src/androidTest/java/com/maubis/scarlet/base/MigrationTest.java b/base/src/androidTest/java/com/maubis/scarlet/base/MigrationTest.java
index cd409dd4..32d92657 100644
--- a/base/src/androidTest/java/com/maubis/scarlet/base/MigrationTest.java
+++ b/base/src/androidTest/java/com/maubis/scarlet/base/MigrationTest.java
@@ -1,11 +1,11 @@
package com.maubis.scarlet.base;
-import android.arch.persistence.db.SupportSQLiteDatabase;
-import android.arch.persistence.db.framework.FrameworkSQLiteOpenHelperFactory;
-import android.arch.persistence.room.testing.MigrationTestHelper;
+import androidx.sqlite.db.SupportSQLiteDatabase;
+import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory;
+import androidx.room.testing.MigrationTestHelper;
import android.database.Cursor;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.github.bijoysingh.starter.util.TextUtils;
import com.maubis.scarlet.base.database.room.AppDatabase;
@@ -20,6 +20,7 @@
import static com.maubis.scarlet.base.database.room.AppDatabase.MIGRATION_10_11;
import static com.maubis.scarlet.base.database.room.AppDatabase.MIGRATION_11_12;
import static com.maubis.scarlet.base.database.room.AppDatabase.MIGRATION_12_13;
+import static com.maubis.scarlet.base.database.room.AppDatabase.MIGRATION_13_14;
import static com.maubis.scarlet.base.database.room.AppDatabase.MIGRATION_2_3;
import static com.maubis.scarlet.base.database.room.AppDatabase.MIGRATION_3_4;
import static com.maubis.scarlet.base.database.room.AppDatabase.MIGRATION_4_5;
@@ -235,6 +236,19 @@ public void migrate11To12() throws IOException {
validate(database, select(TABLE_FOLDER, 1));
}
+ @Test
+ public void migrate11To13() throws IOException {
+ SupportSQLiteDatabase database = helper.createDatabase(TEST_DB, 11);
+ database.execSQL(NOTE_V9);
+ database.close();
+
+ database = helper.runMigrationsAndValidate(TEST_DB, 13, false, MIGRATION_11_12, MIGRATION_12_13);
+ validate(database, select(TABLE_NOTE, 1));
+
+ database.execSQL(FOLDER_V12);
+ validate(database, select(TABLE_FOLDER, 1));
+ }
+
@Test
public void migrate12To13() throws IOException {
SupportSQLiteDatabase database = helper.createDatabase(TEST_DB, 12);
@@ -249,6 +263,34 @@ public void migrate12To13() throws IOException {
Assert.assertTrue(getValue(database, select(TABLE_NOTE, 2, "folder")).equals("32123124"));
}
+ @Test
+ public void migrate11To14() throws IOException {
+ SupportSQLiteDatabase database = helper.createDatabase(TEST_DB, 11);
+ database.execSQL(NOTE_V9);
+ database.close();
+
+ database = helper.runMigrationsAndValidate(TEST_DB, 14, false, MIGRATION_11_12, MIGRATION_12_13, MIGRATION_13_14);
+ validate(database, select(TABLE_NOTE, 1));
+
+ database.execSQL(NOTE_V10);
+ validate(database, select(TABLE_NOTE, 2));
+ Assert.assertTrue(getValue(database, select(TABLE_NOTE, 2, "folder")).equals("32123124"));
+ }
+
+ @Test
+ public void migrate13To14() throws IOException {
+ SupportSQLiteDatabase database = helper.createDatabase(TEST_DB, 13);
+ database.execSQL(NOTE_V9);
+ database.close();
+
+ database = helper.runMigrationsAndValidate(TEST_DB, 14, false, MIGRATION_13_14);
+ validate(database, select(TABLE_NOTE, 1));
+
+ database.execSQL(NOTE_V10);
+ validate(database, select(TABLE_NOTE, 2));
+ Assert.assertTrue(getValue(database, select(TABLE_NOTE, 2, "folder")).equals("32123124"));
+ }
+
private static void validate(SupportSQLiteDatabase database, String query) {
Cursor cursor = database.query(query);
Assert.assertTrue(cursor.moveToNext());
diff --git a/base/src/main/AndroidManifest.xml b/base/src/main/AndroidManifest.xml
index d5a34183..8309489f 100644
--- a/base/src/main/AndroidManifest.xml
+++ b/base/src/main/AndroidManifest.xml
@@ -1,2 +1,132 @@
+
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.maubis.scarlet.base">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/MainActivity.kt b/base/src/main/java/com/maubis/scarlet/base/MainActivity.kt
index 8d404868..977c1984 100644
--- a/base/src/main/java/com/maubis/scarlet/base/MainActivity.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/MainActivity.kt
@@ -1,33 +1,56 @@
package com.maubis.scarlet.base
import android.content.BroadcastReceiver
+import android.content.res.Configuration
import android.os.Bundle
-import android.support.v7.widget.LinearLayoutManager
-import android.support.v7.widget.RecyclerView
-import android.support.v7.widget.StaggeredGridLayoutManager
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.view.View.GONE
import android.widget.GridLayout.VERTICAL
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.facebook.litho.ComponentContext
import com.facebook.litho.LithoView
import com.github.bijoysingh.starter.recyclerview.RecyclerViewBuilder
+import com.maubis.scarlet.base.config.ApplicationBase
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.instance
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppPreferences
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
import com.maubis.scarlet.base.config.CoreConfig
-import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
+import com.maubis.scarlet.base.config.auth.IPendingUploadListener
import com.maubis.scarlet.base.core.note.NoteState
-import com.maubis.scarlet.base.core.note.sort
+import com.maubis.scarlet.base.database.room.folder.Folder
import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.database.room.tag.Tag
import com.maubis.scarlet.base.export.support.NoteExporter
import com.maubis.scarlet.base.export.support.PermissionUtils
-import com.maubis.scarlet.base.main.HomeNavigationState
-import com.maubis.scarlet.base.main.recycler.*
-import com.maubis.scarlet.base.main.sheets.AlertBottomSheet
+import com.maubis.scarlet.base.main.*
+import com.maubis.scarlet.base.main.HomeNavigationMode
+import com.maubis.scarlet.base.main.SearchState
+import com.maubis.scarlet.base.main.recycler.EmptyRecyclerItem
+import com.maubis.scarlet.base.main.recycler.GenericRecyclerItem
+import com.maubis.scarlet.base.main.recycler.getAppUpdateInformationItem
+import com.maubis.scarlet.base.main.recycler.getBackupInformationItem
+import com.maubis.scarlet.base.main.recycler.getInstallProInformationItem
+import com.maubis.scarlet.base.main.recycler.getMigrateToProAppInformationItem
+import com.maubis.scarlet.base.main.recycler.getReviewInformationItem
+import com.maubis.scarlet.base.main.recycler.getSignInInformationItem
+import com.maubis.scarlet.base.main.recycler.getThemeInformationItem
+import com.maubis.scarlet.base.main.recycler.shouldShowAppUpdateInformationItem
+import com.maubis.scarlet.base.main.recycler.shouldShowBackupInformationItem
+import com.maubis.scarlet.base.main.recycler.shouldShowInstallProInformationItem
+import com.maubis.scarlet.base.main.recycler.shouldShowMigrateToProAppInformationItem
+import com.maubis.scarlet.base.main.recycler.shouldShowReviewInformationItem
+import com.maubis.scarlet.base.main.recycler.shouldShowSignInformationItem
+import com.maubis.scarlet.base.main.recycler.shouldShowThemeInformationItem
import com.maubis.scarlet.base.main.sheets.WhatsNewBottomSheet
import com.maubis.scarlet.base.main.sheets.openDeleteTrashSheet
import com.maubis.scarlet.base.main.specs.MainActivityBottomBar
+import com.maubis.scarlet.base.main.specs.MainActivityDisabledSync
import com.maubis.scarlet.base.main.specs.MainActivityFolderBottomBar
+import com.maubis.scarlet.base.main.specs.MainActivitySyncingNow
import com.maubis.scarlet.base.main.utils.MainSnackbar
import com.maubis.scarlet.base.note.activity.INoteOptionSheetActivity
import com.maubis.scarlet.base.note.folder.FolderRecyclerItem
@@ -43,26 +66,39 @@ import com.maubis.scarlet.base.service.getNoteIntentFilter
import com.maubis.scarlet.base.settings.sheet.STORE_KEY_LINE_COUNT
import com.maubis.scarlet.base.settings.sheet.SettingsOptionsBottomSheet.Companion.KEY_MARKDOWN_ENABLED
import com.maubis.scarlet.base.settings.sheet.SettingsOptionsBottomSheet.Companion.KEY_MARKDOWN_HOME_ENABLED
-import com.maubis.scarlet.base.settings.sheet.SortingOptionsBottomSheet
-import com.maubis.scarlet.base.settings.sheet.UISettingsOptionsBottomSheet
import com.maubis.scarlet.base.settings.sheet.sNoteItemLineCount
-import com.maubis.scarlet.base.support.SearchConfig
+import com.maubis.scarlet.base.settings.sheet.sUIUseGridView
+import com.maubis.scarlet.base.support.database.HouseKeeper
import com.maubis.scarlet.base.support.database.HouseKeeperJob
import com.maubis.scarlet.base.support.database.Migrator
import com.maubis.scarlet.base.support.recycler.RecyclerItem
import com.maubis.scarlet.base.support.sheets.openSheet
import com.maubis.scarlet.base.support.specs.ToolbarColorConfig
+import com.maubis.scarlet.base.support.ui.SecuredActivity
import com.maubis.scarlet.base.support.ui.ThemeColorType
-import com.maubis.scarlet.base.support.ui.ThemedActivity
-import com.maubis.scarlet.base.support.unifiedFolderSearchSynchronous
-import com.maubis.scarlet.base.support.unifiedSearchSynchronous
+import com.maubis.scarlet.base.support.ui.sThemeIsAutomatic
+import com.maubis.scarlet.base.support.ui.setThemeFromSystem
import com.maubis.scarlet.base.support.utils.shouldShowWhatsNewSheet
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.search_toolbar_main.*
import kotlinx.android.synthetic.main.toolbar_trash_info.*
-import kotlinx.coroutines.*
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.async
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.newSingleThreadContext
+import java.util.concurrent.atomic.AtomicBoolean
+
+class MainActivity : SecuredActivity(), INoteOptionSheetActivity {
+ companion object {
+ private const val IS_IN_SEARCH_MODE: String = "IS_IN_SEARCH_MODE"
+ private const val NAVIGATION_MODE: String = "NAVIGATION_MODE"
+ private const val SEARCH_TEXT: String = "SEARCH_TEXT"
+ private const val CURRENT_FOLDER_UUID: String = "CURRENT_FOLDER_UUID"
+ private const val TAGS_UUIDS: String = "TAGS_UUIDS"
+ private const val SEARCH_COLORS: String = "SEARCH_COLORS"
+ }
-class MainActivity : ThemedActivity(), INoteOptionSheetActivity {
private val singleThreadDispatcher = newSingleThreadContext("singleThreadDispatcher")
private lateinit var recyclerView: RecyclerView
@@ -72,91 +108,137 @@ class MainActivity : ThemedActivity(), INoteOptionSheetActivity {
private lateinit var receiver: BroadcastReceiver
private lateinit var tagAndColorPicker: TagsAndColorPickerViewHolder
- var config: SearchConfig = SearchConfig(mode = HomeNavigationState.DEFAULT)
+ private var lastSyncPending: AtomicBoolean = AtomicBoolean(false)
+ private var lastSyncHappening: AtomicBoolean = AtomicBoolean(false)
+
+ val state: SearchState = SearchState(mode = HomeNavigationMode.DEFAULT)
var isInSearchMode: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
+ handleIntent()
// Migrate to the newer version of the tags
Migrator(this).start()
- config.mode = HomeNavigationState.DEFAULT
+ state.mode = HomeNavigationMode.DEFAULT
setupRecyclerView()
setListeners()
- notifyThemeChange()
+
+ if (sThemeIsAutomatic) {
+ setThemeFromSystem(this)
+ }
+ sAppTheme.notifyChange(this)
if (shouldShowWhatsNewSheet()) {
openSheet(this, WhatsNewBottomSheet())
}
}
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+
+ outState.putBoolean(IS_IN_SEARCH_MODE, isInSearchMode)
+ outState.putString(SEARCH_TEXT, state.text)
+ outState.putIntegerArrayList(SEARCH_COLORS, ArrayList(state.colors))
+ outState.putInt(NAVIGATION_MODE, state.mode.ordinal)
+ outState.putString(CURRENT_FOLDER_UUID, state.currentFolder?.uuid)
+ outState.putStringArrayList(TAGS_UUIDS, ArrayList(state.tags.map { it.uuid }))
+ }
+
+ override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
+ super.onRestoreInstanceState(savedInstanceState)
+
+ if (savedInstanceState != null) {
+ isInSearchMode = savedInstanceState.getBoolean(IS_IN_SEARCH_MODE)
+ state.text = savedInstanceState.getString(SEARCH_TEXT, "")
+ state.colors = savedInstanceState.getIntegerArrayList(SEARCH_COLORS) ?: ArrayList()
+ state.mode = HomeNavigationMode.values()[savedInstanceState.getInt(NAVIGATION_MODE)]
+ savedInstanceState.getString(CURRENT_FOLDER_UUID)?.let {
+ state.currentFolder = instance.foldersDatabase().getByUUID(it)
+ }
+ savedInstanceState.getStringArrayList(TAGS_UUIDS)?.forEach {
+ instance.tagsDatabase().getByUUID(it)?.let { state.tags.add(it) }
+ }
+ }
+ }
+
+ override fun onConfigurationChanged(configuration: Configuration) {
+ super.onConfigurationChanged(configuration)
+ startActivity(MainActivityActions.NIL.intent(this))
+ finish()
+ }
+
fun setListeners() {
- snackbar = MainSnackbar(bottomSnackbar, { setupData() })
+ snackbar = MainSnackbar(bottomSnackbar) { loadData() }
deleteTrashIcon.setOnClickListener { openDeleteTrashSheet(this@MainActivity) }
searchBackButton.setOnClickListener {
onBackPressed()
}
searchCloseIcon.setOnClickListener { onBackPressed() }
searchBox.addTextChangedListener(object : TextWatcher {
- override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
-
- }
+ override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
startSearch(charSequence.toString())
}
- override fun afterTextChanged(editable: Editable) {
-
- }
+ override fun afterTextChanged(editable: Editable) {}
})
tagAndColorPicker = TagsAndColorPickerViewHolder(
- this,
- tagsFlexBox,
- { tag ->
- val isTagSelected = config.tags.filter { it.uuid == tag.uuid }.isNotEmpty()
- when (isTagSelected) {
- true -> {
- config.tags.removeAll { it.uuid == tag.uuid }
- startSearch(searchBox.text.toString())
- tagAndColorPicker.notifyChanged()
- }
- false -> {
- openTag(tag)
- tagAndColorPicker.notifyChanged()
- }
+ this,
+ tagsFlexBox,
+ { tag ->
+ val isTagSelected = state.tags.filter { it.uuid == tag.uuid }.isNotEmpty()
+ when (isTagSelected) {
+ true -> {
+ state.tags.removeAll { it.uuid == tag.uuid }
+ startSearch(searchBox.text.toString())
+ tagAndColorPicker.notifyChanged()
}
- },
- { color ->
- when (config.colors.contains(color)) {
- true -> config.colors.remove(color)
- false -> config.colors.add(color)
+ false -> {
+ openTag(tag)
+ tagAndColorPicker.notifyChanged()
}
- tagAndColorPicker.notifyChanged()
- startSearch(searchBox.text.toString())
- })
+ }
+ },
+ { color ->
+ when (state.colors.contains(color)) {
+ true -> state.colors.remove(color)
+ false -> state.colors.add(color)
+ }
+ tagAndColorPicker.notifyChanged()
+ startSearch(searchBox.text.toString())
+ })
}
fun setupRecyclerView() {
- val staggeredView = UISettingsOptionsBottomSheet.useGridView
val isTablet = resources.getBoolean(R.bool.is_tablet)
- val isMarkdownEnabled = CoreConfig.instance.store().get(KEY_MARKDOWN_ENABLED, true)
- val isMarkdownHomeEnabled = CoreConfig.instance.store().get(KEY_MARKDOWN_HOME_ENABLED, true)
+ val isMarkdownEnabled = sAppPreferences.get(KEY_MARKDOWN_ENABLED, true)
+ val isMarkdownHomeEnabled = sAppPreferences.get(KEY_MARKDOWN_HOME_ENABLED, true)
val adapterExtra = Bundle()
adapterExtra.putBoolean(KEY_MARKDOWN_ENABLED, isMarkdownEnabled && isMarkdownHomeEnabled)
adapterExtra.putInt(STORE_KEY_LINE_COUNT, sNoteItemLineCount)
- adapter = NoteAppAdapter(this, staggeredView, isTablet)
+ adapter = NoteAppAdapter(this, sUIUseGridView, isTablet)
adapter.setExtra(adapterExtra)
recyclerView = RecyclerViewBuilder(this)
- .setView(this, R.id.recycler_view)
- .setAdapter(adapter)
- .setLayoutManager(getLayoutManager(staggeredView, isTablet))
- .build()
+ .setView(this, R.id.recycler_view)
+ .setAdapter(adapter)
+ .setLayoutManager(getLayoutManager(sUIUseGridView, isTablet))
+ .build()
+
+ vSwipeToRefresh.setOnRefreshListener {
+ when {
+ instance.authenticator().isLoggedIn(this)
+ && !instance.authenticator().isLegacyLoggedIn()
+ && !lastSyncHappening.get() -> instance.authenticator().requestSync(true)
+ else -> vSwipeToRefresh.isRefreshing = false
+ }
+ }
}
private fun getLayoutManager(isStaggeredView: Boolean, isTabletView: Boolean): RecyclerView.LayoutManager {
@@ -168,65 +250,50 @@ class MainActivity : ThemedActivity(), INoteOptionSheetActivity {
fun notifyAdapterExtraChanged() {
setupRecyclerView()
- resetAndSetupData()
+ resetAndLoadData()
}
- /**
- * Start: Home Navigation Clicks
- */
- fun onHomeClick() {
+ fun onModeChange(mode: HomeNavigationMode) {
GlobalScope.launch(Dispatchers.Main) {
- config.resetMode(HomeNavigationState.DEFAULT)
+ state.mode = mode
unifiedSearch()
notifyModeChange()
}
}
- fun onFavouritesClick() {
- GlobalScope.launch(Dispatchers.Main) {
- config.resetMode(HomeNavigationState.FAVOURITE)
- unifiedSearch()
- notifyModeChange()
- }
+ private fun notifyModeChange() {
+ val isTrash = state.mode === HomeNavigationMode.TRASH
+ deleteToolbar.visibility = if (isTrash) View.VISIBLE else GONE
}
- fun onArchivedClick() {
+ fun onFolderChange(folder: Folder?) {
GlobalScope.launch(Dispatchers.Main) {
- config.resetMode(HomeNavigationState.ARCHIVED)
+ state.currentFolder = folder
unifiedSearch()
- notifyModeChange()
+ notifyFolderChange()
}
}
- fun onTrashClick() {
- GlobalScope.launch(Dispatchers.Main) {
- config.resetMode(HomeNavigationState.TRASH)
- unifiedSearch()
- notifyModeChange()
- }
- }
+ private fun notifyFolderChange() {
+ val componentContext = ComponentContext(this)
+ lithoPreBottomToolbar.removeAllViews()
- fun onLockedClick() {
- GlobalScope.launch(Dispatchers.Main) {
- config.resetMode(HomeNavigationState.LOCKED)
- unifiedSearch()
- notifyModeChange()
+ val currentFolder = state.currentFolder
+ if (currentFolder != null) {
+ lithoPreBottomToolbar.addView(LithoView.create(componentContext,
+ MainActivityFolderBottomBar.create(componentContext)
+ .folder(currentFolder)
+ .build()))
}
+ else
+ notifyDisabledLegacySync()
}
- private fun notifyModeChange() {
- val isTrash = config.mode === HomeNavigationState.TRASH
- deleteToolbar.visibility = if (isTrash) View.VISIBLE else GONE
- }
-
- /**
- * End: Home Navigation Clicks
- */
-
private fun handleNewItems(notes: List) {
adapter.clearItems()
if (!isInSearchMode) {
adapter.addItem(GenericRecyclerItem(RecyclerItem.Type.TOOLBAR))
+ addInformationItem(1)
}
if (notes.isEmpty()) {
adapter.addItem(EmptyRecyclerItem())
@@ -235,13 +302,12 @@ class MainActivity : ThemedActivity(), INoteOptionSheetActivity {
notes.forEach {
adapter.addItem(it)
}
- addInformationItem(1)
}
private fun addInformationItem(index: Int) {
val informationItem = when {
shouldShowMigrateToProAppInformationItem(this) -> getMigrateToProAppInformationItem(this)
- shouldShowSignInformationItem() -> getSignInInformationItem(this)
+ shouldShowSignInformationItem(this) -> getSignInInformationItem(this)
shouldShowAppUpdateInformationItem() -> getAppUpdateInformationItem(this)
shouldShowReviewInformationItem() -> getReviewInformationItem(this)
shouldShowInstallProInformationItem() -> getInstallProInformationItem(this)
@@ -257,59 +323,101 @@ class MainActivity : ThemedActivity(), INoteOptionSheetActivity {
private suspend fun unifiedSearchSynchronous(): List {
val allItems = emptyList().toMutableList()
- allItems.addAll(unifiedFolderSearchSynchronous(config)
- .map {
- GlobalScope.async(Dispatchers.IO) {
- var notesCount = -1
- if (config.hasFilter()) {
- val folderConfig = config.copy()
- folderConfig.folders.clear()
- folderConfig.folders.add(it)
- notesCount = unifiedSearchSynchronous(folderConfig).size
- if (notesCount == 0) {
- return@async null
- }
- folderConfig.folders.clear()
- }
- FolderRecyclerItem(
- context = this@MainActivity,
- folder = it,
- click = {
- config.folders.clear()
- config.folders.add(it)
- unifiedSearch()
- notifyFolderChange()
- },
- longClick = {
- CreateOrEditFolderBottomSheet.openSheet(this@MainActivity, it, { _, _ -> setupData() })
- },
- selected = config.hasFolder(it),
- contents = notesCount)
- }
- }
- .map { it.await() }
- .filterNotNull())
- allItems.addAll(unifiedSearchSynchronous(config)
- .map { GlobalScope.async(Dispatchers.IO) { NoteRecyclerItem(this@MainActivity, it) } }
- .map { it.await() })
+ if (state.currentFolder != null) {
+ val allNotes = unifiedSearchSynchronous(state)
+ allItems.addAll(allNotes
+ .map { GlobalScope.async(Dispatchers.IO) { NoteRecyclerItem(this@MainActivity, it) } }
+ .map { it.await() })
+ return allItems
+ }
+
+ val allNotes = unifiedSearchWithoutFolder(state)
+ val directAcceptableFolders = filterDirectlyValidFolders(state)
+ allItems.addAll(CoreConfig.foldersDb.getAll()
+ .map {
+ GlobalScope.async(Dispatchers.IO) {
+ val isDirectFolder = directAcceptableFolders.contains(it)
+ val notesCount = filterFolder(allNotes, it).size
+ if (state.hasFilter() && notesCount == 0 && !isDirectFolder) {
+ return@async null
+ }
+
+ FolderRecyclerItem(
+ context = this@MainActivity,
+ folder = it,
+ click = { onFolderChange(it) },
+ longClick = {
+ CreateOrEditFolderBottomSheet.openSheet(this@MainActivity, it, { _, _ -> loadData() })
+ },
+ selected = state.currentFolder?.uuid == it.uuid,
+ contents = notesCount)
+ }
+ }
+ .map { it.await() }
+ .filterNotNull())
+ allItems.addAll(filterOutFolders(allNotes)
+ .map { GlobalScope.async(Dispatchers.IO) { NoteRecyclerItem(this@MainActivity, it) } }
+ .map { it.await() })
return allItems
}
- fun notifyFolderChange() {
+ private fun notifyDisabledLegacySync() {
val componentContext = ComponentContext(this)
lithoPreBottomToolbar.removeAllViews()
- if (config.folders.isEmpty()) {
+ if (!instance.authenticator().isLegacyLoggedIn()) {
return
}
- val folder = config.folders.first()
lithoPreBottomToolbar.addView(LithoView.create(componentContext,
- MainActivityFolderBottomBar.create(componentContext)
- .folder(folder)
- .build()))
+ MainActivityDisabledSync.create(componentContext)
+ .onClick {
+ instance.authenticator().openTransferDataActivity(componentContext.androidContext)?.run()
+ }
+ .build()))
}
- fun unifiedSearch() {
+ fun notifySyncingInformation(isSyncHappening: Boolean, isSyncPending: Boolean) {
+ val componentContext = ComponentContext(this)
+ if (!instance.authenticator().isLoggedIn(this)
+ || instance.authenticator().isLegacyLoggedIn()) {
+ return
+ }
+
+ if (lastSyncPending.getAndSet(isSyncPending) == isSyncPending
+ && lastSyncHappening.getAndSet(isSyncHappening) == isSyncHappening) {
+ return
+ }
+
+ if (!isSyncPending && !isSyncHappening) {
+ GlobalScope.launch(Dispatchers.Main) {
+ lithoSyncingBottomToolbar.removeAllViews()
+ }
+ return
+ }
+
+ GlobalScope.launch(Dispatchers.Main) {
+ lithoSyncingBottomToolbar.removeAllViews()
+ lithoSyncingBottomToolbar.addView(LithoView.create(componentContext,
+ MainActivitySyncingNow.create(componentContext)
+ .isSyncHappening(isSyncHappening)
+ .onClick {
+ if (!lastSyncHappening.get()) {
+ instance.authenticator().requestSync(true)
+ }
+ }
+ .onLongClick {
+ if (!lastSyncHappening.get()) {
+ instance.authenticator().showPendingSync(this@MainActivity)
+ }
+ }
+ .build()))
+ if (!isSyncHappening && isSyncPending) {
+ instance.authenticator().requestSync(false)
+ }
+ }
+ }
+
+ private fun unifiedSearch() {
GlobalScope.launch(Dispatchers.Main) {
val items = GlobalScope.async(Dispatchers.IO) { unifiedSearchSynchronous() }
handleNewItems(items.await())
@@ -317,57 +425,68 @@ class MainActivity : ThemedActivity(), INoteOptionSheetActivity {
}
fun openTag(tag: Tag) {
- config.mode = if (config.mode == HomeNavigationState.LOCKED) HomeNavigationState.DEFAULT else config.mode
- config.tags.add(tag)
+ state.mode = if (state.mode == HomeNavigationMode.LOCKED) HomeNavigationMode.DEFAULT else state.mode
+ state.tags.add(tag)
unifiedSearch()
notifyModeChange()
}
override fun onResume() {
super.onResume()
- CoreConfig.instance.startListener(this)
- setupData()
+ instance.startListener(this)
+ loadData()
registerNoteReceiver()
+ notifyFolderChange()
+
+ if (isInSearchMode)
+ enterSearchMode()
+
+ instance.authenticator().setPendingUploadListener(object : IPendingUploadListener {
+ override fun onPendingSyncsUpdate(isSyncHappening: Boolean) {
+ notifySyncingInformation(isSyncHappening, lastSyncPending.get())
+ GlobalScope.launch(Dispatchers.Main) {
+ vSwipeToRefresh.isRefreshing = false
+ }
+ }
+
+ override fun onPendingStateUpdate(isDataSyncPending: Boolean) {
+ notifySyncingInformation(lastSyncHappening.get(), isDataSyncPending)
+ }
+ })
+ instance.authenticator().requestSync(false)
}
- fun resetAndSetupData() {
- config.clear()
- setupData()
+ fun resetAndLoadData() {
+ state.clear()
+ loadData()
}
- fun setupData() {
- return when (config.mode) {
- HomeNavigationState.FAVOURITE -> onFavouritesClick()
- HomeNavigationState.ARCHIVED -> onArchivedClick()
- HomeNavigationState.TRASH -> onTrashClick()
- HomeNavigationState.LOCKED -> onLockedClick()
- HomeNavigationState.DEFAULT -> onHomeClick()
- else -> onHomeClick()
+ fun loadData() = onModeChange(state.mode)
+
+ fun enterSearchMode() {
+ isInSearchMode = true
+ searchBox.setText(state.text)
+ searchToolbar.visibility = View.VISIBLE
+ tryOpeningTheKeyboard()
+ GlobalScope.launch(Dispatchers.Main) {
+ GlobalScope.async(Dispatchers.IO) { tagAndColorPicker.reset() }.await()
+ tagAndColorPicker.notifyChanged()
}
+ searchBox.requestFocus()
}
- fun setSearchMode(mode: Boolean) {
- isInSearchMode = mode
- searchToolbar.visibility = if (isInSearchMode) View.VISIBLE else View.GONE
+ fun quitSearchMode() {
+ isInSearchMode = false
searchBox.setText("")
-
- if (isInSearchMode) {
- tryOpeningTheKeyboard()
- GlobalScope.launch(Dispatchers.Main) {
- GlobalScope.async(Dispatchers.IO) { tagAndColorPicker.reset() }.await()
- tagAndColorPicker.notifyChanged()
- }
- searchBox.requestFocus()
- } else {
- tryClosingTheKeyboard()
- config.clearSearchBar()
- setupData()
- }
+ tryClosingTheKeyboard()
+ searchToolbar.visibility = View.GONE
+ state.clearSearchBar()
+ loadData()
}
private fun startSearch(keyword: String) {
GlobalScope.launch(singleThreadDispatcher) {
- config.text = keyword
+ state.text = keyword
val items = GlobalScope.async(Dispatchers.IO) { unifiedSearchSynchronous() }
GlobalScope.launch(Dispatchers.Main) {
handleNewItems(items.await())
@@ -377,11 +496,12 @@ class MainActivity : ThemedActivity(), INoteOptionSheetActivity {
override fun onBackPressed() {
when {
- isInSearchMode && searchBox.text.toString().isBlank() -> setSearchMode(false)
+ isInSearchMode && searchBox.text.toString().isBlank() -> quitSearchMode()
isInSearchMode -> searchBox.setText("")
- config.hasFilter() -> {
- config.clear()
- onHomeClick()
+ state.currentFolder != null -> onFolderChange(null)
+ state.hasFilter() -> {
+ state.clear()
+ onModeChange(HomeNavigationMode.DEFAULT)
notifyFolderChange()
}
else -> super.onBackPressed()
@@ -391,6 +511,7 @@ class MainActivity : ThemedActivity(), INoteOptionSheetActivity {
override fun onPause() {
super.onPause()
unregisterReceiver(receiver)
+ instance.authenticator().setPendingUploadListener(null)
}
override fun onDestroy() {
@@ -401,17 +522,16 @@ class MainActivity : ThemedActivity(), INoteOptionSheetActivity {
override fun onStop() {
super.onStop()
if (PermissionUtils().getStoragePermissionManager(this).hasAllPermissions()) {
+ HouseKeeper(this).removeOlderClips()
NoteExporter().tryAutoExport()
}
}
override fun notifyThemeChange() {
setSystemTheme()
-
- val theme = CoreConfig.instance.themeController()
containerLayoutMain.setBackgroundColor(getThemeColor())
- val toolbarIconColor = theme.get(ThemeColorType.TOOLBAR_ICON)
+ val toolbarIconColor = sAppTheme.get(ThemeColorType.TOOLBAR_ICON)
deleteTrashIcon.setColorFilter(toolbarIconColor)
deletesAutomatically.setTextColor(toolbarIconColor)
@@ -420,18 +540,20 @@ class MainActivity : ThemedActivity(), INoteOptionSheetActivity {
private fun registerNoteReceiver() {
receiver = SyncedNoteBroadcastReceiver {
- setupData()
+ loadData()
}
registerReceiver(receiver, getNoteIntentFilter())
}
- fun setBottomToolbar() {
+ private fun setBottomToolbar() {
val componentContext = ComponentContext(this)
lithoBottomToolbar.removeAllViews()
- lithoBottomToolbar.addView(LithoView.create(componentContext,
+ lithoBottomToolbar.addView(
+ LithoView.create(
+ componentContext,
MainActivityBottomBar.create(componentContext)
- .colorConfig(ToolbarColorConfig())
- .build()))
+ .colorConfig(ToolbarColorConfig())
+ .build()))
}
/**
@@ -439,30 +561,30 @@ class MainActivity : ThemedActivity(), INoteOptionSheetActivity {
*/
override fun updateNote(note: Note) {
note.save(this)
- setupData()
+ loadData()
}
override fun markItem(note: Note, state: NoteState) {
note.mark(this, state)
- setupData()
+ loadData()
}
override fun moveItemToTrashOrDelete(note: Note) {
snackbar.softUndo(this, note)
note.softDelete(this)
- setupData()
+ loadData()
}
override fun notifyTagsChanged(note: Note) {
- setupData()
+ loadData()
}
override fun getSelectMode(note: Note): String {
- return config.mode.name
+ return state.mode.name
}
override fun notifyResetOrDismiss() {
- setupData()
+ loadData()
}
override fun lockedContentIsHidden() = true
diff --git a/base/src/main/java/com/maubis/scarlet/base/MainActivityExtensions.kt b/base/src/main/java/com/maubis/scarlet/base/MainActivityExtensions.kt
new file mode 100644
index 00000000..00b164ab
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/MainActivityExtensions.kt
@@ -0,0 +1,75 @@
+package com.maubis.scarlet.base
+
+import android.content.Context
+import android.content.Intent
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
+import com.maubis.scarlet.base.settings.sheet.ThemeColorPickerBottomSheet
+import com.maubis.scarlet.base.settings.sheet.TypefacePickerBottomSheet
+import com.maubis.scarlet.base.support.sheets.openSheet
+import com.maubis.scarlet.base.support.ui.font.sPreferenceTypeface
+import com.maubis.scarlet.base.support.ui.sThemeLabel
+
+const val INTENT_KEY_ADDITIONAL_ACTION = "additional_action"
+
+enum class MainActivityActions {
+ NIL,
+ COLOR_PICKER,
+ TYPEFACE_PICKER;
+
+ fun intent(context: Context): Intent {
+ val intent = Intent(context, MainActivity::class.java)
+ intent.putExtra(INTENT_KEY_ADDITIONAL_ACTION, this.name)
+ return intent
+ }
+}
+
+fun MainActivity.handleIntent() {
+ val actionFromIntent = intent.getStringExtra(INTENT_KEY_ADDITIONAL_ACTION)
+ if (actionFromIntent === null || actionFromIntent.isEmpty()) {
+ return
+ }
+
+ val action = try {
+ MainActivityActions.valueOf(actionFromIntent)
+ } catch (exception: Exception) {
+ null
+ }
+
+ if (action === null) {
+ return
+ }
+ performAction(action)
+}
+
+fun MainActivity.performAction(action: MainActivityActions) {
+ val activity = this
+ when (action) {
+ MainActivityActions.NIL -> {
+ }
+ MainActivityActions.COLOR_PICKER -> {
+ openSheet(this, ThemeColorPickerBottomSheet().apply {
+ this.onThemeChange = { theme ->
+ if (sThemeLabel != theme.name) {
+ sThemeLabel = theme.name
+ sAppTheme.notifyChange(activity)
+ activity.startActivity(MainActivityActions.COLOR_PICKER.intent(activity))
+ activity.finish()
+ }
+ }
+ })
+ }
+ MainActivityActions.TYPEFACE_PICKER -> {
+ openSheet(this, TypefacePickerBottomSheet().apply {
+ this.onTypefaceChange = { typeface ->
+ if (sPreferenceTypeface != typeface.name) {
+ sPreferenceTypeface = typeface.name
+ sAppTypeface.notifyChange(activity)
+ activity.startActivity(MainActivityActions.TYPEFACE_PICKER.intent(activity))
+ activity.finish()
+ }
+ }
+ })
+ }
+ }
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/config/ApplicationBase.kt b/base/src/main/java/com/maubis/scarlet/base/config/ApplicationBase.kt
index 349bf02a..ead2eec5 100644
--- a/base/src/main/java/com/maubis/scarlet/base/config/ApplicationBase.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/config/ApplicationBase.kt
@@ -1,14 +1,63 @@
package com.maubis.scarlet.base.config
import android.app.Application
+import androidx.biometric.BiometricManager
import com.evernote.android.job.JobManager
import com.facebook.soloader.SoLoader
+import com.github.bijoysingh.starter.prefs.Store
+import com.github.bijoysingh.starter.prefs.VersionedStore
+import com.maubis.scarlet.base.core.note.NoteImage
+import com.maubis.scarlet.base.export.remote.FolderRemoteDatabase
import com.maubis.scarlet.base.note.reminders.ReminderJobCreator
+import com.maubis.scarlet.base.support.ui.ThemeManager
+import com.maubis.scarlet.base.support.ui.font.TypefaceController
+import com.maubis.scarlet.base.support.utils.DateFormatUtils
+import com.maubis.scarlet.base.support.utils.Flavor
+import com.maubis.scarlet.base.support.utils.ImageCache
+import com.maubis.scarlet.base.support.utils.maybeThrow
+import com.maubis.scarlet.base.support.utils.sDateFormat
abstract class ApplicationBase : Application() {
override fun onCreate() {
super.onCreate()
+
+ // Preferences
+ sAppPreferences = VersionedStore.get(this, "USER_PREFERENCES", 1)
+
+ sBiometricManager = BiometricManager.from(this)
+
+ sDateFormat = DateFormatUtils(this)
SoLoader.init(this, false)
- JobManager.create(this).addJobCreator(ReminderJobCreator())
+ try {
+ JobManager.create(this).addJobCreator(ReminderJobCreator())
+ } catch (exception: Exception) {
+ maybeThrow(exception)
+ }
+
+ // Setup Image Cache
+ sAppImageStorage = NoteImage(this)
+ sAppImageCache = ImageCache(this)
+
+ // Setup Application Theme
+ sAppTheme = ThemeManager()
+ sAppTheme.setup(this)
+ sAppTypeface = TypefaceController(this)
+ }
+
+ companion object {
+ lateinit var instance: CoreConfig
+
+ lateinit var sAppFlavor: Flavor
+
+ lateinit var sAppImageStorage: NoteImage
+ lateinit var sAppImageCache: ImageCache
+
+ lateinit var sAppPreferences: Store
+
+ lateinit var sAppTheme: ThemeManager
+ lateinit var sAppTypeface: TypefaceController
+ lateinit var sBiometricManager: BiometricManager
+
+ var folderSync: FolderRemoteDatabase? = null
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/config/CoreConfig.kt b/base/src/main/java/com/maubis/scarlet/base/config/CoreConfig.kt
index 6c6576f4..379816d1 100644
--- a/base/src/main/java/com/maubis/scarlet/base/config/CoreConfig.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/config/CoreConfig.kt
@@ -1,14 +1,7 @@
package com.maubis.scarlet.base.config
-import android.content.Context
-import android.graphics.Typeface
-import android.support.v4.content.res.ResourcesCompat
-import android.support.v7.app.AppCompatActivity
-import com.github.ajalt.reprint.core.Reprint
-import com.github.bijoysingh.starter.prefs.Store
-import com.maubis.markdown.MarkdownConfig
-import com.maubis.markdown.MarkdownConfig.Companion.config
-import com.maubis.scarlet.base.R
+import androidx.appcompat.app.AppCompatActivity
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.instance
import com.maubis.scarlet.base.config.auth.IAuthenticator
import com.maubis.scarlet.base.config.remote.IRemoteConfigFetcher
import com.maubis.scarlet.base.core.folder.IFolderActor
@@ -17,23 +10,13 @@ import com.maubis.scarlet.base.core.tag.ITagActor
import com.maubis.scarlet.base.database.FoldersProvider
import com.maubis.scarlet.base.database.NotesProvider
import com.maubis.scarlet.base.database.TagsProvider
+import com.maubis.scarlet.base.database.remote.IRemoteDatabaseState
import com.maubis.scarlet.base.database.room.AppDatabase
import com.maubis.scarlet.base.database.room.folder.Folder
import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.database.room.tag.Tag
-import com.maubis.scarlet.base.export.remote.FolderRemoteDatabase
-import com.maubis.scarlet.base.support.ui.IThemeManager
-import com.maubis.scarlet.base.support.utils.Flavor
-import com.maubis.scarlet.base.support.utils.ImageCache
-abstract class CoreConfig(context: Context) {
-
- init {
- Reprint.initialize(context)
- config.spanConfig.headingTypeface = ResourcesCompat.getFont(context, R.font.monserrat) ?: Typeface.DEFAULT
- FONT_MONSERRAT = config.spanConfig.headingTypeface
- FONT_OPEN_SANS = ResourcesCompat.getFont(context, R.font.open_sans) ?: Typeface.DEFAULT
- }
+abstract class CoreConfig {
abstract fun database(): AppDatabase
@@ -51,27 +34,15 @@ abstract class CoreConfig(context: Context) {
abstract fun folderActions(folder: Folder): IFolderActor
- abstract fun themeController(): IThemeManager
-
abstract fun remoteConfigFetcher(): IRemoteConfigFetcher
- abstract fun startListener(activity: AppCompatActivity)
-
- abstract fun appFlavor(): Flavor
+ abstract fun remoteDatabaseState(): IRemoteDatabaseState
- abstract fun store(): Store
-
- abstract fun externalFolderSync(): FolderRemoteDatabase
-
- abstract fun imageCache(): ImageCache
+ abstract fun startListener(activity: AppCompatActivity)
companion object {
- lateinit var instance: CoreConfig
val notesDb get() = instance.notesDatabase()
val tagsDb get() = instance.tagsDatabase()
val foldersDb get() = instance.foldersDatabase()
-
- var FONT_MONSERRAT: Typeface = Typeface.DEFAULT
- var FONT_OPEN_SANS: Typeface = Typeface.DEFAULT
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/config/MaterialNoteConfig.kt b/base/src/main/java/com/maubis/scarlet/base/config/MaterialNoteConfig.kt
index 559fb162..a60b1736 100644
--- a/base/src/main/java/com/maubis/scarlet/base/config/MaterialNoteConfig.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/config/MaterialNoteConfig.kt
@@ -1,9 +1,7 @@
package com.maubis.scarlet.base.config
import android.content.Context
-import android.support.v7.app.AppCompatActivity
-import com.github.bijoysingh.starter.prefs.Store
-import com.github.bijoysingh.starter.prefs.VersionedStore
+import androidx.appcompat.app.AppCompatActivity
import com.maubis.scarlet.base.config.auth.IAuthenticator
import com.maubis.scarlet.base.config.auth.NullAuthenticator
import com.maubis.scarlet.base.config.remote.IRemoteConfigFetcher
@@ -17,31 +15,18 @@ import com.maubis.scarlet.base.core.tag.MaterialTagActor
import com.maubis.scarlet.base.database.FoldersProvider
import com.maubis.scarlet.base.database.NotesProvider
import com.maubis.scarlet.base.database.TagsProvider
+import com.maubis.scarlet.base.database.remote.IRemoteDatabaseState
import com.maubis.scarlet.base.database.room.AppDatabase
import com.maubis.scarlet.base.database.room.folder.Folder
import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.database.room.tag.Tag
-import com.maubis.scarlet.base.export.remote.FolderRemoteDatabase
-import com.maubis.scarlet.base.export.support.ExternalFolderSync
-import com.maubis.scarlet.base.support.ui.IThemeManager
-import com.maubis.scarlet.base.support.ui.ThemeManager
-import com.maubis.scarlet.base.support.utils.Flavor
-import com.maubis.scarlet.base.support.utils.ImageCache
-import java.lang.ref.WeakReference
-const val USER_PREFERENCES_STORE_NAME = "USER_PREFERENCES";
-const val USER_PREFERENCES_VERSION = 1;
-
-open class MaterialNoteConfig(context: Context) : CoreConfig(context) {
+open class MaterialNoteConfig(context: Context) : CoreConfig() {
val db = AppDatabase.createDatabase(context)
val notesProvider = NotesProvider()
val tagsProvider = TagsProvider()
val foldersProvider = FoldersProvider()
- val store = VersionedStore.get(context, USER_PREFERENCES_STORE_NAME, USER_PREFERENCES_VERSION)
- val appTheme = ThemeManager()
- val externalFolderSync = FolderRemoteDatabase(WeakReference(context))
- val imageCache = ImageCache(context)
override fun database(): AppDatabase = db
@@ -59,17 +44,14 @@ open class MaterialNoteConfig(context: Context) : CoreConfig(context) {
override fun folderActions(folder: Folder): IFolderActor = MaterialFolderActor(folder)
- override fun themeController(): IThemeManager = appTheme
-
override fun remoteConfigFetcher(): IRemoteConfigFetcher = NullRemoteConfigFetcher()
- override fun startListener(activity: AppCompatActivity) {}
-
- override fun appFlavor(): Flavor = Flavor.NONE
+ override fun remoteDatabaseState(): IRemoteDatabaseState {
+ return object : IRemoteDatabaseState {
+ override fun notifyInsert(data: Any, onExecution: () -> Unit) {}
+ override fun notifyRemove(data: Any, onExecution: () -> Unit) {}
+ }
+ }
- override fun store(): Store = store
-
- override fun externalFolderSync(): FolderRemoteDatabase = externalFolderSync
-
- override fun imageCache(): ImageCache = imageCache
+ override fun startListener(activity: AppCompatActivity) {}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/config/auth/IAuthenticator.kt b/base/src/main/java/com/maubis/scarlet/base/config/auth/IAuthenticator.kt
index c1881636..5cf57465 100644
--- a/base/src/main/java/com/maubis/scarlet/base/config/auth/IAuthenticator.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/config/auth/IAuthenticator.kt
@@ -1,18 +1,31 @@
package com.maubis.scarlet.base.config.auth
import android.content.Context
+import com.maubis.scarlet.base.support.ui.ThemedActivity
interface IAuthenticator {
fun setup(context: Context)
- fun isLoggedIn(): Boolean
+ fun isLoggedIn(context: Context): Boolean
- fun userId(): String?
+ fun isLegacyLoggedIn(): Boolean
+
+ fun userId(context: Context): String?
fun openLoginActivity(context: Context): Runnable?
fun openForgetMeActivity(context: Context): Runnable?
+ fun openTransferDataActivity(context: Context): Runnable?
+
+ fun openLogoutActivity(context: Context): Runnable?
+
+ fun setPendingUploadListener(listener: IPendingUploadListener?)
+
+ fun showPendingSync(activity: ThemedActivity)
+
+ fun requestSync(forced: Boolean)
+
fun logout()
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/config/auth/IPendingUploadListener.kt b/base/src/main/java/com/maubis/scarlet/base/config/auth/IPendingUploadListener.kt
new file mode 100644
index 00000000..365512fc
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/config/auth/IPendingUploadListener.kt
@@ -0,0 +1,13 @@
+package com.maubis.scarlet.base.config.auth
+
+interface IPendingUploadListener {
+ /**
+ * Fires when the pending state changes.
+ */
+ fun onPendingStateUpdate(isDataSyncPending: Boolean)
+
+ /**
+ * Pending Sync Count state change
+ */
+ fun onPendingSyncsUpdate(isSyncHappening: Boolean)
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/config/auth/NullAuthenticator.kt b/base/src/main/java/com/maubis/scarlet/base/config/auth/NullAuthenticator.kt
index 275d268d..ce66c911 100644
--- a/base/src/main/java/com/maubis/scarlet/base/config/auth/NullAuthenticator.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/config/auth/NullAuthenticator.kt
@@ -1,18 +1,31 @@
package com.maubis.scarlet.base.config.auth
import android.content.Context
+import com.maubis.scarlet.base.support.ui.ThemedActivity
class NullAuthenticator : IAuthenticator {
+
override fun openLoginActivity(context: Context): Runnable? = null
override fun openForgetMeActivity(context: Context): Runnable? = null
+ override fun openTransferDataActivity(context: Context): Runnable? = null
+
+ override fun openLogoutActivity(context: Context): Runnable? = null
+
override fun logout() {}
override fun setup(context: Context) {}
- override fun userId(): String? = null
+ override fun userId(context: Context): String? = null
+
+ override fun isLoggedIn(context: Context): Boolean = false
+
+ override fun isLegacyLoggedIn(): Boolean = false
+
+ override fun setPendingUploadListener(listener: IPendingUploadListener?) {}
- override fun isLoggedIn(): Boolean = false
+ override fun requestSync(forced: Boolean) {}
+ override fun showPendingSync(activity: ThemedActivity) {}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/config/remote/RemoteConfig.kt b/base/src/main/java/com/maubis/scarlet/base/config/remote/RemoteConfig.kt
index 209be365..0760e7e3 100644
--- a/base/src/main/java/com/maubis/scarlet/base/config/remote/RemoteConfig.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/config/remote/RemoteConfig.kt
@@ -1,6 +1,5 @@
package com.maubis.scarlet.base.config.remote
-
class RemoteConfig(
- val rc_lite_production_version: Int?,
- val rc_full_production_version: Int?)
+ val rc_lite_production_version: Int?,
+ val rc_full_production_version: Int?)
diff --git a/base/src/main/java/com/maubis/scarlet/base/core/folder/MaterialFolderActor.kt b/base/src/main/java/com/maubis/scarlet/base/core/folder/MaterialFolderActor.kt
index d52aff45..ab120899 100644
--- a/base/src/main/java/com/maubis/scarlet/base/core/folder/MaterialFolderActor.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/core/folder/MaterialFolderActor.kt
@@ -1,19 +1,20 @@
package com.maubis.scarlet.base.core.folder
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.folderSync
import com.maubis.scarlet.base.database.room.folder.Folder
import com.maubis.scarlet.base.export.data.ExportableFolder
open class MaterialFolderActor(val folder: Folder) : IFolderActor {
override fun offlineSave() {
- val id = CoreConfig.instance.foldersDatabase().database().insertFolder(folder)
+ val id = ApplicationBase.instance.foldersDatabase().database().insertFolder(folder)
folder.uid = if (folder.isUnsaved()) id.toInt() else folder.uid
- CoreConfig.instance.foldersDatabase().notifyInsertFolder(folder)
+ ApplicationBase.instance.foldersDatabase().notifyInsertFolder(folder)
}
override fun onlineSave() {
- CoreConfig.instance.externalFolderSync().insert(ExportableFolder(folder))
+ folderSync?.insert(ExportableFolder(folder))
}
override fun save() {
@@ -25,14 +26,14 @@ open class MaterialFolderActor(val folder: Folder) : IFolderActor {
if (folder.isUnsaved()) {
return
}
- CoreConfig.instance.foldersDatabase().database().delete(folder)
- CoreConfig.instance.foldersDatabase().notifyDelete(folder)
+ ApplicationBase.instance.foldersDatabase().database().delete(folder)
+ ApplicationBase.instance.foldersDatabase().notifyDelete(folder)
folder.uid = 0
}
override fun delete() {
offlineDelete()
- CoreConfig.instance.externalFolderSync().remove(ExportableFolder(folder))
+ folderSync?.remove(ExportableFolder(folder))
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/core/format/Format.kt b/base/src/main/java/com/maubis/scarlet/base/core/format/Format.kt
index 9b140fd1..26ad9b1f 100644
--- a/base/src/main/java/com/maubis/scarlet/base/core/format/Format.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/core/format/Format.kt
@@ -1,5 +1,6 @@
package com.maubis.scarlet.base.core.format
+import com.maubis.scarlet.base.note.creation.sheet.sEditorMoveChecked
import org.json.JSONObject
import java.util.*
@@ -62,17 +63,33 @@ class Format {
}
fun sectionPreservingSort(formats: List): List {
+ if (!sEditorMoveChecked) {
+ return formats
+ }
+
val mutableFormats = formats.toMutableList()
var index = 0
while (index < formats.size - 1) {
val currentItem = mutableFormats[index]
val nextItem = mutableFormats[index + 1]
- if (currentItem.formatType == FormatType.CHECKLIST_CHECKED && nextItem.formatType == FormatType.CHECKLIST_UNCHECKED) {
+ if (currentItem.formatType == FormatType.CHECKLIST_CHECKED
+ && nextItem.formatType == FormatType.CHECKLIST_UNCHECKED) {
Collections.swap(mutableFormats, index, index + 1)
continue
}
index += 1
}
+ while (index > 0) {
+ val currentItem = mutableFormats[index]
+ val nextItem = mutableFormats[index - 1]
+
+ if (currentItem.formatType == FormatType.CHECKLIST_UNCHECKED
+ && nextItem.formatType == FormatType.CHECKLIST_CHECKED) {
+ Collections.swap(mutableFormats, index, index - 1)
+ continue
+ }
+ index -= 1
+ }
return mutableFormats
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/core/format/FormatBuilder.kt b/base/src/main/java/com/maubis/scarlet/base/core/format/FormatBuilder.kt
index f2e357e1..d751f0cb 100644
--- a/base/src/main/java/com/maubis/scarlet/base/core/format/FormatBuilder.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/core/format/FormatBuilder.kt
@@ -1,8 +1,8 @@
package com.maubis.scarlet.base.core.format
-import com.maubis.markdown.segmenter.TextSegmenter
-import com.maubis.scarlet.base.note.toFormat
-import com.maubis.scarlet.base.note.toRawFormat
+import com.maubis.markdown.segmenter.MarkdownSegmentType
+import com.maubis.scarlet.base.note.toInternalFormats
+import com.maubis.scarlet.base.support.utils.maybeThrow
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
@@ -39,41 +39,15 @@ class FormatBuilder {
continue
}
- val moreFormats = TextSegmenter(format.text).get().map { it.toRawFormat() }
- var lastFormat: Format? = null
- for (rawFormat in moreFormats) {
- val isCheckedType = (rawFormat.formatType == FormatType.CHECKLIST_UNCHECKED || rawFormat.formatType == FormatType.CHECKLIST_CHECKED)
- if (lastFormat != null && !isCheckedType) {
- lastFormat.text += "\n"
- lastFormat.text += rawFormat.text
- continue
- }
-
- if (!isCheckedType) {
- rawFormat.formatType = FormatType.TEXT
- lastFormat = rawFormat
- continue
- }
-
- if (lastFormat != null) {
- extractedFormats.add(lastFormat)
- lastFormat = null
- }
-
- rawFormat.text = rawFormat.text
- .removePrefix("[] ")
- .removePrefix("[x] ")
- .removePrefix("[ ] ")
- .removePrefix("[X] ")
- extractedFormats.add(rawFormat)
- }
- if (lastFormat !== null) {
- extractedFormats.add(lastFormat)
- }
-
+ val moreFormats = format.text.toInternalFormats(
+ arrayOf(
+ MarkdownSegmentType.CHECKLIST_CHECKED,
+ MarkdownSegmentType.CHECKLIST_UNCHECKED))
+ extractedFormats.addAll(moreFormats)
}
return getDescription(extractedFormats)
}
+
fun getFormats(note: String): List {
val formats = ArrayList()
try {
@@ -85,9 +59,11 @@ class FormatBuilder {
format.uid = formats.size
formats.add(format)
} catch (innerException: JSONException) {
+ maybeThrow(innerException)
}
}
} catch (exception: Exception) {
+ maybeThrow(exception)
}
return formats
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/core/format/FormatType.kt b/base/src/main/java/com/maubis/scarlet/base/core/format/FormatType.kt
index af39f361..72be2fd6 100644
--- a/base/src/main/java/com/maubis/scarlet/base/core/format/FormatType.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/core/format/FormatType.kt
@@ -4,6 +4,9 @@ enum class FormatType {
TAG,
TEXT,
NUMBERED_LIST,
+ BULLET_1,
+ BULLET_2,
+ BULLET_3,
IMAGE,
HEADING,// HEADING_1
SUB_HEADING, // HEADING_2
@@ -13,5 +16,5 @@ enum class FormatType {
CODE,
QUOTE,
SEPARATOR,
- EMPTY,
+ EMPTY
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/core/note/INoteActor.kt b/base/src/main/java/com/maubis/scarlet/base/core/note/INoteActor.kt
index e02acf65..2496e72f 100644
--- a/base/src/main/java/com/maubis/scarlet/base/core/note/INoteActor.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/core/note/INoteActor.kt
@@ -1,7 +1,7 @@
package com.maubis.scarlet.base.core.note
import android.content.Context
-import android.support.v7.app.AppCompatActivity
+import androidx.appcompat.app.AppCompatActivity
interface INoteActor {
diff --git a/base/src/main/java/com/maubis/scarlet/base/core/note/MaterialNoteActor.kt b/base/src/main/java/com/maubis/scarlet/base/core/note/MaterialNoteActor.kt
index 24a35df4..ddbc6764 100644
--- a/base/src/main/java/com/maubis/scarlet/base/core/note/MaterialNoteActor.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/core/note/MaterialNoteActor.kt
@@ -3,23 +3,29 @@ package com.maubis.scarlet.base.core.note
import android.app.NotificationManager
import android.content.Context
import android.os.AsyncTask
-import android.os.Build
-import android.support.v7.app.AppCompatActivity
+import androidx.appcompat.app.AppCompatActivity
import com.github.bijoysingh.starter.util.IntentUtils
import com.github.bijoysingh.starter.util.TextUtils
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.folderSync
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppImageStorage
import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
-import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.core.format.FormatBuilder
+import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.export.data.ExportableNote
import com.maubis.scarlet.base.main.activity.WidgetConfigureActivity
-import com.maubis.scarlet.base.note.*
+import com.maubis.scarlet.base.note.deleteToSync
+import com.maubis.scarlet.base.note.getFullText
+import com.maubis.scarlet.base.note.getTitleForSharing
+import com.maubis.scarlet.base.note.mark
+import com.maubis.scarlet.base.note.save
+import com.maubis.scarlet.base.note.saveWithoutSync
import com.maubis.scarlet.base.notification.NotificationConfig
import com.maubis.scarlet.base.notification.NotificationHandler
-import com.maubis.scarlet.base.widget.AllNotesWidgetProvider.Companion.notifyAllChanged
import com.maubis.scarlet.base.service.FloatingNoteService
-import com.maubis.scarlet.base.support.utils.ImageCache
+import com.maubis.scarlet.base.support.utils.OsVersionUtils
+import com.maubis.scarlet.base.widget.AllNotesWidgetProvider.Companion.notifyAllChanged
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.util.*
@@ -31,10 +37,10 @@ open class MaterialNoteActor(val note: Note) : INoteActor {
override fun share(context: Context) {
IntentUtils.ShareBuilder(context)
- .setSubject(note.getTitle())
- .setText(note.getText())
- .setChooserText(context.getString(R.string.share_using))
- .share()
+ .setSubject(note.getTitleForSharing())
+ .setText(note.getFullText())
+ .setChooserText(context.getString(R.string.share_using))
+ .share()
}
override fun popup(activity: AppCompatActivity) {
@@ -51,7 +57,7 @@ open class MaterialNoteActor(val note: Note) : INoteActor {
}
override fun onlineSave(context: Context) {
- CoreConfig.instance.externalFolderSync().insert(ExportableNote(note))
+ folderSync?.insert(ExportableNote(note))
}
override fun save(context: Context) {
@@ -68,7 +74,7 @@ open class MaterialNoteActor(val note: Note) : INoteActor {
}
override fun offlineDelete(context: Context) {
- NoteImage(context).deleteAllFiles(note)
+ sAppImageStorage.deleteAllFiles(note)
if (note.isUnsaved()) {
return
}
@@ -92,9 +98,8 @@ open class MaterialNoteActor(val note: Note) : INoteActor {
note.save(activity)
}
-
override fun onlineDelete(context: Context) {
- CoreConfig.instance.externalFolderSync().remove(ExportableNote(note))
+ folderSync?.remove(ExportableNote(note))
}
override fun delete(context: Context) {
@@ -107,14 +112,14 @@ open class MaterialNoteActor(val note: Note) : INoteActor {
notifyAllChanged(context)
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?
notificationManager?.cancel(note.uid)
- CoreConfig.instance.imageCache().deleteNote(note.uuid)
+ ApplicationBase.sAppImageCache.deleteNote(note.uuid)
}
protected fun onNoteUpdated(context: Context) {
WidgetConfigureActivity.notifyNoteChange(context, note)
notifyAllChanged(context)
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?
- if (Build.VERSION.SDK_INT >= 23 && notificationManager != null) {
+ if (OsVersionUtils.canExtractActiveNotifications() && notificationManager != null) {
for (notification in notificationManager.activeNotifications) {
if (notification.id == note.uid) {
val handler = NotificationHandler(context)
diff --git a/base/src/main/java/com/maubis/scarlet/base/core/note/NoteBuilder.kt b/base/src/main/java/com/maubis/scarlet/base/core/note/NoteBuilder.kt
index b0d8d563..8f152e70 100644
--- a/base/src/main/java/com/maubis/scarlet/base/core/note/NoteBuilder.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/core/note/NoteBuilder.kt
@@ -3,10 +3,10 @@ package com.maubis.scarlet.base.core.note
import com.github.bijoysingh.starter.util.RandomHelper
import com.github.bijoysingh.starter.util.TextUtils
import com.google.gson.Gson
-import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.core.format.Format
import com.maubis.scarlet.base.core.format.FormatBuilder
import com.maubis.scarlet.base.core.format.FormatType
+import com.maubis.scarlet.base.database.room.note.Note
import java.util.*
fun generateUUID() = UUID.randomUUID().toString()
@@ -23,6 +23,7 @@ class NoteBuilder {
note.updateTimestamp = note.timestamp
note.color = -0xff8695
note.folder = ""
+ note.description = FormatBuilder().getDescription(emptyList())
return note
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/core/note/NoteExtensions.kt b/base/src/main/java/com/maubis/scarlet/base/core/note/NoteExtensions.kt
index bc706808..ec58e522 100644
--- a/base/src/main/java/com/maubis/scarlet/base/core/note/NoteExtensions.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/core/note/NoteExtensions.kt
@@ -2,11 +2,10 @@ package com.maubis.scarlet.base.core.note
import com.github.bijoysingh.starter.util.TextUtils
import com.google.gson.Gson
-import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.core.format.Format
import com.maubis.scarlet.base.core.format.FormatBuilder
-import com.maubis.scarlet.base.note.saveWithoutSync
-import java.util.*
+import com.maubis.scarlet.base.database.room.note.Note
+import com.maubis.scarlet.base.support.utils.throwOrReturn
fun Note.isUnsaved(): Boolean {
return this.uid === null || this.uid == 0
@@ -14,13 +13,14 @@ fun Note.isUnsaved(): Boolean {
fun Note.isEqual(note: Note): Boolean {
return TextUtils.areEqualNullIsEmpty(this.state, note.state)
- && TextUtils.areEqualNullIsEmpty(this.description, note.description)
- && TextUtils.areEqualNullIsEmpty(this.uuid, note.uuid)
- && TextUtils.areEqualNullIsEmpty(this.tags, note.tags)
- && this.timestamp.toLong() == note.timestamp.toLong()
- && this.color.toInt() == note.color.toInt()
- && this.locked == note.locked
- && this.pinned == note.pinned
+ && TextUtils.areEqualNullIsEmpty(this.description, note.description)
+ && TextUtils.areEqualNullIsEmpty(this.uuid, note.uuid)
+ && TextUtils.areEqualNullIsEmpty(this.tags, note.tags)
+ && this.timestamp.toLong() == note.timestamp.toLong()
+ && this.color.toInt() == note.color.toInt()
+ && this.locked == note.locked
+ && this.pinned == note.pinned
+ && this.folder == note.folder
}
/**************************************************************************************
@@ -35,15 +35,15 @@ fun Note.getNoteState(): NoteState {
try {
return NoteState.valueOf(this.state)
} catch (exception: Exception) {
- return NoteState.DEFAULT
+ return throwOrReturn(exception, NoteState.DEFAULT)
}
}
fun Note.getMeta(): NoteMeta {
try {
return Gson().fromJson(this.meta, NoteMeta::class.java) ?: NoteMeta()
- } catch (e: Exception) {
- return NoteMeta()
+ } catch (exception: Exception) {
+ return throwOrReturn(exception, NoteMeta())
}
}
@@ -63,6 +63,5 @@ fun Note.setReminderV2(reminder: Reminder) {
fun Note.getTagUUIDs(): MutableSet {
val tags = if (this.tags == null) "" else this.tags
- val split = tags.split(",")
- return HashSet(split)
+ return tags.split(",").filter { it.isNotBlank() }.toMutableSet()
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/core/note/NoteImage.kt b/base/src/main/java/com/maubis/scarlet/base/core/note/NoteImage.kt
index 6bf080e7..5cb70670 100644
--- a/base/src/main/java/com/maubis/scarlet/base/core/note/NoteImage.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/core/note/NoteImage.kt
@@ -4,11 +4,12 @@ import android.content.Context
import android.view.View
import android.widget.ImageView
import com.github.bijoysingh.starter.util.RandomHelper
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase
import com.maubis.scarlet.base.core.format.Format
import com.maubis.scarlet.base.core.format.FormatBuilder
import com.maubis.scarlet.base.core.format.FormatType
import com.maubis.scarlet.base.database.room.note.Note
+import com.maubis.scarlet.base.support.utils.maybeThrow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
@@ -38,7 +39,7 @@ class NoteImage(context: Context) {
fun getFile(noteUUID: String, imageFormat: Format): File {
if (imageFormat.formatType != FormatType.IMAGE) {
- throw IllegalArgumentException("Format should be an Image")
+ maybeThrow("Format should be an Image")
}
return getFile(noteUUID, imageFormat.text)
}
@@ -66,7 +67,7 @@ class NoteImage(context: Context) {
return@launch
}
- val bitmap = CoreConfig.instance.imageCache().loadFromCache(file)
+ val bitmap = ApplicationBase.sAppImageCache.loadFromCache(file)
if (bitmap === null) {
deleteIfExist(file)
GlobalScope.launch(Dispatchers.Main) {
@@ -83,12 +84,13 @@ class NoteImage(context: Context) {
}
}
- fun loadThumbnailFileToImageView(noteUUID: String, imageUuid: String,
- image: ImageView,
- callback: ImageLoadCallback? = null) {
+ fun loadThumbnailFileToImageView(
+ noteUUID: String, imageUuid: String,
+ image: ImageView,
+ callback: ImageLoadCallback? = null) {
GlobalScope.launch {
- val thumbnailFile = CoreConfig.instance.imageCache().thumbnailFile(noteUUID, imageUuid)
- val persistentFile = CoreConfig.instance.imageCache().persistentFile(noteUUID, imageUuid)
+ val thumbnailFile = ApplicationBase.sAppImageCache.thumbnailFile(noteUUID, imageUuid)
+ val persistentFile = ApplicationBase.sAppImageCache.persistentFile(noteUUID, imageUuid)
if (!persistentFile.exists()) {
GlobalScope.launch(Dispatchers.Main) {
@@ -99,7 +101,7 @@ class NoteImage(context: Context) {
}
if (thumbnailFile.exists()) {
- val bitmap = CoreConfig.instance.imageCache().loadFromCache(thumbnailFile)
+ val bitmap = ApplicationBase.sAppImageCache.loadFromCache(thumbnailFile)
if (bitmap === null) {
deleteIfExist(thumbnailFile)
GlobalScope.launch(Dispatchers.Main) {
@@ -116,7 +118,7 @@ class NoteImage(context: Context) {
return@launch
}
- val persistentBitmap = CoreConfig.instance.imageCache().loadFromCache(persistentFile)
+ val persistentBitmap = ApplicationBase.sAppImageCache.loadFromCache(persistentFile)
if (persistentBitmap === null) {
deleteIfExist(persistentFile)
GlobalScope.launch(Dispatchers.Main) {
@@ -126,7 +128,7 @@ class NoteImage(context: Context) {
return@launch
}
- val compressedBitmap = CoreConfig.instance.imageCache().saveThumbnail(thumbnailFile, persistentBitmap)
+ val compressedBitmap = ApplicationBase.sAppImageCache.saveThumbnail(thumbnailFile, persistentBitmap)
GlobalScope.launch(Dispatchers.Main) {
image.visibility = View.VISIBLE
image.setImageBitmap(compressedBitmap)
diff --git a/base/src/main/java/com/maubis/scarlet/base/core/note/NoteReminder.kt b/base/src/main/java/com/maubis/scarlet/base/core/note/NoteReminder.kt
index 8a86b188..9dcfec2d 100644
--- a/base/src/main/java/com/maubis/scarlet/base/core/note/NoteReminder.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/core/note/NoteReminder.kt
@@ -12,11 +12,10 @@ class NoteReminder() {
var interval: ReminderInterval = ReminderInterval.ONCE
var daysOfWeek: IntArray = intArrayOf()
-
constructor(
- alarmTimestamp: Long,
- interval: ReminderInterval,
- daysOfWeek: IntArray) : this() {
+ alarmTimestamp: Long,
+ interval: ReminderInterval,
+ daysOfWeek: IntArray) : this() {
this.alarmTimestamp = alarmTimestamp
this.interval = interval
this.daysOfWeek = daysOfWeek
@@ -50,9 +49,10 @@ class NoteReminder() {
}
}
-class Reminder(var uid: Int = 0,
- var timestamp: Long = 0,
- var interval: ReminderInterval = ReminderInterval.ONCE) {
+class Reminder(
+ var uid: Int = 0,
+ var timestamp: Long = 0,
+ var interval: ReminderInterval = ReminderInterval.ONCE) {
fun toCalendar(): Calendar {
val calendar = Calendar.getInstance()
diff --git a/base/src/main/java/com/maubis/scarlet/base/core/note/NoteSortingUtils.kt b/base/src/main/java/com/maubis/scarlet/base/core/note/NoteSortingUtils.kt
index 1113cc22..cfe48f16 100644
--- a/base/src/main/java/com/maubis/scarlet/base/core/note/NoteSortingUtils.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/core/note/NoteSortingUtils.kt
@@ -1,15 +1,28 @@
package com.maubis.scarlet.base.core.note
import com.maubis.scarlet.base.database.room.note.Note
-import com.maubis.scarlet.base.note.getAlphabets
import com.maubis.scarlet.base.note.getFullText
-import com.maubis.scarlet.base.note.getText
enum class SortingTechnique() {
LAST_MODIFIED,
NEWEST_FIRST,
OLDEST_FIRST,
ALPHABETICAL,
+ NOTE_COLOR,
+ NOTE_TAGS,
+}
+
+/**
+ * Helper class which allow comparison of a pair of objects
+ */
+class ComparablePair, U : Comparable>(val first: T, val second: U) : Comparable> {
+ override fun compareTo(other: ComparablePair): Int {
+ val firstComparison = first.compareTo(other.first)
+ return when {
+ firstComparison == 0 -> second.compareTo(other.second)
+ else -> firstComparison
+ }
+ }
}
fun sort(notes: List, sortingTechnique: SortingTechnique): List {
@@ -24,13 +37,36 @@ fun sort(notes: List, sortingTechnique: SortingTechnique): List {
else note.timestamp
}
SortingTechnique.ALPHABETICAL -> notes.sortedBy { note ->
- val content = note.getAlphabets()
- if (note.pinned || content.isBlank()) 0
- else content[0].toUpperCase().toInt()
+ val content = note.getFullText().trim().filter {
+ ((it in 'a'..'z') || (it in 'A'..'Z'))
+ }
+
+ val sortValue = when {
+ (note.pinned || content.isBlank()) -> 0
+ else -> content[0].toUpperCase().toInt()
+ }
+ ComparablePair(sortValue, note.updateTimestamp)
+ }
+ SortingTechnique.NOTE_COLOR -> notes.sortedBy { note ->
+ ComparablePair(note.color, note.updateTimestamp)
}
- else -> notes.sortedByDescending { note ->
+ SortingTechnique.NOTE_TAGS -> {
+ val tagCounterMap = HashMap()
+ notes.map { it.getTagUUIDs() }.forEach { tags ->
+ tags.forEach { tag ->
+ tagCounterMap[tag] = (tagCounterMap[tag] ?: 0) + 1
+ }
+ }
+ notes.sortedByDescending {
+ val noteTagScore = it.getTagUUIDs().sumBy { tag ->
+ tagCounterMap[tag] ?: 0
+ }
+ ComparablePair(ComparablePair(noteTagScore, it.tags ?: ""), it.updateTimestamp)
+ }
+ }
+ SortingTechnique.NEWEST_FIRST -> notes.sortedByDescending { note ->
if (note.pinned) Long.MAX_VALUE
- else note.timestamp
+ else note.timestamp ?: note.updateTimestamp
}
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/core/tag/MaterialTagActor.kt b/base/src/main/java/com/maubis/scarlet/base/core/tag/MaterialTagActor.kt
index c078e8e8..3d80d88a 100644
--- a/base/src/main/java/com/maubis/scarlet/base/core/tag/MaterialTagActor.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/core/tag/MaterialTagActor.kt
@@ -1,18 +1,18 @@
package com.maubis.scarlet.base.core.tag
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase
import com.maubis.scarlet.base.database.room.tag.Tag
import com.maubis.scarlet.base.export.data.ExportableTag
open class MaterialTagActor(val tag: Tag) : ITagActor {
override fun offlineSave() {
- val id = CoreConfig.instance.tagsDatabase().database().insertTag(tag)
+ val id = ApplicationBase.instance.tagsDatabase().database().insertTag(tag)
tag.uid = if (tag.isUnsaved()) id.toInt() else tag.uid
- CoreConfig.instance.tagsDatabase().notifyInsertTag(tag)
+ ApplicationBase.instance.tagsDatabase().notifyInsertTag(tag)
}
override fun onlineSave() {
- CoreConfig.instance.externalFolderSync().insert(ExportableTag(tag))
+ ApplicationBase.folderSync?.insert(ExportableTag(tag))
}
override fun save() {
@@ -24,14 +24,14 @@ open class MaterialTagActor(val tag: Tag) : ITagActor {
if (tag.isUnsaved()) {
return
}
- CoreConfig.instance.tagsDatabase().database().delete(tag)
- CoreConfig.instance.tagsDatabase().notifyDelete(tag)
+ ApplicationBase.instance.tagsDatabase().database().delete(tag)
+ ApplicationBase.instance.tagsDatabase().notifyDelete(tag)
tag.uid = 0
}
override fun delete() {
offlineDelete()
- CoreConfig.instance.externalFolderSync().remove(ExportableTag(tag))
+ ApplicationBase.folderSync?.remove(ExportableTag(tag))
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/database/FoldersProvider.kt b/base/src/main/java/com/maubis/scarlet/base/database/FoldersProvider.kt
index ca9cf894..79393ddb 100644
--- a/base/src/main/java/com/maubis/scarlet/base/database/FoldersProvider.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/database/FoldersProvider.kt
@@ -1,10 +1,8 @@
package com.maubis.scarlet.base.database
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase
import com.maubis.scarlet.base.database.room.folder.Folder
import com.maubis.scarlet.base.database.room.folder.FolderDao
-import com.maubis.scarlet.base.database.room.tag.Tag
-import com.maubis.scarlet.base.database.room.tag.TagDao
import java.util.concurrent.ConcurrentHashMap
class FoldersProvider {
@@ -26,6 +24,11 @@ class FoldersProvider {
return folders.size
}
+ fun getUUIDs(): List {
+ maybeLoadFromDB()
+ return folders.values.map { it.uuid }
+ }
+
fun getAll(): List {
maybeLoadFromDB()
return folders.values.toList()
@@ -49,7 +52,7 @@ class FoldersProvider {
fun search(string: String): List {
maybeLoadFromDB()
return folders.values
- .filter { string.isBlank() || it.title.contains(string, true) }
+ .filter { string.isBlank() || it.title.contains(string, true) }
}
@Synchronized
@@ -67,6 +70,6 @@ class FoldersProvider {
}
fun database(): FolderDao {
- return CoreConfig.instance.database().folders()
+ return ApplicationBase.instance.database().folders()
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/database/NotesProvider.kt b/base/src/main/java/com/maubis/scarlet/base/database/NotesProvider.kt
index 3857de91..459f1af8 100644
--- a/base/src/main/java/com/maubis/scarlet/base/database/NotesProvider.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/database/NotesProvider.kt
@@ -1,8 +1,7 @@
package com.maubis.scarlet.base.database
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase
import com.maubis.scarlet.base.core.note.INoteContainer
-import com.maubis.scarlet.base.database.room.folder.Folder
import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.database.room.note.NoteDao
import com.maubis.scarlet.base.note.applySanityChecks
@@ -27,6 +26,11 @@ class NotesProvider {
return notes.size
}
+ fun getUUIDs(): List {
+ maybeLoadFromDB()
+ return notes.values.map { it.uuid }
+ }
+
fun getAll(): List {
maybeLoadFromDB()
return notes.values.toList()
@@ -107,6 +111,6 @@ class NotesProvider {
}
fun database(): NoteDao {
- return CoreConfig.instance.database().notes()
+ return ApplicationBase.instance.database().notes()
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/database/TagsProvider.kt b/base/src/main/java/com/maubis/scarlet/base/database/TagsProvider.kt
index d0bd5abf..ca7ac14f 100644
--- a/base/src/main/java/com/maubis/scarlet/base/database/TagsProvider.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/database/TagsProvider.kt
@@ -1,6 +1,6 @@
package com.maubis.scarlet.base.database
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase
import com.maubis.scarlet.base.database.room.tag.Tag
import com.maubis.scarlet.base.database.room.tag.TagDao
import java.util.concurrent.ConcurrentHashMap
@@ -24,6 +24,11 @@ class TagsProvider {
return tags.size
}
+ fun getUUIDs(): List {
+ maybeLoadFromDB()
+ return tags.values.map { it.uuid }
+ }
+
fun getAll(): List {
maybeLoadFromDB()
return tags.values.toList()
@@ -47,7 +52,7 @@ class TagsProvider {
fun search(string: String): List {
maybeLoadFromDB()
return tags.values
- .filter { string.isBlank() || it.title.contains(string, true) }
+ .filter { string.isBlank() || it.title.contains(string, true) }
}
@Synchronized
@@ -65,6 +70,6 @@ class TagsProvider {
}
fun database(): TagDao {
- return CoreConfig.instance.database().tags()
+ return ApplicationBase.instance.database().tags()
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/database/remote/IRemoteDatabaseState.kt b/base/src/main/java/com/maubis/scarlet/base/database/remote/IRemoteDatabaseState.kt
new file mode 100644
index 00000000..4b66085b
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/database/remote/IRemoteDatabaseState.kt
@@ -0,0 +1,6 @@
+package com.maubis.scarlet.base.database.remote
+
+interface IRemoteDatabaseState {
+ fun notifyInsert(data: Any, onExecution: () -> Unit)
+ fun notifyRemove(data: Any, onExecution: () -> Unit)
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/database/remote/IRemoteDatabaseUtils.kt b/base/src/main/java/com/maubis/scarlet/base/database/remote/IRemoteDatabaseUtils.kt
index c1c66c74..3915c55a 100644
--- a/base/src/main/java/com/maubis/scarlet/base/database/remote/IRemoteDatabaseUtils.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/database/remote/IRemoteDatabaseUtils.kt
@@ -44,7 +44,7 @@ object IRemoteDatabaseUtils {
val notifiedTag = TagBuilder().copy(tag)
val existingTag = CoreConfig.tagsDb.getByUUID(tag.uuid())
var isSameAsExisting = existingTag !== null
- && TextUtils.areEqualNullIsEmpty(notifiedTag.title, existingTag.title)
+ && TextUtils.areEqualNullIsEmpty(notifiedTag.title, existingTag.title)
if (existingTag === null) {
notifiedTag.saveWithoutSync()
@@ -62,10 +62,10 @@ object IRemoteDatabaseUtils {
val notifiedFolder = FolderBuilder().copy(folder)
val existingFolder = CoreConfig.foldersDb.getByUUID(folder.uuid())
var isSameAsExisting = existingFolder !== null
- && TextUtils.areEqualNullIsEmpty(notifiedFolder.title, existingFolder.title)
- && (notifiedFolder.color == existingFolder.color)
- && (notifiedFolder.timestamp == existingFolder.timestamp)
- && (notifiedFolder.updateTimestamp == existingFolder.updateTimestamp)
+ && TextUtils.areEqualNullIsEmpty(notifiedFolder.title, existingFolder.title)
+ && (notifiedFolder.color == existingFolder.color)
+ && (notifiedFolder.timestamp == existingFolder.timestamp)
+ && (notifiedFolder.updateTimestamp == existingFolder.updateTimestamp)
if (existingFolder === null) {
notifiedFolder.saveWithoutSync()
@@ -90,8 +90,20 @@ object IRemoteDatabaseUtils {
}
}
+ fun onRemoteRemoveNote(context: Context, noteUUID: String) {
+ val existingNote = CoreConfig.notesDb.getByUUID(noteUUID)
+ if (existingNote !== null && !existingNote.disableBackup) {
+ existingNote.deleteWithoutSync(context)
+ sendNoteBroadcast(context, NoteBroadcast.NOTE_DELETED, existingNote.uuid)
+ }
+ }
+
fun onRemoteRemove(context: Context, tag: ITagContainer) {
- val existingTag = CoreConfig.tagsDb.getByUUID(tag.uuid())
+ onRemoteRemoveTag(context, tag.uuid())
+ }
+
+ fun onRemoteRemoveTag(context: Context, tagUUID: String) {
+ val existingTag = CoreConfig.tagsDb.getByUUID(tagUUID)
if (existingTag !== null) {
existingTag.deleteWithoutSync()
sendNoteBroadcast(context, NoteBroadcast.TAG_DELETED, existingTag.uuid)
@@ -99,7 +111,11 @@ object IRemoteDatabaseUtils {
}
fun onRemoteRemove(context: Context, folder: IFolderContainer) {
- val existingFolder = CoreConfig.foldersDb.getByUUID(folder.uuid())
+ onRemoteRemoveFolder(context, folder.uuid())
+ }
+
+ fun onRemoteRemoveFolder(context: Context, folderUUID: String) {
+ val existingFolder = CoreConfig.foldersDb.getByUUID(folderUUID)
if (existingFolder !== null) {
existingFolder.deleteWithoutSync()
CoreConfig.notesDb.getAll().filter { it.folder == existingFolder.uuid }.forEach {
diff --git a/base/src/main/java/com/maubis/scarlet/base/database/room/AppDatabase.java b/base/src/main/java/com/maubis/scarlet/base/database/room/AppDatabase.java
index feb44cd3..2ca937ff 100644
--- a/base/src/main/java/com/maubis/scarlet/base/database/room/AppDatabase.java
+++ b/base/src/main/java/com/maubis/scarlet/base/database/room/AppDatabase.java
@@ -1,12 +1,13 @@
package com.maubis.scarlet.base.database.room;
-import android.arch.persistence.db.SupportSQLiteDatabase;
-import android.arch.persistence.room.Database;
-import android.arch.persistence.room.Room;
-import android.arch.persistence.room.RoomDatabase;
-import android.arch.persistence.room.migration.Migration;
import android.content.Context;
+import androidx.room.Database;
+import androidx.room.Room;
+import androidx.room.RoomDatabase;
+import androidx.room.migration.Migration;
+import androidx.sqlite.db.SupportSQLiteDatabase;
+
import com.maubis.scarlet.base.database.room.folder.Folder;
import com.maubis.scarlet.base.database.room.folder.FolderDao;
import com.maubis.scarlet.base.database.room.note.Note;
@@ -16,7 +17,7 @@
import com.maubis.scarlet.base.database.room.widget.Widget;
import com.maubis.scarlet.base.database.room.widget.WidgetDao;
-@Database(entities = {Note.class, Tag.class, Widget.class, Folder.class}, version = 13)
+@Database(entities = {Note.class, Tag.class, Widget.class, Folder.class}, version = 14)
public abstract class AppDatabase extends RoomDatabase {
public static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@@ -91,7 +92,7 @@ public void migrate(SupportSQLiteDatabase database) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE IF NOT EXISTS folder (`uid` INTEGER PRIMARY KEY " +
- "AUTOINCREMENT NOT NULL, `title` TEXT, `timestamp` INTEGER, " +
+ "AUTOINCREMENT, `title` TEXT, `timestamp` INTEGER, " +
"`updateTimestamp` INTEGER NOT NULL, `color` INTEGER, `uuid` TEXT)");
database.execSQL("CREATE INDEX `index_folder_uid` ON `folder` (`uid`)");
}
@@ -99,15 +100,36 @@ public void migrate(SupportSQLiteDatabase database) {
public static final Migration MIGRATION_12_13 = new Migration(12, 13) {
@Override
public void migrate(SupportSQLiteDatabase database) {
+ database.beginTransaction();
+ database.execSQL("CREATE TEMPORARY TABLE folder_backup(`title` TEXT, `timestamp` INTEGER, " +
+ "`updateTimestamp` INTEGER NOT NULL, `color` INTEGER, `uuid` TEXT)");
+ database.execSQL("INSERT INTO folder_backup SELECT title, timestamp, updateTimestamp, color, uuid FROM folder");
+ database.execSQL("DROP TABLE folder");
+ database.execSQL("CREATE TABLE folder(`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
+ " `title` TEXT, `timestamp` INTEGER, " +
+ "`updateTimestamp` INTEGER NOT NULL, `color` INTEGER, `uuid` TEXT)");
+ database.execSQL("CREATE INDEX IF NOT EXISTS `index_folder_uid` ON `folder` (`uid`)");
+ database.execSQL("INSERT INTO folder SELECT NULL, title, timestamp, updateTimestamp, color, uuid FROM folder_backup");
+ database.execSQL("DROP TABLE folder_backup");
database.execSQL("ALTER TABLE note ADD COLUMN folder TEXT DEFAULT ''");
+ database.setTransactionSuccessful();
+ database.endTransaction();
+ }
+ };
+ public static final Migration MIGRATION_13_14 = new Migration(13, 14) {
+ @Override
+ public void migrate(SupportSQLiteDatabase database) {
}
};
public static AppDatabase createDatabase(Context context) {
return Room.databaseBuilder(context, AppDatabase.class, "note-database")
.allowMainThreadQueries()
- .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, MIGRATION_5_6, MIGRATION_6_7, MIGRATION_7_8, MIGRATION_8_9, MIGRATION_9_10, MIGRATION_10_11, MIGRATION_11_12, MIGRATION_12_13)
- .build();
+ .addMigrations(
+ MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, MIGRATION_5_6,
+ MIGRATION_6_7, MIGRATION_7_8, MIGRATION_8_9, MIGRATION_9_10, MIGRATION_10_11,
+ MIGRATION_11_12, MIGRATION_12_13, MIGRATION_13_14
+ ).build();
}
public abstract NoteDao notes();
diff --git a/base/src/main/java/com/maubis/scarlet/base/database/room/folder/Folder.java b/base/src/main/java/com/maubis/scarlet/base/database/room/folder/Folder.java
index 16e58666..c3f3a064 100644
--- a/base/src/main/java/com/maubis/scarlet/base/database/room/folder/Folder.java
+++ b/base/src/main/java/com/maubis/scarlet/base/database/room/folder/Folder.java
@@ -1,8 +1,8 @@
package com.maubis.scarlet.base.database.room.folder;
-import android.arch.persistence.room.Entity;
-import android.arch.persistence.room.Index;
-import android.arch.persistence.room.PrimaryKey;
+import androidx.room.Entity;
+import androidx.room.Index;
+import androidx.room.PrimaryKey;
/**
* Underlying Database, difficult to migrate to Kotlin without breaking the Database.
diff --git a/base/src/main/java/com/maubis/scarlet/base/database/room/folder/FolderDao.java b/base/src/main/java/com/maubis/scarlet/base/database/room/folder/FolderDao.java
index 0052c6d6..5b0b29e0 100644
--- a/base/src/main/java/com/maubis/scarlet/base/database/room/folder/FolderDao.java
+++ b/base/src/main/java/com/maubis/scarlet/base/database/room/folder/FolderDao.java
@@ -1,12 +1,10 @@
package com.maubis.scarlet.base.database.room.folder;
-import android.arch.persistence.room.Dao;
-import android.arch.persistence.room.Delete;
-import android.arch.persistence.room.Insert;
-import android.arch.persistence.room.OnConflictStrategy;
-import android.arch.persistence.room.Query;
-
-import com.maubis.scarlet.base.database.room.note.Note;
+import androidx.room.Dao;
+import androidx.room.Delete;
+import androidx.room.Insert;
+import androidx.room.OnConflictStrategy;
+import androidx.room.Query;
import java.util.List;
diff --git a/base/src/main/java/com/maubis/scarlet/base/database/room/note/Note.java b/base/src/main/java/com/maubis/scarlet/base/database/room/note/Note.java
index 70ed043c..92595d22 100644
--- a/base/src/main/java/com/maubis/scarlet/base/database/room/note/Note.java
+++ b/base/src/main/java/com/maubis/scarlet/base/database/room/note/Note.java
@@ -1,8 +1,8 @@
package com.maubis.scarlet.base.database.room.note;
-import android.arch.persistence.room.Entity;
-import android.arch.persistence.room.Index;
-import android.arch.persistence.room.PrimaryKey;
+import androidx.room.Entity;
+import androidx.room.Index;
+import androidx.room.PrimaryKey;
/**
* Underlying Database, difficult to migrate to Kotlin without breaking the Database.
@@ -29,7 +29,7 @@ public class Note {
public boolean locked;
- public String tags;
+ public String tags = "";
public long updateTimestamp;
diff --git a/base/src/main/java/com/maubis/scarlet/base/database/room/note/NoteDao.java b/base/src/main/java/com/maubis/scarlet/base/database/room/note/NoteDao.java
index a0f776a4..024b7022 100644
--- a/base/src/main/java/com/maubis/scarlet/base/database/room/note/NoteDao.java
+++ b/base/src/main/java/com/maubis/scarlet/base/database/room/note/NoteDao.java
@@ -1,10 +1,10 @@
package com.maubis.scarlet.base.database.room.note;
-import android.arch.persistence.room.Dao;
-import android.arch.persistence.room.Delete;
-import android.arch.persistence.room.Insert;
-import android.arch.persistence.room.OnConflictStrategy;
-import android.arch.persistence.room.Query;
+import androidx.room.Dao;
+import androidx.room.Delete;
+import androidx.room.Insert;
+import androidx.room.OnConflictStrategy;
+import androidx.room.Query;
import java.util.List;
@@ -38,8 +38,7 @@ public interface NoteDao {
@Query("SELECT * FROM note WHERE tags LIKE :uuidRegex ORDER BY pinned DESC, timestamp DESC")
List getNoteByTag(String uuidRegex);
- @Query("SELECT COUNT(*) FROM note WHERE tags LIKE :uuidRegex ORDER BY pinned DESC, timestamp "
- + "DESC")
+ @Query("SELECT COUNT(*) FROM note WHERE tags LIKE :uuidRegex ORDER BY pinned DESC, timestamp " + "DESC")
int getNoteCountByTag(String uuidRegex);
@Query("SELECT * FROM note WHERE uid = :uid LIMIT 1")
diff --git a/base/src/main/java/com/maubis/scarlet/base/database/room/tag/Tag.java b/base/src/main/java/com/maubis/scarlet/base/database/room/tag/Tag.java
index 3bb2d189..f60a1a97 100644
--- a/base/src/main/java/com/maubis/scarlet/base/database/room/tag/Tag.java
+++ b/base/src/main/java/com/maubis/scarlet/base/database/room/tag/Tag.java
@@ -1,8 +1,8 @@
package com.maubis.scarlet.base.database.room.tag;
-import android.arch.persistence.room.Entity;
-import android.arch.persistence.room.Index;
-import android.arch.persistence.room.PrimaryKey;
+import androidx.room.Entity;
+import androidx.room.Index;
+import androidx.room.PrimaryKey;
@Entity(tableName = "tag", indices = {@Index("uid")})
public class Tag {
diff --git a/base/src/main/java/com/maubis/scarlet/base/database/room/tag/TagDao.java b/base/src/main/java/com/maubis/scarlet/base/database/room/tag/TagDao.java
index a0e56c05..26099a9c 100644
--- a/base/src/main/java/com/maubis/scarlet/base/database/room/tag/TagDao.java
+++ b/base/src/main/java/com/maubis/scarlet/base/database/room/tag/TagDao.java
@@ -1,10 +1,10 @@
package com.maubis.scarlet.base.database.room.tag;
-import android.arch.persistence.room.Dao;
-import android.arch.persistence.room.Delete;
-import android.arch.persistence.room.Insert;
-import android.arch.persistence.room.OnConflictStrategy;
-import android.arch.persistence.room.Query;
+import androidx.room.Dao;
+import androidx.room.Delete;
+import androidx.room.Insert;
+import androidx.room.OnConflictStrategy;
+import androidx.room.Query;
import java.util.List;
diff --git a/base/src/main/java/com/maubis/scarlet/base/database/room/widget/Widget.java b/base/src/main/java/com/maubis/scarlet/base/database/room/widget/Widget.java
index 7d0b301a..3eea9aad 100644
--- a/base/src/main/java/com/maubis/scarlet/base/database/room/widget/Widget.java
+++ b/base/src/main/java/com/maubis/scarlet/base/database/room/widget/Widget.java
@@ -1,8 +1,8 @@
package com.maubis.scarlet.base.database.room.widget;
-import android.arch.persistence.room.Entity;
-import android.arch.persistence.room.Index;
-import android.arch.persistence.room.PrimaryKey;
+import androidx.room.Entity;
+import androidx.room.Index;
+import androidx.room.PrimaryKey;
@Entity(tableName = "widget", indices = {@Index("widgetId")})
public class Widget {
diff --git a/base/src/main/java/com/maubis/scarlet/base/database/room/widget/WidgetDao.java b/base/src/main/java/com/maubis/scarlet/base/database/room/widget/WidgetDao.java
index 9b868efb..005e16c1 100644
--- a/base/src/main/java/com/maubis/scarlet/base/database/room/widget/WidgetDao.java
+++ b/base/src/main/java/com/maubis/scarlet/base/database/room/widget/WidgetDao.java
@@ -1,10 +1,10 @@
package com.maubis.scarlet.base.database.room.widget;
-import android.arch.persistence.room.Dao;
-import android.arch.persistence.room.Delete;
-import android.arch.persistence.room.Insert;
-import android.arch.persistence.room.OnConflictStrategy;
-import android.arch.persistence.room.Query;
+import androidx.room.Dao;
+import androidx.room.Delete;
+import androidx.room.Insert;
+import androidx.room.OnConflictStrategy;
+import androidx.room.Query;
import java.util.List;
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/activity/ImportNoteActivity.kt b/base/src/main/java/com/maubis/scarlet/base/export/activity/ImportNoteActivity.kt
index 00fc8f9b..fcd9e70f 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/activity/ImportNoteActivity.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/activity/ImportNoteActivity.kt
@@ -9,19 +9,18 @@ import android.widget.TextView
import com.github.bijoysingh.starter.async.MultiAsyncTask
import com.github.bijoysingh.starter.recyclerview.RecyclerViewBuilder
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
import com.maubis.scarlet.base.export.recycler.FileRecyclerItem
import com.maubis.scarlet.base.export.support.NoteImporter
import com.maubis.scarlet.base.note.recycler.NoteAppAdapter
-import com.maubis.scarlet.base.support.utils.bind
import com.maubis.scarlet.base.support.recycler.RecyclerItem
+import com.maubis.scarlet.base.support.ui.SecuredActivity
import com.maubis.scarlet.base.support.ui.ThemeColorType
-import com.maubis.scarlet.base.support.ui.ThemedActivity
+import com.maubis.scarlet.base.support.utils.bind
import java.io.File
import java.io.FileReader
-
-class ImportNoteActivity : ThemedActivity() {
+class ImportNoteActivity : SecuredActivity() {
val adapter = NoteAppAdapter(this)
var currentlySelectedFile: File? = null
@@ -35,9 +34,9 @@ class ImportNoteActivity : ThemedActivity() {
setContentView(R.layout.activity_import_note_from_file)
RecyclerViewBuilder(this)
- .setView(this, R.id.recycler_view)
- .setAdapter(adapter)
- .build()
+ .setView(this, R.id.recycler_view)
+ .setAdapter(adapter)
+ .build()
val activity = this
backButton.setOnClickListener { onBackPressed() }
@@ -67,8 +66,8 @@ class ImportNoteActivity : ThemedActivity() {
MultiAsyncTask.execute(object : MultiAsyncTask.Task> {
override fun run(): List {
return NoteImporter().getImportableFiles()
- .map { FileRecyclerItem(it.name, it.lastModified(), it.absolutePath, it) }
- .sorted()
+ .map { FileRecyclerItem(it.name, it.lastModified(), it.absolutePath, it) }
+ .sorted()
}
override fun handle(result: List) {
@@ -95,13 +94,12 @@ class ImportNoteActivity : ThemedActivity() {
}
override fun notifyThemeChange() {
- val theme = CoreConfig.instance.themeController()
- background.setBackgroundColor(theme.get(ThemeColorType.BACKGROUND))
- backButton.setColorFilter(theme.get(ThemeColorType.TOOLBAR_ICON))
- pageTitle.setTextColor(theme.get(ThemeColorType.TERTIARY_TEXT))
- importFile.setTextColor(theme.get(ThemeColorType.TERTIARY_TEXT))
+ background.setBackgroundColor(sAppTheme.get(ThemeColorType.BACKGROUND))
+ backButton.setColorFilter(sAppTheme.get(ThemeColorType.TOOLBAR_ICON))
+ pageTitle.setTextColor(sAppTheme.get(ThemeColorType.TERTIARY_TEXT))
+ importFile.setTextColor(sAppTheme.get(ThemeColorType.TERTIARY_TEXT))
importFile.setBackgroundResource(
- if (CoreConfig.instance.themeController().isNightTheme()) R.drawable.light_circular_border_bg
- else R.drawable.dark_circular_border_bg)
+ if (sAppTheme.isNightTheme()) R.drawable.light_circular_border_bg
+ else R.drawable.dark_circular_border_bg)
}
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableData.kt b/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableData.kt
new file mode 100644
index 00000000..ad17e1b4
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableData.kt
@@ -0,0 +1,126 @@
+package com.maubis.scarlet.base.export.data
+
+import com.maubis.scarlet.base.core.folder.IFolderContainer
+import com.maubis.scarlet.base.core.note.NoteState
+import com.maubis.scarlet.base.core.note.generateUUID
+import com.maubis.scarlet.base.core.tag.ITagContainer
+import com.maubis.scarlet.base.core.tag.TagBuilder
+import com.maubis.scarlet.base.database.room.folder.Folder
+import com.maubis.scarlet.base.database.room.tag.Tag
+import org.json.JSONObject
+import java.io.Serializable
+import java.util.*
+
+/**
+ * Data class containing the note as a string of the content which can be stored in user
+ * readable format (markdown) and meta data object
+ */
+class ExportableSplitNote(
+ val content: String,
+ val meta: ExportableNoteMeta) {
+
+ // Default failsafe constructor for Gson to use
+ constructor() : this(
+ "",
+ ExportableNoteMeta())
+}
+
+/**
+ * Data class containing only the meta data for the note which makes it unique to Scarlet
+ */
+class ExportableNoteMeta(
+ val uuid: String,
+ val timestamp: Long,
+ val updateTimestamp: Long,
+ val color: Int,
+ val state: String,
+ val tags: String,
+ val locked: Boolean,
+ val pinned: Boolean,
+ val folder: String) {
+
+ // Default failsafe constructor for Gson to use
+ constructor() : this(
+ "invalid",
+ Calendar.getInstance().timeInMillis,
+ Calendar.getInstance().timeInMillis,
+ -0xff8695,
+ NoteState.DEFAULT.name,
+ "",
+ false,
+ false,
+ "")
+}
+
+/**
+ * Data class for the exportability of tags
+ */
+class ExportableTag(
+ var uuid: String,
+ var title: String
+) : Serializable, ITagContainer {
+
+ override fun title(): String = title
+
+ override fun uuid(): String = uuid
+
+ // Default failsafe constructor for Gson to use
+ constructor() : this("invalid", "")
+
+ constructor(tag: Tag) : this(
+ tag.uuid,
+ tag.title
+ )
+
+ companion object {
+ fun fromJSON(json: JSONObject): ExportableTag {
+ val version = if (json.has("version")) json.getInt("version") else 1
+ return when (version) {
+ 1 -> fromJSONObjectV1(json)
+ else -> fromJSONObjectV1(json)
+ }
+ }
+
+ fun fromJSONObjectV1(json: JSONObject): ExportableTag {
+ return ExportableTag(
+ generateUUID(),
+ json["title"] as String)
+ }
+
+ fun getBestPossibleTagObject(json: JSONObject): Tag {
+ return TagBuilder().copy(fromJSON(json))
+ }
+ }
+}
+
+/**
+ * Data class for the exportability of folder
+ */
+class ExportableFolder(
+ val uuid: String,
+ val title: String,
+ val timestamp: Long,
+ val updateTimestamp: Long,
+ val color: Int
+) : Serializable, IFolderContainer {
+ override fun timestamp(): Long = timestamp
+ override fun updateTimestamp(): Long = updateTimestamp
+ override fun color(): Int = color
+ override fun title(): String = title
+ override fun uuid(): String = uuid
+
+ constructor(folder: Folder) : this(
+ folder.uuid ?: "",
+ folder.title ?: "",
+ folder.timestamp ?: 0,
+ folder.updateTimestamp,
+ folder.color ?: 0)
+
+ // Default failsafe constructor for Gson to use
+ constructor() : this(
+ "invalid",
+ "",
+ Calendar.getInstance().timeInMillis,
+ Calendar.getInstance().timeInMillis,
+ -0xff8695)
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableExtensions.kt b/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableExtensions.kt
new file mode 100644
index 00000000..a65f67dd
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableExtensions.kt
@@ -0,0 +1,96 @@
+package com.maubis.scarlet.base.export.data
+
+import com.maubis.scarlet.base.core.format.FormatBuilder
+import com.maubis.scarlet.base.core.format.FormatType
+import com.maubis.scarlet.base.core.note.getFormats
+import com.maubis.scarlet.base.database.room.folder.Folder
+import com.maubis.scarlet.base.database.room.note.Note
+import com.maubis.scarlet.base.database.room.tag.Tag
+import com.maubis.scarlet.base.note.toInternalFormats
+
+/**
+ * Converts the note which is markdown into internal format
+ */
+fun fromExportedMarkdown(content: String): String {
+ val formats = content.toInternalFormats()
+ return FormatBuilder().getDescription(formats)
+}
+
+/**
+ * Converts the note's internal description format into markdown which can be used to export.
+ */
+fun Note.toExportedMarkdown(): String {
+ val markdownBuilder = StringBuilder()
+ getFormats().forEach { format ->
+ val text = format.text
+ val formatMarkdown = when (format.formatType) {
+ FormatType.NUMBERED_LIST -> "- $text"
+ FormatType.HEADING -> "# $text"
+ FormatType.HEADING_3 -> "### $text"
+ FormatType.BULLET_1 -> "- $text"
+ FormatType.BULLET_2 -> " - $text"
+ FormatType.BULLET_3 -> " - $text"
+ FormatType.CHECKLIST_CHECKED -> "[x] $text"
+ FormatType.CHECKLIST_UNCHECKED -> "[ ] $text"
+ FormatType.SUB_HEADING -> "## $text"
+ FormatType.CODE -> "```\n$text\n```"
+ FormatType.QUOTE -> "> $text"
+ // TODO: Fix the fact that markdown parsing wont parse this correctly
+ FormatType.IMAGE -> "$text"
+ FormatType.SEPARATOR -> "\n---\n"
+ FormatType.TEXT -> text
+
+ // NOTE: All the following states should never happen at this place
+
+ FormatType.TAG -> ""
+ FormatType.EMPTY -> ""
+ }
+ markdownBuilder.append(formatMarkdown)
+ markdownBuilder.append("\n")
+ }
+ return markdownBuilder.toString().trim()
+}
+
+fun Note.getExportableSplitNote(): ExportableSplitNote {
+ return ExportableSplitNote(
+ toExportedMarkdown(),
+ getExportableNoteMeta())
+}
+
+fun Note.getExportableNoteMeta(): ExportableNoteMeta {
+ return ExportableNoteMeta(
+ uuid,
+ timestamp,
+ updateTimestamp,
+ color,
+ state,
+ if (tags == null) "" else tags,
+ locked,
+ pinned,
+ folder
+ )
+}
+
+fun Note.mergeMetas(meta: ExportableNoteMeta) {
+ uuid = meta.uuid
+ state = meta.state
+ timestamp = meta.timestamp
+ updateTimestamp = meta.updateTimestamp
+ color = meta.color
+ tags = meta.tags
+ pinned = meta.pinned
+ locked = meta.locked
+ folder = meta.folder
+}
+
+fun Folder.getExportableFolder(): ExportableFolder {
+ return ExportableFolder(
+ uuid,
+ title,
+ timestamp,
+ updateTimestamp,
+ color
+ )
+}
+
+fun Tag.getExportableTag(): ExportableTag = ExportableTag(uuid, title)
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableFileFormat.kt b/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableFileFormat.kt
index fbfdd65e..49a92b6a 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableFileFormat.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableFileFormat.kt
@@ -1,7 +1,7 @@
package com.maubis.scarlet.base.export.data
class ExportableFileFormat(
- val version: Int,
- val notes: List,
- val tags: List,
- val folders: List?)
\ No newline at end of file
+ val version: Int,
+ val notes: List,
+ val tags: List,
+ val folders: List?)
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableFolder.kt b/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableFolder.kt
deleted file mode 100644
index 006e2233..00000000
--- a/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableFolder.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.maubis.scarlet.base.export.data
-
-import com.maubis.scarlet.base.core.folder.IFolderContainer
-import com.maubis.scarlet.base.database.room.folder.Folder
-import java.io.Serializable
-
-class ExportableFolder(
- val uuid: String,
- val title: String,
- val timestamp: Long,
- val updateTimestamp: Long,
- val color: Int
-) : Serializable, IFolderContainer {
- override fun timestamp(): Long = timestamp
- override fun updateTimestamp(): Long = updateTimestamp
- override fun color(): Int = color
- override fun title(): String = title
- override fun uuid(): String = uuid
-
- constructor(folder: Folder) : this(
- folder.uuid ?: "",
- folder.title ?: "",
- folder.timestamp ?: 0,
- folder.updateTimestamp,
- folder.color ?: 0)
-}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableNote.kt b/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableNote.kt
index 08acf717..20d4406d 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableNote.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableNote.kt
@@ -1,28 +1,28 @@
package com.maubis.scarlet.base.export.data
import android.content.Context
-import com.maubis.scarlet.base.database.room.note.Note
-import com.maubis.scarlet.base.database.room.tag.Tag
+import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
import com.maubis.scarlet.base.core.note.INoteContainer
import com.maubis.scarlet.base.core.note.NoteBuilder
import com.maubis.scarlet.base.core.note.generateUUID
+import com.maubis.scarlet.base.database.room.note.Note
+import com.maubis.scarlet.base.database.room.tag.Tag
import com.maubis.scarlet.base.note.save
import com.maubis.scarlet.base.note.tag.save
-import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
import org.json.JSONArray
import org.json.JSONObject
import java.io.Serializable
class ExportableNote(
- var uuid: String,
- var description: String,
- var timestamp: Long,
- var updateTimestamp: Long,
- var color: Int,
- var state: String,
- var tags: String,
- var meta: Map,
- var folder: String
+ var uuid: String,
+ var description: String,
+ var timestamp: Long,
+ var updateTimestamp: Long,
+ var color: Int,
+ var state: String,
+ var tags: String,
+ var meta: Map,
+ var folder: String
) : Serializable, INoteContainer {
override fun uuid(): String = uuid
@@ -48,15 +48,15 @@ class ExportableNote(
override fun folder(): String = folder
constructor(note: Note) : this(
- note.uuid,
- note.description,
- note.timestamp,
- note.updateTimestamp,
- note.color,
- note.state,
- note.tags ?: "",
- emptyMap(),
- note.folder
+ note.uuid,
+ note.description,
+ note.timestamp,
+ note.updateTimestamp,
+ note.color,
+ note.state,
+ note.tags ?: "",
+ emptyMap(),
+ note.folder
)
fun saveIfNeeded(context: Context) {
@@ -75,41 +75,41 @@ class ExportableNote(
fun fromJSONObjectV2(json: JSONObject): ExportableNote {
return ExportableNote(
- generateUUID(),
- json["description"] as String,
- json["timestamp"] as Long,
- json["timestamp"] as Long,
- json["color"] as Int,
- "",
- "",
- emptyMap(),
- "")
+ generateUUID(),
+ json["description"] as String,
+ json["timestamp"] as Long,
+ json["timestamp"] as Long,
+ json["color"] as Int,
+ "",
+ "",
+ emptyMap(),
+ "")
}
fun fromJSONObjectV3(json: JSONObject): ExportableNote {
return ExportableNote(
- generateUUID(),
- json["description"] as String,
- json["timestamp"] as Long,
- json["timestamp"] as Long,
- json["color"] as Int,
- json["state"] as String,
- convertTagsJSONArrayToString(json["tags"] as JSONArray),
- emptyMap(),
- "")
+ generateUUID(),
+ json["description"] as String,
+ json["timestamp"] as Long,
+ json["timestamp"] as Long,
+ json["color"] as Int,
+ json["state"] as String,
+ convertTagsJSONArrayToString(json["tags"] as JSONArray),
+ emptyMap(),
+ "")
}
fun fromJSONObjectV4(json: JSONObject): ExportableNote {
return ExportableNote(
- json["uuid"] as String,
- json["description"] as String,
- json["timestamp"] as Long,
- json["timestamp"] as Long,
- json["color"] as Int,
- json["state"] as String,
- convertTagsJSONArrayToString(json["tags"] as JSONArray),
- emptyMap(),
- "")
+ json["uuid"] as String,
+ json["description"] as String,
+ json["timestamp"] as Long,
+ json["timestamp"] as Long,
+ json["color"] as Int,
+ json["state"] as String,
+ convertTagsJSONArrayToString(json["tags"] as JSONArray),
+ emptyMap(),
+ "")
}
private fun convertTagsJSONArrayToString(tags: JSONArray): String {
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableTag.kt b/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableTag.kt
deleted file mode 100644
index 6e0ad4fe..00000000
--- a/base/src/main/java/com/maubis/scarlet/base/export/data/ExportableTag.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.maubis.scarlet.base.export.data
-
-import com.maubis.scarlet.base.database.room.tag.Tag
-import com.maubis.scarlet.base.core.note.generateUUID
-import com.maubis.scarlet.base.core.tag.ITagContainer
-import com.maubis.scarlet.base.core.tag.TagBuilder
-import org.json.JSONObject
-import java.io.Serializable
-
-class ExportableTag(
- var uuid: String,
- var title: String
-) : Serializable, ITagContainer {
-
- override fun title(): String = title
-
- override fun uuid(): String = uuid
-
- constructor(tag: Tag) : this(
- tag.uuid,
- tag.title
- )
-
- companion object {
- fun fromJSON(json: JSONObject): ExportableTag {
- val version = if (json.has("version")) json.getInt("version") else 1
- return when (version) {
- 1 -> fromJSONObjectV1(json)
- else -> fromJSONObjectV1(json)
- }
- }
-
- fun fromJSONObjectV1(json: JSONObject): ExportableTag {
- return ExportableTag(
- generateUUID(),
- json["title"] as String)
- }
-
- fun getBestPossibleTagObject(json: JSONObject): Tag {
- return TagBuilder().copy(fromJSON(json))
- }
- }
-}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/recycler/FileImportViewHolder.kt b/base/src/main/java/com/maubis/scarlet/base/export/recycler/FileImportViewHolder.kt
index b0398925..1f85aeb1 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/recycler/FileImportViewHolder.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/recycler/FileImportViewHolder.kt
@@ -7,13 +7,14 @@ import android.os.Environment
import android.view.View
import android.widget.TextView
import com.github.bijoysingh.starter.recyclerview.RecyclerViewHolder
-import com.github.bijoysingh.starter.util.DateFormatter
import com.github.bijoysingh.starter.util.LocaleManager
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
import com.maubis.scarlet.base.export.activity.ImportNoteActivity
import com.maubis.scarlet.base.support.recycler.RecyclerItem
import com.maubis.scarlet.base.support.ui.ThemeColorType
+import com.maubis.scarlet.base.support.utils.sDateFormat
import java.io.File
class FileImportViewHolder(context: Context, root: View)
@@ -25,26 +26,32 @@ class FileImportViewHolder(context: Context, root: View)
private val fileSize: TextView = findViewById(R.id.file_size)
init {
- val theme = CoreConfig.instance.themeController()
- fileName.setTextColor(theme.get(ThemeColorType.SECONDARY_TEXT))
- filePath.setTextColor(theme.get(ThemeColorType.HINT_TEXT))
- fileDate.setTextColor(theme.get(ThemeColorType.TERTIARY_TEXT))
- fileSize.setTextColor(theme.get(ThemeColorType.TERTIARY_TEXT))
+ fileName.setTextColor(sAppTheme.get(ThemeColorType.SECONDARY_TEXT))
+ filePath.setTextColor(sAppTheme.get(ThemeColorType.HINT_TEXT))
+ fileDate.setTextColor(sAppTheme.get(ThemeColorType.TERTIARY_TEXT))
+ fileSize.setTextColor(sAppTheme.get(ThemeColorType.TERTIARY_TEXT))
}
override fun populate(data: RecyclerItem, extra: Bundle?) {
val item = data as FileRecyclerItem
fileName.text = item.name
+ fileName.typeface = ApplicationBase.sAppTypeface.title()
+
filePath.text = getPath(item)
+ filePath.typeface = ApplicationBase.sAppTypeface.text()
+
fileDate.text = getSubtitleText(item.file)
+ fileDate.typeface = ApplicationBase.sAppTypeface.text()
+
fileSize.text = getMetaText(item.file)
+ fileSize.typeface = ApplicationBase.sAppTypeface.text()
root.setOnClickListener {
(context as ImportNoteActivity).select(item)
}
root.setBackgroundColor(
- if (item.selected) CoreConfig.instance.themeController().get(
- context, R.color.material_grey_100, R.color.dark_hint_text) else Color.TRANSPARENT)
+ if (item.selected) sAppTheme.get(
+ context, R.color.material_grey_100, R.color.dark_hint_text) else Color.TRANSPARENT)
}
private fun getPath(item: FileRecyclerItem): String {
@@ -54,7 +61,7 @@ class FileImportViewHolder(context: Context, root: View)
}
private fun getSubtitleText(file: File): String {
- return DateFormatter.getDate("dd MMM yy \u00B7 hh:mm a", file.lastModified())
+ return sDateFormat.readableFullTime(file.lastModified())
}
private fun getMetaText(file: File): String {
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/recycler/FileRecyclerItem.kt b/base/src/main/java/com/maubis/scarlet/base/export/recycler/FileRecyclerItem.kt
index e095d898..c9670b44 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/recycler/FileRecyclerItem.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/recycler/FileRecyclerItem.kt
@@ -5,10 +5,11 @@ import com.maubis.scarlet.base.export.support.AUTO_BACKUP_FILENAME
import com.maubis.scarlet.base.support.recycler.RecyclerItem
import java.io.File
-class FileRecyclerItem(val name: String,
- val date: Long,
- val path: String,
- val file: File) : RecyclerItem(), Comparable {
+class FileRecyclerItem(
+ val name: String,
+ val date: Long,
+ val path: String,
+ val file: File) : RecyclerItem(), Comparable {
var selected = false
override val type = Type.FILE
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/remote/FolderRemoteDatabase.kt b/base/src/main/java/com/maubis/scarlet/base/export/remote/FolderRemoteDatabase.kt
index b6f4c8fe..19534139 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/remote/FolderRemoteDatabase.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/remote/FolderRemoteDatabase.kt
@@ -33,23 +33,23 @@ class FolderRemoteDatabase(val weakContext: WeakReference) : IRemoteDat
rootFolder = File(Environment.getExternalStorageDirectory(), sFolderSyncPath)
val notesFolder = File(rootFolder, "notes")
notesRemoteFolder = RemoteFolder(
- notesFolder,
- ExportableNote::class.java,
- { it -> onRemoteInsert(it) },
- { it -> onRemoteRemove(ExportableNote(it, "", 0L, 0L, 0, NoteState.DEFAULT.name, "", emptyMap(), "")) },
- onNotesInit)
+ notesFolder,
+ ExportableNote::class.java,
+ { it -> onRemoteInsert(it) },
+ { it -> onRemoteRemove(ExportableNote(it, "", 0L, 0L, 0, NoteState.DEFAULT.name, "", emptyMap(), "")) },
+ onNotesInit)
tagsRemoteFolder = RemoteFolder(
- File(rootFolder, "tags"),
- ExportableTag::class.java,
- { it -> onRemoteInsert(it) },
- { it -> onRemoteRemove(ExportableTag(it, "")) },
- onTagsInit)
+ File(rootFolder, "tags"),
+ ExportableTag::class.java,
+ { it -> onRemoteInsert(it) },
+ { it -> onRemoteRemove(ExportableTag(it, "")) },
+ onTagsInit)
foldersRemoteFolder = RemoteFolder(
- File(rootFolder, "folders"),
- ExportableFolder::class.java,
- { it -> onRemoteInsert(it) },
- { it -> onRemoteRemove(ExportableFolder(it, "", 0L, 0L, 0)) },
- onFoldersInit)
+ File(rootFolder, "folders"),
+ ExportableFolder::class.java,
+ { it -> onRemoteInsert(it) },
+ { it -> onRemoteRemove(ExportableFolder(it, "", 0L, 0L, 0)) },
+ onFoldersInit)
val context = weakContext.get()
if (context !== null) {
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/remote/RemoteFolder.kt b/base/src/main/java/com/maubis/scarlet/base/export/remote/RemoteFolder.kt
index 29cd1ceb..ddda8cba 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/remote/RemoteFolder.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/remote/RemoteFolder.kt
@@ -2,8 +2,9 @@ package com.maubis.scarlet.base.export.remote
import com.github.bijoysingh.starter.util.FileManager
import com.google.gson.Gson
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppPreferences
import com.maubis.scarlet.base.export.support.KEY_EXTERNAL_FOLDER_SYNC_LAST_SCAN
+import com.maubis.scarlet.base.support.utils.maybeThrow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
@@ -11,18 +12,19 @@ import java.io.File
const val LAST_MODIFIED_ERROR_MARGIN = 7 * 1000 * 60 * 60 * 24L
-class RemoteFolder(val folder: File,
- val klass: Class,
- val onRemoteInsert: (T) -> Unit,
- val onRemoteDelete: (String) -> Unit,
- val onInitComplete: () -> Unit) {
+class RemoteFolder(
+ val folder: File,
+ val klass: Class,
+ val onRemoteInsert: (T) -> Unit,
+ val onRemoteDelete: (String) -> Unit,
+ val onInitComplete: () -> Unit) {
val deletedFolder = File(folder, "deleted")
val uuids = HashSet()
val deletedUuids = HashSet()
val lastScanKey = "${KEY_EXTERNAL_FOLDER_SYNC_LAST_SCAN}_${folder.name}"
- var lastScan = CoreConfig.instance.store().get(lastScanKey, 0L)
+ var lastScan = sAppPreferences.get(lastScanKey, 0L)
init {
GlobalScope.launch(Dispatchers.IO) {
@@ -37,6 +39,7 @@ class RemoteFolder(val folder: File,
onRemoteInsert(item)
}
} catch (exception: Exception) {
+ maybeThrow(exception)
}
}
}
@@ -50,7 +53,7 @@ class RemoteFolder(val folder: File,
}
onInitComplete()
- CoreConfig.instance.store().put(lastScanKey, System.currentTimeMillis())
+ sAppPreferences.put(lastScanKey, System.currentTimeMillis())
}
}
@@ -64,6 +67,7 @@ class RemoteFolder(val folder: File,
val file = file(uuid)
FileManager.writeToFile(file, data)
} catch (exception: Exception) {
+ maybeThrow(exception)
}
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/remote/RemoteImagesFolder.kt b/base/src/main/java/com/maubis/scarlet/base/export/remote/RemoteImagesFolder.kt
index d1828ac4..62a2aa4d 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/remote/RemoteImagesFolder.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/remote/RemoteImagesFolder.kt
@@ -5,6 +5,7 @@ import com.maubis.scarlet.base.core.format.FormatBuilder
import com.maubis.scarlet.base.core.format.FormatType
import com.maubis.scarlet.base.export.data.ExportableNote
import com.maubis.scarlet.base.support.utils.ImageCache
+import com.maubis.scarlet.base.support.utils.maybeThrow
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.File
@@ -75,7 +76,6 @@ class RemoteImagesFolder(context: Context, val folder: File) {
val imageFiles = noteFolder.listFiles() ?: emptyArray()
imageFiles.filter { it.isFile }
-
val imagesKnown = internalCache.imagesForNote(note.uuid()).map { it.name }
imageFiles.forEach {
if (!imagesKnown.contains(it.name)) {
@@ -107,6 +107,7 @@ class RemoteImagesFolder(context: Context, val folder: File) {
inStream.close()
outStream.close()
} catch (exception: Exception) {
+ maybeThrow(exception)
}
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/sheet/BackupSettingsOptionsBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/export/sheet/BackupSettingsOptionsBottomSheet.kt
index ad39a96d..0896c071 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/sheet/BackupSettingsOptionsBottomSheet.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/sheet/BackupSettingsOptionsBottomSheet.kt
@@ -5,16 +5,16 @@ import com.facebook.litho.ComponentContext
import com.github.bijoysingh.starter.util.IntentUtils
import com.maubis.scarlet.base.MainActivity
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
import com.maubis.scarlet.base.export.activity.ImportNoteActivity
import com.maubis.scarlet.base.export.support.PermissionUtils
-import com.maubis.scarlet.base.main.sheets.EnterPincodeBottomSheet
-import com.maubis.scarlet.base.settings.sheet.SecurityOptionsBottomSheet
+import com.maubis.scarlet.base.security.controller.PinLockController.isPinCodeEnabled
+import com.maubis.scarlet.base.security.sheets.openUnlockSheet
+import com.maubis.scarlet.base.security.sheets.openVerifySheet
import com.maubis.scarlet.base.support.sheets.LithoOptionBottomSheet
import com.maubis.scarlet.base.support.sheets.LithoOptionsItem
import com.maubis.scarlet.base.support.sheets.openSheet
import com.maubis.scarlet.base.support.ui.ThemedActivity
-import com.maubis.scarlet.base.support.utils.Flavor
+import com.maubis.scarlet.base.support.utils.FlavorUtils
class BackupSettingsOptionsBottomSheet : LithoOptionBottomSheet() {
override fun title(): Int = R.string.home_option_backup_options
@@ -22,7 +22,8 @@ class BackupSettingsOptionsBottomSheet : LithoOptionBottomSheet() {
override fun getOptions(componentContext: ComponentContext, dialog: Dialog): List {
val activity = context as MainActivity
val options = ArrayList()
- options.add(LithoOptionsItem(
+ options.add(
+ LithoOptionsItem(
title = R.string.home_option_install_from_store,
subtitle = R.string.home_option_install_from_store_subtitle,
icon = R.drawable.ic_action_play,
@@ -30,77 +31,71 @@ class BackupSettingsOptionsBottomSheet : LithoOptionBottomSheet() {
IntentUtils.openAppPlayStore(context)
dismiss()
},
- visible = CoreConfig.instance.appFlavor() == Flavor.NONE
- ))
+ visible = FlavorUtils.isOpenSource()
+ ))
options.add(LithoOptionsItem(
- title = R.string.home_option_export,
- subtitle = R.string.home_option_export_subtitle,
- icon = R.drawable.ic_export,
- listener = {
- val manager = PermissionUtils().getStoragePermissionManager(activity)
- val hasAllPermissions = manager.hasAllPermissions()
- when (hasAllPermissions) {
- true -> {
- openExportSheet(activity)
- dismiss()
- }
- false -> {
- openSheet(activity, PermissionBottomSheet())
- }
+ title = R.string.home_option_export,
+ subtitle = R.string.home_option_export_subtitle,
+ icon = R.drawable.ic_export,
+ listener = {
+ val manager = PermissionUtils().getStoragePermissionManager(activity)
+ val hasAllPermissions = manager.hasAllPermissions()
+ when (hasAllPermissions) {
+ true -> {
+ openExportSheet(activity)
+ dismiss()
+ }
+ false -> {
+ openSheet(activity, PermissionBottomSheet())
}
}
+ }
))
options.add(LithoOptionsItem(
- title = R.string.home_option_import,
- subtitle = R.string.home_option_import_subtitle,
- icon = R.drawable.ic_import,
- listener = {
- val manager = PermissionUtils().getStoragePermissionManager(activity)
- val hasAllPermissions = manager.hasAllPermissions()
- when (hasAllPermissions) {
- true -> {
- IntentUtils.startActivity(activity, ImportNoteActivity::class.java)
- dismiss()
- }
- false -> {
- openSheet(activity, PermissionBottomSheet())
- }
+ title = R.string.home_option_import,
+ subtitle = R.string.home_option_import_subtitle,
+ icon = R.drawable.ic_import,
+ listener = {
+ val manager = PermissionUtils().getStoragePermissionManager(activity)
+ val hasAllPermissions = manager.hasAllPermissions()
+ when (hasAllPermissions) {
+ true -> {
+ IntentUtils.startActivity(activity, ImportNoteActivity::class.java)
+ dismiss()
+ }
+ false -> {
+ openSheet(activity, PermissionBottomSheet())
}
}
+ }
))
options.add(LithoOptionsItem(
- title = R.string.import_export_layout_folder_sync,
- subtitle = R.string.import_export_layout_folder_sync_details,
- icon = R.drawable.icon_folder_sync,
- listener = {
- val manager = PermissionUtils().getStoragePermissionManager(activity)
- val hasAllPermissions = manager.hasAllPermissions()
- when (hasAllPermissions) {
- true -> {
- openSheet(activity, ExternalFolderSyncBottomSheet())
- }
- false -> openSheet(activity, PermissionBottomSheet())
+ title = R.string.import_export_layout_folder_sync,
+ subtitle = R.string.import_export_layout_folder_sync_details,
+ icon = R.drawable.icon_folder_sync,
+ listener = {
+ val manager = PermissionUtils().getStoragePermissionManager(activity)
+ val hasAllPermissions = manager.hasAllPermissions()
+ when (hasAllPermissions) {
+ true -> {
+ openSheet(activity, ExternalFolderSyncBottomSheet())
}
+ false -> openSheet(activity, PermissionBottomSheet())
}
+ }
))
return options
}
private fun openExportSheet(activity: MainActivity) {
- if (!SecurityOptionsBottomSheet.hasPinCodeEnabled()) {
+ if (!isPinCodeEnabled()) {
openSheet(activity, ExportNotesBottomSheet())
return
}
- EnterPincodeBottomSheet.openUnlockSheet(
- activity as ThemedActivity,
- object : EnterPincodeBottomSheet.PincodeSuccessListener {
- override fun onFailure() {
- openExportSheet(activity)
- }
- override fun onSuccess() {
- openSheet(activity, ExportNotesBottomSheet())
- }
- })
+ openUnlockSheet(
+ activity = activity as ThemedActivity,
+ onUnlockSuccess = { openSheet(activity, ExportNotesBottomSheet()) },
+ onUnlockFailure = { openExportSheet(activity) })
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/sheet/ExportNotesBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/export/sheet/ExportNotesBottomSheet.kt
index 45b69abb..d5d2ce06 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/sheet/ExportNotesBottomSheet.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/sheet/ExportNotesBottomSheet.kt
@@ -3,7 +3,7 @@ package com.maubis.scarlet.base.export.sheet
import android.app.Dialog
import android.content.Intent
import android.graphics.Typeface
-import android.support.v4.content.FileProvider
+import androidx.core.content.FileProvider
import com.facebook.litho.Column
import com.facebook.litho.Component
import com.facebook.litho.ComponentContext
@@ -12,9 +12,19 @@ import com.facebook.yoga.YogaEdge
import com.github.bijoysingh.starter.util.ToastHelper
import com.maubis.scarlet.base.MainActivity
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
-import com.maubis.scarlet.base.export.support.*
-import com.maubis.scarlet.base.support.sheets.*
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppFlavor
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
+import com.maubis.scarlet.base.export.support.GenericFileProvider
+import com.maubis.scarlet.base.export.support.NoteExporter
+import com.maubis.scarlet.base.export.support.PermissionUtils
+import com.maubis.scarlet.base.export.support.sAutoBackupMode
+import com.maubis.scarlet.base.export.support.sBackupLockedNotes
+import com.maubis.scarlet.base.export.support.sBackupMarkdown
+import com.maubis.scarlet.base.support.sheets.LithoBottomSheet
+import com.maubis.scarlet.base.support.sheets.LithoOptionsItem
+import com.maubis.scarlet.base.support.sheets.OptionItemLayout
+import com.maubis.scarlet.base.support.sheets.getLithoBottomSheetTitle
+import com.maubis.scarlet.base.support.sheets.openSheet
import com.maubis.scarlet.base.support.specs.BottomSheetBar
import com.maubis.scarlet.base.support.specs.separatorSpec
import com.maubis.scarlet.base.support.ui.ThemeColorType
@@ -25,7 +35,7 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
val NOTES_EXPORT_FOLDER
- get() = when (CoreConfig.instance.appFlavor()) {
+ get() = when (sAppFlavor) {
Flavor.NONE -> "MaterialNotes"
Flavor.LITE -> "Scarlet"
Flavor.PRO -> "ScarletPro"
@@ -41,90 +51,96 @@ class ExportNotesBottomSheet : LithoBottomSheet() {
val filenameRender = "${file?.parentFile?.name}/${file?.name}"
val component = Column.create(componentContext)
- .widthPercent(100f)
- .paddingDip(YogaEdge.VERTICAL, 8f)
- .child(getLithoBottomSheetTitle(componentContext)
- .textRes(R.string.import_export_layout_exporting)
- .paddingDip(YogaEdge.HORIZONTAL, 20f)
- .marginDip(YogaEdge.HORIZONTAL, 0f))
- .child(Text.create(componentContext)
- .textSizeRes(R.dimen.font_size_large)
- .text(filenameRender)
- .typeface(Typeface.MONOSPACE)
- .paddingDip(YogaEdge.HORIZONTAL, 20f)
- .textColor(CoreConfig.instance.themeController().get(ThemeColorType.TERTIARY_TEXT)))
- .child(separatorSpec(componentContext).alpha(0.5f))
+ .widthPercent(100f)
+ .paddingDip(YogaEdge.VERTICAL, 8f)
+ .child(
+ getLithoBottomSheetTitle(componentContext)
+ .textRes(R.string.import_export_layout_exporting)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .marginDip(YogaEdge.HORIZONTAL, 0f))
+ .child(
+ Text.create(componentContext)
+ .textSizeRes(R.dimen.font_size_large)
+ .text(filenameRender)
+ .typeface(Typeface.MONOSPACE)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .textColor(sAppTheme.get(ThemeColorType.TERTIARY_TEXT)))
+ .child(separatorSpec(componentContext).alpha(0.5f))
getOptions(componentContext).forEach {
if (it.visible) {
component.child(OptionItemLayout.create(componentContext)
- .option(it)
- .onClick {
- it.listener()
- reset(componentContext.androidContext, dialog)
- })
+ .option(it)
+ .onClick {
+ it.listener()
+ reset(componentContext.androidContext, dialog)
+ })
}
}
component.child(BottomSheetBar.create(componentContext)
- .primaryActionRes(R.string.import_export_layout_exporting_done)
- .onPrimaryClick {
- GlobalScope.launch {
- val notes = NoteExporter().getExportContent()
- val success = NoteExporter().saveToManualExportFile(notes)
- GlobalScope.launch(Dispatchers.Main) {
- ToastHelper.show(activity, if (success) R.string.import_export_layout_exported else R.string.import_export_layout_export_failed)
- dismiss()
- }
- }
- }
- .secondaryActionRes(R.string.import_export_layout_exporting_share)
- .onSecondaryClick {
- GlobalScope.launch {
- val notes = NoteExporter().getExportContent()
- NoteExporter().saveToManualExportFile(notes)
+ .primaryActionRes(R.string.import_export_layout_exporting_done)
+ .onPrimaryClick {
+ GlobalScope.launch {
+ val notes = NoteExporter().getExportContent()
+ val success = NoteExporter().saveToManualExportFile(notes)
+ GlobalScope.launch(Dispatchers.Main) {
+ ToastHelper.show(
+ activity, if (success) R.string.import_export_layout_exported else R.string.import_export_layout_export_failed)
+ dismiss()
+ }
+ }
+ }
+ .secondaryActionRes(R.string.import_export_layout_exporting_share)
+ .onSecondaryClick {
+ GlobalScope.launch {
+ val notes = NoteExporter().getExportContent()
+ NoteExporter().saveToManualExportFile(notes)
- if (file == null || !file.exists()) {
- return@launch
- }
+ if (file == null || !file.exists()) {
+ return@launch
+ }
- val uri = FileProvider.getUriForFile(activity, GenericFileProvider.PROVIDER, file)
+ val uri = FileProvider.getUriForFile(activity, GenericFileProvider.PROVIDER, file)
- val intent = Intent(Intent.ACTION_SEND)
- intent.type = "text/plain"
- intent.putExtra(Intent.EXTRA_STREAM, uri)
- startActivity(Intent.createChooser(intent, getString(R.string.share_using)))
+ val intent = Intent(Intent.ACTION_SEND)
+ intent.type = "text/plain"
+ intent.putExtra(Intent.EXTRA_STREAM, uri)
+ startActivity(Intent.createChooser(intent, getString(R.string.share_using)))
- GlobalScope.launch(Dispatchers.Main) {
- dismiss()
- }
- }
- }
- .paddingDip(YogaEdge.HORIZONTAL, 20f)
- .paddingDip(YogaEdge.VERTICAL, 8f))
+ GlobalScope.launch(Dispatchers.Main) {
+ dismiss()
+ }
+ }
+ }
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .paddingDip(YogaEdge.VERTICAL, 8f))
return component.build()
}
fun getOptions(componentContext: ComponentContext): List {
val activity = componentContext.androidContext as MainActivity
val options = ArrayList()
- options.add(LithoOptionsItem(
+ options.add(
+ LithoOptionsItem(
title = R.string.home_option_export_markdown,
subtitle = R.string.home_option_export_markdown_subtitle,
icon = R.drawable.ic_markdown_logo,
listener = { sBackupMarkdown = !sBackupMarkdown },
isSelectable = true,
selected = sBackupMarkdown
- ))
- options.add(LithoOptionsItem(
+ ))
+ options.add(
+ LithoOptionsItem(
title = R.string.import_export_locked,
subtitle = R.string.import_export_locked_details,
icon = R.drawable.ic_action_lock,
listener = { sBackupLockedNotes = !sBackupLockedNotes },
isSelectable = true,
selected = sBackupLockedNotes
- ))
- options.add(LithoOptionsItem(
+ ))
+ options.add(
+ LithoOptionsItem(
title = R.string.home_option_auto_export,
subtitle = R.string.home_option_auto_export_subtitle,
icon = R.drawable.ic_time,
@@ -143,7 +159,7 @@ class ExportNotesBottomSheet : LithoBottomSheet() {
},
isSelectable = true,
selected = sAutoBackupMode
- ))
+ ))
return options
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/sheet/ExternalFolderSyncBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/export/sheet/ExternalFolderSyncBottomSheet.kt
index 0bb3651e..30d364c2 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/sheet/ExternalFolderSyncBottomSheet.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/sheet/ExternalFolderSyncBottomSheet.kt
@@ -7,10 +7,10 @@ import com.facebook.litho.Component
import com.facebook.litho.ComponentContext
import com.facebook.litho.widget.Text
import com.facebook.yoga.YogaEdge
-import com.maubis.scarlet.base.MainActivity
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
-import com.maubis.scarlet.base.config.CoreConfig.Companion.FONT_MONSERRAT
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
+import com.maubis.scarlet.base.export.support.ExternalFolderSync
import com.maubis.scarlet.base.export.support.sExternalFolderSync
import com.maubis.scarlet.base.export.support.sFolderSyncBackupLocked
import com.maubis.scarlet.base.export.support.sFolderSyncPath
@@ -21,76 +21,79 @@ import com.maubis.scarlet.base.support.sheets.getLithoBottomSheetTitle
import com.maubis.scarlet.base.support.specs.BottomSheetBar
import com.maubis.scarlet.base.support.specs.separatorSpec
import com.maubis.scarlet.base.support.ui.ThemeColorType
-import com.maubis.scarlet.base.support.ui.ThemedActivity
-
class ExternalFolderSyncBottomSheet : LithoBottomSheet() {
override fun getComponent(componentContext: ComponentContext, dialog: Dialog): Component {
- val activity = componentContext.androidContext as ThemedActivity
-
val component = Column.create(componentContext)
- .widthPercent(100f)
- .paddingDip(YogaEdge.VERTICAL, 8f)
- .child(getLithoBottomSheetTitle(componentContext)
- .textRes(R.string.import_export_layout_folder_sync_title)
- .paddingDip(YogaEdge.HORIZONTAL, 20f)
- .marginDip(YogaEdge.HORIZONTAL, 0f))
- .child(Text.create(componentContext)
- .textSizeRes(R.dimen.font_size_large)
- .textRes(R.string.import_export_layout_folder_sync_description)
- .paddingDip(YogaEdge.HORIZONTAL, 20f)
- .textColor(CoreConfig.instance.themeController().get(ThemeColorType.TERTIARY_TEXT)))
- .child(separatorSpec(componentContext).alpha(0.5f))
- .child(Text.create(componentContext)
- .textSizeRes(R.dimen.font_size_xlarge)
- .typeface(FONT_MONSERRAT)
- .textRes(R.string.import_export_layout_folder_sync_folder)
- .paddingDip(YogaEdge.HORIZONTAL, 20f)
- .textColor(CoreConfig.instance.themeController().get(ThemeColorType.SECTION_HEADER)))
- .child(Text.create(componentContext)
- .textSizeRes(R.dimen.font_size_large)
- .text(sFolderSyncPath)
- .typeface(Typeface.MONOSPACE)
- .paddingDip(YogaEdge.HORIZONTAL, 20f)
- .paddingDip(YogaEdge.VERTICAL, 8f)
- .textColor(CoreConfig.instance.themeController().get(ThemeColorType.TERTIARY_TEXT)))
- .child(separatorSpec(componentContext).alpha(0.5f))
+ .widthPercent(100f)
+ .paddingDip(YogaEdge.VERTICAL, 8f)
+ .child(
+ getLithoBottomSheetTitle(componentContext)
+ .textRes(R.string.import_export_layout_folder_sync_title)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .marginDip(YogaEdge.HORIZONTAL, 0f))
+ .child(
+ Text.create(componentContext)
+ .textSizeRes(R.dimen.font_size_large)
+ .typeface(sAppTypeface.text())
+ .textRes(R.string.import_export_layout_folder_sync_description)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .textColor(sAppTheme.get(ThemeColorType.TERTIARY_TEXT)))
+ .child(separatorSpec(componentContext).alpha(0.5f))
+ .child(
+ Text.create(componentContext)
+ .textSizeRes(R.dimen.font_size_xlarge)
+ .typeface(sAppTypeface.title())
+ .textRes(R.string.import_export_layout_folder_sync_folder)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .textColor(sAppTheme.get(ThemeColorType.SECTION_HEADER)))
+ .child(
+ Text.create(componentContext)
+ .textSizeRes(R.dimen.font_size_large)
+ .text(sFolderSyncPath)
+ .typeface(Typeface.MONOSPACE)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .paddingDip(YogaEdge.VERTICAL, 8f)
+ .textColor(sAppTheme.get(ThemeColorType.TERTIARY_TEXT)))
+ .child(separatorSpec(componentContext).alpha(0.5f))
- getOptions(componentContext).forEach {
+ getOptions().forEach {
if (it.visible) {
component.child(OptionItemLayout.create(componentContext)
- .option(it)
- .onClick {
- it.listener()
- reset(componentContext.androidContext, dialog)
- })
+ .option(it)
+ .onClick {
+ it.listener()
+ reset(componentContext.androidContext, dialog)
+ })
}
}
component.child(BottomSheetBar.create(componentContext)
- .primaryActionRes(if (sExternalFolderSync) R.string.import_export_layout_folder_sync_disable else R.string.import_export_layout_folder_sync_enable)
- .isActionNegative(sExternalFolderSync)
- .onPrimaryClick {
- sExternalFolderSync = !sExternalFolderSync
- reset(componentContext.androidContext, dialog)
- }
- .paddingDip(YogaEdge.HORIZONTAL, 20f)
- .paddingDip(YogaEdge.VERTICAL, 8f))
+ .primaryActionRes(
+ if (sExternalFolderSync) R.string.import_export_layout_folder_sync_disable else R.string.import_export_layout_folder_sync_enable)
+ .isActionNegative(sExternalFolderSync)
+ .onPrimaryClick {
+ sExternalFolderSync = !sExternalFolderSync
+ ExternalFolderSync.enable(componentContext.androidContext, sExternalFolderSync)
+ reset(componentContext.androidContext, dialog)
+ }
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .paddingDip(YogaEdge.VERTICAL, 8f))
return component.build()
}
- fun getOptions(componentContext: ComponentContext): List {
- val activity = componentContext.androidContext as MainActivity
+ fun getOptions(): List {
val options = ArrayList()
- options.add(LithoOptionsItem(
+ options.add(
+ LithoOptionsItem(
title = R.string.import_export_locked,
subtitle = R.string.import_export_locked_details,
icon = R.drawable.ic_action_lock,
listener = { sFolderSyncBackupLocked = !sFolderSyncBackupLocked },
isSelectable = true,
selected = sFolderSyncBackupLocked
- ))
+ ))
return options
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/sheet/PermissionBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/export/sheet/PermissionBottomSheet.kt
index 23da9de3..f3c09393 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/sheet/PermissionBottomSheet.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/sheet/PermissionBottomSheet.kt
@@ -7,7 +7,8 @@ import com.facebook.litho.ComponentContext
import com.facebook.litho.widget.Text
import com.facebook.yoga.YogaEdge
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
import com.maubis.scarlet.base.export.support.PermissionUtils
import com.maubis.scarlet.base.support.sheets.LithoBottomSheet
import com.maubis.scarlet.base.support.sheets.getLithoBottomSheetTitle
@@ -19,27 +20,30 @@ class PermissionBottomSheet : LithoBottomSheet() {
override fun getComponent(componentContext: ComponentContext, dialog: Dialog): Component {
val activity = context as ThemedActivity
val component = Column.create(componentContext)
- .widthPercent(100f)
- .paddingDip(YogaEdge.VERTICAL, 8f)
- .paddingDip(YogaEdge.HORIZONTAL, 20f)
- .child(getLithoBottomSheetTitle(componentContext)
- .textRes(R.string.permission_layout_give_permission)
- .marginDip(YogaEdge.HORIZONTAL, 0f))
- .child(Text.create(componentContext)
- .textSizeRes(R.dimen.font_size_large)
- .marginDip(YogaEdge.BOTTOM, 16f)
- .textRes(R.string.permission_layout_give_permission_details)
- .textColor(CoreConfig.instance.themeController().get(ThemeColorType.TERTIARY_TEXT)))
- .child(BottomSheetBar.create(componentContext)
- .primaryActionRes(R.string.permission_layout_give_permission_ok)
- .onPrimaryClick {
- val manager = PermissionUtils().getStoragePermissionManager(activity)
- manager.requestPermissions()
- dismiss()
- }.secondaryActionRes(R.string.delete_sheet_delete_trash_no)
- .onSecondaryClick {
- dismiss()
- }.paddingDip(YogaEdge.VERTICAL, 8f))
+ .widthPercent(100f)
+ .paddingDip(YogaEdge.VERTICAL, 8f)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .child(
+ getLithoBottomSheetTitle(componentContext)
+ .textRes(R.string.permission_layout_give_permission)
+ .marginDip(YogaEdge.HORIZONTAL, 0f))
+ .child(
+ Text.create(componentContext)
+ .typeface(sAppTypeface.text())
+ .textSizeRes(R.dimen.font_size_large)
+ .marginDip(YogaEdge.BOTTOM, 16f)
+ .textRes(R.string.permission_layout_give_permission_details)
+ .textColor(sAppTheme.get(ThemeColorType.TERTIARY_TEXT)))
+ .child(BottomSheetBar.create(componentContext)
+ .primaryActionRes(R.string.permission_layout_give_permission_ok)
+ .onPrimaryClick {
+ val manager = PermissionUtils().getStoragePermissionManager(activity)
+ manager.requestPermissions()
+ dismiss()
+ }.secondaryActionRes(R.string.delete_sheet_delete_trash_no)
+ .onSecondaryClick {
+ dismiss()
+ }.paddingDip(YogaEdge.VERTICAL, 8f))
return component.build()
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/support/ExternalFolderSync.kt b/base/src/main/java/com/maubis/scarlet/base/export/support/ExternalFolderSync.kt
index d7acb3e5..f31dc604 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/support/ExternalFolderSync.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/support/ExternalFolderSync.kt
@@ -3,19 +3,22 @@ package com.maubis.scarlet.base.export.support
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
-import android.os.Build
-import android.support.v4.content.ContextCompat
+import androidx.core.content.ContextCompat
import com.github.bijoysingh.starter.util.ToastHelper
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.folderSync
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppPreferences
import com.maubis.scarlet.base.export.data.ExportableFolder
import com.maubis.scarlet.base.export.data.ExportableNote
import com.maubis.scarlet.base.export.data.ExportableTag
+import com.maubis.scarlet.base.export.remote.FolderRemoteDatabase
import com.maubis.scarlet.base.export.sheet.NOTES_EXPORT_FOLDER
+import com.maubis.scarlet.base.support.utils.OsVersionUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
-
+import java.lang.ref.WeakReference
const val KEY_EXTERNAL_FOLDER_SYNC_ENABLED = "external_folder_sync_enabled"
const val KEY_EXTERNAL_FOLDER_SYNC_LAST_SCAN = "external_folder_sync_last_sync"
@@ -23,21 +26,22 @@ const val KEY_EXTERNAL_FOLDER_SYNC_BACKUP_LOCKED = "external_folder_sync_backup_
const val KEY_EXTERNAL_FOLDER_SYNC_PATH = "external_folder_sync_path"
var sExternalFolderSync: Boolean
- get() = CoreConfig.instance.store().get(KEY_EXTERNAL_FOLDER_SYNC_ENABLED, false)
- set(value) = CoreConfig.instance.store().put(KEY_EXTERNAL_FOLDER_SYNC_ENABLED, value)
+ get() = sAppPreferences.get(KEY_EXTERNAL_FOLDER_SYNC_ENABLED, false)
+ set(value) = sAppPreferences.put(KEY_EXTERNAL_FOLDER_SYNC_ENABLED, value)
var sFolderSyncPath: String
- get() = CoreConfig.instance.store().get(KEY_EXTERNAL_FOLDER_SYNC_PATH, "$NOTES_EXPORT_FOLDER/Sync/")
- set(value) = CoreConfig.instance.store().put(KEY_EXTERNAL_FOLDER_SYNC_PATH, value)
+ get() = sAppPreferences.get(KEY_EXTERNAL_FOLDER_SYNC_PATH, "$NOTES_EXPORT_FOLDER/Sync/")
+ set(value) = sAppPreferences.put(KEY_EXTERNAL_FOLDER_SYNC_PATH, value)
var sFolderSyncBackupLocked: Boolean
- get() = CoreConfig.instance.store().get(KEY_EXTERNAL_FOLDER_SYNC_BACKUP_LOCKED, true)
- set(value) = CoreConfig.instance.store().put(KEY_EXTERNAL_FOLDER_SYNC_BACKUP_LOCKED, value)
+ get() = sAppPreferences.get(KEY_EXTERNAL_FOLDER_SYNC_BACKUP_LOCKED, true)
+ set(value) = sAppPreferences.put(KEY_EXTERNAL_FOLDER_SYNC_BACKUP_LOCKED, value)
object ExternalFolderSync {
fun hasPermission(context: Context): Boolean {
- return !(Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
+ return !(OsVersionUtils.requiresPermissions()
+ && ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
}
fun enable(context: Context, enabled: Boolean) {
@@ -45,7 +49,7 @@ object ExternalFolderSync {
if (!hasPermission(context)) {
GlobalScope.launch(Dispatchers.Main) {
ToastHelper.show(context, R.string.permission_layout_give_permission_details)
- CoreConfig.instance.externalFolderSync().reset()
+ folderSync?.reset()
}
return
}
@@ -53,27 +57,27 @@ object ExternalFolderSync {
loadFirstTime()
} else {
sExternalFolderSync = false
- CoreConfig.instance.externalFolderSync().reset()
+ folderSync?.reset()
}
}
fun loadFirstTime() {
- CoreConfig.instance.externalFolderSync().init(
- {
- CoreConfig.instance.notesDatabase().getAll().forEach {
- CoreConfig.instance.externalFolderSync().insert(ExportableNote(it))
- }
- },
- {
- CoreConfig.instance.tagsDatabase().getAll().forEach {
- CoreConfig.instance.externalFolderSync().insert(ExportableTag(it))
- }
- },
- {
- CoreConfig.instance.foldersDatabase().getAll().forEach {
- CoreConfig.instance.externalFolderSync().insert(ExportableFolder(it))
- }
- })
+ folderSync?.init(
+ {
+ ApplicationBase.instance.notesDatabase().getAll().forEach {
+ folderSync?.insert(ExportableNote(it))
+ }
+ },
+ {
+ ApplicationBase.instance.tagsDatabase().getAll().forEach {
+ folderSync?.insert(ExportableTag(it))
+ }
+ },
+ {
+ ApplicationBase.instance.foldersDatabase().getAll().forEach {
+ folderSync?.insert(ExportableFolder(it))
+ }
+ })
}
fun setup(context: Context) {
@@ -85,6 +89,7 @@ object ExternalFolderSync {
sExternalFolderSync = false
return
}
- CoreConfig.instance.externalFolderSync().init()
+ folderSync = FolderRemoteDatabase(WeakReference(context))
+ folderSync?.init()
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/support/GenericFileProvider.kt b/base/src/main/java/com/maubis/scarlet/base/export/support/GenericFileProvider.kt
index 428e369e..60e813d9 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/support/GenericFileProvider.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/support/GenericFileProvider.kt
@@ -1,6 +1,6 @@
package com.maubis.scarlet.base.export.support
-import android.support.v4.content.FileProvider
+import androidx.core.content.FileProvider
class GenericFileProvider : FileProvider() {
companion object {
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/support/NoteExporter.kt b/base/src/main/java/com/maubis/scarlet/base/export/support/NoteExporter.kt
index c548cbaa..8c9c8e83 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/support/NoteExporter.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/support/NoteExporter.kt
@@ -2,10 +2,9 @@ package com.maubis.scarlet.base.export.support
import android.os.AsyncTask
import android.os.Environment
-import com.github.bijoysingh.starter.util.DateFormatter
import com.github.bijoysingh.starter.util.FileManager
import com.google.gson.Gson
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppPreferences
import com.maubis.scarlet.base.config.CoreConfig.Companion.foldersDb
import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
import com.maubis.scarlet.base.config.CoreConfig.Companion.tagsDb
@@ -13,11 +12,11 @@ import com.maubis.scarlet.base.export.data.ExportableFileFormat
import com.maubis.scarlet.base.export.data.ExportableFolder
import com.maubis.scarlet.base.export.data.ExportableNote
import com.maubis.scarlet.base.export.data.ExportableTag
+import com.maubis.scarlet.base.export.data.toExportedMarkdown
import com.maubis.scarlet.base.export.sheet.NOTES_EXPORT_FILENAME
import com.maubis.scarlet.base.export.sheet.NOTES_EXPORT_FOLDER
-import com.maubis.scarlet.base.note.getFullText
+import com.maubis.scarlet.base.support.utils.sDateFormat
import java.io.File
-import java.util.*
const val KEY_NOTE_VERSION = "KEY_NOTE_VERSION"
const val KEY_BACKUP_LOCATION = "KEY_BACKUP_LOCATION"
@@ -31,18 +30,18 @@ const val AUTO_BACKUP_INTERVAL_MS = 1000 * 60 * 60 * 6 // 6 hours update
const val STORE_KEY_BACKUP_MARKDOWN = "KEY_BACKUP_MARKDOWN"
var sBackupMarkdown: Boolean
- get() = CoreConfig.instance.store().get(STORE_KEY_BACKUP_MARKDOWN, false)
- set(value) = CoreConfig.instance.store().put(STORE_KEY_BACKUP_MARKDOWN, value)
+ get() = sAppPreferences.get(STORE_KEY_BACKUP_MARKDOWN, false)
+ set(value) = sAppPreferences.put(STORE_KEY_BACKUP_MARKDOWN, value)
const val STORE_KEY_BACKUP_LOCKED = "KEY_BACKUP_LOCKED"
var sBackupLockedNotes: Boolean
- get() = CoreConfig.instance.store().get(STORE_KEY_BACKUP_LOCKED, true)
- set(value) = CoreConfig.instance.store().put(STORE_KEY_BACKUP_LOCKED, value)
+ get() = sAppPreferences.get(STORE_KEY_BACKUP_LOCKED, true)
+ set(value) = sAppPreferences.put(STORE_KEY_BACKUP_LOCKED, value)
const val STORE_KEY_AUTO_BACKUP_MODE = "KEY_AUTO_BACKUP_MODE"
var sAutoBackupMode: Boolean
- get() = CoreConfig.instance.store().get(STORE_KEY_AUTO_BACKUP_MODE, false)
- set(value) = CoreConfig.instance.store().put(STORE_KEY_AUTO_BACKUP_MODE, value)
+ get() = sAppPreferences.get(STORE_KEY_AUTO_BACKUP_MODE, false)
+ set(value) = sAppPreferences.put(STORE_KEY_AUTO_BACKUP_MODE, value)
class NoteExporter() {
@@ -52,9 +51,9 @@ class NoteExporter() {
}
val notes = notesDb
- .getAll()
- .filter { sBackupLockedNotes || !it.locked }
- .map { ExportableNote(it) }
+ .getAll()
+ .filter { sBackupLockedNotes || !it.locked }
+ .map { ExportableNote(it) }
val tags = tagsDb.getAll().map { ExportableTag(it) }
val folders = foldersDb.getAll().map { ExportableFolder(it) }
val fileContent = ExportableFileFormat(EXPORT_VERSION, notes, tags, folders)
@@ -64,11 +63,11 @@ class NoteExporter() {
private fun getMarkdownExportContent(): String {
var totalText = "$EXPORT_NOTE_SEPARATOR\n\n"
notesDb.getAll()
- .map { it.getFullText() }
- .forEach {
- totalText += it
- totalText += "\n\n$EXPORT_NOTE_SEPARATOR\n\n"
- }
+ .map { it.toExportedMarkdown() }
+ .forEach {
+ totalText += it
+ totalText += "\n\n$EXPORT_NOTE_SEPARATOR\n\n"
+ }
return totalText
}
@@ -77,23 +76,26 @@ class NoteExporter() {
if (!sAutoBackupMode) {
return@execute
}
- val lastBackup = CoreConfig.instance.store().get(KEY_AUTO_BACKUP_LAST_TIMESTAMP, 0L)
+ val lastBackup = sAppPreferences.get(KEY_AUTO_BACKUP_LAST_TIMESTAMP, 0L)
val lastTimestamp = notesDb.getLastTimestamp()
if (lastBackup + AUTO_BACKUP_INTERVAL_MS >= lastTimestamp) {
return@execute
}
- val exportFile = getOrCreateFileForExport(AUTO_BACKUP_FILENAME + " " + DateFormatter.getDate("dd_MMM_yyyy", Calendar.getInstance()))
+ val exportFile = getOrCreateFileForExport(
+ "$AUTO_BACKUP_FILENAME ${sDateFormat.getDateForBackup()}")
if (exportFile === null) {
return@execute
}
saveToFile(exportFile, getExportContent())
- CoreConfig.instance.store().put(KEY_AUTO_BACKUP_LAST_TIMESTAMP, System.currentTimeMillis())
+ sAppPreferences
+ .put(KEY_AUTO_BACKUP_LAST_TIMESTAMP, System.currentTimeMillis())
}
}
fun getOrCreateManualExportFile(): File? {
- return getOrCreateFileForExport(NOTES_EXPORT_FILENAME + " " + DateFormatter.getDate("dd_MMM_yyyy HH_mm", Calendar.getInstance()))
+ return getOrCreateFileForExport(
+ "$NOTES_EXPORT_FILENAME ${sDateFormat.getTimestampForBackup()}")
}
fun getOrCreateFileForExport(filename: String): File? {
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/support/NoteImporter.kt b/base/src/main/java/com/maubis/scarlet/base/export/support/NoteImporter.kt
index f9823b68..f897e83f 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/support/NoteImporter.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/support/NoteImporter.kt
@@ -13,6 +13,8 @@ import com.maubis.scarlet.base.export.data.ExportableNote
import com.maubis.scarlet.base.note.folder.saveIfUnique
import com.maubis.scarlet.base.note.save
import com.maubis.scarlet.base.note.tag.saveIfUnique
+import com.maubis.scarlet.base.support.utils.maybeThrow
+import com.maubis.scarlet.base.support.utils.throwOrReturn
import org.json.JSONArray
import java.io.BufferedReader
import java.io.File
@@ -58,19 +60,20 @@ class NoteImporter() {
}
} catch (exception: Exception) {
importNoteFallback(content, context)
+ maybeThrow(exception)
}
}
private fun importNoteFallback(content: String, context: Context) {
content
- .split(EXPORT_NOTE_SEPARATOR)
- .map {
- it.trim()
- }
- .filter { it.isNotBlank() }
- .forEach {
- NoteBuilder().gen("", it).save(context)
- }
+ .split(EXPORT_NOTE_SEPARATOR)
+ .map {
+ it.trim()
+ }
+ .filter { it.isNotBlank() }
+ .forEach {
+ NoteBuilder().gen("", it).save(context)
+ }
}
fun getImportableFiles(): List {
@@ -100,13 +103,12 @@ class NoteImporter() {
files.addAll(childFile)
}
} catch (exception: Exception) {
- // Failed
+ maybeThrow(exception)
}
return files
}
-
fun readFileInputStream(inputStreamReader: InputStreamReader): String {
lateinit var reader: BufferedReader
try {
@@ -120,7 +122,7 @@ class NoteImporter() {
return fileContents.toString()
} catch (exception: IOException) {
reader.close()
- return ""
+ return throwOrReturn(exception, "")
}
}
@@ -131,7 +133,7 @@ class NoteImporter() {
private fun isValidFile(filePath: String, validExtension: String): Boolean {
return filePath.endsWith("." + validExtension)
- || filePath.endsWith("." + validExtension.toUpperCase())
+ || filePath.endsWith("." + validExtension.toUpperCase())
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/export/support/PermissionUtils.kt b/base/src/main/java/com/maubis/scarlet/base/export/support/PermissionUtils.kt
index 214f21f5..b2272db7 100644
--- a/base/src/main/java/com/maubis/scarlet/base/export/support/PermissionUtils.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/export/support/PermissionUtils.kt
@@ -1,13 +1,14 @@
package com.maubis.scarlet.base.export.support
import android.Manifest
-import android.support.v7.app.AppCompatActivity
+import androidx.appcompat.app.AppCompatActivity
import com.github.bijoysingh.starter.util.PermissionManager
class PermissionUtils() {
fun getStoragePermissionManager(activity: AppCompatActivity): PermissionManager {
val manager = PermissionManager(activity)
- manager.setPermissions(arrayOf(
+ manager.setPermissions(
+ arrayOf(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE))
return manager
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/HomeNavigationState.kt b/base/src/main/java/com/maubis/scarlet/base/main/HomeNavigationMode.kt
similarity index 80%
rename from base/src/main/java/com/maubis/scarlet/base/main/HomeNavigationState.kt
rename to base/src/main/java/com/maubis/scarlet/base/main/HomeNavigationMode.kt
index 032301e7..61b3e972 100644
--- a/base/src/main/java/com/maubis/scarlet/base/main/HomeNavigationState.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/main/HomeNavigationMode.kt
@@ -3,7 +3,7 @@ package com.maubis.scarlet.base.main
/**
* Superset of the Note State class
*/
-enum class HomeNavigationState {
+enum class HomeNavigationMode {
DEFAULT,
TRASH,
FAVOURITE,
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/SearchState.kt b/base/src/main/java/com/maubis/scarlet/base/main/SearchState.kt
new file mode 100644
index 00000000..b32e57d9
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/main/SearchState.kt
@@ -0,0 +1,113 @@
+package com.maubis.scarlet.base.main
+
+import com.maubis.scarlet.base.config.ApplicationBase
+import com.maubis.scarlet.base.config.CoreConfig.Companion.foldersDb
+import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
+import com.maubis.scarlet.base.core.note.NoteState
+import com.maubis.scarlet.base.core.note.sort
+import com.maubis.scarlet.base.database.room.folder.Folder
+import com.maubis.scarlet.base.database.room.note.Note
+import com.maubis.scarlet.base.database.room.tag.Tag
+import com.maubis.scarlet.base.note.getFullText
+import com.maubis.scarlet.base.note.isNoteLockedButAppUnlocked
+import com.maubis.scarlet.base.settings.sheet.SortingOptionsBottomSheet
+
+class SearchState(
+ var text: String = "",
+ var mode: HomeNavigationMode = HomeNavigationMode.DEFAULT,
+ var currentFolder: Folder? = null,
+ var colors: MutableList = emptyList().toMutableList(),
+ var tags: MutableList = emptyList().toMutableList()) {
+
+ fun hasFilter(): Boolean {
+ return currentFolder != null
+ || tags.isNotEmpty()
+ || colors.isNotEmpty()
+ || text.isNotBlank()
+ || mode !== HomeNavigationMode.DEFAULT
+ }
+
+ fun clear(): SearchState {
+ mode = HomeNavigationMode.DEFAULT
+ text = ""
+ colors.clear()
+ tags.clear()
+ currentFolder = null
+ return this
+ }
+
+ fun clearSearchBar(): SearchState {
+ text = ""
+ colors.clear()
+ tags.clear()
+ return this
+ }
+
+ fun copy(): SearchState {
+ return SearchState(
+ text,
+ mode,
+ currentFolder,
+ colors.filter { true }.toMutableList(),
+ tags.filter { true }.toMutableList())
+ }
+}
+
+fun unifiedSearchSynchronous(state: SearchState): List {
+ val sorting = SortingOptionsBottomSheet.getSortingState()
+ val notes = unifiedSearchWithoutFolder(state)
+ .filter {
+ val currentFolder = state.currentFolder
+ if (currentFolder == null)
+ it.folder.isBlank()
+ else
+ currentFolder.uuid == it.folder
+ }
+ return sort(notes, sorting)
+}
+
+fun filterFolder(notes: List, folder: Folder): List {
+ val sorting = SortingOptionsBottomSheet.getSortingState()
+ val filteredNotes = notes.filter { it.folder == folder.uuid }
+ return sort(filteredNotes, sorting)
+}
+
+fun filterOutFolders(notes: List): List {
+ val allFoldersUUIDs = ApplicationBase.instance.foldersDatabase().getAll().map { it.uuid }
+ val sorting = SortingOptionsBottomSheet.getSortingState()
+ val filteredNotes = notes.filter { !allFoldersUUIDs.contains(it.folder) }
+ return sort(filteredNotes, sorting)
+}
+
+fun unifiedSearchWithoutFolder(state: SearchState): List {
+ return getNotesForMode(state)
+ .filter { state.colors.isEmpty() || state.colors.contains(it.color) }
+ .filter { note -> state.tags.isEmpty() || state.tags.filter { note.tags !== null && note.tags.contains(it.uuid) }.isNotEmpty() }
+ .filter {
+ when {
+ state.text.isBlank() -> true
+ it.locked && !it.isNoteLockedButAppUnlocked() -> false
+ else -> it.getFullText().contains(state.text, true)
+ }
+ }
+}
+
+fun filterDirectlyValidFolders(state: SearchState): List {
+ if (state.currentFolder != null) {
+ return emptyList()
+ }
+
+ return foldersDb.getAll()
+ .filter { state.colors.isEmpty() || state.colors.contains(it.color) }
+ .filter { it.title.contains(state.text, true) }
+}
+
+fun getNotesForMode(state: SearchState): List {
+ return when (state.mode) {
+ HomeNavigationMode.FAVOURITE -> notesDb.getByNoteState(arrayOf(NoteState.FAVOURITE.name))
+ HomeNavigationMode.ARCHIVED -> notesDb.getByNoteState(arrayOf(NoteState.ARCHIVED.name))
+ HomeNavigationMode.TRASH -> notesDb.getByNoteState(arrayOf(NoteState.TRASH.name))
+ HomeNavigationMode.DEFAULT -> notesDb.getByNoteState(arrayOf(NoteState.DEFAULT.name, NoteState.FAVOURITE.name))
+ HomeNavigationMode.LOCKED -> notesDb.getNoteByLocked(true)
+ }
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/activity/OpenTextIntentOrFileActivity.kt b/base/src/main/java/com/maubis/scarlet/base/main/activity/OpenTextIntentOrFileActivity.kt
index 17f3940d..453b808b 100644
--- a/base/src/main/java/com/maubis/scarlet/base/main/activity/OpenTextIntentOrFileActivity.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/main/activity/OpenTextIntentOrFileActivity.kt
@@ -2,7 +2,6 @@ package com.maubis.scarlet.base.main.activity
import android.content.Context
import android.content.Intent
-import android.os.Build
import android.os.Bundle
import android.text.Editable
import android.text.SpannableString
@@ -14,27 +13,25 @@ import com.github.bijoysingh.starter.async.MultiAsyncTask
import com.github.bijoysingh.starter.util.TextUtils
import com.github.bijoysingh.uibasics.views.UITextView
import com.maubis.markdown.Markdown
+import com.maubis.markdown.spannable.clearMarkdownSpans
import com.maubis.markdown.spannable.setFormats
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
-import com.maubis.scarlet.base.database.room.note.Note
+import com.maubis.scarlet.base.config.ApplicationBase
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
import com.maubis.scarlet.base.core.note.NoteBuilder
+import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.export.support.NoteImporter
import com.maubis.scarlet.base.note.creation.activity.ViewAdvancedNoteActivity
import com.maubis.scarlet.base.note.save
-import com.maubis.scarlet.base.support.utils.bind
+import com.maubis.scarlet.base.support.ui.SecuredActivity
import com.maubis.scarlet.base.support.ui.ThemeColorType
-import com.maubis.scarlet.base.support.ui.ThemedActivity
+import com.maubis.scarlet.base.support.utils.bind
import java.io.InputStreamReader
-import android.support.annotation.NonNull
-import android.text.style.*
-import com.maubis.markdown.spannable.clearMarkdownSpans
-
const val KEEP_PACKAGE = "com.google.android.keep"
const val INTENT_KEY_DIRECT_NOTES_TRANSFER = "direct_notes_transfer"
-class OpenTextIntentOrFileActivity : ThemedActivity() {
+class OpenTextIntentOrFileActivity : SecuredActivity() {
lateinit var context: Context
@@ -61,7 +58,6 @@ class OpenTextIntentOrFileActivity : ThemedActivity() {
setView()
notifyThemeChange()
-
val spannable = SpannableString(contentText)
spannable.setFormats(Markdown.getSpanInfo(contentText).spans)
content.setText(spannable, TextView.BufferType.SPANNABLE)
@@ -85,13 +81,12 @@ class OpenTextIntentOrFileActivity : ThemedActivity() {
override fun afterTextChanged(text: Editable) {
}
-
})
}
override fun onResume() {
super.onResume()
- CoreConfig.instance.startListener(this)
+ ApplicationBase.instance.startListener(this)
}
private fun setView() {
@@ -115,21 +110,6 @@ class OpenTextIntentOrFileActivity : ThemedActivity() {
}
fun handleIntent(): Boolean {
- val hasDirectIntent = handleDirectSendText(intent)
- if (hasDirectIntent) {
- return false
- }
-
- val hasSendIntent = handleSendText(intent)
- if (hasSendIntent) {
- val note = when (isCallerKeep()) {
- true -> NoteBuilder().gen(titleText, NoteBuilder().genFromKeep(contentText))
- false -> NoteBuilder().gen(titleText, contentText)
- }
- note.save(this)
- startActivity(ViewAdvancedNoteActivity.getIntent(this, note))
- return false
- }
val hasFileIntent = handleFileIntent(intent)
if (hasFileIntent) {
return true
@@ -137,62 +117,39 @@ class OpenTextIntentOrFileActivity : ThemedActivity() {
return false
}
- fun handleSendText(intent: Intent): Boolean {
- val sharedText = intent.getStringExtra(Intent.EXTRA_TEXT)
- val sharedTitle = intent.getStringExtra(Intent.EXTRA_TITLE)
- val sharedSubject = intent.getStringExtra(Intent.EXTRA_SUBJECT)
-
- titleText = sharedSubject ?: sharedTitle ?: ""
- contentText = sharedText ?: ""
- return sharedText != null
- }
-
- fun handleDirectSendText(intent: Intent): Boolean {
- val sharedText = intent.getStringExtra(INTENT_KEY_DIRECT_NOTES_TRANSFER)
- if (sharedText === null || sharedText.isBlank()) {
+ fun handleFileIntent(intent: Intent): Boolean {
+ val data = intent.data
+ val lastPathSegment = data?.lastPathSegment
+ if (data === null || lastPathSegment === null) {
return false
}
- NoteImporter().gen(this, sharedText)
- return true
- }
- fun handleFileIntent(intent: Intent): Boolean {
- val data = intent.data
try {
val inputStream = contentResolver.openInputStream(data)
contentText = NoteImporter().readFileInputStream(InputStreamReader(inputStream))
- filenameText = data.lastPathSegment
- inputStream.close()
+ filenameText = lastPathSegment
+ inputStream?.close()
return true
} catch (exception: Exception) {
return false
}
}
- fun isCallerKeep(): Boolean {
- return when {
- Build.VERSION.SDK_INT >= 22 && (referrer?.toString() ?: "").contains(KEEP_PACKAGE) -> true
- callingPackage?.contains(KEEP_PACKAGE) ?: false -> true
- (intent?.`package` ?: "").contains(KEEP_PACKAGE) -> true
- else -> false
- }
- }
-
override fun notifyThemeChange() {
setSystemTheme();
val containerLayout = findViewById(R.id.container_layout);
containerLayout.setBackgroundColor(getThemeColor());
- val toolbarIconColor = CoreConfig.instance.themeController().get(ThemeColorType.TOOLBAR_ICON);
+ val toolbarIconColor = sAppTheme.get(ThemeColorType.TOOLBAR_ICON);
backButton.setColorFilter(toolbarIconColor)
- val textColor = CoreConfig.instance.themeController().get(ThemeColorType.SECONDARY_TEXT)
+ val textColor = sAppTheme.get(ThemeColorType.SECONDARY_TEXT)
filename.setTextColor(textColor)
title.setTextColor(textColor)
content.setTextColor(textColor)
- val actionColor = CoreConfig.instance.themeController().get(ThemeColorType.TOOLBAR_ICON)
+ val actionColor = sAppTheme.get(ThemeColorType.TOOLBAR_ICON)
actionDone.setImageTint(actionColor)
actionDone.setTextColor(actionColor)
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/activity/WidgetConfigureActivity.kt b/base/src/main/java/com/maubis/scarlet/base/main/activity/WidgetConfigureActivity.kt
index 91da6a31..5d2d1bdb 100644
--- a/base/src/main/java/com/maubis/scarlet/base/main/activity/WidgetConfigureActivity.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/main/activity/WidgetConfigureActivity.kt
@@ -2,18 +2,16 @@ package com.maubis.scarlet.base.main.activity
import android.app.Activity
import android.app.Application
-import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Bundle
-import android.support.v4.content.ContextCompat
import android.widget.RemoteViews
+import androidx.core.content.ContextCompat
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase
import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
-import com.maubis.scarlet.base.core.note.NoteState
import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.database.room.widget.Widget
import com.maubis.scarlet.base.note.creation.activity.ViewAdvancedNoteActivity
@@ -37,8 +35,8 @@ class WidgetConfigureActivity : SelectableNotesActivityBase(), INoteSelectorActi
val extras = intent.extras
if (extras != null) {
appWidgetId = extras.getInt(
- AppWidgetManager.EXTRA_APPWIDGET_ID,
- AppWidgetManager.INVALID_APPWIDGET_ID)
+ AppWidgetManager.EXTRA_APPWIDGET_ID,
+ AppWidgetManager.INVALID_APPWIDGET_ID)
}
if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
@@ -55,7 +53,7 @@ class WidgetConfigureActivity : SelectableNotesActivityBase(), INoteSelectorActi
override fun onNoteClicked(note: Note) {
val widget = Widget(appWidgetId, note.uuid)
- CoreConfig.instance.database().widgets().insert(widget)
+ ApplicationBase.instance.database().widgets().insert(widget)
createWidget(widget)
}
@@ -82,8 +80,7 @@ class WidgetConfigureActivity : SelectableNotesActivityBase(), INoteSelectorActi
return
}
- val intent = ViewAdvancedNoteActivity.getIntent(context, note)
- val pendingIntent = PendingIntent.getActivity(context, 5000 + note.uid, intent, 0)
+ val pendingIntent = ViewAdvancedNoteActivity.getIntentWithStack(context, note)
val views = RemoteViews(context.getPackageName(), R.layout.widget_layout)
views.setTextViewText(R.id.description, getWidgetNoteText(note))
@@ -103,8 +100,8 @@ class WidgetConfigureActivity : SelectableNotesActivityBase(), INoteSelectorActi
private fun notifyNoteChangeBroadcast(context: Context, note: Note): Intent? {
val application: Application = context.applicationContext as Application
val ids = AppWidgetManager.getInstance(application).getAppWidgetIds(
- ComponentName(application, NoteWidgetProvider::class.java))
- val widgets = CoreConfig.instance.database().widgets().getByNote(note.uuid)
+ ComponentName(application, NoteWidgetProvider::class.java))
+ val widgets = ApplicationBase.instance.database().widgets().getByNote(note.uuid)
val widgetIds = ArrayList()
for (widget in widgets) {
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/recycler/EmptyRecyclerHolder.kt b/base/src/main/java/com/maubis/scarlet/base/main/recycler/EmptyRecyclerHolder.kt
index 9f43e917..122347e2 100644
--- a/base/src/main/java/com/maubis/scarlet/base/main/recycler/EmptyRecyclerHolder.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/main/recycler/EmptyRecyclerHolder.kt
@@ -4,7 +4,7 @@ import android.content.Context
import android.os.Bundle
import android.view.View
import com.github.bijoysingh.starter.recyclerview.RecyclerViewHolder
-import com.github.bijoysingh.starter.util.IntentUtils
+import com.maubis.scarlet.base.MainActivity
import com.maubis.scarlet.base.note.creation.activity.CreateNoteActivity
import com.maubis.scarlet.base.support.recycler.RecyclerItem
@@ -13,7 +13,11 @@ class EmptyRecyclerHolder(context: Context, itemView: View) : RecyclerViewHolder
override fun populate(data: RecyclerItem, extra: Bundle) {
setFullSpan()
itemView.setOnClickListener {
- IntentUtils.startActivity(context, CreateNoteActivity::class.java)
+ val newNoteIntent = CreateNoteActivity.getNewNoteIntent(
+ context,
+ folder = (context as MainActivity).state.currentFolder?.uuid ?: ""
+ )
+ context.startActivity(newNoteIntent)
}
}
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/recycler/InformationRecyclerHolder.kt b/base/src/main/java/com/maubis/scarlet/base/main/recycler/InformationRecyclerHolder.kt
index ef32b299..04a16741 100644
--- a/base/src/main/java/com/maubis/scarlet/base/main/recycler/InformationRecyclerHolder.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/main/recycler/InformationRecyclerHolder.kt
@@ -7,6 +7,7 @@ import android.widget.TextView
import com.github.bijoysingh.starter.recyclerview.RecyclerViewHolder
import com.github.bijoysingh.uibasics.views.UITextView
import com.maubis.scarlet.base.R
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
import com.maubis.scarlet.base.support.recycler.RecyclerItem
class InformationRecyclerHolder(context: Context, itemView: View) : RecyclerViewHolder(context, itemView) {
@@ -19,8 +20,12 @@ class InformationRecyclerHolder(context: Context, itemView: View) : RecyclerView
return
}
title.setText(data.title)
+ title.label.typeface = sAppTypeface.title()
title.setImageResource(data.icon)
+
text.setText(data.source)
+ text.typeface = sAppTypeface.text()
+
itemView.setOnClickListener {
data.function()
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/recycler/InformationRecyclerItem.kt b/base/src/main/java/com/maubis/scarlet/base/main/recycler/InformationRecyclerItem.kt
index 70f912c4..52428f9f 100644
--- a/base/src/main/java/com/maubis/scarlet/base/main/recycler/InformationRecyclerItem.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/main/recycler/InformationRecyclerItem.kt
@@ -6,15 +6,16 @@ import com.github.bijoysingh.starter.util.IntentUtils
import com.github.bijoysingh.starter.util.ToastHelper
import com.maubis.scarlet.base.MainActivity
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppPreferences
import com.maubis.scarlet.base.export.sheet.BackupSettingsOptionsBottomSheet
import com.maubis.scarlet.base.export.support.NoteExporter
import com.maubis.scarlet.base.main.activity.INTENT_KEY_DIRECT_NOTES_TRANSFER
import com.maubis.scarlet.base.settings.sheet.UISettingsOptionsBottomSheet
import com.maubis.scarlet.base.support.recycler.RecyclerItem
import com.maubis.scarlet.base.support.sheets.openSheet
-import com.maubis.scarlet.base.support.utils.Flavor
-import com.maubis.scarlet.base.support.utils.FlavourUtils
+import com.maubis.scarlet.base.support.utils.FlavorUtils
+import com.maubis.scarlet.base.support.utils.maybeThrow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
@@ -38,136 +39,134 @@ class InformationRecyclerItem(val icon: Int, val title: Int, val source: Int, va
fun probability(probability: Float): Boolean = Random().nextFloat() <= probability
fun shouldShowAppUpdateInformationItem(): Boolean {
- return !CoreConfig.instance.remoteConfigFetcher().isLatestVersion()
+ return !ApplicationBase.instance.remoteConfigFetcher().isLatestVersion()
}
fun getAppUpdateInformationItem(context: Context): InformationRecyclerItem {
return InformationRecyclerItem(
- R.drawable.ic_info,
- R.string.information_card_title,
- R.string.information_new_app_update
+ R.drawable.ic_info,
+ R.string.information_card_title,
+ R.string.information_new_app_update
) { IntentUtils.openAppPlayStore(context) }
}
fun shouldShowReviewInformationItem(): Boolean {
return probability(0.01f)
- && !CoreConfig.instance.store().get(KEY_INFO_RATE_AND_REVIEW, false)
+ && !sAppPreferences.get(KEY_INFO_RATE_AND_REVIEW, false)
}
fun getReviewInformationItem(context: Context): InformationRecyclerItem {
return InformationRecyclerItem(
- R.drawable.ic_rating,
- R.string.home_option_rate_and_review,
- R.string.home_option_rate_and_review_subtitle
+ R.drawable.ic_rating,
+ R.string.home_option_rate_and_review,
+ R.string.home_option_rate_and_review_subtitle
) {
- CoreConfig.instance.store().put(KEY_INFO_RATE_AND_REVIEW, true)
+ sAppPreferences.put(KEY_INFO_RATE_AND_REVIEW, true)
IntentUtils.openAppPlayStore(context)
}
}
fun shouldShowThemeInformationItem(): Boolean {
return probability(0.01f)
- && !CoreConfig.instance.store().get(KEY_THEME_OPTIONS, false)
+ && !sAppPreferences.get(KEY_THEME_OPTIONS, false)
}
fun getThemeInformationItem(activity: MainActivity): InformationRecyclerItem {
return InformationRecyclerItem(
- R.drawable.ic_action_grid,
- R.string.home_option_ui_experience,
- R.string.home_option_ui_experience_subtitle
+ R.drawable.ic_action_grid,
+ R.string.home_option_ui_experience,
+ R.string.home_option_ui_experience_subtitle
) {
- CoreConfig.instance.store().put(KEY_THEME_OPTIONS, true)
- UISettingsOptionsBottomSheet.openSheet(activity)
+ sAppPreferences.put(KEY_THEME_OPTIONS, true)
+ openSheet(activity, UISettingsOptionsBottomSheet())
}
}
fun shouldShowBackupInformationItem(): Boolean {
return probability(0.01f)
- && !CoreConfig.instance.store().get(KEY_BACKUP_OPTIONS, false)
+ && !sAppPreferences.get(KEY_BACKUP_OPTIONS, false)
}
fun getBackupInformationItem(activity: MainActivity): InformationRecyclerItem {
return InformationRecyclerItem(
- R.drawable.ic_export,
- R.string.home_option_backup_options,
- R.string.home_option_backup_options_subtitle
+ R.drawable.ic_export,
+ R.string.home_option_backup_options,
+ R.string.home_option_backup_options_subtitle
) {
- CoreConfig.instance.store().put(KEY_BACKUP_OPTIONS, true)
+ sAppPreferences.put(KEY_BACKUP_OPTIONS, true)
openSheet(activity, BackupSettingsOptionsBottomSheet())
}
}
-
fun shouldShowInstallProInformationItem(): Boolean {
return probability(0.01f)
- && CoreConfig.instance.store().get(KEY_INFO_INSTALL_PRO_v2, 0) < KEY_INFO_INSTALL_PRO_MAX_COUNT
- && CoreConfig.instance.appFlavor() != Flavor.PRO
+ && sAppPreferences.get(KEY_INFO_INSTALL_PRO_v2, 0) < KEY_INFO_INSTALL_PRO_MAX_COUNT
+ && !FlavorUtils.isPro()
}
fun getInstallProInformationItem(context: Context): InformationRecyclerItem {
return InformationRecyclerItem(
- R.drawable.ic_favorite_white_48dp,
- R.string.install_pro_app,
- R.string.information_install_pro
+ R.drawable.ic_favorite_white_48dp,
+ R.string.install_pro_app,
+ R.string.information_install_pro
) {
notifyProUpsellShown()
IntentUtils.openAppPlayStore(context, "com.bijoysingh.quicknote.pro")
}
}
-fun shouldShowSignInformationItem(): Boolean {
- if (CoreConfig.instance.authenticator().isLoggedIn()
- || CoreConfig.instance.appFlavor() == Flavor.NONE) {
+fun shouldShowSignInformationItem(context: Context): Boolean {
+ if (ApplicationBase.instance.authenticator().isLoggedIn(context) || FlavorUtils.isOpenSource()) {
return false
}
- if (CoreConfig.instance.store().get(KEY_FORCE_SHOW_SIGN_IN, false)) {
- CoreConfig.instance.store().put(KEY_FORCE_SHOW_SIGN_IN, false)
+ if (sAppPreferences.get(KEY_FORCE_SHOW_SIGN_IN, false)) {
+ sAppPreferences.put(KEY_FORCE_SHOW_SIGN_IN, false)
return true
}
return probability(0.01f)
- && !CoreConfig.instance.store().get(KEY_INFO_SIGN_IN, false)
+ && !sAppPreferences.get(KEY_INFO_SIGN_IN, false)
}
fun getSignInInformationItem(context: Context): InformationRecyclerItem {
return InformationRecyclerItem(
- R.drawable.ic_sign_in_options,
- R.string.home_option_login_with_app,
- R.string.home_option_login_with_app_subtitle
+ R.drawable.ic_sign_in_options,
+ R.string.home_option_login_with_app,
+ R.string.home_option_login_with_app_subtitle
) {
- CoreConfig.instance.authenticator().openLoginActivity(context)?.run()
+ ApplicationBase.instance.authenticator().openLoginActivity(context)?.run()
notifyProUpsellShown()
}
}
fun notifyProUpsellShown() {
- val proUpsellCount = CoreConfig.instance.store().get(KEY_INFO_INSTALL_PRO_v2, 0)
- CoreConfig.instance.store().put(KEY_INFO_INSTALL_PRO_v2, proUpsellCount + 1)
+ val proUpsellCount = sAppPreferences.get(KEY_INFO_INSTALL_PRO_v2, 0)
+ sAppPreferences.put(KEY_INFO_INSTALL_PRO_v2, proUpsellCount + 1)
}
-
fun shouldShowMigrateToProAppInformationItem(context: Context): Boolean {
- return CoreConfig.instance.appFlavor() == Flavor.LITE
- && FlavourUtils.hasProAppInstalled(context)
- && !CoreConfig.instance.store().get(KEY_MIGRATE_TO_PRO_SUCCESS, false)
+ return FlavorUtils.isLite()
+ && FlavorUtils.hasProAppInstalled(context)
+ && !sAppPreferences.get(KEY_MIGRATE_TO_PRO_SUCCESS, false)
}
fun getMigrateToProAppInformationItem(context: Context): InformationRecyclerItem {
return InformationRecyclerItem(
- R.drawable.ic_import,
- R.string.home_option_migrate_to_pro,
- R.string.home_option_migrate_to_pro_details
+ R.drawable.ic_import,
+ R.string.home_option_migrate_to_pro,
+ R.string.home_option_migrate_to_pro_details
) {
GlobalScope.launch(Dispatchers.Main) {
val notes = GlobalScope.async(Dispatchers.IO) { NoteExporter().getExportContent() }
val intent = Intent(Intent.ACTION_SEND)
- .putExtra(INTENT_KEY_DIRECT_NOTES_TRANSFER, notes.await())
- .setType("text/plain")
- .setPackage(FlavourUtils.PRO_APP_PACKAGE_NAME)
+ .putExtra(INTENT_KEY_DIRECT_NOTES_TRANSFER, notes.await())
+ .setType("text/plain")
+ .setPackage(FlavorUtils.PRO_APP_PACKAGE_NAME)
try {
context.startActivity(intent)
- CoreConfig.instance.store().put(KEY_MIGRATE_TO_PRO_SUCCESS, true)
- } catch (e: Exception) {
+ sAppPreferences.put(KEY_MIGRATE_TO_PRO_SUCCESS, true)
+ } catch (exception: Exception) {
ToastHelper.show(context, "Failed transferring notes to Scarlet Pro")
+ maybeThrow(exception)
}
}
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/recycler/ToolbarMainRecyclerHolder.kt b/base/src/main/java/com/maubis/scarlet/base/main/recycler/ToolbarMainRecyclerHolder.kt
index a506c13c..90a9dc24 100644
--- a/base/src/main/java/com/maubis/scarlet/base/main/recycler/ToolbarMainRecyclerHolder.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/main/recycler/ToolbarMainRecyclerHolder.kt
@@ -2,22 +2,24 @@ package com.maubis.scarlet.base.main.recycler
import android.content.Context
import android.os.Bundle
-import android.support.v7.widget.StaggeredGridLayoutManager
import android.view.View
import android.widget.ImageView
import android.widget.TextView
+import androidx.appcompat.app.AppCompatActivity
+import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.github.bijoysingh.starter.recyclerview.RecyclerViewHolder
import com.maubis.scarlet.base.BuildConfig
import com.maubis.scarlet.base.MainActivity
+import com.maubis.scarlet.base.MainActivityActions
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
-import com.maubis.scarlet.base.export.sheet.BackupSettingsOptionsBottomSheet
-import com.maubis.scarlet.base.settings.sheet.DeleteAndMoreOptionsBottomSheet
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
+import com.maubis.scarlet.base.performAction
import com.maubis.scarlet.base.settings.sheet.SettingsOptionsBottomSheet
import com.maubis.scarlet.base.support.recycler.RecyclerItem
-import com.maubis.scarlet.base.support.sheets.openSheet
import com.maubis.scarlet.base.support.ui.ThemeColorType
import com.maubis.scarlet.base.support.ui.visibility
+import com.maubis.scarlet.base.support.utils.maybeThrow
class ToolbarMainRecyclerHolder(context: Context, itemView: View) : RecyclerViewHolder(context, itemView) {
@@ -29,24 +31,25 @@ class ToolbarMainRecyclerHolder(context: Context, itemView: View) : RecyclerView
override fun populate(data: RecyclerItem, extra: Bundle) {
setFullSpan()
toolbarIconSearch.setOnClickListener {
- (context as MainActivity).setSearchMode(true)
+ (context as MainActivity).enterSearchMode()
}
toolbarIconSettings.setOnClickListener {
SettingsOptionsBottomSheet.openSheet((context as MainActivity))
}
- val titleColor = CoreConfig.instance.themeController().get(ThemeColorType.SECONDARY_TEXT)
+ val titleColor = sAppTheme.get(ThemeColorType.SECONDARY_TEXT)
toolbarTitle.setTextColor(titleColor)
+ toolbarTitle.typeface = sAppTypeface.heading()
- val toolbarIconColor = CoreConfig.instance.themeController().get(ThemeColorType.SECONDARY_TEXT)
+ val toolbarIconColor = sAppTheme.get(ThemeColorType.SECONDARY_TEXT)
toolbarIconSearch.setColorFilter(toolbarIconColor)
toolbarIconSettings.setColorFilter(toolbarIconColor)
toolbarIconDebug.visibility = visibility(BuildConfig.DEBUG)
toolbarIconDebug.setColorFilter(toolbarIconColor)
toolbarIconDebug.setOnClickListener {
- openSheet((context as MainActivity), DeleteAndMoreOptionsBottomSheet())
+ (context as MainActivity).performAction(MainActivityActions.TYPEFACE_PICKER)
}
}
}
@@ -55,6 +58,7 @@ fun RecyclerViewHolder.setFullSpan() {
try {
val layoutParams = itemView.getLayoutParams() as StaggeredGridLayoutManager.LayoutParams
layoutParams.isFullSpan = true
- } catch (e: Exception) {
+ } catch (exception: Exception) {
+ maybeThrow(itemView.context as AppCompatActivity, exception)
}
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/sheets/AlertBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/main/sheets/AlertBottomSheet.kt
index c8414d27..8d038e1f 100644
--- a/base/src/main/java/com/maubis/scarlet/base/main/sheets/AlertBottomSheet.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/main/sheets/AlertBottomSheet.kt
@@ -8,6 +8,8 @@ import com.facebook.litho.widget.Text
import com.facebook.yoga.YogaEdge
import com.maubis.scarlet.base.MainActivity
import com.maubis.scarlet.base.R
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppPreferences
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
import com.maubis.scarlet.base.config.CoreConfig
import com.maubis.scarlet.base.core.format.Format
import com.maubis.scarlet.base.core.note.NoteState
@@ -22,25 +24,25 @@ import com.maubis.scarlet.base.support.ui.ThemeColorType
import com.maubis.scarlet.base.support.ui.ThemedActivity
data class AlertSheetConfig(
- val title: Int = R.string.delete_sheet_are_you_sure,
- val description: Int = R.string.delete_sheet_delete_note_permanently,
- val positiveText: Int = R.string.delete_sheet_delete_trash_yes,
- val negativeText: Int = R.string.delete_sheet_delete_trash_no,
- val onPositiveClick: () -> Unit = {},
- val onNegativeClick: () -> Unit = {})
+ val title: Int = R.string.delete_sheet_are_you_sure,
+ val description: Int = R.string.delete_sheet_delete_note_permanently,
+ val positiveText: Int = R.string.delete_sheet_delete_trash_yes,
+ val negativeText: Int = R.string.delete_sheet_delete_trash_no,
+ val onPositiveClick: () -> Unit = {},
+ val onNegativeClick: () -> Unit = {})
fun openDeleteNotePermanentlySheet(activity: ThemedActivity, note: Note, onDelete: () -> Unit) {
openSheet(activity, AlertBottomSheet().apply {
this.config = AlertSheetConfig(
- title = R.string.delete_sheet_are_you_sure,
- description = R.string.delete_sheet_delete_note_permanently,
- positiveText = R.string.delete_sheet_delete_trash_yes,
- negativeText = R.string.delete_sheet_delete_trash_no,
- onPositiveClick = {
- note.delete(activity)
- onDelete()
- },
- onNegativeClick = {})
+ title = R.string.delete_sheet_are_you_sure,
+ description = R.string.delete_sheet_delete_note_permanently,
+ positiveText = R.string.delete_sheet_delete_trash_yes,
+ negativeText = R.string.delete_sheet_delete_trash_no,
+ onPositiveClick = {
+ note.delete(activity)
+ onDelete()
+ },
+ onNegativeClick = {})
})
}
@@ -48,29 +50,30 @@ class AlertBottomSheet : LithoBottomSheet() {
var config: AlertSheetConfig = AlertSheetConfig()
override fun getComponent(componentContext: ComponentContext, dialog: Dialog): Component {
- val activity = context as ThemedActivity
val component = Column.create(componentContext)
- .widthPercent(100f)
- .paddingDip(YogaEdge.VERTICAL, 8f)
- .paddingDip(YogaEdge.HORIZONTAL, 20f)
- .child(getLithoBottomSheetTitle(componentContext)
- .textRes(config.title)
- .marginDip(YogaEdge.HORIZONTAL, 0f))
- .child(Text.create(componentContext)
- .textSizeRes(R.dimen.font_size_large)
- .textRes(config.description)
- .marginDip(YogaEdge.BOTTOM, 16f)
- .textColor(CoreConfig.instance.themeController().get(ThemeColorType.TERTIARY_TEXT)))
- .child(BottomSheetBar.create(componentContext)
- .primaryActionRes(config.positiveText)
- .onPrimaryClick {
- config.onPositiveClick()
- dismiss()
- }.secondaryActionRes(config.negativeText)
- .onSecondaryClick {
- config.onNegativeClick()
- dismiss()
- }.paddingDip(YogaEdge.VERTICAL, 8f))
+ .widthPercent(100f)
+ .paddingDip(YogaEdge.VERTICAL, 8f)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .child(
+ getLithoBottomSheetTitle(componentContext)
+ .textRes(config.title)
+ .marginDip(YogaEdge.HORIZONTAL, 0f))
+ .child(
+ Text.create(componentContext)
+ .textSizeRes(R.dimen.font_size_large)
+ .textRes(config.description)
+ .marginDip(YogaEdge.BOTTOM, 16f)
+ .textColor(sAppTheme.get(ThemeColorType.TERTIARY_TEXT)))
+ .child(BottomSheetBar.create(componentContext)
+ .primaryActionRes(config.positiveText)
+ .onPrimaryClick {
+ config.onPositiveClick()
+ dismiss()
+ }.secondaryActionRes(config.negativeText)
+ .onSecondaryClick {
+ config.onNegativeClick()
+ dismiss()
+ }.paddingDip(YogaEdge.VERTICAL, 8f))
return component.build()
}
}
@@ -78,63 +81,62 @@ class AlertBottomSheet : LithoBottomSheet() {
fun openDeleteAllXSheet(activity: MainActivity, subtitle: Int, onSuccess: () -> Unit) {
openSheet(activity, AlertBottomSheet().apply {
this.config = AlertSheetConfig(
- title = R.string.delete_sheet_are_you_sure,
- description = subtitle,
- positiveText = R.string.delete_sheet_delete_trash_yes,
- negativeText = R.string.delete_sheet_delete_trash_no,
- onPositiveClick = {
- onSuccess()
- },
- onNegativeClick = {})
+ title = R.string.delete_sheet_are_you_sure,
+ description = subtitle,
+ positiveText = R.string.delete_sheet_delete_trash_yes,
+ negativeText = R.string.delete_sheet_delete_trash_no,
+ onPositiveClick = {
+ onSuccess()
+ },
+ onNegativeClick = {})
})
}
fun openDeleteFormatDialog(activity: ViewAdvancedNoteActivity, format: Format) {
openSheet(activity, AlertBottomSheet().apply {
this.config = AlertSheetConfig(
- title = R.string.delete_sheet_are_you_sure,
- description = R.string.image_delete_all_devices,
- positiveText = R.string.delete_sheet_delete_trash_yes,
- negativeText = R.string.delete_sheet_delete_trash_no,
- onPositiveClick = {
- activity.deleteFormat(format)
- },
- onNegativeClick = {})
+ title = R.string.delete_sheet_are_you_sure,
+ description = R.string.image_delete_all_devices,
+ positiveText = R.string.delete_sheet_delete_trash_yes,
+ negativeText = R.string.delete_sheet_delete_trash_no,
+ onPositiveClick = {
+ activity.deleteFormat(format)
+ },
+ onNegativeClick = {})
})
}
const val STORE_KEY_IMAGE_SYNC_NOTICE = "IMAGE_SYNC_NOTICE"
var sImageSyncNoticeShown: Int
- get() = CoreConfig.instance.store().get(STORE_KEY_IMAGE_SYNC_NOTICE, 0)
- set(value) = CoreConfig.instance.store().put(STORE_KEY_IMAGE_SYNC_NOTICE, value)
-
+ get() = sAppPreferences.get(STORE_KEY_IMAGE_SYNC_NOTICE, 0)
+ set(value) = sAppPreferences.put(STORE_KEY_IMAGE_SYNC_NOTICE, value)
fun openImageNotSynced(activity: ThemedActivity) {
openSheet(activity, AlertBottomSheet().apply {
this.config = AlertSheetConfig(
- title = R.string.image_not_uploaded,
- description = R.string.image_not_uploaded_details,
- positiveText = R.string.image_not_uploaded_i_understand,
- negativeText = R.string.delete_sheet_delete_trash_no,
- onPositiveClick = { sImageSyncNoticeShown = 1 },
- onNegativeClick = {})
+ title = R.string.image_not_uploaded,
+ description = R.string.image_not_uploaded_details,
+ positiveText = R.string.image_not_uploaded_i_understand,
+ negativeText = R.string.delete_sheet_delete_trash_no,
+ onPositiveClick = { sImageSyncNoticeShown = 1 },
+ onNegativeClick = {})
})
}
fun openDeleteTrashSheet(activity: MainActivity) {
openSheet(activity, AlertBottomSheet().apply {
this.config = AlertSheetConfig(
- title = R.string.delete_sheet_are_you_sure,
- description = R.string.delete_sheet_delete_trash,
- positiveText = R.string.delete_sheet_delete_trash_yes,
- negativeText = R.string.delete_sheet_delete_trash_no,
- onPositiveClick = {
- val notes = CoreConfig.notesDb.getByNoteState(arrayOf(NoteState.TRASH.name))
- for (note in notes) {
- note.delete(activity)
- }
- activity.setupData()
- },
- onNegativeClick = {})
+ title = R.string.delete_sheet_are_you_sure,
+ description = R.string.delete_sheet_delete_trash,
+ positiveText = R.string.delete_sheet_delete_trash_yes,
+ negativeText = R.string.delete_sheet_delete_trash_no,
+ onPositiveClick = {
+ val notes = CoreConfig.notesDb.getByNoteState(arrayOf(NoteState.TRASH.name))
+ for (note in notes) {
+ note.delete(activity)
+ }
+ activity.loadData()
+ },
+ onNegativeClick = {})
})
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/sheets/EnterPincodeBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/main/sheets/EnterPincodeBottomSheet.kt
deleted file mode 100644
index cb6dee59..00000000
--- a/base/src/main/java/com/maubis/scarlet/base/main/sheets/EnterPincodeBottomSheet.kt
+++ /dev/null
@@ -1,288 +0,0 @@
-package com.maubis.scarlet.base.main.sheets
-
-import android.app.Dialog
-import android.content.DialogInterface
-import android.text.Editable
-import android.text.TextWatcher
-import android.view.KeyEvent
-import android.view.View
-import android.view.inputmethod.EditorInfo
-import android.widget.EditText
-import android.widget.ImageView
-import android.widget.TextView
-import com.github.ajalt.reprint.core.AuthenticationFailureReason
-import com.github.ajalt.reprint.core.AuthenticationListener
-import com.github.ajalt.reprint.core.Reprint
-import com.github.bijoysingh.starter.util.LocaleManager
-import com.maubis.scarlet.base.MainActivity
-import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
-import com.maubis.scarlet.base.settings.sheet.SecurityOptionsBottomSheet
-import com.maubis.scarlet.base.settings.sheet.SecurityOptionsBottomSheet.Companion.hasPinCodeEnabled
-import com.maubis.scarlet.base.support.ui.ThemeColorType
-import com.maubis.scarlet.base.support.ui.ThemedActivity
-import com.maubis.scarlet.base.support.ui.ThemedBottomSheetFragment
-
-
-class EnterPincodeBottomSheet : ThemedBottomSheetFragment() {
-
- var listener: PincodeListener? = null
-
- override fun getBackgroundView(): Int {
- return R.id.container_layout
- }
-
- override fun setupView(dialog: Dialog?) {
- super.setupView(dialog)
- if (dialog == null) {
- return
- }
-
- if (listener == null) {
- dismiss()
- }
-
- val title = dialog.findViewById(R.id.options_title)
- val action = dialog.findViewById(R.id.action_button)
- val enterPin = dialog.findViewById(R.id.enter_pin)
- val pinLength = dialog.findViewById(R.id.pin_length)
- val fingerprint = dialog.findViewById(R.id.fingerprint)
- val removeBtn = dialog.findViewById(R.id.action_remove_button)
-
- title.setTextColor(CoreConfig.instance.themeController().get(ThemeColorType.SECONDARY_TEXT))
- enterPin.setTextColor(CoreConfig.instance.themeController().get(ThemeColorType.SECONDARY_TEXT))
-
- val hintColor = CoreConfig.instance.themeController().get(ThemeColorType.HINT_TEXT)
- enterPin.setHintTextColor(hintColor)
- pinLength.setTextColor(hintColor)
-
- title.setText(listener!!.getTitle())
- action.setText(listener!!.getActionTitle())
- fingerprint.visibility = if (listener!!.isFingerprintEnabled()) View.VISIBLE else View.INVISIBLE
- enterPin.addTextChangedListener(object : TextWatcher {
- override fun afterTextChanged(p0: Editable?) {
- // Ignore
- }
-
- override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
- // Ignore
- }
-
- override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
- if (p0 == null) {
- return
- }
- if (p0.length > 4) {
- enterPin.setText(p0.substring(0, 4))
- return
- }
- val text = LocaleManager.toString(p0.length) + " / " + LocaleManager.toString(PIN_LENGTH)
- pinLength.text = text
- }
- })
- removeBtn.setOnClickListener {
- listener!!.onRemoveButtonClick()
- dismiss()
- }
- removeBtn.visibility = if (listener!!.isRemoveButtonEnabled()) View.VISIBLE else View.GONE
-
- enterPin.setOnEditorActionListener { _, actionId, event ->
- if (event == null) {
- if (actionId != EditorInfo.IME_ACTION_DONE && actionId != EditorInfo.IME_ACTION_NEXT) {
- return@setOnEditorActionListener false
- }
- } else if (actionId == EditorInfo.IME_NULL || actionId == KeyEvent.KEYCODE_ENTER) {
- if (event.getAction() != KeyEvent.ACTION_DOWN) {
- return@setOnEditorActionListener true
- }
- } else {
- return@setOnEditorActionListener false
- }
-
- if (enterPin.length() != PIN_LENGTH) {
- return@setOnEditorActionListener false
- }
-
- listener!!.onPasswordRequested(enterPin.text.toString())
- dismiss()
- return@setOnEditorActionListener true
- }
-
- action.setOnClickListener {
- val pinCode = enterPin.text.toString()
- if (enterPin.length() != PIN_LENGTH) {
- return@setOnClickListener
- }
-
- listener!!.onPasswordRequested(pinCode)
- dismiss()
- }
-
- if (listener!!.isFingerprintEnabled()) {
- Reprint.authenticate(object : AuthenticationListener {
- override fun onSuccess(moduleTag: Int) {
- listener!!.onSuccess()
- dismiss()
- }
-
- override fun onFailure(
- failureReason: AuthenticationFailureReason?,
- fatal: Boolean,
- errorMessage: CharSequence?,
- moduleTag: Int,
- errorCode: Int) {
- // Ignore
- }
- })
- }
- makeBackgroundTransparent(dialog, R.id.root_layout)
- }
-
- override fun onDismiss(dialog: DialogInterface?) {
- super.onDismiss(dialog)
- Reprint.cancelAuthentication()
- }
-
- override fun onCancel(dialog: DialogInterface?) {
- super.onCancel(dialog)
- Reprint.cancelAuthentication()
- }
-
- override fun getLayout(): Int = R.layout.bottom_sheet_pin_code
-
- override fun getBackgroundCardViewIds(): Array = arrayOf(R.id.enter_code_card)
-
- companion object {
-
- const val PIN_LENGTH = 4
-
- fun openSheet(activity: ThemedActivity, listener: PincodeListener) {
- val sheet = EnterPincodeBottomSheet()
-
- sheet.listener = listener
- sheet.show(activity.supportFragmentManager, sheet.tag)
- }
-
- fun openCreateSheet(
- activity: ThemedActivity,
- listener: PincodeSuccessOnlyListener) {
- openSheet(activity, object : PincodeListener {
- override fun getTitle(): Int = R.string.security_sheet_enter_new_pin_title
-
- override fun getActionTitle(): Int = R.string.security_sheet_button_set
-
- override fun isFingerprintEnabled(): Boolean = false
-
- override fun isRemoveButtonEnabled(): Boolean = true
-
- override fun onRemoveButtonClick() {
- CoreConfig.instance.store().put(SecurityOptionsBottomSheet.KEY_SECURITY_CODE, "")
- sNoPinSetupNoticeShown = false
- listener.onSuccess()
-
- if (activity is MainActivity)
- activity.setupData()
- }
-
- override fun onPasswordRequested(password: String) {
- CoreConfig.instance.store().put(SecurityOptionsBottomSheet.KEY_SECURITY_CODE, password)
- listener.onSuccess()
- }
-
- override fun onSuccess() {
- }
- })
- }
-
- fun openVerifySheet(
- activity: ThemedActivity,
- listener: PincodeSuccessListener) {
- openUnlockSheetBase(
- activity,
- listener,
- R.string.security_sheet_enter_current_pin_title,
- R.string.security_sheet_button_verify
- )
- }
-
- fun openUnlockSheet(
- activity: ThemedActivity,
- listener: PincodeSuccessOnlyListener) {
- if (!hasPinCodeEnabled()) {
- if (sNoPinSetupNoticeShown) {
- listener.onSuccess()
- return
- }
- com.maubis.scarlet.base.support.sheets.openSheet(activity, NoPincodeBottomSheet().apply {
- this.onSuccess = { listener.onSuccess() }
- })
- return
- }
-
- openUnlockSheetBase(
- activity,
- listener,
- R.string.security_sheet_enter_pin_to_unlock_title,
- R.string.security_sheet_button_unlock
- )
- }
-
- private fun openUnlockSheetBase(
- activity: ThemedActivity,
- listener: PincodeSuccessOnlyListener,
- title: Int,
- actionTitle: Int) {
- openSheet(activity, object : PincodeListener {
- override fun getTitle(): Int = title
-
- override fun getActionTitle(): Int = actionTitle
-
- override fun isFingerprintEnabled(): Boolean {
- return Reprint.hasFingerprintRegistered() &&
- CoreConfig.instance.store().get(SecurityOptionsBottomSheet.KEY_FINGERPRINT_ENABLED, true)
- }
-
- override fun onPasswordRequested(password: String) {
- val currentPassword = CoreConfig.instance.store().get(SecurityOptionsBottomSheet.KEY_SECURITY_CODE, "")
- if (currentPassword != "" && currentPassword == password) {
- listener.onSuccess()
- } else if (listener is PincodeSuccessListener) {
- listener.onFailure()
- }
- }
-
- override fun isRemoveButtonEnabled(): Boolean = false
-
- override fun onRemoveButtonClick() {
- }
-
- override fun onSuccess() {
- listener.onSuccess()
- }
- })
- }
- }
-
- interface PincodeSuccessOnlyListener {
- fun onSuccess()
- }
-
- interface PincodeSuccessListener : PincodeSuccessOnlyListener {
-
- fun onFailure()
- }
-
- interface PincodeListener : PincodeSuccessOnlyListener {
- fun getTitle(): Int
-
- fun getActionTitle(): Int
-
- fun isFingerprintEnabled(): Boolean
-
- fun isRemoveButtonEnabled(): Boolean
-
- fun onPasswordRequested(password: String): Unit
-
- fun onRemoveButtonClick(): Unit
- }
-}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/sheets/ExceptionBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/main/sheets/ExceptionBottomSheet.kt
new file mode 100644
index 00000000..12ebf806
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/main/sheets/ExceptionBottomSheet.kt
@@ -0,0 +1,58 @@
+package com.maubis.scarlet.base.main.sheets
+
+import android.app.Dialog
+import android.content.Intent
+import android.net.Uri
+import android.util.Log
+import com.facebook.litho.Column
+import com.facebook.litho.Component
+import com.facebook.litho.ComponentContext
+import com.facebook.litho.widget.Text
+import com.facebook.yoga.YogaEdge
+import com.maubis.markdown.Markdown
+import com.maubis.scarlet.base.R
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
+import com.maubis.scarlet.base.support.sheets.LithoBottomSheet
+import com.maubis.scarlet.base.support.sheets.getLithoBottomSheetTitle
+import com.maubis.scarlet.base.support.specs.BottomSheetBar
+import com.maubis.scarlet.base.support.ui.ThemeColorType
+
+class ExceptionBottomSheet : LithoBottomSheet() {
+ var exception: Exception = RuntimeException()
+
+ override fun getComponent(componentContext: ComponentContext, dialog: Dialog): Component {
+ val component = Column.create(componentContext)
+ .widthPercent(100f)
+ .paddingDip(YogaEdge.VERTICAL, 8f)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .child(
+ getLithoBottomSheetTitle(componentContext)
+ .textRes(R.string.exception_sheet_title)
+ .marginDip(YogaEdge.HORIZONTAL, 0f))
+ .child(
+ Text.create(componentContext)
+ .typeface(sAppTypeface.code())
+ .textSizeRes(R.dimen.font_size_small)
+ .text(Markdown.render("```\n${Log.getStackTraceString(exception)}\n```", true))
+ .marginDip(YogaEdge.BOTTOM, 16f)
+ .textColor(sAppTheme.get(ThemeColorType.TERTIARY_TEXT)))
+ .child(BottomSheetBar.create(componentContext)
+ .primaryActionRes(R.string.exception_sheet_crash_app)
+ .onPrimaryClick {
+ throw exception
+ }.secondaryActionRes(R.string.exception_sheet_mail)
+ .onSecondaryClick {
+ try {
+ val intent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:team.thecodershub@gmail.com"))
+ intent.putExtra(Intent.EXTRA_SUBJECT, "[Exception] The application threw an exception")
+ intent.putExtra(Intent.EXTRA_TEXT, "Hi, my app threw this exception\n${Log.getStackTraceString(exception)}")
+ startActivity(Intent.createChooser(intent, "Send email to developer..."))
+ } catch (exception: Exception) {
+ // Ignore this one ;)
+ }
+ dismiss()
+ }.paddingDip(YogaEdge.VERTICAL, 8f))
+ return component.build()
+ }
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/sheets/HomeNavigationBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/main/sheets/HomeNavigationBottomSheet.kt
deleted file mode 100644
index 37bd8fb5..00000000
--- a/base/src/main/java/com/maubis/scarlet/base/main/sheets/HomeNavigationBottomSheet.kt
+++ /dev/null
@@ -1,207 +0,0 @@
-package com.maubis.scarlet.base.main.sheets
-
-import android.app.Dialog
-import android.support.v4.content.ContextCompat
-import android.view.View
-import android.widget.LinearLayout
-import android.widget.TextView
-import com.github.bijoysingh.starter.util.LocaleManager
-import com.github.bijoysingh.uibasics.views.UITextView
-import com.maubis.scarlet.base.MainActivity
-import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
-import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
-import com.maubis.scarlet.base.config.CoreConfig.Companion.tagsDb
-import com.maubis.scarlet.base.core.tag.TagBuilder
-import com.maubis.scarlet.base.main.HomeNavigationState
-import com.maubis.scarlet.base.note.tag.TagOptionsItem
-import com.maubis.scarlet.base.note.tag.sheet.CreateOrEditTagBottomSheet
-import com.maubis.scarlet.base.note.tag.view.HomeTagView
-import com.maubis.scarlet.base.settings.sheet.SettingsOptionsBottomSheet
-import com.maubis.scarlet.base.support.SearchConfig
-import com.maubis.scarlet.base.support.option.OptionsItem
-import com.maubis.scarlet.base.support.sheets.GridBottomSheetBase
-import com.maubis.scarlet.base.support.ui.Theme
-import com.maubis.scarlet.base.support.ui.ThemeColorType
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.async
-import kotlinx.coroutines.launch
-
-class HomeNavigationBottomSheet : GridBottomSheetBase() {
-
- override fun setupViewWithDialog(dialog: Dialog) {
- resetOptions(dialog)
- resetTags(dialog)
- setAddTagOption(dialog)
- makeBackgroundTransparent(dialog, R.id.root_layout)
- }
-
- private fun getOptions(): List {
- val activity = context as MainActivity
- val options = ArrayList()
- options.add(OptionsItem(
- title = R.string.nav_home,
- subtitle = R.string.nav_home_details,
- icon = R.drawable.ic_home_white_48dp,
- selected = activity.config.mode == HomeNavigationState.DEFAULT,
- listener = View.OnClickListener {
- activity.onHomeClick();
- dismiss();
- }
- ))
- options.add(OptionsItem(
- title = R.string.nav_favourites,
- subtitle = R.string.nav_favourites_details,
- icon = R.drawable.ic_favorite_white_48dp,
- selected = activity.config.mode == HomeNavigationState.FAVOURITE,
- listener = View.OnClickListener {
- activity.onFavouritesClick();
- dismiss();
- }
- ))
- options.add(OptionsItem(
- title = R.string.nav_archived,
- subtitle = R.string.nav_archived_details,
- icon = R.drawable.ic_archive_white_48dp,
- selected = activity.config.mode == HomeNavigationState.ARCHIVED,
- listener = View.OnClickListener {
- activity.onArchivedClick();
- dismiss();
- }
- ))
- options.add(OptionsItem(
- title = R.string.nav_locked,
- subtitle = R.string.nav_locked_details,
- icon = R.drawable.ic_action_lock,
- selected = activity.config.mode == HomeNavigationState.LOCKED,
- listener = View.OnClickListener {
- activity.onLockedClick();
- dismiss();
- }
- ))
- options.add(OptionsItem(
- title = R.string.nav_trash,
- subtitle = R.string.nav_trash_details,
- icon = R.drawable.ic_delete_white_48dp,
- selected = activity.config.mode == HomeNavigationState.TRASH,
- listener = View.OnClickListener {
- activity.onTrashClick();
- dismiss();
- }
- ))
- options.add(OptionsItem(
- title = R.string.nav_settings,
- subtitle = R.string.nav_settings,
- icon = R.drawable.ic_action_settings,
- listener = View.OnClickListener {
- SettingsOptionsBottomSheet.openSheet(activity)
- dismiss();
- }
- ))
- return options
- }
-
- fun resetOptions(dialog: Dialog) {
- GlobalScope.launch(Dispatchers.Main) {
- val items = GlobalScope.async(Dispatchers.IO) { getOptions() }
- setOptions(dialog, items.await())
- }
- }
-
- fun resetTags(dialog: Dialog) {
- GlobalScope.launch(Dispatchers.Main) {
- val tags = GlobalScope.async(Dispatchers.IO) { getTagOptions() }
-
- val titleView = dialog.findViewById(R.id.tag_options_title)
- titleView.setTextColor(
- CoreConfig.instance.themeController().get(themedContext(),
- Theme.DARK, ThemeColorType.SECONDARY_TEXT))
-
- val layout = dialog.findViewById(R.id.options_container)
- layout.removeAllViews()
- setTagOptions(dialog, tags.await())
- }
- }
-
- private fun setTagOptions(dialog: Dialog, options: List) {
- val layout = dialog.findViewById(R.id.options_container);
- for (option in options.sorted()) {
- val contentView = HomeTagView(View.inflate(context, R.layout.layout_home_tag_item, null))
- contentView.title.setText(option.tag.title)
- contentView.rootView.setOnClickListener(option.listener)
- contentView.subtitle.visibility = View.GONE
- contentView.icon.setImageResource(option.getIcon())
-
- contentView.action.setImageResource(option.getEditIcon());
- contentView.action.setColorFilter(CoreConfig.instance.themeController().get(themedContext(), Theme.DARK, ThemeColorType.HINT_TEXT));
- contentView.action.setOnClickListener(option.editListener)
-
- if (option.usages > 0) {
- contentView.subtitle.setText(LocaleManager.toString(option.usages))
- contentView.subtitle.visibility = View.VISIBLE
- }
-
- contentView.title.setTextColor(getOptionsTitleColor(option.selected))
- contentView.subtitle.setTextColor(getOptionsSubtitleColor(option.selected))
- contentView.icon.setColorFilter(getOptionsTitleColor(option.selected))
-
- layout.addView(contentView.rootView)
- }
- }
-
- private fun getTagOptions(): List {
- val activity = context as MainActivity
- val options = ArrayList()
- for (tag in tagsDb.getAll()) {
- options.add(TagOptionsItem(
- tag = tag,
- usages = notesDb.getNoteCountByTag(tag.uuid),
- listener = View.OnClickListener {
- activity.config = SearchConfig(mode = HomeNavigationState.DEFAULT)
- activity.openTag(tag)
- dismiss()
- },
- editable = true,
- editListener = View.OnClickListener {
- CreateOrEditTagBottomSheet.openSheet(activity, tag, { _, _ -> resetTags(dialog) })
- }
- ))
- }
- return options
- }
-
- private fun setAddTagOption(dialog: Dialog) {
- val hintTextColor = CoreConfig.instance.themeController().get(themedContext(), Theme.DARK, ThemeColorType.HINT_TEXT)
- val newTagButton = dialog.findViewById(R.id.new_tag_button)
- newTagButton.setTextColor(hintTextColor)
- newTagButton.setImageTint(hintTextColor)
- newTagButton.setOnClickListener { onNewTagClick() }
- newTagButton.icon.alpha = 0.6f
- }
-
- private fun onNewTagClick() {
- val activity = context as MainActivity
- CreateOrEditTagBottomSheet.openSheet(activity, TagBuilder().emptyTag(), { _, _ -> resetTags(dialog) })
- }
-
- override fun getOptionsTitleColor(selected: Boolean): Int {
- return ContextCompat.getColor(themedContext(), R.color.light_primary_text)
- }
-
- override fun getOptionsSubtitleColor(selected: Boolean): Int {
- return ContextCompat.getColor(themedContext(), R.color.light_secondary_text)
- }
-
- override fun getBackgroundCardViewIds(): Array = emptyArray()
-
- override fun getLayout(): Int = R.layout.bottom_sheet_home_navigation
-
- companion object {
- fun openSheet(activity: MainActivity) {
- val sheet = HomeNavigationBottomSheet()
-
- sheet.show(activity.supportFragmentManager, sheet.tag)
- }
- }
-}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/sheets/HomeOptionsBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/main/sheets/HomeOptionsBottomSheet.kt
new file mode 100644
index 00000000..d679691f
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/main/sheets/HomeOptionsBottomSheet.kt
@@ -0,0 +1,263 @@
+package com.maubis.scarlet.base.main.sheets
+
+import android.app.Dialog
+import android.graphics.Typeface
+import com.facebook.litho.ClickEvent
+import com.facebook.litho.Column
+import com.facebook.litho.Component
+import com.facebook.litho.ComponentContext
+import com.facebook.litho.Row
+import com.facebook.litho.annotations.LayoutSpec
+import com.facebook.litho.annotations.OnCreateLayout
+import com.facebook.litho.annotations.OnEvent
+import com.facebook.litho.annotations.Prop
+import com.facebook.litho.widget.Text
+import com.facebook.yoga.YogaAlign
+import com.facebook.yoga.YogaEdge
+import com.maubis.scarlet.base.MainActivity
+import com.maubis.scarlet.base.R
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
+import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.core.tag.TagBuilder
+import com.maubis.scarlet.base.database.room.tag.Tag
+import com.maubis.scarlet.base.main.HomeNavigationMode
+import com.maubis.scarlet.base.note.tag.sheet.CreateOrEditTagBottomSheet
+import com.maubis.scarlet.base.settings.sheet.SettingsOptionsBottomSheet
+import com.maubis.scarlet.base.support.sheets.LithoBottomSheet
+import com.maubis.scarlet.base.support.sheets.LithoLabelOptionsItem
+import com.maubis.scarlet.base.support.sheets.LithoOptionsItem
+import com.maubis.scarlet.base.support.sheets.OptionItemLayout
+import com.maubis.scarlet.base.support.sheets.OptionLabelItemLayout
+import com.maubis.scarlet.base.support.sheets.getLithoBottomSheetTitle
+import com.maubis.scarlet.base.support.specs.RoundIcon
+import com.maubis.scarlet.base.support.ui.ThemeColorType
+
+class LithoTagOptionsItem(
+ val tag: Tag,
+ val usages: Int = 0,
+ val isSelected: Boolean = false,
+ val isEditable: Boolean = false,
+ val editListener: () -> Unit = {},
+ val listener: () -> Unit = {}) {
+}
+
+@LayoutSpec
+object TagItemLayoutSpec {
+ @OnCreateLayout
+ fun onCreate(context: ComponentContext, @Prop option: LithoTagOptionsItem): Component {
+ val titleColor = sAppTheme.get(ThemeColorType.SECONDARY_TEXT)
+ val selectedColor = when (sAppTheme.isNightTheme()) {
+ true -> context.getColor(R.color.material_blue_400)
+ false -> context.getColor(R.color.material_blue_700)
+ }
+
+ val icon: Int
+ val bgColor: Int
+ val bgAlpha: Int
+ val textColor: Int
+ val typeface: Typeface
+ when (option.isSelected) {
+ true -> {
+ icon = R.drawable.ic_action_label
+ bgColor = selectedColor
+ bgAlpha = 200
+ textColor = selectedColor
+ typeface = sAppTypeface.subHeading()
+ }
+ false -> {
+ icon = R.drawable.ic_action_label_unselected
+ bgColor = titleColor
+ bgAlpha = 15
+ textColor = titleColor
+ typeface = sAppTypeface.title()
+ }
+ }
+
+ val row = Row.create(context)
+ .widthPercent(100f)
+ .alignItems(YogaAlign.CENTER)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .paddingDip(YogaEdge.VERTICAL, 12f)
+ .child(
+ RoundIcon.create(context)
+ .iconRes(icon)
+ .bgColor(bgColor)
+ .iconColor(titleColor)
+ .iconSizeRes(R.dimen.toolbar_round_icon_size)
+ .iconPaddingRes(R.dimen.toolbar_round_icon_padding)
+ .bgAlpha(bgAlpha)
+ .onClick { }
+ .isClickDisabled(true)
+ .marginDip(YogaEdge.END, 16f))
+ .child(
+ Text.create(context)
+ .flexGrow(1f)
+ .text(option.tag.title)
+ .textSizeRes(R.dimen.font_size_normal)
+ .typeface(typeface)
+ .textStyle(Typeface.BOLD)
+ .textColor(textColor))
+
+ if (option.usages > 0) {
+ row.child(
+ Text.create(context)
+ .text("${option.usages}")
+ .textSizeRes(R.dimen.font_size_normal)
+ .textColor(titleColor)
+ .marginDip(YogaEdge.HORIZONTAL, 8f))
+ }
+
+ if (option.isEditable) {
+ row.child(RoundIcon.create(context)
+ .iconRes(R.drawable.ic_edit_white_48dp)
+ .bgColor(titleColor)
+ .bgAlpha(15)
+ .iconAlpha(0.9f)
+ .iconColor(titleColor)
+ .iconSizeRes(R.dimen.toolbar_round_icon_size)
+ .iconPaddingRes(R.dimen.toolbar_round_icon_padding)
+ .onClick { option.editListener() }
+ .isClickDisabled(false)
+ .marginDip(YogaEdge.START, 12f))
+ }
+
+ row.clickHandler(OptionItemLayout.onItemClick(context))
+ return row.build()
+ }
+
+ @OnEvent(ClickEvent::class)
+ fun onItemClick(context: ComponentContext, @Prop option: LithoTagOptionsItem) {
+ option.listener()
+ }
+}
+
+class HomeOptionsBottomSheet : LithoBottomSheet() {
+
+ override fun getComponent(componentContext: ComponentContext, dialog: Dialog): Component {
+ val activity = context as MainActivity
+ val options = getOptions()
+ val component = Column.create(componentContext)
+ .widthPercent(100f)
+ .child(
+ Column.create(componentContext)
+ .paddingDip(YogaEdge.TOP, 20f)
+ .paddingDip(YogaEdge.BOTTOM, 20f)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .child(
+ Row.create(componentContext)
+ .child(OptionLabelItemLayout.create(componentContext).option(options[0]).onClick { options[0].listener() })
+ .child(OptionLabelItemLayout.create(componentContext).option(options[1]).onClick { options[1].listener() })
+ .child(OptionLabelItemLayout.create(componentContext).option(options[2]).onClick { options[2].listener() })
+ )
+ .child(
+ Row.create(componentContext)
+ .child(OptionLabelItemLayout.create(componentContext).option(options[3]).onClick { options[3].listener() })
+ .child(OptionLabelItemLayout.create(componentContext).option(options[4]).onClick { options[4].listener() })
+ .child(OptionLabelItemLayout.create(componentContext).option(options[5]).onClick { options[5].listener() })
+ ))
+
+ val tagsComponent = Column.create(componentContext)
+ .paddingDip(YogaEdge.TOP, 8f)
+ .paddingDip(YogaEdge.BOTTOM, 20f)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .backgroundRes(R.color.dark_hint_text)
+ .child(
+ getLithoBottomSheetTitle(componentContext)
+ .textRes(R.string.tag_sheet_choose_tag)
+ .marginDip(YogaEdge.BOTTOM, 12f))
+ getTagOptions().forEach {
+ tagsComponent.child(TagItemLayout.create(componentContext).option(it))
+ }
+
+ val addTag = LithoOptionsItem(
+ title = R.string.tag_sheet_new_tag_button,
+ subtitle = 0,
+ icon = R.drawable.icon_add_note,
+ listener = { CreateOrEditTagBottomSheet.openSheet(activity, TagBuilder().emptyTag()) { _, _ -> reset(activity, dialog) } })
+ tagsComponent.child(OptionItemLayout.create(componentContext).option(addTag).onClick { addTag.listener() })
+
+ component.child(tagsComponent)
+ return component.build()
+ }
+
+ override fun bottomMargin(): Float = 0f
+
+ private fun getOptions(): List {
+ val activity = context as MainActivity
+ val options = ArrayList()
+ options.add(LithoLabelOptionsItem(
+ title = R.string.nav_home,
+ icon = R.drawable.ic_home_white_48dp,
+ listener = {
+ activity.onModeChange(HomeNavigationMode.DEFAULT)
+ dismiss()
+ }
+ ))
+ options.add(LithoLabelOptionsItem(
+ title = R.string.nav_favourites,
+ icon = R.drawable.ic_favorite_white_48dp,
+ listener = {
+ activity.onModeChange(HomeNavigationMode.FAVOURITE)
+ dismiss()
+ }
+ ))
+ options.add(LithoLabelOptionsItem(
+ title = R.string.nav_archived,
+ icon = R.drawable.ic_archive_white_48dp,
+ listener = {
+ activity.onModeChange(HomeNavigationMode.ARCHIVED)
+ dismiss()
+ }
+ ))
+ options.add(LithoLabelOptionsItem(
+ title = R.string.nav_locked,
+ icon = R.drawable.ic_action_lock,
+ listener = {
+ activity.onModeChange(HomeNavigationMode.LOCKED)
+ dismiss()
+ }
+ ))
+ options.add(LithoLabelOptionsItem(
+ title = R.string.nav_trash,
+ icon = R.drawable.ic_delete_white_48dp,
+ listener = {
+ activity.onModeChange(HomeNavigationMode.TRASH)
+ dismiss()
+ }
+ ))
+ options.add(LithoLabelOptionsItem(
+ title = R.string.nav_settings,
+ icon = R.drawable.ic_action_settings,
+ listener = {
+ SettingsOptionsBottomSheet.openSheet(activity)
+ dismiss()
+ }
+ ))
+ return options
+ }
+
+ private fun getTagOptions(): List {
+ val activity = context as MainActivity
+ val options = ArrayList()
+ for (tag in CoreConfig.tagsDb.getAll()) {
+ options.add(LithoTagOptionsItem(
+ tag = tag,
+ usages = CoreConfig.notesDb.getNoteCountByTag(tag.uuid),
+ listener = {
+ activity.openTag(tag)
+ dismiss()
+ },
+ isEditable = true,
+ isSelected = false,
+ editListener = {
+ CreateOrEditTagBottomSheet.openSheet(activity, tag) { _, _ ->
+ reset(activity, dialog)
+ }
+ }
+ ))
+ }
+ options.sortByDescending { it.usages }
+ return options
+ }
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/sheets/InstallProUpsellBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/main/sheets/InstallProUpsellBottomSheet.kt
index 3d3f4c0f..b84ae1b2 100644
--- a/base/src/main/java/com/maubis/scarlet/base/main/sheets/InstallProUpsellBottomSheet.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/main/sheets/InstallProUpsellBottomSheet.kt
@@ -8,41 +8,58 @@ import com.facebook.litho.widget.Text
import com.facebook.yoga.YogaEdge
import com.github.bijoysingh.starter.util.IntentUtils
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
-import com.maubis.scarlet.base.config.CoreConfig.Companion.FONT_MONSERRAT
+import com.maubis.scarlet.base.config.ApplicationBase
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
import com.maubis.scarlet.base.support.sheets.LithoBottomSheet
import com.maubis.scarlet.base.support.sheets.getLithoBottomSheetTitle
import com.maubis.scarlet.base.support.specs.BottomSheetBar
+import com.maubis.scarlet.base.support.specs.GridSectionItem
+import com.maubis.scarlet.base.support.specs.GridSectionOptionItem
+import com.maubis.scarlet.base.support.specs.GridSectionView
import com.maubis.scarlet.base.support.ui.ThemeColorType
-import com.maubis.scarlet.base.support.ui.ThemedActivity
class InstallProUpsellBottomSheet : LithoBottomSheet() {
override fun getComponent(componentContext: ComponentContext, dialog: Dialog): Component {
- val activity = context as ThemedActivity
+ val options = listOf(
+ GridSectionOptionItem(R.drawable.ic_whats_new, R.string.install_pro_sheet_latest_updates, {}),
+ GridSectionOptionItem(R.drawable.ic_action_lock, R.string.install_pro_sheet_app_lock, {}),
+ GridSectionOptionItem(R.drawable.ic_action_day_mode, R.string.install_pro_sheet_app_themes,
+ {}),
+ GridSectionOptionItem(R.drawable.ic_title_white_48dp, R.string.install_pro_sheet_font_size, {}),
+ GridSectionOptionItem(R.drawable.ic_note_white_48dp, R.string.install_pro_sheet_note_options, {}),
+ GridSectionOptionItem(R.drawable.ic_action_color, R.string.install_pro_sheet_viewer_bg, {}),
+ GridSectionOptionItem(R.drawable.icon_typeface, R.string.home_option_typeface, {}),
+ GridSectionOptionItem(R.drawable.icon_widget, R.string.install_pro_sheet_widget_options, {}))
+
val component = Column.create(componentContext)
- .widthPercent(100f)
- .paddingDip(YogaEdge.VERTICAL, 8f)
- .paddingDip(YogaEdge.HORIZONTAL, 20f)
- .child(getLithoBottomSheetTitle(componentContext)
- .textRes(R.string.available_in_pro_only)
- .marginDip(YogaEdge.HORIZONTAL, 0f))
- .child(Text.create(componentContext)
- .textSizeRes(R.dimen.font_size_large)
- .marginDip(YogaEdge.BOTTOM, 4f)
- .textRes(R.string.why_install_pro)
- .typeface(FONT_MONSERRAT)
- .textColor(CoreConfig.instance.themeController().get(ThemeColorType.SECTION_HEADER)))
- .child(Text.create(componentContext)
- .textSizeRes(R.dimen.font_size_large)
- .marginDip(YogaEdge.BOTTOM, 16f)
- .textRes(R.string.why_install_pro_details)
- .textColor(CoreConfig.instance.themeController().get(ThemeColorType.TERTIARY_TEXT)))
- .child(BottomSheetBar.create(componentContext)
- .primaryActionRes(R.string.install_pro_app)
- .onPrimaryClick {
- IntentUtils.openAppPlayStore(activity, "com.bijoysingh.quicknote.pro")
- dismiss()
- }.paddingDip(YogaEdge.VERTICAL, 8f))
+ .widthPercent(100f)
+ .paddingDip(YogaEdge.VERTICAL, 8f)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .child(
+ getLithoBottomSheetTitle(componentContext)
+ .textRes(R.string.available_in_pro_only)
+ .marginDip(YogaEdge.HORIZONTAL, 0f))
+ .child(
+ Text.create(componentContext)
+ .textSizeRes(R.dimen.font_size_large)
+ .marginDip(YogaEdge.BOTTOM, 16f)
+ .textRes(R.string.why_install_pro)
+ .typeface(ApplicationBase.sAppTypeface.title())
+ .textColor(sAppTheme.get(ThemeColorType.TERTIARY_TEXT)))
+ .child(
+ GridSectionView.create(componentContext)
+ .maxLines(3)
+ .numColumns(2)
+ .iconSizeRes(R.dimen.primary_round_icon_size)
+ .section(GridSectionItem(options = options))
+ .showSeparator(false))
+ .child(BottomSheetBar.create(componentContext)
+ .primaryActionRes(R.string.install_pro_app)
+ .onPrimaryClick {
+ IntentUtils.openAppPlayStore(activity, "com.bijoysingh.quicknote.pro")
+ dismiss()
+ }
+ .paddingDip(YogaEdge.VERTICAL, 8f))
return component.build()
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/sheets/NoPincodeBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/main/sheets/NoPincodeBottomSheet.kt
deleted file mode 100644
index 0a0d34c1..00000000
--- a/base/src/main/java/com/maubis/scarlet/base/main/sheets/NoPincodeBottomSheet.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.maubis.scarlet.base.main.sheets
-
-import android.app.Dialog
-import com.facebook.litho.Column
-import com.facebook.litho.Component
-import com.facebook.litho.ComponentContext
-import com.facebook.litho.widget.Text
-import com.facebook.yoga.YogaEdge
-import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
-import com.maubis.scarlet.base.support.sheets.LithoBottomSheet
-import com.maubis.scarlet.base.support.sheets.getLithoBottomSheetTitle
-import com.maubis.scarlet.base.support.specs.BottomSheetBar
-import com.maubis.scarlet.base.support.ui.ThemeColorType
-import com.maubis.scarlet.base.support.ui.ThemedActivity
-
-
-const val STORE_KEY_NO_PIN_ASK = "KEY_NO_PIN_ASK"
-var sNoPinSetupNoticeShown: Boolean
- get() = CoreConfig.instance.store().get(STORE_KEY_NO_PIN_ASK, false)
- set(value) = CoreConfig.instance.store().put(STORE_KEY_NO_PIN_ASK, value)
-
-class NoPincodeBottomSheet : LithoBottomSheet() {
- var onSuccess: () -> Unit = {}
-
- override fun getComponent(componentContext: ComponentContext, dialog: Dialog): Component {
- val activity = context as ThemedActivity
- val component = Column.create(componentContext)
- .widthPercent(100f)
- .paddingDip(YogaEdge.VERTICAL, 8f)
- .paddingDip(YogaEdge.HORIZONTAL, 20f)
- .child(getLithoBottomSheetTitle(componentContext)
- .textRes(R.string.no_pincode_sheet_title)
- .marginDip(YogaEdge.HORIZONTAL, 0f))
- .child(Text.create(componentContext)
- .textSizeRes(R.dimen.font_size_large)
- .textRes(R.string.no_pincode_sheet_details)
- .marginDip(YogaEdge.BOTTOM, 16f)
- .textColor(CoreConfig.instance.themeController().get(ThemeColorType.TERTIARY_TEXT)))
- .child(BottomSheetBar.create(componentContext)
- .primaryActionRes(R.string.no_pincode_sheet_set_up)
- .onPrimaryClick {
- EnterPincodeBottomSheet.openCreateSheet(activity, object : EnterPincodeBottomSheet.PincodeSuccessOnlyListener {
- override fun onSuccess() {
- // Ignore this
- }
- })
- dismiss()
- }
- .secondaryActionRes(R.string.no_pincode_sheet_dont_ask)
- .onSecondaryClick {
- onSuccess()
- dismiss()
- }
- .tertiaryActionRes(R.string.no_pincode_sheet_not_now)
- .onTertiaryClick {
- onSuccess()
- dismiss()
- }
- .paddingDip(YogaEdge.VERTICAL, 8f))
- return component.build()
- }
-}
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/sheets/WhatsNewBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/main/sheets/WhatsNewBottomSheet.kt
index 0d3c5c82..a999df3c 100644
--- a/base/src/main/java/com/maubis/scarlet/base/main/sheets/WhatsNewBottomSheet.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/main/sheets/WhatsNewBottomSheet.kt
@@ -1,95 +1,69 @@
package com.maubis.scarlet.base.main.sheets
import android.app.Dialog
-import android.content.Intent
-import android.net.Uri
import com.facebook.litho.Column
import com.facebook.litho.Component
import com.facebook.litho.ComponentContext
import com.facebook.litho.widget.Text
import com.facebook.yoga.YogaEdge
-import com.maubis.markdown.Markdown
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
-import com.maubis.scarlet.base.config.CoreConfig.Companion.FONT_MONSERRAT
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
import com.maubis.scarlet.base.support.sheets.LithoBottomSheet
import com.maubis.scarlet.base.support.sheets.getLithoBottomSheetTitle
import com.maubis.scarlet.base.support.specs.BottomSheetBar
+import com.maubis.scarlet.base.support.specs.GridSectionItem
+import com.maubis.scarlet.base.support.specs.GridSectionOptionItem
+import com.maubis.scarlet.base.support.specs.GridSectionView
import com.maubis.scarlet.base.support.ui.ThemeColorType
+import com.maubis.scarlet.base.support.utils.FlavorUtils
+import com.maubis.scarlet.base.support.utils.OsVersionUtils
+
+const val WHATS_NEW_SHEET_INDEX = 11
class WhatsNewBottomSheet : LithoBottomSheet() {
override fun getComponent(componentContext: ComponentContext, dialog: Dialog): Component {
+ val options = listOf(
+ if (FlavorUtils.isOpenSource()) null else GridSectionOptionItem(R.drawable.gdrive_icon, R.string.whats_new_sheet_google_drive, {}),
+ GridSectionOptionItem(R.drawable.icon_share_image, R.string.whats_new_sheet_photo_share, {}),
+ GridSectionOptionItem(R.drawable.ic_action_color, R.string.whats_new_sheet_note_color, {}),
+ GridSectionOptionItem(R.drawable.icon_typeface, R.string.whats_new_sheet_choose_fonts, {}),
+ GridSectionOptionItem(R.drawable.icon_languages, R.string.whats_new_sheet_more_languages, {}),
+ if (!OsVersionUtils.canAddLauncherShortcuts()) null else GridSectionOptionItem(
+ R.drawable.icon_shortcut, R.string.whats_new_sheet_launcher_shortcuts, {}),
+ GridSectionOptionItem(R.drawable.ic_option_fingerprint, R.string.whats_new_sheet_biometric_improvements, {}),
+ GridSectionOptionItem(R.drawable.ic_markdown_logo, R.string.whats_new_sheet_markdown_improvements, {}),
+ GridSectionOptionItem(R.drawable.icon_widget, R.string.whats_new_sheet_ui_improvements, {}))
+
val component = Column.create(componentContext)
- .widthPercent(100f)
- .paddingDip(YogaEdge.VERTICAL, 8f)
- .paddingDip(YogaEdge.HORIZONTAL, 20f)
- .child(getLithoBottomSheetTitle(componentContext)
- .textRes(R.string.whats_new_title)
- .marginDip(YogaEdge.HORIZONTAL, 0f))
- .child(Text.create(componentContext)
- .textSizeRes(R.dimen.font_size_large)
- .marginDip(YogaEdge.BOTTOM, 16f)
- .text(WHATS_NEW_DETAILS_SUBTITLE)
- .textColor(CoreConfig.instance.themeController().get(ThemeColorType.TERTIARY_TEXT)))
- .child(Text.create(componentContext)
- .textSizeRes(R.dimen.font_size_xlarge)
- .marginDip(YogaEdge.BOTTOM, 4f)
- .text(WHATS_NEW_DETAILS_NEW_FEATURES_TITLE)
- .typeface(FONT_MONSERRAT)
- .textColor(CoreConfig.instance.themeController().get(ThemeColorType.SECTION_HEADER)))
- .child(Text.create(componentContext)
- .textSizeRes(R.dimen.font_size_large)
- .marginDip(YogaEdge.BOTTOM, 16f)
- .text(Markdown.render(WHATS_NEW_DETAILS_NEW_FEATURES_MD, true))
- .textColor(CoreConfig.instance.themeController().get(ThemeColorType.TERTIARY_TEXT)))
- .child(Text.create(componentContext)
- .textSizeRes(R.dimen.font_size_xlarge)
- .marginDip(YogaEdge.BOTTOM, 4f)
- .text(WHATS_NEW_DETAILS_LAST_RELEASE_TITLE)
- .typeface(FONT_MONSERRAT)
- .textColor(CoreConfig.instance.themeController().get(ThemeColorType.SECTION_HEADER)))
- .child(Text.create(componentContext)
- .textSizeRes(R.dimen.font_size_large)
- .marginDip(YogaEdge.BOTTOM, 16f)
- .text(Markdown.render(WHATS_NEW_DETAILS_LAST_RELEASE_MD, true))
- .textColor(CoreConfig.instance.themeController().get(ThemeColorType.TERTIARY_TEXT)))
- .child(BottomSheetBar.create(componentContext)
- .primaryActionRes(R.string.import_export_layout_exporting_done)
- .onPrimaryClick {
- dismiss()
- }
- .onSecondaryClick {
- val url = GOOGLE_TRANSLATE_URL + "en/" + Uri.encode(WHATS_NEW_DETAILS_NEW_FEATURES_MD)
- startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
- dismiss()
- }
- .secondaryActionRes(R.string.whats_new_translate)
- .paddingDip(YogaEdge.VERTICAL, 8f))
+ .widthPercent(100f)
+ .paddingDip(YogaEdge.VERTICAL, 8f)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .child(
+ getLithoBottomSheetTitle(componentContext)
+ .textRes(R.string.whats_new_title)
+ .marginDip(YogaEdge.HORIZONTAL, 0f))
+ .child(
+ Text.create(componentContext)
+ .textSizeRes(R.dimen.font_size_large)
+ .marginDip(YogaEdge.BOTTOM, 16f)
+ .textRes(R.string.whats_new_sheet_subtitle)
+ .typeface(sAppTypeface.title())
+ .textColor(sAppTheme.get(ThemeColorType.TERTIARY_TEXT)))
+ .child(
+ GridSectionView.create(componentContext)
+ .maxLines(3)
+ .numColumns(2)
+ .iconSizeRes(R.dimen.ultra_large_round_icon_size)
+ .section(GridSectionItem(options = options.filterNotNull()))
+ .showSeparator(false))
+ .child(BottomSheetBar.create(componentContext)
+ .primaryActionRes(R.string.import_export_layout_exporting_done)
+ .onPrimaryClick {
+ dismiss()
+ }
+ .paddingDip(YogaEdge.VERTICAL, 8f))
return component.build()
}
-
- companion object {
- val WHATS_NEW_UID = 9
- val GOOGLE_TRANSLATE_URL = "https://translate.google.com/#auto/"
-
- val WHATS_NEW_DETAILS_SUBTITLE = "A lot has changed in this update, here is a summary of those changes."
- val WHATS_NEW_DETAILS_NEW_FEATURES_TITLE = "New Features"
- val WHATS_NEW_DETAILS_LAST_RELEASE_TITLE = "Last Release"
- val WHATS_NEW_DETAILS_NEW_FEATURES_MD =
- "- **All New UI:** New Note and Settings UI. Cleaner, faster and built for easy use.\n\n" +
- "- **Easier Editor:** Easier and faster ways to get markdown, and section options.\n\n" +
- "- **Realtime Markdown:** When you type in markdown you get real time conversion and formatting.\n\n" +
- "- **More Editor Options:** Head over to settings to get more control on the editor experience.\n\n" +
- "- **More Themes:** Pro Users get more themes for the app, and the default dark theme is even darker now.\n\n" +
- "- **Folder Sync:** Sync all your notes to an external folder live along with images.\n\n" +
- "- **Widget Options:** Widgets now show formatted text! You can also configure what notes to see in the widget.\n\n" +
- "Even more little things which help you enjoy using this app everyday"
- val WHATS_NEW_DETAILS_LAST_RELEASE_MD =
- "- **New UI and Icon:** New Search and Top Actionbar UI and icon\n\n" +
- "- **Widgets:** Added a new list of notes widget. Also fixed widget not updating bug.\n\n" +
- "- **Reminder:** Improved reminders to be more reliable."
-
-
- }
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/specs/MainActivityBottomBarSpec.kt b/base/src/main/java/com/maubis/scarlet/base/main/specs/MainActivityBottomBarSpec.kt
index 4f51b36f..a37defb4 100644
--- a/base/src/main/java/com/maubis/scarlet/base/main/specs/MainActivityBottomBarSpec.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/main/specs/MainActivityBottomBarSpec.kt
@@ -1,30 +1,44 @@
package com.maubis.scarlet.base.main.specs
+import android.content.pm.ShortcutInfo
import android.graphics.Color
+import android.graphics.drawable.Icon
import android.text.Layout
+import com.facebook.litho.ClickEvent
+import com.facebook.litho.Column
import com.facebook.litho.Component
import com.facebook.litho.ComponentContext
+import com.facebook.litho.LongClickEvent
import com.facebook.litho.Row
import com.facebook.litho.annotations.LayoutSpec
import com.facebook.litho.annotations.OnCreateLayout
+import com.facebook.litho.annotations.OnEvent
import com.facebook.litho.annotations.Prop
+import com.facebook.litho.widget.Image
+import com.facebook.litho.widget.Progress
import com.facebook.litho.widget.Text
import com.facebook.yoga.YogaAlign
import com.facebook.yoga.YogaEdge
import com.maubis.scarlet.base.MainActivity
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig.Companion.FONT_MONSERRAT
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
import com.maubis.scarlet.base.core.folder.FolderBuilder
import com.maubis.scarlet.base.database.room.folder.Folder
-import com.maubis.scarlet.base.main.sheets.HomeNavigationBottomSheet
+import com.maubis.scarlet.base.main.sheets.HomeOptionsBottomSheet
import com.maubis.scarlet.base.note.creation.activity.CreateNoteActivity
+import com.maubis.scarlet.base.note.creation.activity.NoteIntentRouterActivity
+import com.maubis.scarlet.base.note.creation.sheet.sNoteDefaultColor
import com.maubis.scarlet.base.note.folder.sheet.CreateOrEditFolderBottomSheet
-import com.maubis.scarlet.base.settings.sheet.sNoteDefaultColor
+import com.maubis.scarlet.base.support.addShortcut
+import com.maubis.scarlet.base.support.sheets.openSheet
import com.maubis.scarlet.base.support.specs.EmptySpec
import com.maubis.scarlet.base.support.specs.ToolbarColorConfig
import com.maubis.scarlet.base.support.specs.bottomBarCard
import com.maubis.scarlet.base.support.specs.bottomBarRoundIcon
import com.maubis.scarlet.base.support.ui.ColorUtil
+import com.maubis.scarlet.base.support.ui.ThemeColorType
+import com.maubis.scarlet.base.support.utils.OsVersionUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
@@ -32,45 +46,60 @@ import kotlinx.coroutines.launch
@LayoutSpec
object MainActivityBottomBarSpec {
@OnCreateLayout
- fun onCreate(context: ComponentContext,
- @Prop colorConfig: ToolbarColorConfig): Component {
+ fun onCreate(
+ context: ComponentContext,
+ @Prop colorConfig: ToolbarColorConfig): Component {
val activity = context.androidContext as MainActivity
val row = Row.create(context)
- .widthPercent(100f)
- .alignItems(YogaAlign.CENTER)
- .paddingDip(YogaEdge.HORIZONTAL, 4f)
+ .widthPercent(100f)
+ .alignItems(YogaAlign.CENTER)
+ .paddingDip(YogaEdge.HORIZONTAL, 4f)
row.child(bottomBarRoundIcon(context, colorConfig)
- .bgColor(Color.TRANSPARENT)
- .iconRes(R.drawable.ic_apps_white_48dp)
- .onClick {
- HomeNavigationBottomSheet.openSheet(activity)
- })
+ .bgColor(Color.TRANSPARENT)
+ .iconRes(R.drawable.ic_apps_white_48dp)
+ .onClick {
+ openSheet(activity, HomeOptionsBottomSheet())
+ })
row.child(EmptySpec.create(context).heightDip(1f).flexGrow(1f))
row.child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.icon_add_notebook)
- .onClick {
- CreateOrEditFolderBottomSheet.openSheet(
- activity,
- FolderBuilder().emptyFolder(sNoteDefaultColor),
- { _, _ -> activity.setupData() })
- })
+ .iconRes(R.drawable.icon_add_notebook)
+ .onClick {
+ CreateOrEditFolderBottomSheet.openSheet(
+ activity,
+ FolderBuilder().emptyFolder(sNoteDefaultColor),
+ { _, _ -> activity.loadData() })
+ })
row.child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.icon_add_list)
- .onClick {
- val intent = CreateNoteActivity.getNewChecklistNoteIntent(
- activity,
- activity.config.folders.firstOrNull()?.uuid ?: "")
- activity.startActivity(intent)
- })
+ .iconRes(R.drawable.icon_add_list)
+ .onClick {
+ val intent = CreateNoteActivity.getNewChecklistNoteIntent(
+ activity,
+ activity.state.currentFolder?.uuid ?: "")
+ activity.startActivity(intent)
+ })
row.child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.icon_add_note)
- .onClick {
- val intent = CreateNoteActivity.getNewNoteIntent(
- activity,
- activity.config.folders.firstOrNull()?.uuid ?: "")
- activity.startActivity(intent)
- })
+ .iconRes(R.drawable.icon_add_note)
+ .isLongClickEnabled(true)
+ .onLongClick {
+ if (!OsVersionUtils.canAddLauncherShortcuts()) {
+ return@onLongClick
+ }
+
+ val shortcut = ShortcutInfo.Builder(activity, "scarlet_notes___create_note")
+ .setShortLabel(activity.getString(R.string.shortcut_add_note))
+ .setLongLabel(activity.getString(R.string.shortcut_add_note))
+ .setIcon(Icon.createWithResource(activity, R.mipmap.create_launcher))
+ .setIntent(NoteIntentRouterActivity.create())
+ .build()
+ addShortcut(activity, shortcut)
+ }
+ .onClick {
+ val intent = CreateNoteActivity.getNewNoteIntent(
+ activity,
+ activity.state.currentFolder?.uuid ?: "")
+ activity.startActivity(intent)
+ })
return bottomBarCard(context, row.build(), colorConfig).build()
}
}
@@ -80,44 +109,153 @@ object MainActivityFolderBottomBarSpec {
@OnCreateLayout
fun onCreate(context: ComponentContext, @Prop folder: Folder): Component {
val colorConfig = ToolbarColorConfig(
- toolbarBackgroundColor = folder.color,
- toolbarIconColor = when (ColorUtil.isLightColored(folder.color)) {
- true -> context.getColor(R.color.dark_tertiary_text)
- false -> context.getColor(R.color.light_secondary_text)
- }
+ toolbarBackgroundColor = folder.color,
+ toolbarIconColor = when (ColorUtil.isLightColored(folder.color)) {
+ true -> context.getColor(R.color.dark_tertiary_text)
+ false -> context.getColor(R.color.light_secondary_text)
+ }
)
val activity = context.androidContext as MainActivity
val row = Row.create(context)
- .widthPercent(100f)
- .alignItems(YogaAlign.CENTER)
- .paddingDip(YogaEdge.HORIZONTAL, 4f)
+ .widthPercent(100f)
+ .alignItems(YogaAlign.CENTER)
+ .paddingDip(YogaEdge.HORIZONTAL, 4f)
row.child(bottomBarRoundIcon(context, colorConfig)
- .bgColor(Color.TRANSPARENT)
- .iconRes(R.drawable.ic_close_white_48dp)
- .onClick {
- GlobalScope.launch {
- activity.config.folders.clear()
- activity.unifiedSearch()
- GlobalScope.launch(Dispatchers.Main) {
- activity.notifyFolderChange()
- }
- }
- })
- row.child(Text.create(context)
- .typeface(FONT_MONSERRAT)
+ .bgColor(Color.TRANSPARENT)
+ .iconRes(R.drawable.ic_close_white_48dp)
+ .onClick { activity.onFolderChange(null) })
+ row.child(
+ Text.create(context)
+ .typeface(sAppTypeface.title())
.textAlignment(Layout.Alignment.ALIGN_CENTER)
.flexGrow(1f)
.text(folder.title)
.textSizeRes(R.dimen.font_size_normal)
- .textColor(colorConfig.toolbarIconColor))
+ .textColor(colorConfig.toolbarIconColor)
+ .clickHandler(MainActivityFolderBottomBar.onClickEvent(context)))
+ row.child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_more_options)
+ .isClickDisabled(true)
+ .clickHandler(MainActivityFolderBottomBar.onClickEvent(context))
+ .onClick {})
+ return bottomBarCard(context, row.build(), colorConfig).build()
+ }
+
+ @OnEvent(ClickEvent::class)
+ fun onClickEvent(context: ComponentContext, @Prop folder: Folder) {
+ val activity = context.androidContext as MainActivity
+ if (activity.state.currentFolder != null) {
+ CreateOrEditFolderBottomSheet.openSheet(activity, folder) { _, _ -> activity.loadData() }
+ }
+ }
+}
+
+@LayoutSpec
+object MainActivityDisabledSyncSpec {
+ @OnCreateLayout
+ fun onCreate(context: ComponentContext): Component {
+ val colorConfig = ToolbarColorConfig(
+ toolbarBackgroundColor = context.getColor(R.color.material_blue_grey_800),
+ toolbarIconColor = context.getColor(R.color.light_secondary_text)
+ )
+ val row = Row.create(context)
+ .widthPercent(100f)
+ .alignItems(YogaAlign.CENTER)
+ .paddingDip(YogaEdge.HORIZONTAL, 4f)
row.child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_more_options)
- .onClick {
- if (activity.config.folders.isEmpty()) {
- return@onClick
- }
- CreateOrEditFolderBottomSheet.openSheet(activity, folder, { _, _ -> activity.setupData() })
- })
+ .bgColor(Color.TRANSPARENT)
+ .iconRes(R.drawable.ic_info)
+ .onClick {
+ GlobalScope.launch {
+
+ }
+ })
+ row.child(
+ Column.create(context)
+ .flexGrow(1f)
+ .paddingDip(YogaEdge.ALL, 8f)
+ .child(
+ Text.create(context)
+ .typeface(sAppTypeface.subHeading())
+ .textRes(R.string.firebase_no_sync_warning)
+ .textSizeRes(R.dimen.font_size_normal)
+ .textColor(colorConfig.toolbarIconColor))
+ .child(
+ Text.create(context)
+ .typeface(sAppTypeface.title())
+ .textRes(R.string.firebase_no_sync_warning_details)
+ .textSizeRes(R.dimen.font_size_small)
+ .textColor(colorConfig.toolbarIconColor)))
+ row.clickHandler(MainActivityDisabledSync.onClickEvent(context))
return bottomBarCard(context, row.build(), colorConfig).build()
}
+
+ @OnEvent(ClickEvent::class)
+ fun onClickEvent(context: ComponentContext, @Prop onClick: () -> Unit) {
+ onClick()
+ }
+}
+
+@LayoutSpec
+object MainActivitySyncingNowSpec {
+ @OnCreateLayout
+ fun onCreate(context: ComponentContext, @Prop isSyncHappening: Boolean): Component {
+ val colorConfig = ToolbarColorConfig(
+ toolbarBackgroundColor = sAppTheme.get(ThemeColorType.TOOLBAR_BACKGROUND),
+ toolbarIconColor = sAppTheme.get(ThemeColorType.TOOLBAR_ICON)
+ )
+ val syncText = when (isSyncHappening) {
+ true -> R.string.home_syncing_top_layout
+ false -> R.string.home_pending_backup_top_layout
+ }
+ val syncIcon = when (isSyncHappening) {
+ true -> Progress.create(context)
+ .widthDip(24f)
+ .alpha(0.8f)
+ .marginDip(YogaEdge.END, 8f)
+ .color(colorConfig.toolbarIconColor)
+ false -> Image.create(context)
+ .heightDip(24f)
+ .widthDip(24f)
+ .marginDip(YogaEdge.END, 8f)
+ .alpha(0.8f)
+ .drawableRes(R.drawable.icon_folder_sync)
+ }
+
+ val row = Row.create(context)
+ .widthPercent(100f)
+ .alignItems(YogaAlign.CENTER)
+ .paddingDip(YogaEdge.HORIZONTAL, 8f)
+ .paddingDip(YogaEdge.VERTICAL, 8f)
+ .alpha(0.8f)
+ .child(EmptySpec.create(context).flexGrow(1f))
+ .child(
+ Row.create(context)
+ .alignItems(YogaAlign.CENTER)
+ .alignContent(YogaAlign.CENTER)
+ .paddingDip(YogaEdge.VERTICAL, 8f)
+ .paddingDip(YogaEdge.HORIZONTAL, 12f)
+ .backgroundRes(R.drawable.pending_sync_capsule)
+ .clickHandler(MainActivitySyncingNow.onClickEvent(context))
+ .longClickHandler(MainActivitySyncingNow.onLongClickEvent(context))
+ .child(syncIcon)
+ .child(
+ Text.create(context)
+ .typeface(sAppTypeface.title())
+ .textRes(syncText)
+ .textSizeRes(R.dimen.font_size_normal)
+ .textColorRes(R.color.light_secondary_text)))
+ return row.build()
+ }
+
+ @OnEvent(ClickEvent::class)
+ fun onClickEvent(context: ComponentContext, @Prop onClick: () -> Unit) {
+ onClick()
+ }
+
+ @OnEvent(LongClickEvent::class)
+ fun onLongClickEvent(context: ComponentContext, @Prop onLongClick: () -> Unit): Boolean {
+ onLongClick()
+ return true
+ }
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/main/utils/MainSnackbar.kt b/base/src/main/java/com/maubis/scarlet/base/main/utils/MainSnackbar.kt
index dd72dd54..27143d35 100644
--- a/base/src/main/java/com/maubis/scarlet/base/main/utils/MainSnackbar.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/main/utils/MainSnackbar.kt
@@ -7,10 +7,10 @@ import android.view.View.VISIBLE
import android.widget.LinearLayout
import android.widget.TextView
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.core.note.NoteBuilder
import com.maubis.scarlet.base.core.note.NoteState
import com.maubis.scarlet.base.core.note.getNoteState
+import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.note.save
class MainSnackbar(val layout: LinearLayout, val alwaysRunnable: () -> Unit) {
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/MarkdownExtensions.kt b/base/src/main/java/com/maubis/scarlet/base/note/MarkdownExtensions.kt
index 5789689b..f35140bf 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/MarkdownExtensions.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/MarkdownExtensions.kt
@@ -1,32 +1,79 @@
package com.maubis.scarlet.base.note
-import com.maubis.markdown.segmenter.MarkdownSegment
import com.maubis.markdown.segmenter.MarkdownSegmentType
+import com.maubis.markdown.segmenter.TextSegmenter
import com.maubis.scarlet.base.core.format.Format
import com.maubis.scarlet.base.core.format.FormatType
-fun MarkdownSegment.toFormat(): Format {
- return Format(type().toFormatType(), strip())
+fun String.toInternalFormats(): List {
+ return toInternalFormats(
+ arrayOf(
+ MarkdownSegmentType.HEADING_1,
+ MarkdownSegmentType.HEADING_2,
+ MarkdownSegmentType.HEADING_3,
+ MarkdownSegmentType.BULLET_1,
+ MarkdownSegmentType.BULLET_2,
+ MarkdownSegmentType.BULLET_3,
+ MarkdownSegmentType.CODE,
+ MarkdownSegmentType.QUOTE,
+ MarkdownSegmentType.CHECKLIST_UNCHECKED,
+ MarkdownSegmentType.CHECKLIST_CHECKED,
+ MarkdownSegmentType.SEPARATOR,
+ MarkdownSegmentType.IMAGE))
}
-fun MarkdownSegment.toRawFormat(): Format {
- return Format(type().toFormatType(), text())
-}
+/**
+ * Converts a string to the internal format types using the Markdown Segmentation Library.
+ * It's possible to pass specific formats which will be preserved in the formats
+ */
+fun String.toInternalFormats(whitelistedSegments: Array): List {
+ val extractedFormats = emptyList().toMutableList()
+ val segments = TextSegmenter(this).get()
+
+ var lastFormat: Format? = null
+ segments.forEach { segment ->
+ val isSegmentWhitelisted = whitelistedSegments.contains(segment.type())
+ val newFormat = when {
+ !isSegmentWhitelisted -> null
+ segment.type() == MarkdownSegmentType.HEADING_1 -> Format(FormatType.HEADING, segment.strip())
+ segment.type() == MarkdownSegmentType.HEADING_2 -> Format(FormatType.SUB_HEADING, segment.strip())
+ segment.type() == MarkdownSegmentType.HEADING_3 -> Format(FormatType.HEADING_3, segment.strip())
+ segment.type() == MarkdownSegmentType.BULLET_1 -> Format(FormatType.BULLET_1, segment.strip())
+ segment.type() == MarkdownSegmentType.BULLET_2 -> Format(FormatType.BULLET_2, segment.strip())
+ segment.type() == MarkdownSegmentType.BULLET_3 -> Format(FormatType.BULLET_3, segment.strip())
+ segment.type() == MarkdownSegmentType.CODE -> Format(FormatType.CODE, segment.strip())
+ segment.type() == MarkdownSegmentType.QUOTE -> Format(FormatType.QUOTE, segment.strip())
+ segment.type() == MarkdownSegmentType.CHECKLIST_UNCHECKED -> Format(FormatType.CHECKLIST_UNCHECKED, segment.strip())
+ segment.type() == MarkdownSegmentType.CHECKLIST_CHECKED -> Format(FormatType.CHECKLIST_CHECKED, segment.strip())
+ segment.type() == MarkdownSegmentType.SEPARATOR -> Format(FormatType.SEPARATOR)
+ segment.type() == MarkdownSegmentType.IMAGE -> Format(FormatType.IMAGE, segment.strip().trim())
+ else -> null
+ }
+
+ val tempLastFormat = lastFormat
+ when {
+ tempLastFormat !== null && newFormat !== null -> {
+ extractedFormats.add(tempLastFormat)
+ extractedFormats.add(newFormat)
+ lastFormat = null
+ }
+ tempLastFormat === null && newFormat !== null -> {
+ extractedFormats.add(newFormat)
+ }
+ tempLastFormat !== null && newFormat === null -> {
+ tempLastFormat.text += "\n"
+ tempLastFormat.text += segment.text()
+ lastFormat = tempLastFormat
+ }
+ tempLastFormat == null && newFormat === null -> {
+ lastFormat = Format(FormatType.TEXT, segment.text())
+ }
+ }
+ }
-fun MarkdownSegmentType.toFormatType(): FormatType {
- return when (this) {
- MarkdownSegmentType.INVALID -> FormatType.EMPTY
- MarkdownSegmentType.HEADING_1 -> FormatType.HEADING
- MarkdownSegmentType.HEADING_2 -> FormatType.SUB_HEADING
- MarkdownSegmentType.HEADING_3 -> FormatType.HEADING_3
- MarkdownSegmentType.NORMAL -> FormatType.TEXT
- MarkdownSegmentType.CODE -> FormatType.CODE
- MarkdownSegmentType.BULLET_1 -> FormatType.TEXT
- MarkdownSegmentType.BULLET_2 -> FormatType.TEXT
- MarkdownSegmentType.BULLET_3 -> FormatType.TEXT
- MarkdownSegmentType.QUOTE -> FormatType.QUOTE
- MarkdownSegmentType.SEPARATOR -> FormatType.SEPARATOR
- MarkdownSegmentType.CHECKLIST_UNCHECKED -> FormatType.CHECKLIST_UNCHECKED
- MarkdownSegmentType.CHECKLIST_CHECKED -> FormatType.CHECKLIST_CHECKED
+ val tempLastFormat = lastFormat
+ if (tempLastFormat !== null) {
+ extractedFormats.add(tempLastFormat)
}
+ return extractedFormats
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/NoteExtensions.kt b/base/src/main/java/com/maubis/scarlet/base/note/NoteExtensions.kt
index f5ca2348..19eb49e2 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/NoteExtensions.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/NoteExtensions.kt
@@ -1,12 +1,15 @@
package com.maubis.scarlet.base.note
import android.content.Context
-import android.content.Intent
-import android.util.Log
-import com.github.bijoysingh.starter.util.DateFormatter
import com.google.gson.Gson
import com.maubis.markdown.Markdown
-import com.maubis.markdown.segmenter.TextSegmenter
+import com.maubis.markdown.MarkdownConfig
+import com.maubis.markdown.spannable.MarkdownType
+import com.maubis.markdown.spannable.bold
+import com.maubis.markdown.spannable.font
+import com.maubis.markdown.spannable.relativeSize
+import com.maubis.markdown.spannable.strike
+import com.maubis.scarlet.base.config.ApplicationBase
import com.maubis.scarlet.base.config.CoreConfig
import com.maubis.scarlet.base.config.CoreConfig.Companion.tagsDb
import com.maubis.scarlet.base.core.format.Format
@@ -15,41 +18,32 @@ import com.maubis.scarlet.base.core.note.NoteState
import com.maubis.scarlet.base.core.note.generateUUID
import com.maubis.scarlet.base.core.note.getFormats
import com.maubis.scarlet.base.core.note.getTagUUIDs
+import com.maubis.scarlet.base.core.note.isUnsaved
import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.database.room.tag.Tag
-import com.maubis.scarlet.base.main.sheets.EnterPincodeBottomSheet
-import com.maubis.scarlet.base.note.creation.activity.CreateNoteActivity
-import com.maubis.scarlet.base.note.creation.activity.INTENT_KEY_DISTRACTION_FREE
-import com.maubis.scarlet.base.note.creation.activity.INTENT_KEY_NOTE_ID
-import com.maubis.scarlet.base.note.creation.activity.ViewAdvancedNoteActivity
-import com.maubis.scarlet.base.settings.sheet.sNoteDefaultColor
+import com.maubis.scarlet.base.note.creation.activity.NoteIntentRouterActivity
+import com.maubis.scarlet.base.note.creation.sheet.sNoteDefaultColor
+import com.maubis.scarlet.base.security.controller.PinLockController.needsLockCheck
+import com.maubis.scarlet.base.security.sheets.openUnlockSheet
+import com.maubis.scarlet.base.settings.sheet.sInternalShowUUID
+import com.maubis.scarlet.base.settings.sheet.sSecurityAppLockEnabled
+import com.maubis.scarlet.base.settings.sheet.sUIMarkdownEnabledOnHome
+import com.maubis.scarlet.base.support.BitmapHelper
+import com.maubis.scarlet.base.support.ui.ColorUtil
import com.maubis.scarlet.base.support.ui.ThemedActivity
-import com.maubis.scarlet.base.support.utils.removeMarkdownHeaders
+import com.maubis.scarlet.base.support.ui.sThemeDarkenNoteColor
+import com.maubis.scarlet.base.support.utils.sDateFormat
import java.util.*
import kotlin.collections.ArrayList
-fun Note.log(context: Context): String {
- val log = HashMap()
- log["note"] = this
- log["_title"] = getTitle()
- log["_text"] = getText()
- log["_image"] = getImageFile()
- log["_locked"] = getLockedText(false)
- log["_fullText"] = getFullText()
- log["_displayTime"] = getDisplayTime()
- log["_tag"] = getTagString()
- log["_formats"] = getFormats()
- return Gson().toJson(log)
-}
-
fun Note.log(): String {
val log = HashMap()
log["note"] = this
- log["_title"] = getTitle()
- log["_text"] = getText()
+ log["_text"] = getFullText()
log["_image"] = getImageFile()
log["_fullText"] = getFullText()
log["_displayTime"] = getDisplayTime()
+ log["_tag"] = getTagString()
log["_formats"] = getFormats()
return Gson().toJson(log)
}
@@ -57,20 +51,69 @@ fun Note.log(): String {
/**************************************************************************************
************* Content and Display Information Functions Functions ********************
**************************************************************************************/
-fun Note.getTitle(): String {
+
+fun Note.getFullTextForDirectMarkdownRender(): String {
+ var text = getFullText()
+ text = text.replace("\n[x] ", "\n\u2611 ")
+ text = text.replace("\n[ ] ", "\n\u2610 ")
+ text = text.replace("\n- ", "\n\u2022 ")
+ return text
+}
+
+fun Note.getMarkdownForListView(): CharSequence {
+ var text = getFullTextForDirectMarkdownRender()
+ if (sUIMarkdownEnabledOnHome) {
+ return markdownFormatForList(text)
+ }
+ return text
+}
+
+internal fun markdownFormatForList(text: String): CharSequence {
+ return Markdown.renderWithCustomFormatting(text, true) { spannable, spanInfo ->
+ val s = spanInfo.start
+ val e = spanInfo.end
+ when (spanInfo.markdownType) {
+ MarkdownType.HEADING_1 -> {
+ spannable.relativeSize(1.2f, s, e)
+ .font(MarkdownConfig.config.spanConfig.headingTypeface, s, e)
+ .bold(s, e)
+ true
+ }
+ MarkdownType.HEADING_2 -> {
+ spannable.relativeSize(1.1f, s, e)
+ .font(MarkdownConfig.config.spanConfig.headingTypeface, s, e)
+ .bold(s, e)
+ true
+ }
+ MarkdownType.HEADING_3 -> {
+ spannable.relativeSize(1.0f, s, e)
+ .font(MarkdownConfig.config.spanConfig.headingTypeface, s, e)
+ .bold(s, e)
+ true
+ }
+ MarkdownType.CHECKLIST_CHECKED -> {
+ spannable.strike(s, e)
+ true
+ }
+ else -> false
+ }
+ }
+}
+
+fun Note.getTitleForSharing(): String {
val formats = getFormats()
if (formats.isEmpty()) {
return ""
}
val format = formats.first()
+ val headingFormats = listOf(FormatType.HEADING, FormatType.SUB_HEADING, FormatType.HEADING_3)
return when {
- format.formatType === FormatType.HEADING -> format.text
- format.formatType === FormatType.SUB_HEADING -> format.text
+ headingFormats.contains(format.formatType) -> format.text
else -> ""
}
}
-fun Note.getText(): String {
+fun Note.getTextForSharing(): String {
val formats = getFormats().toMutableList()
if (formats.isEmpty()) {
return ""
@@ -89,7 +132,12 @@ fun Note.getText(): String {
stringBuilder.append("\n")
}
}
- return stringBuilder.toString().trim()
+
+ val text = stringBuilder.toString().trim()
+ if (sInternalShowUUID) {
+ return "`$uuid`\n\n$text"
+ }
+ return text
}
fun Note.getSmartFormats(): List {
@@ -98,7 +146,7 @@ fun Note.getSmartFormats(): List {
val smartFormats = ArrayList()
formats.forEach {
if (it.formatType == FormatType.TEXT) {
- val moreFormats = TextSegmenter(it.text).get().map { it.toFormat() }
+ val moreFormats = it.text.toInternalFormats()
moreFormats.forEach { format ->
format.uid = maxIndex
smartFormats.add(format)
@@ -117,45 +165,24 @@ fun Note.getImageFile(): String {
return format?.text ?: ""
}
-fun Note.getMarkdownTitle(isMarkdownEnabled: Boolean): CharSequence {
- val titleString = getTitle()
- return when {
- titleString.isBlank() -> ""
- !isMarkdownEnabled -> Markdown.render(removeMarkdownHeaders(titleString), true)
- else -> titleString
- }
-}
-
-fun Note.getMarkdownText(isMarkdownEnabled: Boolean): CharSequence {
- return when {
- isMarkdownEnabled -> Markdown.render(removeMarkdownHeaders(getText()), true)
- else -> getText()
- }
-}
-
fun Note.getFullText(): String {
- val formats = getFormats()
- return formats.map { it -> it.markdownText }.joinToString(separator = "\n").trim()
-}
-
-fun Note.getAlphabets(): String {
- val formats = getFormats()
- return formats.map { it -> it.markdownText }.joinToString(separator = "\n").trim().filter {
- ((it in 'a'..'z') || (it in 'A'..'Z'))
+ val fullText = getFormats().map { it -> it.markdownText }.joinToString(separator = "\n").trim()
+ if (sInternalShowUUID) {
+ return "`$uuid`\n$fullText"
}
+ return fullText
}
-fun Note.getUnreliablyStrippedText(context: Context): String {
- val builder = StringBuilder()
- builder.append(Markdown.render(removeMarkdownHeaders(getTitle())), true)
- builder.append(Markdown.render(removeMarkdownHeaders(getText())), true)
- return builder.toString().trim { it <= ' ' }
+fun Note.isNoteLockedButAppUnlocked(): Boolean {
+ return this.locked && !needsLockCheck() && sSecurityAppLockEnabled
}
-fun Note.getLockedText(isMarkdownEnabled: Boolean): CharSequence {
+fun Note.getLockedAwareTextForHomeList(): CharSequence {
+ val lockedText = "******************\n***********\n****************"
return when {
- this.locked -> "******************\n***********\n****************"
- else -> getMarkdownText(isMarkdownEnabled)
+ isNoteLockedButAppUnlocked() || !this.locked -> getMarkdownForListView()
+ !sUIMarkdownEnabledOnHome -> "${getTitleForSharing()}\n$lockedText"
+ else -> markdownFormatForList("# ${getTitleForSharing()}\n\n```\n$lockedText\n```")
}
}
@@ -170,12 +197,12 @@ fun Note.getDisplayTime(): String {
Calendar.getInstance().timeInMillis - time < 1000 * 60 * 60 * 2 -> "hh:mm aa"
else -> "dd MMMM"
}
- return DateFormatter.getDate(format, time)
+ return sDateFormat.readableTime(format, time)
}
fun Note.getTagString(): String {
val tags = getTags()
- return tags.map { it -> '`' + it.title + '`' }.joinToString(separator = " ")
+ return tags.map { it -> "` ${it.title} `" }.joinToString(separator = " ")
}
fun Note.getTags(): Set {
@@ -216,6 +243,13 @@ fun Note.removeTag(tag: Tag) {
this.tags = tags.joinToString(separator = ",")
}
+fun Note.adjustedColor(): Int {
+ return when (sThemeDarkenNoteColor) {
+ true -> ColorUtil.darkOrDarkerColor(color ?: sNoteDefaultColor)
+ false -> color ?: sNoteDefaultColor
+ }
+}
+
/**************************************************************************************
******************************* Note Action Functions ********************************
**************************************************************************************/
@@ -229,47 +263,40 @@ fun Note.mark(context: Context, noteState: NoteState) {
fun Note.edit(context: Context) {
if (this.locked) {
if (context is ThemedActivity) {
- EnterPincodeBottomSheet.openUnlockSheet(context, object : EnterPincodeBottomSheet.PincodeSuccessListener {
- override fun onFailure() {
- edit(context)
- }
-
- override fun onSuccess() {
- openEdit(context)
- }
- })
+ openUnlockSheet(
+ activity = context,
+ onUnlockSuccess = { context.startActivity(NoteIntentRouterActivity.edit(context, this)) },
+ onUnlockFailure = { edit(context) })
}
return
}
- openEdit(context)
-}
-
-fun Note.view(context: Context) {
- val intent = Intent(context, ViewAdvancedNoteActivity::class.java)
- intent.putExtra(INTENT_KEY_NOTE_ID, this.uid)
- context.startActivity(intent)
+ context.startActivity(NoteIntentRouterActivity.edit(context, this))
}
-fun Note.viewDistractionFree(context: Context) {
- val intent = Intent(context, ViewAdvancedNoteActivity::class.java)
- intent.putExtra(INTENT_KEY_NOTE_ID, this.uid)
- intent.putExtra(INTENT_KEY_DISTRACTION_FREE, true)
- context.startActivity(intent)
+fun Note.share(context: Context) {
+ ApplicationBase.instance.noteActions(this).share(context)
}
-fun Note.openEdit(context: Context) {
- val intent = Intent(context, CreateNoteActivity::class.java)
- intent.putExtra(INTENT_KEY_NOTE_ID, this.uid)
- context.startActivity(intent)
+fun Note.hasImages(): Boolean {
+ val imageFormats = getFormats().filter { it.formatType == FormatType.IMAGE }
+ return imageFormats.isNotEmpty()
}
-
-fun Note.share(context: Context) {
- CoreConfig.instance.noteActions(this).share(context)
+fun Note.shareImages(context: Context) {
+ val imageFormats = getFormats().filter { it.formatType == FormatType.IMAGE }
+ val bitmaps = imageFormats
+ .map { ApplicationBase.sAppImageStorage.getFile(uuid, it.text) }
+ .filter { it.exists() }
+ .map { BitmapHelper.loadFromFile(it) }
+ .filterNotNull()
+ when {
+ bitmaps.size == 1 -> BitmapHelper.send(context, bitmaps.first())
+ bitmaps.size > 1 -> BitmapHelper.send(context, bitmaps)
+ }
}
fun Note.copy(context: Context) {
- CoreConfig.instance.noteActions(this).copy(context)
+ ApplicationBase.instance.noteActions(this).copy(context)
}
/**************************************************************************************
@@ -292,15 +319,23 @@ fun Note.save(context: Context) {
saveWithoutSync(context)
return
}
- CoreConfig.instance.noteActions(this).save(context)
+ ApplicationBase.instance.noteActions(this).save(context)
+}
+
+fun Note.unsafeSave_INTERNAL_USE_ONLY() {
+ applySanityChecks()
+
+ val id = CoreConfig.notesDb.database().insertNote(this)
+ uid = if (isUnsaved()) id.toInt() else uid
+ CoreConfig.notesDb.notifyInsertNote(this)
}
fun Note.saveWithoutSync(context: Context) {
- CoreConfig.instance.noteActions(this).offlineSave(context)
+ ApplicationBase.instance.noteActions(this).offlineSave(context)
}
fun Note.saveToSync(context: Context) {
- CoreConfig.instance.noteActions(this).onlineSave(context)
+ ApplicationBase.instance.noteActions(this).onlineSave(context)
}
fun Note.delete(context: Context) {
@@ -308,17 +343,17 @@ fun Note.delete(context: Context) {
deleteWithoutSync(context)
return
}
- CoreConfig.instance.noteActions(this).delete(context)
+ ApplicationBase.instance.noteActions(this).delete(context)
}
fun Note.deleteWithoutSync(context: Context) {
- CoreConfig.instance.noteActions(this).offlineDelete(context)
+ ApplicationBase.instance.noteActions(this).offlineDelete(context)
}
fun Note.deleteToSync(context: Context) {
- CoreConfig.instance.noteActions(this).onlineDelete(context)
+ ApplicationBase.instance.noteActions(this).onlineDelete(context)
}
fun Note.softDelete(context: Context) {
- CoreConfig.instance.noteActions(this).softDelete(context)
+ ApplicationBase.instance.noteActions(this).softDelete(context)
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/actions/NoteOptionsBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/note/actions/NoteOptionsBottomSheet.kt
index f6549acc..0fc534da 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/actions/NoteOptionsBottomSheet.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/actions/NoteOptionsBottomSheet.kt
@@ -2,37 +2,54 @@ package com.maubis.scarlet.base.note.actions
import android.app.Dialog
import android.content.Intent
-import android.support.v4.content.ContextCompat
+import android.content.pm.ShortcutInfo
+import android.graphics.drawable.Icon
import android.view.View
import android.widget.GridLayout
+import android.widget.LinearLayout
+import android.widget.LinearLayout.VERTICAL
import android.widget.TextView
+import androidx.core.content.ContextCompat
import com.github.bijoysingh.starter.util.RandomHelper
import com.maubis.markdown.Markdown
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
import com.maubis.scarlet.base.core.note.NoteBuilder
import com.maubis.scarlet.base.core.note.NoteState
import com.maubis.scarlet.base.core.note.getNoteState
import com.maubis.scarlet.base.database.room.note.Note
-import com.maubis.scarlet.base.main.sheets.EnterPincodeBottomSheet
import com.maubis.scarlet.base.main.sheets.InstallProUpsellBottomSheet
import com.maubis.scarlet.base.main.sheets.openDeleteNotePermanentlySheet
-import com.maubis.scarlet.base.note.*
import com.maubis.scarlet.base.note.activity.INoteOptionSheetActivity
-import com.maubis.scarlet.base.note.folder.sheet.FolderChooseOptionsBottomSheet
+import com.maubis.scarlet.base.note.copy
+import com.maubis.scarlet.base.note.creation.activity.NoteIntentRouterActivity
+import com.maubis.scarlet.base.note.edit
+import com.maubis.scarlet.base.note.folder.sheet.FolderChooserBottomSheet
+import com.maubis.scarlet.base.note.getFullText
+import com.maubis.scarlet.base.note.getTagString
+import com.maubis.scarlet.base.note.getTitleForSharing
+import com.maubis.scarlet.base.note.hasImages
import com.maubis.scarlet.base.note.reminders.sheet.ReminderBottomSheet
+import com.maubis.scarlet.base.note.save
import com.maubis.scarlet.base.note.selection.activity.KEY_SELECT_EXTRA_MODE
import com.maubis.scarlet.base.note.selection.activity.KEY_SELECT_EXTRA_NOTE_ID
import com.maubis.scarlet.base.note.selection.activity.SelectNotesActivity
-import com.maubis.scarlet.base.note.tag.sheet.TagChooseOptionsBottomSheet
+import com.maubis.scarlet.base.note.share
+import com.maubis.scarlet.base.note.shareImages
+import com.maubis.scarlet.base.note.tag.sheet.TagChooserBottomSheet
import com.maubis.scarlet.base.notification.NotificationConfig
import com.maubis.scarlet.base.notification.NotificationHandler
+import com.maubis.scarlet.base.security.sheets.openUnlockSheet
import com.maubis.scarlet.base.settings.sheet.ColorPickerBottomSheet
import com.maubis.scarlet.base.settings.sheet.ColorPickerDefaultController
+import com.maubis.scarlet.base.support.addShortcut
import com.maubis.scarlet.base.support.option.OptionsItem
import com.maubis.scarlet.base.support.sheets.GridBottomSheetBase
+import com.maubis.scarlet.base.support.sheets.openSheet
import com.maubis.scarlet.base.support.ui.ThemedActivity
-import com.maubis.scarlet.base.support.utils.Flavor
+import com.maubis.scarlet.base.support.utils.FlavorUtils
+import com.maubis.scarlet.base.support.utils.OsVersionUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
@@ -57,14 +74,14 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
private fun setupGrid(dialog: Dialog, note: Note) {
val gridLayoutIds = arrayOf(
- R.id.quick_actions_properties,
- R.id.note_properties,
- R.id.grid_layout)
+ R.id.quick_actions_properties,
+ R.id.note_properties,
+ R.id.grid_layout)
val gridOptionFunctions = arrayOf(
- { noteForAction: Note -> getQuickActions(noteForAction) },
- { noteForAction: Note -> getNotePropertyOptions(noteForAction) },
- { noteForAction: Note -> getOptions(noteForAction) })
+ { noteForAction: Note -> getQuickActions(noteForAction) },
+ { noteForAction: Note -> getNotePropertyOptions(noteForAction) },
+ { noteForAction: Note -> getOptions(noteForAction) })
gridOptionFunctions.forEachIndexed { index, function ->
GlobalScope.launch(Dispatchers.Main) {
val items = GlobalScope.async(Dispatchers.IO) { function(note) }
@@ -75,31 +92,51 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
private fun setupCardViews(note: Note) {
val activity = context as ThemedActivity
- if (activity !is INoteOptionSheetActivity) {
+ val dlg = dialog
+ if (activity !is INoteOptionSheetActivity || dlg === null) {
return
}
- val tagCardLayout = dialog.findViewById(R.id.tag_card_layout)
+ val groupCardLayout = dlg.findViewById(R.id.group_card_layout)
+ val tagCardLayout = dlg.findViewById(R.id.tag_card_layout)
+ val selectCardLayout = dlg.findViewById(R.id.select_notes_layout)
+
+ val selectCardTitle = dlg.findViewById(R.id.select_notes_title)
+ selectCardTitle.typeface = sAppTypeface.title()
+ val selectCardSubtitle = dlg.findViewById(R.id.select_notes_subtitle)
+ selectCardSubtitle.typeface = sAppTypeface.title()
+
val tags = tagCardLayout.findViewById(R.id.tags_content)
- val tagsTitle = tagCardLayout.findViewById(R.id.tags_title)
+ tags.typeface = sAppTypeface.title()
+ val tagSubtitle = tagCardLayout.findViewById(R.id.tags_subtitle)
+ tagSubtitle.typeface = sAppTypeface.title()
+
val tagContent = note.getTagString()
if (tagContent.isNotBlank()) {
GlobalScope.launch(Dispatchers.Main) {
val text = GlobalScope.async(Dispatchers.IO) { Markdown.renderSegment(tagContent, true) }
tags.visibility = View.VISIBLE
- tagsTitle.visibility = View.GONE
+ tagSubtitle.visibility = View.GONE
tags.text = text.await()
+
+ groupCardLayout.orientation = VERTICAL
+
+ val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
+ val margin = activity.resources.getDimension(R.dimen.spacing_xxsmall).toInt()
+ params.setMargins(margin, margin, margin, margin)
+ tagCardLayout.layoutParams = params
+
+ selectCardLayout.layoutParams = params
}
}
tagCardLayout.setOnClickListener {
- TagChooseOptionsBottomSheet.openSheet(
- activity,
- note
- ) { activity.notifyTagsChanged(note) }
+ openSheet(activity, TagChooserBottomSheet().apply {
+ this.note = note
+ dismissListener = { activity.notifyTagsChanged(note) }
+ })
dismiss()
}
- val selectCardLayout = dialog.findViewById(R.id.select_notes_layout)
selectCardLayout.setOnClickListener {
val intent = Intent(context, SelectNotesActivity::class.java)
intent.putExtra(KEY_SELECT_EXTRA_MODE, activity.getSelectMode(note))
@@ -117,7 +154,8 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
}
val options = ArrayList()
- options.add(OptionsItem(
+ options.add(
+ OptionsItem(
title = R.string.restore_note,
subtitle = R.string.tap_for_action_not_trash,
icon = R.drawable.ic_restore,
@@ -126,17 +164,18 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
dismiss()
},
visible = note.getNoteState() == NoteState.TRASH
- ))
+ ))
options.add(OptionsItem(
- title = R.string.edit_note,
- subtitle = R.string.tap_for_action_edit,
- icon = R.drawable.ic_edit_white_48dp,
- listener = View.OnClickListener {
- note.edit(activity)
- dismiss()
- }
+ title = R.string.edit_note,
+ subtitle = R.string.tap_for_action_edit,
+ icon = R.drawable.ic_edit_white_48dp,
+ listener = View.OnClickListener {
+ note.edit(activity)
+ dismiss()
+ }
))
- options.add(OptionsItem(
+ options.add(
+ OptionsItem(
title = R.string.not_favourite_note,
subtitle = R.string.tap_for_action_not_favourite,
icon = R.drawable.ic_favorite_white_48dp,
@@ -145,8 +184,9 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
dismiss()
},
visible = note.getNoteState() == NoteState.FAVOURITE
- ))
- options.add(OptionsItem(
+ ))
+ options.add(
+ OptionsItem(
title = R.string.favourite_note,
subtitle = R.string.tap_for_action_favourite,
icon = R.drawable.ic_favorite_border_white_48dp,
@@ -155,8 +195,9 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
dismiss()
},
visible = note.getNoteState() != NoteState.FAVOURITE
- ))
- options.add(OptionsItem(
+ ))
+ options.add(
+ OptionsItem(
title = R.string.unarchive_note,
subtitle = R.string.tap_for_action_not_archive,
icon = R.drawable.ic_archive_white_48dp,
@@ -165,8 +206,9 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
dismiss()
},
visible = note.getNoteState() == NoteState.ARCHIVED
- ))
- options.add(OptionsItem(
+ ))
+ options.add(
+ OptionsItem(
title = R.string.archive_note,
subtitle = R.string.tap_for_action_archive,
icon = R.drawable.ic_archive_white_48dp,
@@ -175,8 +217,9 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
dismiss()
},
visible = note.getNoteState() != NoteState.ARCHIVED
- ))
- options.add(OptionsItem(
+ ))
+ options.add(
+ OptionsItem(
title = R.string.send_note,
subtitle = R.string.tap_for_action_share,
icon = R.drawable.ic_share_white_48dp,
@@ -185,8 +228,9 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
dismiss()
},
invalid = activity.lockedContentIsHidden() && note.locked
- ))
- options.add(OptionsItem(
+ ))
+ options.add(
+ OptionsItem(
title = R.string.copy_note,
subtitle = R.string.tap_for_action_copy,
icon = R.drawable.ic_content_copy_white_48dp,
@@ -195,8 +239,9 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
dismiss()
},
invalid = activity.lockedContentIsHidden() && note.locked
- ))
- options.add(OptionsItem(
+ ))
+ options.add(
+ OptionsItem(
title = R.string.delete_note_permanently,
subtitle = R.string.tap_for_action_delete,
icon = R.drawable.ic_delete_permanently,
@@ -206,8 +251,9 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
},
visible = note.getNoteState() == NoteState.TRASH,
invalid = activity.lockedContentIsHidden() && note.locked
- ))
- options.add(OptionsItem(
+ ))
+ options.add(
+ OptionsItem(
title = R.string.trash_note,
subtitle = R.string.tap_for_action_trash,
icon = R.drawable.ic_delete_white_48dp,
@@ -217,7 +263,7 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
},
visible = note.getNoteState() != NoteState.TRASH,
invalid = activity.lockedContentIsHidden() && note.locked
- ))
+ ))
return options
}
@@ -229,34 +275,40 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
val options = ArrayList()
options.add(OptionsItem(
- title = R.string.choose_note_color,
- subtitle = R.string.tap_for_action_color,
- icon = R.drawable.ic_action_color,
- listener = View.OnClickListener {
- val config = ColorPickerDefaultController(
- title = R.string.choose_note_color,
- colors = listOf(activity.resources.getIntArray(R.array.bright_colors), activity.resources.getIntArray(R.array.bright_colors_accent)),
- selectedColor = note.color,
- onColorSelected = { color ->
- note.color = color
- activity.updateNote(note)
- }
- )
- com.maubis.scarlet.base.support.sheets.openSheet(activity, ColorPickerBottomSheet().apply { this.config = config })
- dismiss()
- }
+ title = R.string.choose_note_color,
+ subtitle = R.string.tap_for_action_color,
+ icon = R.drawable.ic_action_color,
+ listener = View.OnClickListener {
+ val config = ColorPickerDefaultController(
+ title = R.string.choose_note_color,
+ colors = listOf(
+ activity.resources.getIntArray(R.array.bright_colors), activity.resources.getIntArray(R.array.bright_colors_accent)),
+ selectedColor = note.color,
+ onColorSelected = { color ->
+ note.color = color
+ activity.updateNote(note)
+ }
+ )
+ com.maubis.scarlet.base.support.sheets.openSheet(activity, ColorPickerBottomSheet().apply { this.config = config })
+ dismiss()
+ }
))
options.add(OptionsItem(
- title = if (note.pinned) R.string.unpin_note else R.string.pin_note,
- subtitle = if (note.pinned) R.string.unpin_note else R.string.pin_note,
- icon = R.drawable.ic_pin,
- listener = View.OnClickListener {
- note.pinned = !note.pinned
- activity.updateNote(note)
- dismiss()
- }
+ title = if (note.folder.isBlank()) R.string.folder_option_add_to_notebook else R.string.folder_option_change_notebook,
+ subtitle = R.string.folder_option_add_to_notebook,
+ icon = R.drawable.ic_folder,
+ listener = View.OnClickListener {
+ com.maubis.scarlet.base.support.sheets.openSheet(activity, FolderChooserBottomSheet().apply {
+ this.note = note
+ this.dismissListener = {
+ activity.notifyResetOrDismiss()
+ }
+ })
+ dismiss()
+ }
))
- options.add(OptionsItem(
+ options.add(
+ OptionsItem(
title = R.string.lock_note,
subtitle = R.string.lock_note,
icon = R.drawable.ic_action_lock,
@@ -266,24 +318,24 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
dismiss()
},
visible = !note.locked
- ))
- options.add(OptionsItem(
+ ))
+ options.add(
+ OptionsItem(
title = R.string.unlock_note,
subtitle = R.string.unlock_note,
icon = R.drawable.ic_action_unlock,
listener = View.OnClickListener {
- EnterPincodeBottomSheet.openUnlockSheet(
- activity,
- object : EnterPincodeBottomSheet.PincodeSuccessOnlyListener {
- override fun onSuccess() {
- note.locked = false
- activity.updateNote(note)
- dismiss()
- }
- })
+ openUnlockSheet(
+ activity = activity,
+ onUnlockSuccess = {
+ note.locked = false
+ activity.updateNote(note)
+ dismiss()
+ },
+ onUnlockFailure = { })
},
visible = note.locked
- ))
+ ))
return options
}
@@ -295,17 +347,29 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
val options = ArrayList()
options.add(OptionsItem(
- title = if (note.folder.isBlank()) R.string.folder_option_add_to_notebook else R.string.folder_option_change_notebook,
- subtitle = R.string.folder_option_add_to_notebook,
- icon = R.drawable.ic_folder,
+ title = if (note.pinned) R.string.unpin_note else R.string.pin_note,
+ subtitle = if (note.pinned) R.string.unpin_note else R.string.pin_note,
+ icon = R.drawable.ic_pin,
+ listener = View.OnClickListener {
+ note.pinned = !note.pinned
+ activity.updateNote(note)
+ dismiss()
+ }
+ ))
+ options.add(
+ OptionsItem(
+ title = R.string.share_images,
+ subtitle = R.string.share_images,
+ icon = R.drawable.icon_share_image,
listener = View.OnClickListener {
- FolderChooseOptionsBottomSheet.openSheet(activity, note, {
- activity.notifyResetOrDismiss()
- })
+ note.shareImages(activity)
dismiss()
- }
- ))
- options.add(OptionsItem(
+ },
+ visible = note.hasImages(),
+ invalid = activity.lockedContentIsHidden() && note.locked
+ ))
+ options.add(
+ OptionsItem(
title = R.string.open_in_notification,
subtitle = R.string.open_in_notification,
icon = R.drawable.ic_action_notification,
@@ -315,8 +379,9 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
dismiss()
},
invalid = activity.lockedContentIsHidden() && note.locked
- ))
- options.add(OptionsItem(
+ ))
+ options.add(
+ OptionsItem(
title = R.string.delete_note_permanently,
subtitle = R.string.delete_note_permanently,
icon = R.drawable.ic_delete_permanently,
@@ -326,8 +391,36 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
},
visible = note.getNoteState() !== NoteState.TRASH,
invalid = activity.lockedContentIsHidden() && note.locked
- ))
- options.add(OptionsItem(
+ ))
+
+ options.add(
+ OptionsItem(
+ title = R.string.pin_to_launcher,
+ subtitle = R.string.pin_to_launcher,
+ icon = R.drawable.icon_shortcut,
+ listener = View.OnClickListener {
+ if (!FlavorUtils.isLite() && OsVersionUtils.canAddLauncherShortcuts()) {
+ var title = note.getTitleForSharing()
+ if (title.isBlank()) {
+ title = note.getFullText().split("\n").firstOrNull() ?: "Note"
+ }
+
+ val shortcut = ShortcutInfo.Builder(activity, "scarlet_notes___${note.uuid}")
+ .setShortLabel(title)
+ .setLongLabel(title)
+ .setIcon(Icon.createWithResource(activity, R.mipmap.open_note_launcher))
+ .setIntent(NoteIntentRouterActivity.view(note))
+ .build()
+ addShortcut(activity, shortcut)
+ return@OnClickListener
+ }
+ openSheet(activity, InstallProUpsellBottomSheet())
+ },
+ visible = OsVersionUtils.canAddLauncherShortcuts(),
+ invalid = activity.lockedContentIsHidden() && note.locked
+ ))
+ options.add(
+ OptionsItem(
title = R.string.reminder,
subtitle = R.string.reminder,
icon = R.drawable.ic_action_reminder_icon,
@@ -336,8 +429,9 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
dismiss()
},
invalid = activity.lockedContentIsHidden() && note.locked
- ))
- options.add(OptionsItem(
+ ))
+ options.add(
+ OptionsItem(
title = R.string.duplicate,
subtitle = R.string.duplicate,
icon = R.drawable.ic_duplicate,
@@ -350,8 +444,9 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
dismiss()
},
invalid = activity.lockedContentIsHidden() && note.locked
- ))
- options.add(OptionsItem(
+ ))
+ options.add(
+ OptionsItem(
title = R.string.voice_action_title,
subtitle = R.string.voice_action_title,
icon = R.drawable.ic_action_speak_aloud,
@@ -360,55 +455,58 @@ class NoteOptionsBottomSheet() : GridBottomSheetBase() {
dismiss()
},
invalid = activity.lockedContentIsHidden() && note.locked
- ))
- options.add(OptionsItem(
+ ))
+ options.add(
+ OptionsItem(
title = R.string.view_distraction_free,
subtitle = R.string.view_distraction_free,
icon = R.drawable.ic_action_distraction_free,
listener = View.OnClickListener {
- if (CoreConfig.instance.appFlavor() == Flavor.PRO) {
- note.viewDistractionFree(activity)
+ if (!FlavorUtils.isLite()) {
+ activity.startActivity(NoteIntentRouterActivity.view(activity, note, isDistractionFree = true))
return@OnClickListener
}
- com.maubis.scarlet.base.support.sheets.openSheet(activity, InstallProUpsellBottomSheet())
+ openSheet(activity, InstallProUpsellBottomSheet())
},
- visible = CoreConfig.instance.appFlavor() != Flavor.NONE,
invalid = activity.lockedContentIsHidden() && note.locked
- ))
- options.add(OptionsItem(
+ ))
+ options.add(
+ OptionsItem(
title = R.string.open_in_popup,
subtitle = R.string.tap_for_action_popup,
icon = R.drawable.ic_bubble_chart_white_48dp,
listener = View.OnClickListener {
- CoreConfig.instance.noteActions(note).popup(activity)
+ ApplicationBase.instance.noteActions(note).popup(activity)
dismiss()
},
invalid = activity.lockedContentIsHidden() && note.locked
- ))
- options.add(OptionsItem(
+ ))
+ options.add(
+ OptionsItem(
title = R.string.backup_note_enable,
subtitle = R.string.backup_note_enable,
icon = R.drawable.ic_action_backup,
listener = View.OnClickListener {
- CoreConfig.instance.noteActions(note).enableBackup(activity)
+ ApplicationBase.instance.noteActions(note).enableBackup(activity)
activity.updateNote(note)
dismiss()
},
- visible = note.disableBackup && CoreConfig.instance.appFlavor() != Flavor.NONE,
+ visible = note.disableBackup && FlavorUtils.isPlayStore(),
invalid = activity.lockedContentIsHidden() && note.locked
- ))
- options.add(OptionsItem(
+ ))
+ options.add(
+ OptionsItem(
title = R.string.backup_note_disable,
subtitle = R.string.backup_note_disable,
icon = R.drawable.ic_action_backup_no,
listener = View.OnClickListener {
- CoreConfig.instance.noteActions(note).disableBackup(activity)
+ ApplicationBase.instance.noteActions(note).disableBackup(activity)
activity.updateNote(note)
dismiss()
},
- visible = !note.disableBackup && CoreConfig.instance.appFlavor() != Flavor.NONE,
+ visible = !note.disableBackup && FlavorUtils.isPlayStore(),
invalid = activity.lockedContentIsHidden() && note.locked
- ))
+ ))
return options
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/actions/TextToSpeechBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/note/actions/TextToSpeechBottomSheet.kt
index 5cee9161..bbcefa44 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/actions/TextToSpeechBottomSheet.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/actions/TextToSpeechBottomSheet.kt
@@ -1,17 +1,24 @@
package com.maubis.scarlet.base.note.actions
import android.app.Dialog
-import android.os.Build
import android.speech.tts.TextToSpeech
import android.widget.ImageView
import android.widget.TextView
+import com.maubis.markdown.Markdown
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
import com.maubis.scarlet.base.database.room.note.Note
-import com.maubis.scarlet.base.note.getUnreliablyStrippedText
+import com.maubis.scarlet.base.note.getFullText
import com.maubis.scarlet.base.support.ui.ThemeColorType
import com.maubis.scarlet.base.support.ui.ThemedActivity
import com.maubis.scarlet.base.support.ui.ThemedBottomSheetFragment
+import com.maubis.scarlet.base.support.utils.removeMarkdownHeaders
+
+fun Note.getTextToSpeechText(): String {
+ val builder = StringBuilder()
+ builder.append(Markdown.render(removeMarkdownHeaders(getFullText())), true)
+ return builder.toString().trim { it <= ' ' }
+}
class TextToSpeechBottomSheet : ThemedBottomSheetFragment() {
@@ -26,10 +33,10 @@ class TextToSpeechBottomSheet : ThemedBottomSheetFragment() {
val nonNullNote = note!!
val title = dialog.findViewById(R.id.options_title)
- title.setTextColor(CoreConfig.instance.themeController().get(ThemeColorType.SECONDARY_TEXT))
+ title.setTextColor(sAppTheme.get(ThemeColorType.SECONDARY_TEXT))
val speakPlayPause = dialog.findViewById(R.id.speak_play_pause)
- speakPlayPause.setColorFilter(CoreConfig.instance.themeController().get(ThemeColorType.TOOLBAR_ICON))
+ speakPlayPause.setColorFilter(sAppTheme.get(ThemeColorType.TOOLBAR_ICON))
speakPlayPause.setOnClickListener {
val tts = textToSpeech
if (tts === null) {
@@ -55,12 +62,8 @@ class TextToSpeechBottomSheet : ThemedBottomSheetFragment() {
makeBackgroundTransparent(dialog, R.id.root_layout)
}
- fun speak(note: Note) {
- if (Build.VERSION.SDK_INT >= 21) {
- textToSpeech?.speak(note.getUnreliablyStrippedText(themedContext()), TextToSpeech.QUEUE_FLUSH, null, "NOTE")
- } else {
- textToSpeech?.speak(note.getUnreliablyStrippedText(themedContext()), TextToSpeech.QUEUE_FLUSH, null)
- }
+ private fun speak(note: Note) {
+ textToSpeech?.speak(note.getTextToSpeechText(), TextToSpeech.QUEUE_FLUSH, null, "NOTE")
}
override fun getBackgroundView(): Int = R.id.container_layout
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/activity/INoteOptionSheetActivity.kt b/base/src/main/java/com/maubis/scarlet/base/note/activity/INoteOptionSheetActivity.kt
index a231887b..648772f8 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/activity/INoteOptionSheetActivity.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/activity/INoteOptionSheetActivity.kt
@@ -1,7 +1,7 @@
package com.maubis.scarlet.base.note.activity
-import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.core.note.NoteState
+import com.maubis.scarlet.base.database.room.note.Note
interface INoteOptionSheetActivity {
fun updateNote(note: Note)
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/creation/activity/CreateNoteActivity.kt b/base/src/main/java/com/maubis/scarlet/base/note/creation/activity/CreateNoteActivity.kt
index e0045986..aba6d134 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/creation/activity/CreateNoteActivity.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/creation/activity/CreateNoteActivity.kt
@@ -4,18 +4,22 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Handler
-import android.support.v7.widget.RecyclerView
-import android.support.v7.widget.helper.ItemTouchHelper
+import androidx.recyclerview.widget.ItemTouchHelper
+import androidx.recyclerview.widget.RecyclerView
import com.facebook.litho.ComponentContext
import com.facebook.litho.LithoView
import com.maubis.scarlet.base.R
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppImageStorage
import com.maubis.scarlet.base.config.CoreConfig.Companion.foldersDb
import com.maubis.scarlet.base.core.format.Format
import com.maubis.scarlet.base.core.format.FormatBuilder
import com.maubis.scarlet.base.core.format.FormatType
import com.maubis.scarlet.base.core.format.MarkdownType
-import com.maubis.scarlet.base.core.note.*
+import com.maubis.scarlet.base.core.note.NoteBuilder
import com.maubis.scarlet.base.core.note.NoteImage.Companion.deleteIfExist
+import com.maubis.scarlet.base.core.note.getFormats
+import com.maubis.scarlet.base.core.note.isEqual
+import com.maubis.scarlet.base.core.note.isUnsaved
import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.note.creation.specs.NoteCreationBottomBar
import com.maubis.scarlet.base.note.creation.specs.NoteCreationTopBar
@@ -27,6 +31,7 @@ import com.maubis.scarlet.base.settings.sheet.ColorPickerBottomSheet
import com.maubis.scarlet.base.settings.sheet.ColorPickerDefaultController
import com.maubis.scarlet.base.support.recycler.SimpleItemTouchHelper
import com.maubis.scarlet.base.support.specs.ToolbarColorConfig
+import com.maubis.scarlet.base.support.utils.maybeThrow
import kotlinx.android.synthetic.main.activity_advanced_note.*
import pl.aprilapps.easyphotopicker.DefaultCallback
import pl.aprilapps.easyphotopicker.EasyImage
@@ -40,8 +45,8 @@ open class CreateNoteActivity : ViewAdvancedNoteActivity() {
private var historyIndex = 0
private var historySize = 0L
-
- val history: MutableList = emptyList().toMutableList()
+ private var historyModified = false
+ private val history: MutableList = emptyList().toMutableList()
override val editModeValue: Boolean get() = true
@@ -50,7 +55,7 @@ open class CreateNoteActivity : ViewAdvancedNoteActivity() {
setTouchListener()
startHandler()
}
-
+
override fun onCreationFinished() {
super.onCreationFinished()
history.add(NoteBuilder().copy(note!!))
@@ -89,11 +94,12 @@ open class CreateNoteActivity : ViewAdvancedNoteActivity() {
addDefaultItem()
}
!formats[0].text.startsWith("# ") &&
- formats[0].formatType !== FormatType.HEADING
- && formats[0].formatType !== FormatType.IMAGE -> {
+ formats[0].formatType !== FormatType.HEADING
+ && formats[0].formatType !== FormatType.IMAGE -> {
addEmptyItem(0, FormatType.HEADING)
}
}
+ focus(0)
}
protected open fun addDefaultItem() {
@@ -109,19 +115,20 @@ open class CreateNoteActivity : ViewAdvancedNoteActivity() {
lithoTopToolbar.removeAllViews()
val componentContext = ComponentContext(this)
lithoTopToolbar.addView(
- LithoView.create(componentContext,
- NoteCreationTopBar.create(componentContext).build()))
+ LithoView.create(
+ componentContext,
+ NoteCreationTopBar.create(componentContext).build()))
}
override fun setBottomToolbar() {
val componentContext = ComponentContext(this)
lithoBottomToolbar.removeAllViews()
lithoBottomToolbar.addView(
- LithoView.create(
- componentContext,
- NoteCreationBottomBar.create(componentContext)
- .colorConfig(ToolbarColorConfig(colorConfig.toolbarBackgroundColor, colorConfig.toolbarIconColor))
- .build()))
+ LithoView.create(
+ componentContext,
+ NoteCreationBottomBar.create(componentContext)
+ .colorConfig(ToolbarColorConfig(colorConfig.toolbarBackgroundColor, colorConfig.toolbarIconColor))
+ .build()))
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@@ -132,13 +139,13 @@ open class CreateNoteActivity : ViewAdvancedNoteActivity() {
return
}
- val targetFile = NoteImage(context).renameOrCopy(note!!, imageFile)
+ val targetFile = sAppImageStorage.renameOrCopy(note!!, imageFile)
val index = getFormatIndex(type)
triggerImageLoaded(index, targetFile)
}
- override fun onImagePickerError(e: Exception, source: EasyImage.ImageSource, type: Int) {
- //Some error handling
+ override fun onImagePickerError(exception: Exception, source: EasyImage.ImageSource, type: Int) {
+ maybeThrow(this@CreateNoteActivity, exception)
}
})
}
@@ -180,7 +187,7 @@ open class CreateNoteActivity : ViewAdvancedNoteActivity() {
protected fun maybeUpdateNoteWithoutSync() {
val currentNote = note
- if (currentNote === null) {
+ if (currentNote === null || !formatsInitialised.get()) {
return
}
@@ -188,11 +195,11 @@ open class CreateNoteActivity : ViewAdvancedNoteActivity() {
currentNote.description = FormatBuilder().getSmarterDescription(formats)
// Ignore update if nothing changed. It allows for one undo per few seconds
- if (currentNote.isEqual(vLastNoteInstance)) {
- return
+ when {
+ !historyModified && currentNote.isEqual(vLastNoteInstance) -> return
+ !historyModified -> addNoteToHistory(NoteBuilder().copy(currentNote))
+ else -> historyModified = false
}
-
- addNoteToHistory(NoteBuilder().copy(currentNote))
currentNote.updateTimestamp = Calendar.getInstance().timeInMillis
maybeSaveNote(false)
}
@@ -215,13 +222,13 @@ open class CreateNoteActivity : ViewAdvancedNoteActivity() {
}
}
-
private fun startHandler() {
val handler = Handler()
handler.postDelayed(object : Runnable {
override fun run() {
if (active) {
maybeUpdateNoteWithoutSync()
+ fullScreenView()
handler.postDelayed(this, HANDLER_UPDATE_TIME.toLong())
}
}
@@ -294,7 +301,7 @@ open class CreateNoteActivity : ViewAdvancedNoteActivity() {
val formatToChange = formats[position]
if (!formatToChange.text.isBlank()) {
- val noteImage = NoteImage(context)
+ val noteImage = sAppImageStorage
deleteIfExist(noteImage.getFile(note!!.uuid, formatToChange.text))
}
formatToChange.text = file.name
@@ -307,24 +314,26 @@ open class CreateNoteActivity : ViewAdvancedNoteActivity() {
historyIndex = if (historyIndex == 0) 0 else (historyIndex - 1)
note = NoteBuilder().copy(history.get(historyIndex))
setNote()
+ historyModified = true
}
false -> {
val maxHistoryIndex = history.size - 1
historyIndex = if (historyIndex == maxHistoryIndex) maxHistoryIndex else (historyIndex + 1)
note = NoteBuilder().copy(history.get(historyIndex))
setNote()
+ historyModified = true
}
}
}
fun onColorChangeClick() {
val config = ColorPickerDefaultController(
- title = R.string.choose_note_color,
- colors = listOf(resources.getIntArray(R.array.bright_colors), resources.getIntArray(R.array.bright_colors_accent)),
- selectedColor = note!!.color,
- onColorSelected = { color ->
- setNoteColor(color)
- }
+ title = R.string.choose_note_color,
+ colors = listOf(resources.getIntArray(R.array.bright_colors), resources.getIntArray(R.array.bright_colors_accent)),
+ selectedColor = note!!.color,
+ onColorSelected = { color ->
+ setNoteColor(color)
+ }
)
com.maubis.scarlet.base.support.sheets.openSheet(this, ColorPickerBottomSheet().apply { this.config = config })
}
@@ -391,10 +400,6 @@ open class CreateNoteActivity : ViewAdvancedNoteActivity() {
maybeUpdateNoteWithoutSync()
}
- override fun setFormatChecked(format: Format, checked: Boolean) {
- // do nothing
- }
-
override fun createOrChangeToNextFormat(format: Format) {
val position = getFormatIndex(format)
if (position == -1) {
@@ -402,8 +407,8 @@ open class CreateNoteActivity : ViewAdvancedNoteActivity() {
}
val isCheckList =
- (format.formatType === FormatType.CHECKLIST_UNCHECKED
- || format.formatType === FormatType.CHECKLIST_CHECKED)
+ (format.formatType === FormatType.CHECKLIST_UNCHECKED
+ || format.formatType === FormatType.CHECKLIST_CHECKED)
val newPosition = position + 1
when {
isCheckList -> addEmptyItemAtFocused(FormatBuilder().getNextFormatType(FormatType.CHECKLIST_UNCHECKED))
@@ -413,19 +418,19 @@ open class CreateNoteActivity : ViewAdvancedNoteActivity() {
}
companion object {
- private const val INTENT_KEY_FOLDER = "key_folder"
+ const val INTENT_KEY_FOLDER = "key_folder"
fun getNewNoteIntent(
- context: Context,
- folder: String = ""): Intent {
+ context: Context,
+ folder: String = ""): Intent {
val intent = Intent(context, CreateNoteActivity::class.java)
intent.putExtra(INTENT_KEY_FOLDER, folder)
return intent
}
fun getNewChecklistNoteIntent(
- context: Context,
- folder: String = ""): Intent {
+ context: Context,
+ folder: String = ""): Intent {
val intent = Intent(context, CreateListNoteActivity::class.java)
intent.putExtra(INTENT_KEY_FOLDER, folder)
return intent
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/creation/activity/NoteIntentRouterActivity.kt b/base/src/main/java/com/maubis/scarlet/base/note/creation/activity/NoteIntentRouterActivity.kt
new file mode 100644
index 00000000..1b680e22
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/note/creation/activity/NoteIntentRouterActivity.kt
@@ -0,0 +1,123 @@
+package com.maubis.scarlet.base.note.creation.activity
+
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.instance
+import com.maubis.scarlet.base.database.room.note.Note
+import com.maubis.scarlet.base.note.creation.sheet.sEditorSkipNoteViewer
+
+class NoteIntentRouterActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val data: Uri? = intent?.data
+ if (data === null) {
+ finish()
+ return
+ }
+
+ handleOpenNote(data)
+ handleCreateNote(data)
+ }
+
+ fun handleOpenNote(data: Uri): Boolean {
+ if (data.host != "open_note") {
+ return false
+ }
+
+ val noteUUID = data.getQueryParameter("uuid")
+ if (noteUUID === null) {
+ return false
+ }
+
+ val note = instance.notesDatabase().getByUUID(noteUUID)
+ if (note === null) {
+ return false
+ }
+
+ val intent = when (data.getQueryParameter("is_edit", false)) {
+ true -> edit(this, note)
+ false -> view(this, note, data.getQueryParameter("is_distraction_free", false))
+ }
+ startActivity(intent)
+ return true
+ }
+
+ fun handleCreateNote(data: Uri): Boolean {
+ if (data.host != "create_note") {
+ return false
+ }
+
+ startActivity(create(this))
+ return true
+ }
+
+ companion object {
+
+ private fun Boolean.toInt(): Int {
+ return when (this) {
+ true -> 1
+ else -> 0
+ }
+ }
+
+ private fun Uri.getQueryParameter(key: String, defaultValue: Boolean): Boolean {
+ val param = getQueryParameter(key)
+ if (param === null) {
+ return defaultValue
+ }
+ return param == "1"
+ }
+
+ fun view(context: Context, note: Note, isDistractionFree: Boolean = false): Intent {
+ if (sEditorSkipNoteViewer) {
+ return edit(context, note)
+ }
+
+ return Intent(context, ViewAdvancedNoteActivity::class.java)
+ .putExtra(INTENT_KEY_NOTE_ID, note.uid)
+ .putExtra(INTENT_KEY_DISTRACTION_FREE, isDistractionFree)
+ }
+
+ fun edit(context: Context, note: Note): Intent {
+ return Intent(context, CreateNoteActivity::class.java)
+ .putExtra(INTENT_KEY_NOTE_ID, note.uid)
+ }
+
+ fun create(context: Context, baseFolder: String = ""): Intent {
+ return Intent(context, CreateNoteActivity::class.java)
+ .putExtra(CreateNoteActivity.INTENT_KEY_FOLDER, baseFolder)
+ }
+
+ fun view(note: Note, isDistractionFree: Boolean = false): Intent {
+ val uri = Uri.Builder()
+ .scheme("scarlet")
+ .authority("open_note")
+ .appendQueryParameter("uuid", note.uuid)
+ .appendQueryParameter("is_distraction_free", isDistractionFree.toInt().toString())
+ .build()
+ return Intent(Intent.ACTION_VIEW, uri)
+ }
+
+ fun edit(note: Note): Intent {
+ val uri = Uri.Builder()
+ .scheme("scarlet")
+ .authority("open_note")
+ .appendQueryParameter("uuid", note.uuid)
+ .appendQueryParameter("is_edit", "1")
+ .build()
+ return Intent(Intent.ACTION_VIEW, uri)
+ }
+
+ fun create(): Intent {
+ val uri = Uri.Builder()
+ .scheme("scarlet")
+ .authority("create_note")
+ .build()
+ return Intent(Intent.ACTION_VIEW, uri)
+ }
+ }
+}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/creation/activity/ShareToScarletRouterActivity.kt b/base/src/main/java/com/maubis/scarlet/base/note/creation/activity/ShareToScarletRouterActivity.kt
new file mode 100644
index 00000000..99e1a758
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/note/creation/activity/ShareToScarletRouterActivity.kt
@@ -0,0 +1,131 @@
+package com.maubis.scarlet.base.note.creation.activity
+
+import android.content.Intent
+import android.graphics.BitmapFactory
+import android.net.Uri
+import android.os.Bundle
+import android.os.Parcelable
+import androidx.appcompat.app.AppCompatActivity
+import com.maubis.scarlet.base.MainActivity
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppImageStorage
+import com.maubis.scarlet.base.core.format.Format
+import com.maubis.scarlet.base.core.format.FormatBuilder
+import com.maubis.scarlet.base.core.format.FormatType
+import com.maubis.scarlet.base.core.note.NoteBuilder
+import com.maubis.scarlet.base.core.note.getFormats
+import com.maubis.scarlet.base.database.room.note.Note
+import com.maubis.scarlet.base.export.support.NoteImporter
+import com.maubis.scarlet.base.main.activity.INTENT_KEY_DIRECT_NOTES_TRANSFER
+import com.maubis.scarlet.base.main.activity.KEEP_PACKAGE
+import com.maubis.scarlet.base.note.save
+import com.maubis.scarlet.base.support.BitmapHelper
+import com.maubis.scarlet.base.support.utils.OsVersionUtils
+import java.io.File
+
+class ShareToScarletRouterActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ try {
+ val hasDirectIntent = handleDirectSendText(intent)
+ if (hasDirectIntent) {
+ startActivity(Intent(this, MainActivity::class.java))
+ return
+ }
+
+ val note = handleSendText(intent)
+ if (note === null) {
+ return
+ }
+ startActivity(ViewAdvancedNoteActivity.getIntent(this, note))
+ } finally {
+ finish()
+ }
+ }
+
+ private fun handleSendText(intent: Intent): Note? {
+ val sharedText = intent.getStringExtra(Intent.EXTRA_TEXT) ?: ""
+ val sharedSubject = intent.getStringExtra(Intent.EXTRA_SUBJECT)
+ ?: intent.getStringExtra(Intent.EXTRA_TITLE) ?: ""
+ val sharedImages = when {
+ intent.action == Intent.ACTION_SEND -> handleSendImage(intent)
+ intent.action == Intent.ACTION_SEND_MULTIPLE -> handleSendMultipleImages(intent)
+ else -> emptyList()
+ }
+ if (sharedText.isBlank() && sharedSubject.isBlank() && sharedImages.isEmpty()) {
+ return null
+ }
+
+ val note = when (isCallerKeep()) {
+ true -> NoteBuilder().gen(sharedSubject, NoteBuilder().genFromKeep(sharedText))
+ false -> NoteBuilder().gen(sharedSubject, sharedText)
+ }
+ note.save(this)
+
+ val images = emptyList().toMutableList()
+ for (uri in sharedImages) {
+ try {
+ val inputStream = this.contentResolver.openInputStream(uri)
+ val bitmap = BitmapFactory.decodeStream(inputStream)
+ inputStream?.close()
+
+ val temporaryImage = createTempFile()
+ BitmapHelper.saveToFile(temporaryImage, bitmap)
+
+ images.add(sAppImageStorage.renameOrCopy(note, temporaryImage))
+ temporaryImage.delete()
+ } catch (exception: Exception) {
+ }
+ }
+ val formats = note.getFormats().toMutableList()
+ for (image in images.reversed()) {
+ formats.add(0, Format(FormatType.IMAGE, image.name))
+ }
+ note.description = FormatBuilder().getSmarterDescription(formats)
+ note.save(this)
+ return note
+ }
+
+ private fun handleDirectSendText(intent: Intent): Boolean {
+ val sharedText = intent.getStringExtra(INTENT_KEY_DIRECT_NOTES_TRANSFER)
+ if (sharedText === null || sharedText.isBlank()) {
+ return false
+ }
+ NoteImporter().gen(this, sharedText)
+ return true
+ }
+
+ private fun handleSendImage(intent: Intent): List {
+ val images = emptyList().toMutableList()
+ (intent.getParcelableExtra(Intent.EXTRA_STREAM) as? Uri)?.let {
+ images.add(it)
+ }
+ return images
+ }
+
+ private fun handleSendMultipleImages(intent: Intent): List {
+ val images = emptyList().toMutableList()
+ intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM)?.let {
+ for (parcelable in it) {
+ if (parcelable is Uri) {
+ images.add(parcelable)
+ }
+ }
+ }
+ return images
+ }
+
+ private fun isCallerKeep(): Boolean {
+ return try {
+ when {
+ OsVersionUtils.canExtractReferrer() && (referrer?.toString()
+ ?: "").contains(KEEP_PACKAGE) -> true
+ callingPackage?.contains(KEEP_PACKAGE) ?: false -> true
+ (intent?.`package` ?: "").contains(KEEP_PACKAGE) -> true
+ else -> false
+ }
+ } catch (exception: Exception) {
+ false
+ }
+ }
+}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/creation/activity/ViewNoteActivity.kt b/base/src/main/java/com/maubis/scarlet/base/note/creation/activity/ViewNoteActivity.kt
index 2b803239..948c6f3f 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/creation/activity/ViewNoteActivity.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/creation/activity/ViewNoteActivity.kt
@@ -1,28 +1,35 @@
package com.maubis.scarlet.base.note.creation.activity
+import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.Color
-import android.os.Build
import android.os.Bundle
-import android.support.v7.widget.RecyclerView
import android.view.View
+import androidx.recyclerview.widget.RecyclerView
import com.facebook.litho.ComponentContext
import com.facebook.litho.LithoView
import com.github.bijoysingh.starter.recyclerview.MultiRecyclerViewControllerItem
import com.github.bijoysingh.starter.recyclerview.RecyclerViewBuilder
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppPreferences
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
import com.maubis.scarlet.base.core.format.Format
import com.maubis.scarlet.base.core.format.FormatBuilder
import com.maubis.scarlet.base.core.format.FormatType
import com.maubis.scarlet.base.core.format.sectionPreservingSort
-import com.maubis.scarlet.base.core.note.*
+import com.maubis.scarlet.base.core.note.NoteBuilder
+import com.maubis.scarlet.base.core.note.NoteState
+import com.maubis.scarlet.base.core.note.generateUUID
+import com.maubis.scarlet.base.core.note.getFormats
+import com.maubis.scarlet.base.core.note.isUnsaved
import com.maubis.scarlet.base.database.room.note.Note
-import com.maubis.scarlet.base.note.*
import com.maubis.scarlet.base.note.actions.NoteOptionsBottomSheet
import com.maubis.scarlet.base.note.activity.INoteOptionSheetActivity
+import com.maubis.scarlet.base.note.adjustedColor
+import com.maubis.scarlet.base.note.creation.sheet.sNoteDefaultColor
import com.maubis.scarlet.base.note.creation.specs.NoteViewBottomBar
import com.maubis.scarlet.base.note.creation.specs.NoteViewTopBar
import com.maubis.scarlet.base.note.formats.FormatAdapter
@@ -30,13 +37,25 @@ import com.maubis.scarlet.base.note.formats.IFormatRecyclerViewActivity
import com.maubis.scarlet.base.note.formats.getFormatControllerItems
import com.maubis.scarlet.base.note.formats.recycler.KEY_EDITABLE
import com.maubis.scarlet.base.note.formats.recycler.KEY_NOTE_COLOR
-import com.maubis.scarlet.base.settings.sheet.*
+import com.maubis.scarlet.base.note.getSmartFormats
+import com.maubis.scarlet.base.note.getTagString
+import com.maubis.scarlet.base.note.mark
+import com.maubis.scarlet.base.note.save
+import com.maubis.scarlet.base.note.saveWithoutSync
+import com.maubis.scarlet.base.note.softDelete
+import com.maubis.scarlet.base.settings.sheet.STORE_KEY_TEXT_SIZE
import com.maubis.scarlet.base.settings.sheet.SettingsOptionsBottomSheet.Companion.KEY_MARKDOWN_ENABLED
-import com.maubis.scarlet.base.settings.sheet.UISettingsOptionsBottomSheet.Companion.useNoteColorAsBackground
+import com.maubis.scarlet.base.settings.sheet.sEditorTextSize
+import com.maubis.scarlet.base.settings.sheet.sUIUseNoteColorAsBackground
import com.maubis.scarlet.base.support.specs.ToolbarColorConfig
-import com.maubis.scarlet.base.support.ui.*
-import com.maubis.scarlet.base.support.ui.ColorUtil.darkerColor
+import com.maubis.scarlet.base.support.ui.ColorUtil
+import com.maubis.scarlet.base.support.ui.ColorUtil.darkOrDarkerColor
+import com.maubis.scarlet.base.support.ui.KEY_NIGHT_THEME
+import com.maubis.scarlet.base.support.ui.SecuredActivity
+import com.maubis.scarlet.base.support.ui.Theme
+import com.maubis.scarlet.base.support.ui.ThemeColorType
import com.maubis.scarlet.base.support.utils.bind
+import com.maubis.scarlet.base.widget.getPendingIntentWithStack
import kotlinx.android.synthetic.main.activity_advanced_note.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
@@ -44,25 +63,25 @@ import kotlinx.coroutines.launch
import java.util.*
import java.util.concurrent.atomic.AtomicBoolean
-
const val INTENT_KEY_NOTE_ID = "NOTE_ID"
const val INTENT_KEY_DISTRACTION_FREE = "DISTRACTION_FREE"
-
data class NoteViewColorConfig(
- var backgroundColor: Int = Color.BLACK,
- var toolbarBackgroundColor: Int = Color.BLACK,
- var toolbarIconColor: Int = Color.BLACK,
- var statusBarColor: Int = Color.BLACK)
+ var backgroundColor: Int = Color.BLACK,
+ var toolbarBackgroundColor: Int = Color.BLACK,
+ var toolbarIconColor: Int = Color.BLACK,
+ var statusBarColor: Int = Color.BLACK)
-open class ViewAdvancedNoteActivity : ThemedActivity(), INoteOptionSheetActivity, IFormatRecyclerViewActivity {
+open class ViewAdvancedNoteActivity : SecuredActivity(), INoteOptionSheetActivity, IFormatRecyclerViewActivity {
var focusedFormat: Format? = null
+
protected var note: Note? = null
+ protected lateinit var formats: MutableList
+ protected val formatsInitialised = AtomicBoolean(false)
protected lateinit var context: Context
protected lateinit var adapter: FormatAdapter
- protected lateinit var formats: MutableList
protected lateinit var formatsView: RecyclerView
protected var isDistractionFree: Boolean = false
@@ -109,7 +128,7 @@ open class ViewAdvancedNoteActivity : ThemedActivity(), INoteOptionSheetActivity
override fun onResume() {
super.onResume()
- CoreConfig.instance.startListener(this)
+ ApplicationBase.instance.startListener(this)
if (!creationFinished.get()) {
return
@@ -133,14 +152,12 @@ open class ViewAdvancedNoteActivity : ThemedActivity(), INoteOptionSheetActivity
}
private fun startDistractionFreeMode() {
- var uiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
- or View.SYSTEM_UI_FLAG_FULLSCREEN)
- if (Build.VERSION.SDK_INT >= 19) {
- uiVisibility = (uiVisibility or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
- }
+ val uiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ or View.SYSTEM_UI_FLAG_FULLSCREEN
+ or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
window.decorView.systemUiVisibility = uiVisibility
}
@@ -148,10 +165,10 @@ open class ViewAdvancedNoteActivity : ThemedActivity(), INoteOptionSheetActivity
val currentNote = note
val bundle = Bundle()
bundle.putBoolean(KEY_EDITABLE, editModeValue)
- bundle.putBoolean(KEY_MARKDOWN_ENABLED, CoreConfig.instance.store().get(KEY_MARKDOWN_ENABLED, true))
- bundle.putBoolean(KEY_NIGHT_THEME, CoreConfig.instance.themeController().isNightTheme())
+ bundle.putBoolean(KEY_MARKDOWN_ENABLED, sAppPreferences.get(KEY_MARKDOWN_ENABLED, true))
+ bundle.putBoolean(KEY_NIGHT_THEME, sAppTheme.isNightTheme())
bundle.putInt(STORE_KEY_TEXT_SIZE, sEditorTextSize)
- bundle.putInt(KEY_NOTE_COLOR, currentNote?.color ?: sNoteDefaultColor)
+ bundle.putInt(KEY_NOTE_COLOR, currentNote?.adjustedColor() ?: sNoteDefaultColor)
bundle.putString(INTENT_KEY_NOTE_ID, currentNote?.uuid ?: generateUUID())
adapter.setExtra(bundle)
}
@@ -174,6 +191,7 @@ open class ViewAdvancedNoteActivity : ThemedActivity(), INoteOptionSheetActivity
false -> currentNote.getSmartFormats()
}.toMutableList()
adapter.addItems(formats)
+ formatsInitialised.set(true)
if (!editModeValue) {
maybeAddTags()
@@ -203,9 +221,9 @@ open class ViewAdvancedNoteActivity : ThemedActivity(), INoteOptionSheetActivity
private fun setRecyclerView() {
adapter = FormatAdapter(this)
formatsView = RecyclerViewBuilder(this)
- .setAdapter(adapter)
- .setView(this, R.id.advanced_note_recycler)
- .build()
+ .setAdapter(adapter)
+ .setView(this, R.id.advanced_note_recycler)
+ .build()
}
open fun setFormat(format: Format) {
@@ -244,7 +262,7 @@ open class ViewAdvancedNoteActivity : ThemedActivity(), INoteOptionSheetActivity
}
fun openEditor() {
- note!!.openEdit(context)
+ context.startActivity(NoteIntentRouterActivity.edit(context, note!!))
}
protected open fun notifyToolbarColor() {
@@ -253,24 +271,24 @@ open class ViewAdvancedNoteActivity : ThemedActivity(), INoteOptionSheetActivity
return
}
- val theme = CoreConfig.instance.themeController()
+ val noteColor = currentNote.adjustedColor()
when {
- !useNoteColorAsBackground -> {
- colorConfig.backgroundColor = theme.get(ThemeColorType.BACKGROUND)
- colorConfig.toolbarIconColor = theme.get(ThemeColorType.TOOLBAR_ICON)
+ !sUIUseNoteColorAsBackground -> {
+ colorConfig.backgroundColor = sAppTheme.get(ThemeColorType.BACKGROUND)
+ colorConfig.toolbarIconColor = sAppTheme.get(ThemeColorType.TOOLBAR_ICON)
colorConfig.statusBarColor = colorConfig.backgroundColor
- colorConfig.toolbarBackgroundColor = theme.get(ThemeColorType.TOOLBAR_BACKGROUND)
+ colorConfig.toolbarBackgroundColor = sAppTheme.get(ThemeColorType.TOOLBAR_BACKGROUND)
}
- ColorUtil.isLightColored(currentNote.color) -> {
- colorConfig.backgroundColor = currentNote.color
- colorConfig.toolbarIconColor = theme.get(context, Theme.DARK, ThemeColorType.TOOLBAR_ICON)
- colorConfig.statusBarColor = darkerColor(currentNote.color)
+ ColorUtil.isLightColored(noteColor) -> {
+ colorConfig.backgroundColor = noteColor
+ colorConfig.toolbarIconColor = sAppTheme.get(context, Theme.DARK, ThemeColorType.TOOLBAR_ICON)
+ colorConfig.statusBarColor = darkOrDarkerColor(noteColor)
colorConfig.toolbarBackgroundColor = colorConfig.statusBarColor
}
else -> {
- colorConfig.backgroundColor = currentNote.color
- colorConfig.toolbarIconColor = theme.get(context, Theme.DARK, ThemeColorType.TOOLBAR_ICON)
- colorConfig.statusBarColor = darkerColor(currentNote.color)
+ colorConfig.backgroundColor = noteColor
+ colorConfig.toolbarIconColor = sAppTheme.get(context, Theme.DARK, ThemeColorType.TOOLBAR_ICON)
+ colorConfig.statusBarColor = darkOrDarkerColor(noteColor)
colorConfig.toolbarBackgroundColor = colorConfig.statusBarColor
}
}
@@ -290,18 +308,20 @@ open class ViewAdvancedNoteActivity : ThemedActivity(), INoteOptionSheetActivity
lithoBottomToolbar.removeAllViews()
val componentContext = ComponentContext(this)
lithoBottomToolbar.addView(
- LithoView.create(componentContext,
- NoteViewBottomBar.create(componentContext)
- .colorConfig(ToolbarColorConfig(colorConfig.toolbarBackgroundColor, colorConfig.toolbarIconColor))
- .build()))
+ LithoView.create(
+ componentContext,
+ NoteViewBottomBar.create(componentContext)
+ .colorConfig(ToolbarColorConfig(colorConfig.toolbarBackgroundColor, colorConfig.toolbarIconColor))
+ .build()))
}
protected open fun setTopToolbar() {
lithoTopToolbar.removeAllViews()
val componentContext = ComponentContext(this)
lithoTopToolbar.addView(
- LithoView.create(componentContext,
- NoteViewTopBar.create(componentContext).build()))
+ LithoView.create(
+ componentContext,
+ NoteViewTopBar.create(componentContext).build()))
}
protected open fun setNoteColor(color: Int) {
@@ -340,11 +360,8 @@ open class ViewAdvancedNoteActivity : ThemedActivity(), INoteOptionSheetActivity
notifyToolbarColor()
}
- public override fun onSaveInstanceState(savedInstanceState: Bundle?) {
+ override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
- if (savedInstanceState == null) {
- return
- }
savedInstanceState.putInt(INTENT_KEY_NOTE_ID, if (note == null || note!!.uid == null) 0 else note!!.uid)
}
@@ -358,6 +375,12 @@ open class ViewAdvancedNoteActivity : ThemedActivity(), INoteOptionSheetActivity
intent.putExtra(INTENT_KEY_NOTE_ID, note.uid)
return intent
}
+
+ fun getIntentWithStack(context: Context, note: Note): PendingIntent? {
+ val intent = Intent(context, ViewAdvancedNoteActivity::class.java)
+ intent.putExtra(INTENT_KEY_NOTE_ID, note.uid)
+ return getPendingIntentWithStack(context, 5000 + note.uid, intent)
+ }
}
/**
@@ -396,7 +419,6 @@ open class ViewAdvancedNoteActivity : ThemedActivity(), INoteOptionSheetActivity
* End : INoteOptionSheetActivity
*/
-
/**
* Start : IFormatRecyclerView Functions
*/
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/creation/sheet/EditorOptionsBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/note/creation/sheet/EditorOptionsBottomSheet.kt
index 0133a71b..5d17f82b 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/creation/sheet/EditorOptionsBottomSheet.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/creation/sheet/EditorOptionsBottomSheet.kt
@@ -2,31 +2,42 @@ package com.maubis.scarlet.base.note.creation.sheet
import android.app.Dialog
import com.facebook.litho.ComponentContext
+import com.maubis.scarlet.base.MainActivity
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppPreferences
+import com.maubis.scarlet.base.settings.sheet.ColorPickerBottomSheet
+import com.maubis.scarlet.base.settings.sheet.ColorPickerDefaultController
import com.maubis.scarlet.base.support.sheets.LithoOptionBottomSheet
import com.maubis.scarlet.base.support.sheets.LithoOptionsItem
-
-const val STORE_KEY_EDITOR_OPTIONS_MARKDOWN_ENABLED = "KEY_MARKDOWN_ENABLED"
-const val STORE_KEY_EDITOR_OPTIONS_LIVE_MARKDOWN = "editor_live_markdown"
-const val STORE_KEY_EDITOR_OPTIONS_MARKDOWN_DEFAULT = "editor_markdown_default"
-const val STORE_KEY_EDITOR_OPTIONS_MOVE_HANDLES = "editor_move_handles"
+import com.maubis.scarlet.base.support.sheets.openSheet
var sEditorLiveMarkdown: Boolean
- get() = CoreConfig.instance.store().get(STORE_KEY_EDITOR_OPTIONS_LIVE_MARKDOWN, true)
- set(value) = CoreConfig.instance.store().put(STORE_KEY_EDITOR_OPTIONS_LIVE_MARKDOWN, value)
+ get() = sAppPreferences.get("editor_live_markdown", true)
+ set(value) = sAppPreferences.put("editor_live_markdown", value)
+
+var sEditorMoveChecked: Boolean
+ get() = sAppPreferences.get("editor_move_checked_items", true)
+ set(value) = sAppPreferences.put("editor_move_checked_items", value)
var sEditorMarkdownDefault: Boolean
- get() = CoreConfig.instance.store().get(STORE_KEY_EDITOR_OPTIONS_MARKDOWN_DEFAULT, false)
- set(value) = CoreConfig.instance.store().put(STORE_KEY_EDITOR_OPTIONS_MARKDOWN_DEFAULT, value)
+ get() = sAppPreferences.get("editor_markdown_default", false)
+ set(value) = sAppPreferences.put("editor_markdown_default", value)
+
+var sEditorSkipNoteViewer: Boolean
+ get() = sAppPreferences.get("skip_note_viewer", false)
+ set(value) = sAppPreferences.put("skip_note_viewer", value)
var sEditorMoveHandles: Boolean
- get() = CoreConfig.instance.store().get(STORE_KEY_EDITOR_OPTIONS_MOVE_HANDLES, true)
- set(value) = CoreConfig.instance.store().put(STORE_KEY_EDITOR_OPTIONS_MOVE_HANDLES, value)
+ get() = sAppPreferences.get("editor_move_handles", true)
+ set(value) = sAppPreferences.put("editor_move_handles", value)
var sEditorMarkdownEnabled: Boolean
- get() = CoreConfig.instance.store().get(STORE_KEY_EDITOR_OPTIONS_MARKDOWN_ENABLED, true)
- set(value) = CoreConfig.instance.store().put(STORE_KEY_EDITOR_OPTIONS_MARKDOWN_ENABLED, value)
+ get() = sAppPreferences.get("KEY_MARKDOWN_ENABLED", true)
+ set(value) = sAppPreferences.put("KEY_MARKDOWN_ENABLED", value)
+
+var sNoteDefaultColor: Int
+ get() = sAppPreferences.get("KEY_NOTE_DEFAULT_COLOR", (0xFFD32F2F).toInt())
+ set(value) = sAppPreferences.put("KEY_NOTE_DEFAULT_COLOR", value)
class EditorOptionsBottomSheet : LithoOptionBottomSheet() {
@@ -34,49 +45,90 @@ class EditorOptionsBottomSheet : LithoOptionBottomSheet() {
override fun getOptions(componentContext: ComponentContext, dialog: Dialog): List {
val items = ArrayList()
+ val activity = context as MainActivity
+ items.add(LithoOptionsItem(
+ title = R.string.note_option_default_color,
+ subtitle = R.string.note_option_default_color_subtitle,
+ icon = R.drawable.ic_action_color,
+ listener = {
+ val config = ColorPickerDefaultController(
+ title = R.string.note_option_default_color,
+ colors = listOf(
+ activity.resources.getIntArray(R.array.bright_colors),
+ activity.resources.getIntArray(R.array.bright_colors_accent)),
+ selectedColor = sNoteDefaultColor,
+ onColorSelected = { sNoteDefaultColor = it }
+ )
+ openSheet(activity, ColorPickerBottomSheet().apply { this.config = config })
+ dismiss()
+ }
+ ))
items.add(LithoOptionsItem(
- title = R.string.markdown_sheet_markdown_support,
- subtitle = R.string.markdown_sheet_markdown_support_subtitle,
- icon = R.drawable.ic_markdown_logo,
- selected = sEditorMarkdownEnabled,
- isSelectable = true,
- listener = {
- sEditorMarkdownEnabled = !sEditorMarkdownEnabled
- reset(componentContext.androidContext, dialog)
- }
+ title = R.string.markdown_sheet_markdown_support,
+ subtitle = R.string.markdown_sheet_markdown_support_subtitle,
+ icon = R.drawable.ic_markdown_logo,
+ selected = sEditorMarkdownEnabled,
+ isSelectable = true,
+ listener = {
+ sEditorMarkdownEnabled = !sEditorMarkdownEnabled
+ reset(componentContext.androidContext, dialog)
+ }
))
items.add(LithoOptionsItem(
- title = R.string.editor_option_enable_live_markdown,
- subtitle = R.string.editor_option_enable_live_markdown_description,
- icon = R.drawable.icon_realtime_markdown,
- selected = sEditorLiveMarkdown,
- isSelectable = true,
- listener = {
- sEditorLiveMarkdown = !sEditorLiveMarkdown
- reset(componentContext.androidContext, dialog)
- }
+ title = R.string.editor_option_enable_live_markdown,
+ subtitle = R.string.editor_option_enable_live_markdown_description,
+ icon = R.drawable.icon_realtime_markdown,
+ selected = sEditorLiveMarkdown,
+ isSelectable = true,
+ listener = {
+ sEditorLiveMarkdown = !sEditorLiveMarkdown
+ reset(componentContext.androidContext, dialog)
+ }
+ ))
+ items.add(LithoOptionsItem(
+ title = R.string.editor_option_enable_markdown_mode_default,
+ subtitle = R.string.editor_option_enable_markdown_mode_default_details,
+ icon = R.drawable.ic_formats_logo,
+ selected = sEditorMarkdownDefault,
+ isSelectable = true,
+ listener = {
+ sEditorMarkdownDefault = !sEditorMarkdownDefault
+ reset(componentContext.androidContext, dialog)
+ }
+ ))
+
+ items.add(LithoOptionsItem(
+ title = R.string.editor_option_skip_view_note,
+ subtitle = R.string.editor_option_skip_view_note_details,
+ icon = R.drawable.ic_redo_history,
+ selected = sEditorSkipNoteViewer,
+ isSelectable = true,
+ listener = {
+ sEditorSkipNoteViewer = !sEditorSkipNoteViewer
+ reset(componentContext.androidContext, dialog)
+ }
))
items.add(LithoOptionsItem(
- title = R.string.editor_option_enable_markdown_mode_default,
- subtitle = R.string.editor_option_enable_markdown_mode_default_details,
- icon = R.drawable.ic_formats_logo,
- selected = sEditorMarkdownDefault,
- isSelectable = true,
- listener = {
- sEditorMarkdownDefault = !sEditorMarkdownDefault
- reset(componentContext.androidContext, dialog)
- }
+ title = R.string.editor_option_move_checked_items,
+ subtitle = R.string.editor_option_move_checked_items_description,
+ icon = R.drawable.ic_check_box_white_24dp,
+ selected = sEditorMoveChecked,
+ isSelectable = true,
+ listener = {
+ sEditorMoveChecked = !sEditorMoveChecked
+ reset(componentContext.androidContext, dialog)
+ }
))
items.add(LithoOptionsItem(
- title = R.string.editor_option_enable_move_handle,
- subtitle = R.string.editor_option_enable_move_handle_description,
- icon = R.drawable.icon_drag_indicator,
- selected = sEditorMoveHandles,
- isSelectable = true,
- listener = {
- sEditorMoveHandles = !sEditorMoveHandles
- reset(componentContext.androidContext, dialog)
- }
+ title = R.string.editor_option_enable_move_handle,
+ subtitle = R.string.editor_option_enable_move_handle_description,
+ icon = R.drawable.icon_drag_indicator,
+ selected = sEditorMoveHandles,
+ isSelectable = true,
+ listener = {
+ sEditorMoveHandles = !sEditorMoveHandles
+ reset(componentContext.androidContext, dialog)
+ }
))
return items
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/creation/sheet/FormatActionBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/note/creation/sheet/FormatActionBottomSheet.kt
index a2f88877..ac210e28 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/creation/sheet/FormatActionBottomSheet.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/creation/sheet/FormatActionBottomSheet.kt
@@ -1,101 +1,92 @@
package com.maubis.scarlet.base.note.creation.sheet
import android.app.Dialog
-import android.view.View
+import com.facebook.litho.ComponentContext
import com.github.bijoysingh.starter.util.IntentUtils
import com.github.bijoysingh.starter.util.TextUtils
import com.maubis.scarlet.base.R
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppImageStorage
import com.maubis.scarlet.base.core.format.Format
import com.maubis.scarlet.base.core.format.FormatType
-import com.maubis.scarlet.base.core.note.NoteImage
import com.maubis.scarlet.base.core.note.NoteImage.Companion.deleteIfExist
import com.maubis.scarlet.base.note.creation.activity.ViewAdvancedNoteActivity
-import com.maubis.scarlet.base.support.option.OptionsItem
-import com.maubis.scarlet.base.support.sheets.GridBottomSheetBase
-import com.maubis.scarlet.base.support.ui.ThemedActivity
+import com.maubis.scarlet.base.support.sheets.GridOptionBottomSheet
+import com.maubis.scarlet.base.support.specs.GridSectionItem
+import com.maubis.scarlet.base.support.specs.GridSectionOptionItem
import pl.aprilapps.easyphotopicker.EasyImage
-class FormatActionBottomSheet : GridBottomSheetBase() {
+class FormatActionBottomSheet : GridOptionBottomSheet() {
var noteUUID: String = "default"
var format: Format? = null
- override fun setupViewWithDialog(dialog: Dialog) {
- if (format === null) {
- return
- }
+ override fun title(): Int = R.string.format_action_title
- setOptions(dialog, getOptions(noteUUID, format!!))
- setOptionTitle(dialog, R.string.format_action_title)
- }
+ override fun getOptions(componentContext: ComponentContext, dialog: Dialog): List {
+ val activity = componentContext.androidContext as ViewAdvancedNoteActivity
- private fun getOptions(noteUUID: String, format: Format): List {
- val activity = themedActivity() as ViewAdvancedNoteActivity
- val options = ArrayList()
- options.add(OptionsItem(
- title = R.string.import_export_layout_exporting_share,
- subtitle = R.string.import_export_layout_exporting_share,
+ val sections = ArrayList()
+ val options = ArrayList()
+
+ if (this.format === null) {
+ return sections
+ }
+
+ val format: Format = this.format!!
+ options.add(
+ GridSectionOptionItem(
+ label = R.string.import_export_layout_exporting_share,
icon = R.drawable.ic_share_white_48dp,
- listener = View.OnClickListener {
+ listener = {
IntentUtils.ShareBuilder(activity)
- .setChooserText(activity.getString(R.string.share_using))
- .setText(format.text)
- .share()
+ .setChooserText(activity.getString(R.string.share_using))
+ .setText(format.text)
+ .share()
dismiss()
},
visible = !arrayOf(FormatType.IMAGE, FormatType.SEPARATOR).contains(format.formatType)
- ))
- options.add(OptionsItem(
- title = R.string.format_action_copy,
- subtitle = R.string.format_action_copy,
+ ))
+ options.add(
+ GridSectionOptionItem(
+ label = R.string.format_action_copy,
icon = R.drawable.ic_content_copy_white_48dp,
- listener = View.OnClickListener {
+ listener = {
TextUtils.copyToClipboard(context, format.text)
dismiss()
},
visible = !arrayOf(FormatType.IMAGE, FormatType.SEPARATOR).contains(format.formatType)
- ))
- options.add(OptionsItem(
- title = R.string.format_action_camera,
- subtitle = R.string.format_action_camera,
+ ))
+ options.add(
+ GridSectionOptionItem(
+ label = R.string.format_action_camera,
icon = R.drawable.ic_image_camera,
- listener = View.OnClickListener {
+ listener = {
EasyImage.openCamera(activity, format.uid)
},
visible = format.formatType === FormatType.IMAGE
- ))
- options.add(OptionsItem(
- title = R.string.format_action_gallery,
- subtitle = R.string.format_action_gallery,
+ ))
+ options.add(
+ GridSectionOptionItem(
+ label = R.string.format_action_gallery,
icon = R.drawable.ic_image_gallery,
- listener = View.OnClickListener {
+ listener = {
EasyImage.openGallery(activity, format.uid)
},
visible = format.formatType === FormatType.IMAGE
- ))
- options.add(OptionsItem(
- title = R.string.delete_sheet_delete_trash_yes,
- subtitle = R.string.delete_sheet_delete_trash_yes,
- icon = R.drawable.ic_delete_white_48dp,
- listener = View.OnClickListener {
- activity.deleteFormat(format)
- if (format.formatType === FormatType.IMAGE && !format.text.isBlank()) {
- val noteImage = NoteImage(themedContext())
- deleteIfExist(noteImage.getFile(noteUUID, format))
- }
- dismiss()
+ ))
+ options.add(GridSectionOptionItem(
+ label = R.string.delete_sheet_delete_trash_yes,
+ icon = R.drawable.ic_delete_white_48dp,
+ listener = {
+ activity.deleteFormat(format)
+ if (format.formatType === FormatType.IMAGE && !format.text.isBlank()) {
+ deleteIfExist(sAppImageStorage.getFile(noteUUID, format))
}
+ dismiss()
+ }
))
- return options
- }
-
- companion object {
- fun openSheet(activity: ThemedActivity, noteUUID: String, format: Format) {
- val sheet = FormatActionBottomSheet()
- sheet.format = format
- sheet.noteUUID = noteUUID
- sheet.show(activity.supportFragmentManager, sheet.tag)
- }
+ sections.add(GridSectionItem(options = options))
+ return sections
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/creation/sheet/MarkdownHelpBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/note/creation/sheet/MarkdownHelpBottomSheet.kt
index 37413ed0..cae6b72c 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/creation/sheet/MarkdownHelpBottomSheet.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/creation/sheet/MarkdownHelpBottomSheet.kt
@@ -8,7 +8,8 @@ import com.facebook.litho.widget.Text
import com.facebook.yoga.YogaEdge
import com.maubis.markdown.Markdown
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
import com.maubis.scarlet.base.support.sheets.LithoBottomSheet
import com.maubis.scarlet.base.support.sheets.getLithoBottomSheetTitle
import com.maubis.scarlet.base.support.ui.ThemeColorType
@@ -16,19 +17,23 @@ import com.maubis.scarlet.base.support.ui.ThemeColorType
class MarkdownHelpBottomSheet : LithoBottomSheet() {
override fun getComponent(componentContext: ComponentContext, dialog: Dialog): Component {
val column = Column.create(componentContext)
- .widthPercent(100f)
- .paddingDip(YogaEdge.VERTICAL, 8f)
- .child(getLithoBottomSheetTitle(componentContext).textRes(R.string.markdown_help_sheet_title))
+ .widthPercent(100f)
+ .paddingDip(YogaEdge.VERTICAL, 8f)
+ .child(getLithoBottomSheetTitle(componentContext).textRes(R.string.markdown_help_sheet_title))
- val examples = arrayOf("# Heading", "## Sub Heading", "```\nblock of code\n```", "> quoted text", "**bold**", "*italics*", "_underline_", "~~strike through~~", "`piece of code`")
+ val examples = arrayOf(
+ "# Heading", "## Sub Heading", "```\nblock of code\n```", "> quoted text", "**bold**", "*italics*", "_underline_", "~~strike through~~",
+ "`piece of code`")
examples.forEach {
column
- .child(Text.create(componentContext)
- .text(Markdown.render(it))
- .textSizeRes(R.dimen.font_size_normal)
- .marginDip(YogaEdge.HORIZONTAL, 20f)
- .paddingDip(YogaEdge.VERTICAL, 4f)
- .textColor(CoreConfig.instance.themeController().get(ThemeColorType.SECONDARY_TEXT)))
+ .child(
+ Text.create(componentContext)
+ .typeface(sAppTypeface.text())
+ .text(Markdown.render(it))
+ .textSizeRes(R.dimen.font_size_normal)
+ .marginDip(YogaEdge.HORIZONTAL, 20f)
+ .paddingDip(YogaEdge.VERTICAL, 4f)
+ .textColor(sAppTheme.get(ThemeColorType.SECONDARY_TEXT)))
}
return column.build()
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/creation/specs/NoteViewBottomBarSpec.kt b/base/src/main/java/com/maubis/scarlet/base/note/creation/specs/NoteViewBottomBarSpec.kt
index 30b09346..72db70e8 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/creation/specs/NoteViewBottomBarSpec.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/creation/specs/NoteViewBottomBarSpec.kt
@@ -1,8 +1,20 @@
package com.maubis.scarlet.base.note.creation.specs
import android.graphics.Color
-import com.facebook.litho.*
-import com.facebook.litho.annotations.*
+import com.facebook.litho.ClickEvent
+import com.facebook.litho.Component
+import com.facebook.litho.ComponentContext
+import com.facebook.litho.EventHandler
+import com.facebook.litho.Row
+import com.facebook.litho.StateValue
+import com.facebook.litho.annotations.LayoutSpec
+import com.facebook.litho.annotations.OnCreateInitialState
+import com.facebook.litho.annotations.OnCreateLayout
+import com.facebook.litho.annotations.OnEvent
+import com.facebook.litho.annotations.OnUpdateState
+import com.facebook.litho.annotations.Param
+import com.facebook.litho.annotations.Prop
+import com.facebook.litho.annotations.State
import com.facebook.litho.widget.EmptyComponent
import com.facebook.litho.widget.HorizontalScroll
import com.facebook.yoga.YogaAlign
@@ -35,62 +47,63 @@ object NoteCreationBottomBarSpec {
@OnCreateInitialState
fun onCreateInitialState(
- context: ComponentContext,
- state: StateValue) {
+ context: ComponentContext,
+ state: StateValue) {
state.set(if (sEditorMarkdownDefault) NoteCreateBottomBarType.DEFAULT_MARKDOWNS else NoteCreateBottomBarType.DEFAULT_SEGMENTS)
}
@OnCreateLayout
- fun onCreate(context: ComponentContext,
- @Prop colorConfig: ToolbarColorConfig,
- @State state: NoteCreateBottomBarType): Component {
+ fun onCreate(
+ context: ComponentContext,
+ @Prop colorConfig: ToolbarColorConfig,
+ @State state: NoteCreateBottomBarType): Component {
val row = Row.create(context)
- .widthPercent(100f)
- .paddingDip(YogaEdge.HORIZONTAL, 4f)
- .alignItems(YogaAlign.CENTER)
+ .widthPercent(100f)
+ .paddingDip(YogaEdge.HORIZONTAL, 4f)
+ .alignItems(YogaAlign.CENTER)
val content = when (state) {
NoteCreateBottomBarType.DEFAULT_SEGMENTS ->
NoteCreationSegmentsBottomBar.create(context)
- .colorConfig(colorConfig)
- .flexGrow(1f)
- .toggleButtonClick(NoteCreationBottomBar.onStateChangeClick(context, NoteCreateBottomBarType.ALL_SEGMENTS))
- NoteCreateBottomBarType.DEFAULT_MARKDOWNS -> NoteCreationMarkdownsBottomBar.create(context)
.colorConfig(colorConfig)
.flexGrow(1f)
- .toggleButtonClick(NoteCreationBottomBar.onStateChangeClick(context, NoteCreateBottomBarType.ALL_MARKDOWNS))
+ .toggleButtonClick(NoteCreationBottomBar.onStateChangeClick(context, NoteCreateBottomBarType.ALL_SEGMENTS))
+ NoteCreateBottomBarType.DEFAULT_MARKDOWNS -> NoteCreationMarkdownsBottomBar.create(context)
+ .colorConfig(colorConfig)
+ .flexGrow(1f)
+ .toggleButtonClick(NoteCreationBottomBar.onStateChangeClick(context, NoteCreateBottomBarType.ALL_MARKDOWNS))
NoteCreateBottomBarType.ALL_SEGMENTS -> HorizontalScroll.create(context)
- .flexGrow(1f)
- .contentProps(NoteCreationAllSegmentsBottomBar.create(context).colorConfig(colorConfig))
+ .flexGrow(1f)
+ .contentProps(NoteCreationAllSegmentsBottomBar.create(context).colorConfig(colorConfig))
NoteCreateBottomBarType.ALL_MARKDOWNS -> HorizontalScroll.create(context)
- .flexGrow(1f)
- .contentProps(NoteCreationAllMarkdownsBottomBar.create(context).colorConfig(colorConfig))
+ .flexGrow(1f)
+ .contentProps(NoteCreationAllMarkdownsBottomBar.create(context).colorConfig(colorConfig))
NoteCreateBottomBarType.OPTIONS ->
NoteCreationOptionsBottomBar.create(context)
- .colorConfig(colorConfig)
- .flexGrow(1f)
+ .colorConfig(colorConfig)
+ .flexGrow(1f)
}
row.child(content)
val extraRoundIcon = bottomBarRoundIcon(context, colorConfig)
- .bgColor(Color.TRANSPARENT)
- .onClick { }
- .isClickDisabled(true)
+ .bgColor(Color.TRANSPARENT)
+ .onClick { }
+ .isClickDisabled(true)
val icon = when (state) {
NoteCreateBottomBarType.DEFAULT_SEGMENTS -> extraRoundIcon
- .iconRes(R.drawable.ic_markdown_logo)
- .clickHandler(NoteCreationBottomBar.onStateChangeClick(context, NoteCreateBottomBarType.DEFAULT_MARKDOWNS))
+ .iconRes(R.drawable.ic_markdown_logo)
+ .clickHandler(NoteCreationBottomBar.onStateChangeClick(context, NoteCreateBottomBarType.DEFAULT_MARKDOWNS))
NoteCreateBottomBarType.DEFAULT_MARKDOWNS -> extraRoundIcon
- .iconRes(R.drawable.ic_formats_logo)
- .clickHandler(NoteCreationBottomBar.onStateChangeClick(context, NoteCreateBottomBarType.DEFAULT_SEGMENTS))
+ .iconRes(R.drawable.ic_formats_logo)
+ .clickHandler(NoteCreationBottomBar.onStateChangeClick(context, NoteCreateBottomBarType.DEFAULT_SEGMENTS))
NoteCreateBottomBarType.ALL_SEGMENTS -> extraRoundIcon
- .marginDip(YogaEdge.HORIZONTAL, 4f)
- .iconRes(R.drawable.ic_close_white_48dp)
- .clickHandler(NoteCreationBottomBar.onStateChangeClick(context, NoteCreateBottomBarType.DEFAULT_SEGMENTS))
+ .marginDip(YogaEdge.HORIZONTAL, 4f)
+ .iconRes(R.drawable.ic_close_white_48dp)
+ .clickHandler(NoteCreationBottomBar.onStateChangeClick(context, NoteCreateBottomBarType.DEFAULT_SEGMENTS))
NoteCreateBottomBarType.ALL_MARKDOWNS -> extraRoundIcon
- .marginDip(YogaEdge.HORIZONTAL, 4f)
- .iconRes(R.drawable.ic_close_white_48dp)
- .clickHandler(NoteCreationBottomBar.onStateChangeClick(context, NoteCreateBottomBarType.DEFAULT_MARKDOWNS))
+ .marginDip(YogaEdge.HORIZONTAL, 4f)
+ .iconRes(R.drawable.ic_close_white_48dp)
+ .clickHandler(NoteCreationBottomBar.onStateChangeClick(context, NoteCreateBottomBarType.DEFAULT_MARKDOWNS))
NoteCreateBottomBarType.OPTIONS -> EmptyComponent.create(context)
}
row.child(icon)
@@ -98,11 +111,11 @@ object NoteCreationBottomBarSpec {
val moreIcon = when (state) {
NoteCreateBottomBarType.DEFAULT_MARKDOWNS, NoteCreateBottomBarType.DEFAULT_SEGMENTS, NoteCreateBottomBarType.OPTIONS ->
bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_more_options)
- .bgColor(Color.TRANSPARENT)
- .onClick { }
- .isClickDisabled(true)
- .clickHandler(NoteCreationBottomBar.onStateChangeClick(context, NoteCreateBottomBarType.OPTIONS))
+ .iconRes(R.drawable.ic_more_options)
+ .bgColor(Color.TRANSPARENT)
+ .onClick { }
+ .isClickDisabled(true)
+ .clickHandler(NoteCreationBottomBar.onStateChangeClick(context, NoteCreateBottomBarType.OPTIONS))
else -> EmptyComponent.create(context)
}
row.child(moreIcon)
@@ -110,9 +123,10 @@ object NoteCreationBottomBarSpec {
}
@OnEvent(ClickEvent::class)
- fun onStateChangeClick(context: ComponentContext,
- @State state: NoteCreateBottomBarType,
- @Param nextState: NoteCreateBottomBarType) {
+ fun onStateChangeClick(
+ context: ComponentContext,
+ @State state: NoteCreateBottomBarType,
+ @Param nextState: NoteCreateBottomBarType) {
if (state == NoteCreateBottomBarType.OPTIONS && nextState == NoteCreateBottomBarType.OPTIONS) {
NoteCreationBottomBar.onStateChange(context, NoteCreateBottomBarType.DEFAULT_SEGMENTS)
return
@@ -137,209 +151,214 @@ object NoteCreationBottomBarSpec {
@LayoutSpec
object NoteCreationOptionsBottomBarSpec {
@OnCreateLayout
- fun onCreate(context: ComponentContext,
- @Prop colorConfig: ToolbarColorConfig): Component {
+ fun onCreate(
+ context: ComponentContext,
+ @Prop colorConfig: ToolbarColorConfig): Component {
val activity = context.androidContext as CreateNoteActivity
return Row.create(context)
- .alignItems(YogaAlign.CENTER)
- .child(bottomBarRoundIcon(context, colorConfig)
- .bgColor(Color.TRANSPARENT)
- .iconRes(R.drawable.icon_markdown_help)
- .onClick { openSheet(activity, MarkdownHelpBottomSheet()) })
- .child(EmptySpec.create(context).heightDip(1f).flexGrow(1f))
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_undo_history)
- .onClick { activity.onHistoryClick(true) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .bgColor(activity.note().color)
- .bgAlpha(255)
- .iconRes(R.drawable.ic_empty)
- .onClick { activity.onColorChangeClick() }
- .showBorder(true)
- .iconMarginHorizontalRes(R.dimen.toolbar_round_small_icon_margin_horizontal)
- .iconSizeRes(R.dimen.toolbar_round_small_icon_size))
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_redo_history)
- .onClick { activity.onHistoryClick(false) })
- .child(EmptySpec.create(context).heightDip(1f).flexGrow(1f))
- .build()
+ .alignItems(YogaAlign.CENTER)
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .bgColor(Color.TRANSPARENT)
+ .iconRes(R.drawable.icon_markdown_help)
+ .onClick { openSheet(activity, MarkdownHelpBottomSheet()) })
+ .child(EmptySpec.create(context).heightDip(1f).flexGrow(1f))
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_undo_history)
+ .onClick { activity.onHistoryClick(true) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .bgColor(activity.note().color)
+ .bgAlpha(255)
+ .iconRes(R.drawable.ic_empty)
+ .onClick { activity.onColorChangeClick() }
+ .showBorder(true)
+ .iconMarginHorizontalRes(R.dimen.toolbar_round_small_icon_margin_horizontal)
+ .iconSizeRes(R.dimen.toolbar_round_small_icon_size))
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_redo_history)
+ .onClick { activity.onHistoryClick(false) })
+ .child(EmptySpec.create(context).heightDip(1f).flexGrow(1f))
+ .build()
}
}
@LayoutSpec
object NoteCreationSegmentsBottomBarSpec {
@OnCreateLayout
- fun onCreate(context: ComponentContext,
- @Prop colorConfig: ToolbarColorConfig,
- @Prop toggleButtonClick: EventHandler): Component {
+ fun onCreate(
+ context: ComponentContext,
+ @Prop colorConfig: ToolbarColorConfig,
+ @Prop toggleButtonClick: EventHandler): Component {
val activity = context.androidContext as CreateNoteActivity
return Row.create(context)
- .alignItems(YogaAlign.CENTER)
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_title_white_48dp)
- .onClick { activity.addEmptyItemAtFocused(FormatType.HEADING) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_subject_white_48dp)
- .onClick { activity.addEmptyItemAtFocused(FormatType.TEXT) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_check_box_white_24dp)
- .onClick { activity.addEmptyItemAtFocused(FormatType.CHECKLIST_UNCHECKED) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_format_quote_white_48dp)
- .onClick { activity.addEmptyItemAtFocused(FormatType.QUOTE) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_more_horiz_white_48dp)
- .onClick { }
- .isClickDisabled(true)
- .clickHandler(toggleButtonClick))
- .build()
+ .alignItems(YogaAlign.CENTER)
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_title_white_48dp)
+ .onClick { activity.addEmptyItemAtFocused(FormatType.HEADING) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_subject_white_48dp)
+ .onClick { activity.addEmptyItemAtFocused(FormatType.TEXT) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_check_box_white_24dp)
+ .onClick { activity.addEmptyItemAtFocused(FormatType.CHECKLIST_UNCHECKED) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_format_quote_white_48dp)
+ .onClick { activity.addEmptyItemAtFocused(FormatType.QUOTE) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_more_horiz_white_48dp)
+ .onClick { }
+ .isClickDisabled(true)
+ .clickHandler(toggleButtonClick))
+ .build()
}
}
@LayoutSpec
object NoteCreationMarkdownsBottomBarSpec {
@OnCreateLayout
- fun onCreate(context: ComponentContext,
- @Prop colorConfig: ToolbarColorConfig,
- @Prop toggleButtonClick: EventHandler): Component {
+ fun onCreate(
+ context: ComponentContext,
+ @Prop colorConfig: ToolbarColorConfig,
+ @Prop toggleButtonClick: EventHandler): Component {
val activity = context.androidContext as CreateNoteActivity
return Row.create(context)
- .alignItems(YogaAlign.CENTER)
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_title_white_48dp)
- .onClick { activity.triggerMarkdown(MarkdownType.HEADER) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_markdown_bold)
- .onClick { activity.triggerMarkdown(MarkdownType.BOLD) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_markdown_italics)
- .onClick { activity.triggerMarkdown(MarkdownType.ITALICS) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_format_list_bulleted_white_48dp)
- .onClick { activity.triggerMarkdown(MarkdownType.UNORDERED) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_more_horiz_white_48dp)
- .onClick { }
- .isClickDisabled(true)
- .clickHandler(toggleButtonClick))
- .build()
+ .alignItems(YogaAlign.CENTER)
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_title_white_48dp)
+ .onClick { activity.triggerMarkdown(MarkdownType.HEADER) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_markdown_bold)
+ .onClick { activity.triggerMarkdown(MarkdownType.BOLD) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_markdown_italics)
+ .onClick { activity.triggerMarkdown(MarkdownType.ITALICS) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_format_list_bulleted_white_48dp)
+ .onClick { activity.triggerMarkdown(MarkdownType.UNORDERED) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_more_horiz_white_48dp)
+ .onClick { }
+ .isClickDisabled(true)
+ .clickHandler(toggleButtonClick))
+ .build()
}
}
-
@LayoutSpec
object NoteCreationAllSegmentsBottomBarSpec {
@OnCreateLayout
- fun onCreate(context: ComponentContext,
- @Prop colorConfig: ToolbarColorConfig): Component {
+ fun onCreate(
+ context: ComponentContext,
+ @Prop colorConfig: ToolbarColorConfig): Component {
val activity = context.androidContext as CreateNoteActivity
return Row.create(context)
- .alignSelf(YogaAlign.CENTER)
- .alignItems(YogaAlign.CENTER)
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_title_white_48dp)
- .onClick { activity.addEmptyItemAtFocused(FormatType.HEADING) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_title_white_48dp)
- .iconPaddingRes(R.dimen.toolbar_round_icon_padding_subsize)
- .onClick { activity.addEmptyItemAtFocused(FormatType.SUB_HEADING) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_subject_white_48dp)
- .onClick { activity.addEmptyItemAtFocused(FormatType.TEXT) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_check_box_white_24dp)
- .onClick { activity.addEmptyItemAtFocused(FormatType.CHECKLIST_UNCHECKED) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_format_quote_white_48dp)
- .onClick { activity.addEmptyItemAtFocused(FormatType.QUOTE) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_code_white_48dp)
- .onClick { activity.addEmptyItemAtFocused(FormatType.CODE) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_image_gallery)
- .onClick { activity.addEmptyItemAtFocused(FormatType.IMAGE) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_format_separator)
- .onClick { activity.addEmptyItemAtFocused(FormatType.SEPARATOR) })
- .build()
+ .alignSelf(YogaAlign.CENTER)
+ .alignItems(YogaAlign.CENTER)
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_title_white_48dp)
+ .onClick { activity.addEmptyItemAtFocused(FormatType.HEADING) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_title_white_48dp)
+ .iconPaddingRes(R.dimen.toolbar_round_icon_padding_subsize)
+ .onClick { activity.addEmptyItemAtFocused(FormatType.SUB_HEADING) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_subject_white_48dp)
+ .onClick { activity.addEmptyItemAtFocused(FormatType.TEXT) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_check_box_white_24dp)
+ .onClick { activity.addEmptyItemAtFocused(FormatType.CHECKLIST_UNCHECKED) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_format_quote_white_48dp)
+ .onClick { activity.addEmptyItemAtFocused(FormatType.QUOTE) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_code_white_48dp)
+ .onClick { activity.addEmptyItemAtFocused(FormatType.CODE) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_image_gallery)
+ .onClick { activity.addEmptyItemAtFocused(FormatType.IMAGE) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_format_separator)
+ .onClick { activity.addEmptyItemAtFocused(FormatType.SEPARATOR) })
+ .build()
}
}
@LayoutSpec
object NoteCreationAllMarkdownsBottomBarSpec {
@OnCreateLayout
- fun onCreate(context: ComponentContext,
- @Prop colorConfig: ToolbarColorConfig): Component {
+ fun onCreate(
+ context: ComponentContext,
+ @Prop colorConfig: ToolbarColorConfig): Component {
val activity = context.androidContext as CreateNoteActivity
return Row.create(context)
- .alignSelf(YogaAlign.CENTER)
- .alignItems(YogaAlign.CENTER)
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_title_white_48dp)
- .onClick { activity.triggerMarkdown(MarkdownType.HEADER) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_title_white_48dp)
- .iconPaddingRes(R.dimen.toolbar_round_icon_padding_subsize)
- .onClick { activity.triggerMarkdown(MarkdownType.SUB_HEADER) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_markdown_bold)
- .onClick { activity.triggerMarkdown(MarkdownType.BOLD) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_markdown_italics)
- .onClick { activity.triggerMarkdown(MarkdownType.ITALICS) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_check_box_white_24dp)
- .onClick { activity.triggerMarkdown(MarkdownType.CHECKLIST_UNCHECKED) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_format_list_bulleted_white_48dp)
- .onClick { activity.triggerMarkdown(MarkdownType.UNORDERED) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_markdown_underline)
- .onClick { activity.triggerMarkdown(MarkdownType.UNDERLINE) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_code_white_48dp)
- .onClick { activity.triggerMarkdown(MarkdownType.CODE_BLOCK) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.icon_code_block)
- .onClick { activity.triggerMarkdown(MarkdownType.CODE) })
- .child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_markdown_strikethrough)
- .onClick { activity.triggerMarkdown(MarkdownType.STRIKE_THROUGH) })
- .build()
+ .alignSelf(YogaAlign.CENTER)
+ .alignItems(YogaAlign.CENTER)
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_title_white_48dp)
+ .onClick { activity.triggerMarkdown(MarkdownType.HEADER) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_title_white_48dp)
+ .iconPaddingRes(R.dimen.toolbar_round_icon_padding_subsize)
+ .onClick { activity.triggerMarkdown(MarkdownType.SUB_HEADER) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_markdown_bold)
+ .onClick { activity.triggerMarkdown(MarkdownType.BOLD) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_markdown_italics)
+ .onClick { activity.triggerMarkdown(MarkdownType.ITALICS) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_check_box_white_24dp)
+ .onClick { activity.triggerMarkdown(MarkdownType.CHECKLIST_UNCHECKED) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_format_list_bulleted_white_48dp)
+ .onClick { activity.triggerMarkdown(MarkdownType.UNORDERED) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_markdown_underline)
+ .onClick { activity.triggerMarkdown(MarkdownType.UNDERLINE) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_code_white_48dp)
+ .onClick { activity.triggerMarkdown(MarkdownType.CODE_BLOCK) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.icon_code_block)
+ .onClick { activity.triggerMarkdown(MarkdownType.CODE) })
+ .child(bottomBarRoundIcon(context, colorConfig)
+ .iconRes(R.drawable.ic_markdown_strikethrough)
+ .onClick { activity.triggerMarkdown(MarkdownType.STRIKE_THROUGH) })
+ .build()
}
}
@LayoutSpec
object NoteViewBottomBarSpec {
@OnCreateLayout
- fun onCreate(context: ComponentContext,
- @Prop colorConfig: ToolbarColorConfig): Component {
+ fun onCreate(
+ context: ComponentContext,
+ @Prop colorConfig: ToolbarColorConfig): Component {
val activity = context.androidContext as ViewAdvancedNoteActivity
val row = Row.create(context)
- .widthPercent(100f)
- .alignItems(YogaAlign.CENTER)
+ .widthPercent(100f)
+ .alignItems(YogaAlign.CENTER)
row.child(bottomBarRoundIcon(context, colorConfig)
- .bgColor(Color.TRANSPARENT)
- .iconRes(R.drawable.ic_apps_white_48dp)
- .onClick { activity.openMoreOptions() })
+ .bgColor(Color.TRANSPARENT)
+ .iconRes(R.drawable.ic_apps_white_48dp)
+ .onClick { activity.openMoreOptions() })
row.child(EmptySpec.create(context).heightDip(1f).flexGrow(1f))
row.child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.icon_delete)
- .onClick { activity.moveItemToTrashOrDelete(activity.note()) })
+ .iconRes(R.drawable.icon_delete)
+ .onClick { activity.moveItemToTrashOrDelete(activity.note()) })
row.child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_content_copy_white_48dp)
- .onClick { activity.note().copy(activity) })
+ .iconRes(R.drawable.ic_content_copy_white_48dp)
+ .onClick { activity.note().copy(activity) })
row.child(bottomBarRoundIcon(context, colorConfig)
- .iconRes(R.drawable.ic_share_white_48dp)
- .onClick { activity.note().share(activity) })
+ .iconRes(R.drawable.ic_share_white_48dp)
+ .onClick { activity.note().share(activity) })
row.child(EmptySpec.create(context).heightDip(1f).flexGrow(1f))
row.child(bottomBarRoundIcon(context, colorConfig)
- .bgColor(Color.TRANSPARENT)
- .iconRes(R.drawable.ic_edit_white_48dp)
- .onClick { activity.openEditor() })
+ .bgColor(Color.TRANSPARENT)
+ .iconRes(R.drawable.ic_edit_white_48dp)
+ .onClick { activity.openEditor() })
return bottomBarCard(context, row.build(), colorConfig).build()
}
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/creation/specs/NoteViewTopBarSpec.kt b/base/src/main/java/com/maubis/scarlet/base/note/creation/specs/NoteViewTopBarSpec.kt
index 3252e542..37de919a 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/creation/specs/NoteViewTopBarSpec.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/creation/specs/NoteViewTopBarSpec.kt
@@ -5,9 +5,7 @@ import com.facebook.litho.ComponentContext
import com.facebook.litho.Row
import com.facebook.litho.annotations.LayoutSpec
import com.facebook.litho.annotations.OnCreateLayout
-import com.facebook.litho.annotations.Prop
import com.facebook.yoga.YogaAlign
-import com.maubis.scarlet.base.note.creation.activity.NoteViewColorConfig
import com.maubis.scarlet.base.support.specs.EmptySpec
@LayoutSpec
@@ -15,8 +13,8 @@ object NoteViewTopBarSpec {
@OnCreateLayout
fun onCreate(context: ComponentContext): Component {
val row = Row.create(context)
- .widthPercent(100f)
- .alignItems(YogaAlign.CENTER)
+ .widthPercent(100f)
+ .alignItems(YogaAlign.CENTER)
row.child(EmptySpec.create(context).heightDip(10f))
return row.build()
}
@@ -27,8 +25,8 @@ object NoteCreationTopBarSpec {
@OnCreateLayout
fun onCreate(context: ComponentContext): Component {
val row = Row.create(context)
- .widthPercent(100f)
- .alignItems(YogaAlign.CENTER)
+ .widthPercent(100f)
+ .alignItems(YogaAlign.CENTER)
row.child(EmptySpec.create(context).heightDip(10f))
return row.build()
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderExtensions.kt b/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderExtensions.kt
index e8948504..729684f7 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderExtensions.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderExtensions.kt
@@ -1,9 +1,9 @@
package com.maubis.scarlet.base.note.folder
-import com.github.bijoysingh.starter.util.DateFormatter
-import com.maubis.scarlet.base.config.CoreConfig
-import com.maubis.scarlet.base.database.room.folder.Folder
+import com.maubis.scarlet.base.config.ApplicationBase
import com.maubis.scarlet.base.config.CoreConfig.Companion.foldersDb
+import com.maubis.scarlet.base.database.room.folder.Folder
+import com.maubis.scarlet.base.support.utils.sDateFormat
import java.util.*
fun Folder.saveIfUnique() {
@@ -34,7 +34,7 @@ fun Folder.getDisplayTime(): String {
Calendar.getInstance().timeInMillis - time < 1000 * 60 * 60 * 2 -> "hh:mm aa"
else -> "dd MMMM"
}
- return DateFormatter.getDate(format, time)
+ return sDateFormat.readableTime(format, time)
}
/**************************************************************************************
@@ -42,21 +42,21 @@ fun Folder.getDisplayTime(): String {
**************************************************************************************/
fun Folder.save() {
- CoreConfig.instance.folderActions(this).save()
+ ApplicationBase.instance.folderActions(this).save()
}
fun Folder.saveWithoutSync() {
- CoreConfig.instance.folderActions(this).offlineSave()
+ ApplicationBase.instance.folderActions(this).offlineSave()
}
fun Folder.saveToSync() {
- CoreConfig.instance.folderActions(this).onlineSave()
+ ApplicationBase.instance.folderActions(this).onlineSave()
}
fun Folder.delete() {
- CoreConfig.instance.folderActions(this).delete()
+ ApplicationBase.instance.folderActions(this).delete()
}
fun Folder.deleteWithoutSync() {
- CoreConfig.instance.folderActions(this).offlineDelete()
+ ApplicationBase.instance.folderActions(this).offlineDelete()
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderOptionItem.kt b/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderOptionItem.kt
index 7a7c51b8..2844a0f6 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderOptionItem.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderOptionItem.kt
@@ -4,12 +4,12 @@ import com.maubis.scarlet.base.R
import com.maubis.scarlet.base.database.room.folder.Folder
class FolderOptionsItem(
- val folder: Folder,
- val usages: Int = 0,
- val selected: Boolean = false,
- val editable: Boolean = false,
- val editListener: () -> Unit = {},
- val listener: () -> Unit = {}) {
+ val folder: Folder,
+ val usages: Int = 0,
+ val selected: Boolean = false,
+ val editable: Boolean = false,
+ val editListener: () -> Unit = {},
+ val listener: () -> Unit = {}) {
fun getIcon(): Int = when (selected) {
true -> R.drawable.ic_folder
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderRecyclerHolder.kt b/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderRecyclerHolder.kt
index 3bbc11cc..aadc0ebb 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderRecyclerHolder.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderRecyclerHolder.kt
@@ -2,13 +2,16 @@ package com.maubis.scarlet.base.note.folder
import android.content.Context
import android.os.Bundle
-import android.support.v7.widget.CardView
import android.view.View
import android.widget.TextView
+import androidx.cardview.widget.CardView
import com.github.bijoysingh.starter.recyclerview.RecyclerViewHolder
import com.github.bijoysingh.uibasics.views.UITextView
import com.maubis.scarlet.base.R
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
import com.maubis.scarlet.base.support.recycler.RecyclerItem
+import com.maubis.scarlet.base.support.ui.ColorUtil.darkOrDarkerColor
+import com.maubis.scarlet.base.support.ui.sThemeDarkenNoteColor
class FolderRecyclerHolder(context: Context, view: View) : RecyclerViewHolder(context, view) {
@@ -28,15 +31,22 @@ class FolderRecyclerHolder(context: Context, view: View) : RecyclerViewHolder darkOrDarkerColor(item.folder.color)
+ false -> item.folder.color
+ }
+ view.setCardBackgroundColor(folderColor)
view.setOnClickListener {
item.click()
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderRecyclerItem.kt b/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderRecyclerItem.kt
index cbcd3789..ede0e4a9 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderRecyclerItem.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/folder/FolderRecyclerItem.kt
@@ -1,19 +1,20 @@
package com.maubis.scarlet.base.note.folder
import android.content.Context
-import android.support.v4.content.ContextCompat
+import androidx.core.content.ContextCompat
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.database.room.folder.Folder
import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
+import com.maubis.scarlet.base.database.room.folder.Folder
import com.maubis.scarlet.base.support.recycler.RecyclerItem
import com.maubis.scarlet.base.support.ui.ColorUtil
-class FolderRecyclerItem(context: Context,
- val folder: Folder,
- val click: () -> Unit = {},
- val longClick: () -> Unit = {},
- val selected: Boolean = false,
- contents: Int = -1) : RecyclerItem() {
+class FolderRecyclerItem(
+ context: Context,
+ val folder: Folder,
+ val click: () -> Unit = {},
+ val longClick: () -> Unit = {},
+ val selected: Boolean = false,
+ contents: Int = -1) : RecyclerItem() {
val isLightShaded = ColorUtil.isLightColored(folder.color)
val title = folder.title
@@ -39,6 +40,5 @@ class FolderRecyclerItem(context: Context,
false -> ContextCompat.getColor(context, R.color.light_secondary_text)
}
-
override val type = RecyclerItem.Type.FOLDER
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/folder/SelectorFolderRecyclerHolder.kt b/base/src/main/java/com/maubis/scarlet/base/note/folder/SelectorFolderRecyclerHolder.kt
new file mode 100644
index 00000000..65e4b2a9
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/note/folder/SelectorFolderRecyclerHolder.kt
@@ -0,0 +1,38 @@
+package com.maubis.scarlet.base.note.folder
+
+import android.content.Context
+import android.os.Bundle
+import android.view.View
+import android.widget.ImageView
+import android.widget.TextView
+import com.github.bijoysingh.starter.recyclerview.RecyclerViewHolder
+import com.maubis.scarlet.base.R
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
+import com.maubis.scarlet.base.main.recycler.setFullSpan
+import com.maubis.scarlet.base.support.recycler.RecyclerItem
+import com.maubis.scarlet.base.support.ui.CircleDrawable
+
+class SelectorFolderRecyclerHolder(context: Context, view: View) : RecyclerViewHolder(context, view) {
+
+ protected val title: TextView
+ protected val icon: ImageView
+
+ init {
+ title = view.findViewById(R.id.folder_title)
+ icon = view.findViewById(R.id.folder_icon)
+ }
+
+ override fun populate(itemData: RecyclerItem, extra: Bundle?) {
+ setFullSpan()
+
+ val item = itemData as SelectorFolderRecyclerItem
+ title.text = item.title
+ title.setTextColor(item.titleColor)
+ title.typeface = sAppTypeface.title()
+ title.alpha = 0.8f
+
+ icon.setColorFilter(item.iconColor)
+ icon.background = CircleDrawable(item.folderColor, false)
+ icon.alpha = 0.8f
+ }
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/folder/SelectorFolderRecyclerItem.kt b/base/src/main/java/com/maubis/scarlet/base/note/folder/SelectorFolderRecyclerItem.kt
new file mode 100644
index 00000000..5f1c267f
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/note/folder/SelectorFolderRecyclerItem.kt
@@ -0,0 +1,24 @@
+package com.maubis.scarlet.base.note.folder
+
+import android.content.Context
+import androidx.core.content.ContextCompat
+import com.maubis.scarlet.base.R
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
+import com.maubis.scarlet.base.database.room.folder.Folder
+import com.maubis.scarlet.base.support.recycler.RecyclerItem
+import com.maubis.scarlet.base.support.ui.ColorUtil
+import com.maubis.scarlet.base.support.ui.ThemeColorType
+
+class SelectorFolderRecyclerItem(context: Context, val folder: Folder) : RecyclerItem() {
+
+ val isLightShaded = ColorUtil.isLightColored(folder.color)
+ val title = folder.title
+ val titleColor = sAppTheme.get(ThemeColorType.TERTIARY_TEXT)
+
+ val folderColor = folder.color
+ val iconColor = when (isLightShaded) {
+ true -> ContextCompat.getColor(context, R.color.dark_secondary_text)
+ false -> ContextCompat.getColor(context, R.color.light_primary_text)
+ }
+ override val type = Type.FOLDER
+}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/CreateOrEditFolderBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/CreateOrEditFolderBottomSheet.kt
index 6a3b619b..88101d3e 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/CreateOrEditFolderBottomSheet.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/CreateOrEditFolderBottomSheet.kt
@@ -2,27 +2,25 @@ package com.maubis.scarlet.base.note.folder.sheet
import android.app.Dialog
import android.content.Context
-import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.widget.EditText
import android.widget.TextView
+import androidx.appcompat.app.AppCompatActivity
import com.google.android.flexbox.FlexboxLayout
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
-import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
import com.maubis.scarlet.base.core.folder.isUnsaved
import com.maubis.scarlet.base.database.room.folder.Folder
import com.maubis.scarlet.base.note.folder.delete
import com.maubis.scarlet.base.note.folder.save
-import com.maubis.scarlet.base.note.save
import com.maubis.scarlet.base.settings.view.ColorView
+import com.maubis.scarlet.base.support.sheets.openSheet
import com.maubis.scarlet.base.support.ui.ThemeColorType
import com.maubis.scarlet.base.support.ui.ThemedActivity
import com.maubis.scarlet.base.support.ui.ThemedBottomSheetFragment
import com.maubis.scarlet.base.support.utils.getEditorActionListener
-
class CreateOrEditFolderBottomSheet : ThemedBottomSheetFragment() {
var selectedFolder: Folder? = null
@@ -49,11 +47,10 @@ class CreateOrEditFolderBottomSheet : ThemedBottomSheetFragment() {
val enterFolder = dialog.findViewById(R.id.enter_folder)
val removeBtn = dialog.findViewById(R.id.action_remove_button)
val colorFlexbox = dialog.findViewById(R.id.color_flexbox)
- val colorCard = dialog.findViewById(R.id.core_color_card)
- title.setTextColor(CoreConfig.instance.themeController().get(ThemeColorType.SECONDARY_TEXT))
- enterFolder.setTextColor(CoreConfig.instance.themeController().get(ThemeColorType.SECONDARY_TEXT))
- enterFolder.setHintTextColor(CoreConfig.instance.themeController().get(ThemeColorType.HINT_TEXT))
+ title.setTextColor(sAppTheme.get(ThemeColorType.SECONDARY_TEXT))
+ enterFolder.setTextColor(sAppTheme.get(ThemeColorType.SECONDARY_TEXT))
+ enterFolder.setHintTextColor(sAppTheme.get(ThemeColorType.HINT_TEXT))
title.setText(if (folder.isUnsaved()) R.string.folder_sheet_add_note else R.string.folder_sheet_edit_note)
action.setOnClickListener {
@@ -61,25 +58,24 @@ class CreateOrEditFolderBottomSheet : ThemedBottomSheetFragment() {
sheetOnFolderListener(folder, !updated)
dismiss()
}
+
+ val folderDeleteListener = sheetOnFolderListener
removeBtn.visibility = if (folder.isUnsaved()) GONE else VISIBLE
removeBtn.setOnClickListener {
- folder.delete()
- notesDb.getAll().filter { it.folder == folder.uuid }.forEach {
- it.folder = ""
- it.save(themedContext())
- }
-
- sheetOnFolderListener(folder, true)
+ openSheet(context as AppCompatActivity, DeleteFolderBottomSheet().apply {
+ selectedFolder = folder
+ sheetOnFolderListener = folderDeleteListener
+ })
dismiss()
}
enterFolder.setText(folder.title)
enterFolder.setOnEditorActionListener(getEditorActionListener(
- runnable = {
- val updated = onActionClick(folder, enterFolder.text.toString())
- sheetOnFolderListener(folder, !updated)
- dismiss()
- return@getEditorActionListener true
- }))
+ runnable = {
+ val updated = onActionClick(folder, enterFolder.text.toString())
+ sheetOnFolderListener(folder, !updated)
+ dismiss()
+ return@getEditorActionListener true
+ }))
setColorsList(dialog.context, folder, colorFlexbox)
makeBackgroundTransparent(dialog, R.id.root_layout)
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/DeleteFolderBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/DeleteFolderBottomSheet.kt
new file mode 100644
index 00000000..e7341282
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/DeleteFolderBottomSheet.kt
@@ -0,0 +1,84 @@
+package com.maubis.scarlet.base.note.folder.sheet
+
+import android.app.Dialog
+import androidx.appcompat.app.AppCompatActivity
+import com.facebook.litho.ComponentContext
+import com.maubis.scarlet.base.R
+import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.database.room.folder.Folder
+import com.maubis.scarlet.base.database.room.note.Note
+import com.maubis.scarlet.base.note.folder.delete
+import com.maubis.scarlet.base.note.save
+import com.maubis.scarlet.base.note.softDelete
+import com.maubis.scarlet.base.support.sheets.LithoOptionBottomSheet
+import com.maubis.scarlet.base.support.sheets.LithoOptionsItem
+
+class DeleteFolderBottomSheet : LithoOptionBottomSheet() {
+
+ var selectedFolder: Folder? = null
+ var sheetOnFolderListener: (folder: Folder, deleted: Boolean) -> Unit = { _, _ -> }
+
+ override fun title(): Int = R.string.folder_delete_option_sheet_title
+
+ override fun getOptions(componentContext: ComponentContext, dialog: Dialog): List {
+ val folder = selectedFolder
+ if (folder === null) {
+ dismiss()
+ return emptyList()
+ }
+
+ val activity = context as AppCompatActivity
+ val options = ArrayList()
+ options.add(LithoOptionsItem(
+ title = R.string.folder_delete_option_sheet_remove_folder,
+ subtitle = R.string.folder_delete_option_sheet_remove_folder_details,
+ icon = R.drawable.icon_delete,
+ listener = {
+ folder.delete()
+ executeForFolderContent(folder) {
+ it.folder = ""
+ it.save(activity)
+ }
+
+ sheetOnFolderListener(folder, true)
+ dismiss()
+ }
+ ))
+ options.add(LithoOptionsItem(
+ title = R.string.folder_delete_option_sheet_remove_folder_content,
+ subtitle = R.string.folder_delete_option_sheet_remove_folder_content_details,
+ icon = R.drawable.icon_delete_content,
+ listener = {
+ executeForFolderContent(folder) {
+ it.folder = ""
+ it.softDelete(activity)
+ }
+
+ sheetOnFolderListener(folder, false)
+ dismiss()
+ }
+ ))
+ options.add(LithoOptionsItem(
+ title = R.string.folder_delete_option_sheet_remove_folder_and_content,
+ subtitle = R.string.folder_delete_option_sheet_remove_folder_and_content_details,
+ icon = R.drawable.ic_delete_permanently,
+ listener = {
+ folder.delete()
+ executeForFolderContent(folder) {
+ it.folder = ""
+ it.softDelete(activity)
+ }
+
+ sheetOnFolderListener(folder, true)
+ dismiss()
+ }
+ ))
+ return options
+ }
+
+ private fun executeForFolderContent(folder: Folder, lambda: (Note) -> Unit) {
+ CoreConfig.notesDb.getAll().filter { it.folder == folder.uuid }.forEach {
+ lambda(it)
+ }
+ }
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/FolderChooseOptionsBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/FolderChooseOptionsBottomSheet.kt
deleted file mode 100644
index 728810b0..00000000
--- a/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/FolderChooseOptionsBottomSheet.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-package com.maubis.scarlet.base.note.folder.sheet
-
-import android.app.Dialog
-import android.content.Context
-import android.content.DialogInterface
-import android.view.View
-import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.database.room.folder.Folder
-import com.maubis.scarlet.base.database.room.note.Note
-import com.maubis.scarlet.base.core.folder.FolderBuilder
-import com.maubis.scarlet.base.note.folder.FolderOptionsItem
-import com.maubis.scarlet.base.note.save
-import com.maubis.scarlet.base.config.CoreConfig.Companion.foldersDb
-import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
-import com.maubis.scarlet.base.support.ui.ThemedActivity
-import com.maubis.scarlet.base.support.ui.visibility
-
-class FolderChooseOptionsBottomSheet : FolderOptionItemBottomSheetBase() {
-
- var note: Note? = null
- var dismissListener: () -> Unit = {}
-
- override fun setupViewWithDialog(dialog: Dialog) {
- if (note === null) {
- dismiss()
- return
- }
-
- val options = getOptions()
- dialog.findViewById(R.id.tag_card_layout).visibility = visibility(options.isNotEmpty())
- setOptions(dialog, getOptions())
- }
-
- override fun onNewFolderClick() {
- val activity = context as ThemedActivity
- CreateOrEditFolderBottomSheet.openSheet(activity, FolderBuilder().emptyFolder(), { folder, _ ->
- toggleFolder(activity, note, folder)
- reset(dialog)
- })
- }
-
- fun toggleFolder(context: Context, note: Note?, folder: Folder) {
- val localNote = note
- if (localNote === null) {
- return
- }
- localNote.folder = if (localNote.folder === folder.uuid) "" else folder.uuid
- localNote.save(context)
- }
-
- override fun onDismiss(dialog: DialogInterface?) {
- super.onDismiss(dialog)
- dismissListener()
- }
-
- private fun getOptions(): List {
- val activity = themedContext() as ThemedActivity
- val options = ArrayList()
- val selectedFolder = note!!.folder
- for (folder in foldersDb.getAll()) {
- options.add(FolderOptionsItem(
- folder = folder,
- usages = notesDb.getNoteCountByFolder(folder.uuid),
- listener = {
- toggleFolder(activity, note, folder)
- reset(dialog)
- },
- editListener = {
- CreateOrEditFolderBottomSheet.openSheet(activity, folder, {_,_ -> reset(dialog)})
- },
- selected = folder.uuid == selectedFolder
- ))
- }
- return options
- }
-
- companion object {
- fun openSheet(activity: ThemedActivity, note: Note, dismissListener: () -> Unit) {
- val sheet = FolderChooseOptionsBottomSheet()
-
- sheet.note = note
- sheet.dismissListener = dismissListener
- sheet.show(activity.supportFragmentManager, sheet.tag)
- }
- }
-}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/FolderChooserBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/FolderChooserBottomSheet.kt
new file mode 100644
index 00000000..5bf40c06
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/FolderChooserBottomSheet.kt
@@ -0,0 +1,27 @@
+package com.maubis.scarlet.base.note.folder.sheet
+
+import com.facebook.litho.ComponentContext
+import com.maubis.scarlet.base.database.room.folder.Folder
+import com.maubis.scarlet.base.database.room.note.Note
+import com.maubis.scarlet.base.note.save
+
+class FolderChooserBottomSheet : FolderChooserBottomSheetBase() {
+
+ var note: Note? = null
+
+ override fun preComponentRender(componentContext: ComponentContext) {
+
+ }
+
+ override fun onFolderSelected(folder: Folder) {
+ note!!.folder = when {
+ note!!.folder == folder.uuid -> ""
+ else -> folder.uuid
+ }
+ note!!.save(requireContext())
+ }
+
+ override fun isFolderSelected(folder: Folder): Boolean {
+ return note!!.folder == folder.uuid
+ }
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/FolderChooserBottomSheetBase.kt b/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/FolderChooserBottomSheetBase.kt
new file mode 100644
index 00000000..f01bf783
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/FolderChooserBottomSheetBase.kt
@@ -0,0 +1,171 @@
+package com.maubis.scarlet.base.note.folder.sheet
+
+import android.app.Dialog
+import android.content.DialogInterface
+import android.graphics.Typeface
+import androidx.appcompat.app.AppCompatActivity
+import com.facebook.litho.ClickEvent
+import com.facebook.litho.Column
+import com.facebook.litho.Component
+import com.facebook.litho.ComponentContext
+import com.facebook.litho.Row
+import com.facebook.litho.annotations.LayoutSpec
+import com.facebook.litho.annotations.OnCreateLayout
+import com.facebook.litho.annotations.OnEvent
+import com.facebook.litho.annotations.Prop
+import com.facebook.litho.widget.Text
+import com.facebook.yoga.YogaAlign
+import com.facebook.yoga.YogaEdge
+import com.maubis.scarlet.base.R
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
+import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.core.folder.FolderBuilder
+import com.maubis.scarlet.base.database.room.folder.Folder
+import com.maubis.scarlet.base.support.sheets.LithoBottomSheet
+import com.maubis.scarlet.base.support.sheets.LithoOptionsItem
+import com.maubis.scarlet.base.support.sheets.OptionItemLayout
+import com.maubis.scarlet.base.support.sheets.getLithoBottomSheetTitle
+import com.maubis.scarlet.base.support.specs.RoundIcon
+import com.maubis.scarlet.base.support.ui.ThemeColorType
+import com.maubis.scarlet.base.support.ui.ThemedActivity
+
+data class FolderOptionsItem(
+ val folder: Folder,
+ val isSelected: Boolean = false,
+ val listener: () -> Unit = {})
+
+@LayoutSpec
+object FolderItemLayoutSpec {
+ @OnCreateLayout
+ fun onCreate(context: ComponentContext, @Prop option: FolderOptionsItem): Component {
+ val titleColor = sAppTheme.get(ThemeColorType.SECONDARY_TEXT)
+ val selectedColor = when (sAppTheme.isNightTheme()) {
+ true -> context.getColor(R.color.material_blue_400)
+ false -> context.getColor(R.color.material_blue_700)
+ }
+
+ val icon: Int
+ val bgColor: Int
+ val bgAlpha: Int
+ val textColor: Int
+ val typeface: Typeface
+ when (option.isSelected) {
+ true -> {
+ icon = R.drawable.ic_folder
+ bgColor = selectedColor
+ bgAlpha = 200
+ textColor = selectedColor
+ typeface = sAppTypeface.subHeading()
+ }
+ false -> {
+ icon = R.drawable.ic_folder
+ bgColor = titleColor
+ bgAlpha = 15
+ textColor = titleColor
+ typeface = sAppTypeface.title()
+ }
+ }
+
+ val row = Row.create(context)
+ .widthPercent(100f)
+ .alignItems(YogaAlign.CENTER)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .paddingDip(YogaEdge.VERTICAL, 12f)
+ .child(
+ RoundIcon.create(context)
+ .iconRes(icon)
+ .bgColor(bgColor)
+ .iconColor(titleColor)
+ .iconSizeRes(R.dimen.toolbar_round_icon_size)
+ .iconPaddingRes(R.dimen.toolbar_round_icon_padding)
+ .bgAlpha(bgAlpha)
+ .onClick { }
+ .isClickDisabled(true)
+ .marginDip(YogaEdge.END, 16f))
+ .child(
+ Text.create(context)
+ .flexGrow(1f)
+ .text(option.folder.title)
+ .textSizeRes(R.dimen.font_size_normal)
+ .typeface(typeface)
+ .textStyle(Typeface.BOLD)
+ .textColor(textColor))
+ row.clickHandler(OptionItemLayout.onItemClick(context))
+ return row.build()
+ }
+
+ @OnEvent(ClickEvent::class)
+ fun onItemClick(context: ComponentContext, @Prop option: FolderOptionsItem) {
+ option.listener()
+ }
+}
+
+abstract class FolderChooserBottomSheetBase : LithoBottomSheet() {
+
+ var dismissListener: () -> Unit = {}
+
+ protected abstract fun preComponentRender(componentContext: ComponentContext)
+ protected abstract fun onFolderSelected(folder: Folder)
+ protected abstract fun isFolderSelected(folder: Folder): Boolean
+
+ override fun getComponent(componentContext: ComponentContext, dialog: Dialog): Component {
+ preComponentRender(componentContext)
+ val activity = context as ThemedActivity
+ val component = Column.create(componentContext)
+ .widthPercent(100f)
+ val foldersComponent = Column.create(componentContext)
+ .paddingDip(YogaEdge.TOP, 8f)
+ .paddingDip(YogaEdge.BOTTOM, 8f)
+ .paddingDip(YogaEdge.HORIZONTAL, 20f)
+ .child(
+ getLithoBottomSheetTitle(componentContext)
+ .textRes(R.string.folder_option_change_notebook)
+ .marginDip(YogaEdge.BOTTOM, 12f))
+ getFolderOptions().forEach {
+ foldersComponent.child(FolderItemLayout.create(componentContext).option(it))
+ }
+
+ val addTag = LithoOptionsItem(
+ title = R.string.folder_sheet_add_note,
+ subtitle = 0,
+ icon = R.drawable.icon_add_notebook,
+ listener = {
+ CreateOrEditFolderBottomSheet.openSheet(activity, FolderBuilder().emptyFolder()) { folder, _ ->
+ onFolderSelected(folder)
+ reset(activity, dialog)
+ }
+ })
+ foldersComponent.child(OptionItemLayout.create(componentContext)
+ .option(addTag)
+ .backgroundRes(R.drawable.accent_rounded_bg)
+ .marginDip(YogaEdge.TOP, 16f)
+ .onClick { addTag.listener() })
+
+ component.child(foldersComponent)
+ return component.build()
+ }
+
+ private fun getFolderOptions(): List {
+ val activity = context as AppCompatActivity
+ val options = ArrayList()
+ for (folder in CoreConfig.foldersDb.getAll()) {
+ options.add(
+ FolderOptionsItem(
+ folder = folder,
+ listener = {
+ onFolderSelected(folder)
+ reset(activity, dialog)
+ },
+ isSelected = isFolderSelected(folder)
+ ))
+ }
+ options.sortByDescending { if (it.isSelected) 1 else 0 }
+ return options
+ }
+
+ override fun onDismiss(dialog: DialogInterface) {
+ super.onDismiss(dialog)
+ dismissListener()
+ }
+}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/FolderOptionItemBottomSheetBase.kt b/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/FolderOptionItemBottomSheetBase.kt
deleted file mode 100644
index ee0c966f..00000000
--- a/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/FolderOptionItemBottomSheetBase.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-package com.maubis.scarlet.base.note.folder.sheet
-
-import android.app.Dialog
-import android.view.View
-import android.view.View.GONE
-import android.widget.LinearLayout
-import com.github.bijoysingh.uibasics.views.UIActionView
-import com.github.bijoysingh.uibasics.views.UITextView
-import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
-import com.maubis.scarlet.base.note.folder.FolderOptionsItem
-import com.maubis.scarlet.base.support.ui.ThemeColorType
-import com.maubis.scarlet.base.support.ui.ThemedBottomSheetFragment
-
-abstract class FolderOptionItemBottomSheetBase : ThemedBottomSheetFragment() {
-
- override fun setupView(dialog: Dialog?) {
- super.setupView(dialog)
- if (dialog == null) {
- return
- }
- reset(dialog)
- setAddFolderOption(dialog)
- makeBackgroundTransparent(dialog, R.id.root_layout)
- }
-
- abstract fun setupViewWithDialog(dialog: Dialog)
-
- abstract fun onNewFolderClick()
-
- override fun getBackgroundView(): Int {
- return R.id.options_layout
- }
-
- override fun getBackgroundCardViewIds(): Array = arrayOf(R.id.tag_card_layout)
-
- fun setAddFolderOption(dialog: Dialog) {
- val newFolderButton = dialog.findViewById(R.id.new_tag_button);
- newFolderButton.setText(R.string.folder_sheet_add_note)
- newFolderButton.setOnClickListener { onNewFolderClick() }
- newFolderButton.icon.alpha = 0.6f
- }
-
- fun reset(dialog: Dialog) {
- val layout = dialog.findViewById(R.id.options_container)
- layout.removeAllViews()
- setupViewWithDialog(dialog)
- }
-
- fun setOptions(dialog: Dialog, options: List) {
- val layout = dialog.findViewById(R.id.options_container)
- for (option in options) {
- val contentView = View.inflate(context, R.layout.layout_option_sheet_item, null) as UIActionView
- contentView.setTitle(option.folder.title)
- contentView.setOnClickListener { option.listener() }
- contentView.subtitle.visibility = GONE
- contentView.setImageResource(option.getIcon())
-
- if (option.editable) {
- contentView.setActionResource(option.getEditIcon());
- contentView.setActionTint(CoreConfig.instance.themeController().get(ThemeColorType.HINT_TEXT));
- contentView.setActionClickListener { option.editListener() }
- }
-
- contentView.setTitleColor(getOptionsTitleColor(option.selected))
- contentView.setSubtitleColor(getOptionsSubtitleColor(option.selected))
- contentView.setImageTint(getOptionsTitleColor(option.selected))
-
- layout.addView(contentView)
- }
- }
-
- override fun getLayout(): Int = R.layout.bottom_sheet_tag_options
-}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/SelectedFolderChooseOptionBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/SelectedFolderChooseOptionBottomSheet.kt
index 99f269b8..8f7aa044 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/SelectedFolderChooseOptionBottomSheet.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/folder/sheet/SelectedFolderChooseOptionBottomSheet.kt
@@ -1,71 +1,28 @@
package com.maubis.scarlet.base.note.folder.sheet
-import android.app.Dialog
-import android.content.Context
-import android.content.DialogInterface
-import android.view.View
-import com.maubis.scarlet.base.R
+import com.facebook.litho.ComponentContext
import com.maubis.scarlet.base.database.room.folder.Folder
-import com.maubis.scarlet.base.database.room.note.Note
-import com.maubis.scarlet.base.database.room.tag.Tag
-import com.maubis.scarlet.base.core.folder.FolderBuilder
-import com.maubis.scarlet.base.note.folder.FolderOptionsItem
-import com.maubis.scarlet.base.note.save
import com.maubis.scarlet.base.note.selection.activity.SelectNotesActivity
-import com.maubis.scarlet.base.config.CoreConfig.Companion.foldersDb
-import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
-import com.maubis.scarlet.base.support.ui.ThemedActivity
-import com.maubis.scarlet.base.support.ui.visibility
-class SelectedFolderChooseOptionsBottomSheet : FolderOptionItemBottomSheetBase() {
+class SelectedFolderChooseOptionsBottomSheet : FolderChooserBottomSheetBase() {
var onActionListener: (Folder, Boolean) -> Unit = { _, _ -> }
-
- override fun setupViewWithDialog(dialog: Dialog) {
- val options = getOptions()
- dialog.findViewById(R.id.tag_card_layout).visibility = visibility(options.isNotEmpty())
- setOptions(dialog, getOptions())
- }
-
- override fun onNewFolderClick() {
- val activity = context as ThemedActivity
- CreateOrEditFolderBottomSheet.openSheet(activity, FolderBuilder().emptyFolder(), { folder, _ ->
- onActionListener(folder, true)
- reset(dialog)
- })
+ var selectedFolders: MutableList = emptyList().toMutableList()
+ var selectedFolder: String = ""
+
+ override fun preComponentRender(componentContext: ComponentContext) {
+ val activity = requireContext() as SelectNotesActivity
+ selectedFolders.clear()
+ selectedFolders.addAll(activity.getAllSelectedNotes().map { it.folder }.distinct())
+ selectedFolder = selectedFolders.firstOrNull() ?: ""
}
- private fun getOptions(): List {
- val activity = themedContext() as SelectNotesActivity
- val options = ArrayList()
-
- val folders = activity.getAllSelectedNotes().map { it.folder }.distinct()
- val selectedFolder = when (folders.size) {
- 1 -> folders.first()
- else -> ""
- }
- for (folder in foldersDb.getAll()) {
- options.add(FolderOptionsItem(
- folder = folder,
- usages = notesDb.getNoteCountByFolder(folder.uuid),
- listener = {
- onActionListener(folder, folder.uuid != selectedFolder)
- reset(dialog)
- },
- editListener = {
- CreateOrEditFolderBottomSheet.openSheet(activity, folder, {_,_ -> reset(dialog)})
- },
- selected = folder.uuid == selectedFolder
- ))
- }
- return options
+ override fun onFolderSelected(folder: Folder) {
+ onActionListener(folder, true)
+ onActionListener(folder, folder.uuid != selectedFolder)
}
- companion object {
- fun openSheet(activity: ThemedActivity, listener: (Folder, Boolean) -> Unit) {
- val sheet = SelectedFolderChooseOptionsBottomSheet()
- sheet.onActionListener = listener
- sheet.show(activity.supportFragmentManager, sheet.tag)
- }
+ override fun isFolderSelected(folder: Folder): Boolean {
+ return folder.uuid == selectedFolder
}
}
\ No newline at end of file
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/formats/FormatControllerList.kt b/base/src/main/java/com/maubis/scarlet/base/note/formats/FormatControllerList.kt
index 1c144cc5..2133998f 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/formats/FormatControllerList.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/formats/FormatControllerList.kt
@@ -4,82 +4,106 @@ import com.github.bijoysingh.starter.recyclerview.MultiRecyclerViewControllerIte
import com.maubis.scarlet.base.R
import com.maubis.scarlet.base.core.format.Format
import com.maubis.scarlet.base.core.format.FormatType
-import com.maubis.scarlet.base.note.formats.recycler.*
+import com.maubis.scarlet.base.note.formats.recycler.FormatBulletViewHolder
+import com.maubis.scarlet.base.note.formats.recycler.FormatImageViewHolder
+import com.maubis.scarlet.base.note.formats.recycler.FormatListViewHolder
+import com.maubis.scarlet.base.note.formats.recycler.FormatQuoteViewHolder
+import com.maubis.scarlet.base.note.formats.recycler.FormatSeparatorViewHolder
+import com.maubis.scarlet.base.note.formats.recycler.FormatTextViewHolder
+import com.maubis.scarlet.base.note.formats.recycler.NullFormatHolder
import java.util.*
fun getFormatControllerItems(): List> {
val list = ArrayList>()
list.add(
- MultiRecyclerViewControllerItem.Builder()
- .viewType(FormatType.TAG.ordinal)
- .layoutFile(R.layout.item_format_tag)
- .holderClass(FormatTextViewHolder::class.java)
- .build())
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(FormatType.TAG.ordinal)
+ .layoutFile(R.layout.item_format_tag)
+ .holderClass(FormatTextViewHolder::class.java)
+ .build())
list.add(
- MultiRecyclerViewControllerItem.Builder()
- .viewType(FormatType.TEXT.ordinal)
- .layoutFile(R.layout.item_format_text)
- .holderClass(FormatTextViewHolder::class.java)
- .build())
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(FormatType.TEXT.ordinal)
+ .layoutFile(R.layout.item_format_text)
+ .holderClass(FormatTextViewHolder::class.java)
+ .build())
list.add(
- MultiRecyclerViewControllerItem.Builder()
- .viewType(FormatType.HEADING.ordinal)
- .layoutFile(R.layout.item_format_heading)
- .holderClass(FormatTextViewHolder::class.java)
- .build())
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(FormatType.HEADING.ordinal)
+ .layoutFile(R.layout.item_format_heading)
+ .holderClass(FormatTextViewHolder::class.java)
+ .build())
list.add(
- MultiRecyclerViewControllerItem.Builder()
- .viewType(FormatType.SUB_HEADING.ordinal)
- .layoutFile(R.layout.item_format_heading)
- .holderClass(FormatTextViewHolder::class.java)
- .build())
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(FormatType.SUB_HEADING.ordinal)
+ .layoutFile(R.layout.item_format_heading)
+ .holderClass(FormatTextViewHolder::class.java)
+ .build())
list.add(
- MultiRecyclerViewControllerItem.Builder()
- .viewType(FormatType.HEADING_3.ordinal)
- .layoutFile(R.layout.item_format_heading)
- .holderClass(FormatTextViewHolder::class.java)
- .build())
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(FormatType.HEADING_3.ordinal)
+ .layoutFile(R.layout.item_format_heading)
+ .holderClass(FormatTextViewHolder::class.java)
+ .build())
list.add(
- MultiRecyclerViewControllerItem.Builder()
- .viewType(FormatType.QUOTE.ordinal)
- .layoutFile(R.layout.item_format_quote)
- .holderClass(FormatQuoteViewHolder::class.java)
- .build())
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(FormatType.QUOTE.ordinal)
+ .layoutFile(R.layout.item_format_quote)
+ .holderClass(FormatQuoteViewHolder::class.java)
+ .build())
list.add(
- MultiRecyclerViewControllerItem.Builder()
- .viewType(FormatType.CODE.ordinal)
- .layoutFile(R.layout.item_format_code)
- .holderClass(FormatTextViewHolder::class.java)
- .build())
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(FormatType.CODE.ordinal)
+ .layoutFile(R.layout.item_format_code)
+ .holderClass(FormatTextViewHolder::class.java)
+ .build())
list.add(
- MultiRecyclerViewControllerItem.Builder()
- .viewType(FormatType.CHECKLIST_CHECKED.ordinal)
- .layoutFile(R.layout.item_format_list)
- .holderClass(FormatListViewHolder::class.java)
- .build())
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(FormatType.BULLET_1.ordinal)
+ .layoutFile(R.layout.item_format_bullet)
+ .holderClass(FormatBulletViewHolder::class.java)
+ .build())
list.add(
- MultiRecyclerViewControllerItem.Builder()
- .viewType(FormatType.CHECKLIST_UNCHECKED.ordinal)
- .layoutFile(R.layout.item_format_list)
- .holderClass(FormatListViewHolder::class.java)
- .build())
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(FormatType.BULLET_2.ordinal)
+ .layoutFile(R.layout.item_format_bullet)
+ .holderClass(FormatBulletViewHolder::class.java)
+ .build())
list.add(
- MultiRecyclerViewControllerItem.Builder()
- .viewType(FormatType.IMAGE.ordinal)
- .layoutFile(R.layout.item_format_image)
- .holderClass(FormatImageViewHolder::class.java)
- .build())
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(FormatType.BULLET_3.ordinal)
+ .layoutFile(R.layout.item_format_bullet)
+ .holderClass(FormatBulletViewHolder::class.java)
+ .build())
list.add(
- MultiRecyclerViewControllerItem.Builder()
- .viewType(FormatType.SEPARATOR.ordinal)
- .layoutFile(R.layout.item_format_separator)
- .holderClass(FormatSeparatorViewHolder::class.java)
- .build())
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(FormatType.CHECKLIST_CHECKED.ordinal)
+ .layoutFile(R.layout.item_format_list)
+ .holderClass(FormatListViewHolder::class.java)
+ .build())
list.add(
- MultiRecyclerViewControllerItem.Builder()
- .viewType(FormatType.EMPTY.ordinal)
- .layoutFile(R.layout.item_format_fab_space)
- .holderClass(NullFormatHolder::class.java)
- .build())
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(FormatType.CHECKLIST_UNCHECKED.ordinal)
+ .layoutFile(R.layout.item_format_list)
+ .holderClass(FormatListViewHolder::class.java)
+ .build())
+ list.add(
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(FormatType.IMAGE.ordinal)
+ .layoutFile(R.layout.item_format_image)
+ .holderClass(FormatImageViewHolder::class.java)
+ .build())
+ list.add(
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(FormatType.SEPARATOR.ordinal)
+ .layoutFile(R.layout.item_format_separator)
+ .holderClass(FormatSeparatorViewHolder::class.java)
+ .build())
+ list.add(
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(FormatType.EMPTY.ordinal)
+ .layoutFile(R.layout.item_format_fab_space)
+ .holderClass(NullFormatHolder::class.java)
+ .build())
return list
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatBulletViewHolder.kt b/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatBulletViewHolder.kt
new file mode 100644
index 00000000..fd923863
--- /dev/null
+++ b/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatBulletViewHolder.kt
@@ -0,0 +1,41 @@
+package com.maubis.scarlet.base.note.formats.recycler
+
+import android.content.Context
+import android.view.View
+import android.widget.ImageView
+import com.maubis.scarlet.base.R
+import com.maubis.scarlet.base.core.format.Format
+import com.maubis.scarlet.base.core.format.FormatType
+import com.maubis.scarlet.base.support.ui.visibility
+
+class FormatBulletViewHolder(context: Context, view: View) : FormatTextViewHolder(context, view) {
+
+ private val firstMargin: View = root.findViewById(R.id.first_margin)
+ private val secondMargin: View = root.findViewById(R.id.second_margin)
+ private val icon: ImageView = root.findViewById(R.id.icon)
+
+ override fun populate(data: Format, config: FormatViewHolderConfig) {
+ super.populate(data, config)
+ icon.setColorFilter(config.iconColor)
+
+ when (data.formatType) {
+ FormatType.BULLET_1 -> {
+ icon.setImageResource(R.drawable.icon_bullet_1)
+ firstMargin.visibility = visibility(false)
+ secondMargin.visibility = visibility(false)
+ }
+ FormatType.BULLET_2 -> {
+ icon.setImageResource(R.drawable.icon_bullet_2)
+ firstMargin.visibility = visibility(false)
+ secondMargin.visibility = visibility(true)
+ }
+ FormatType.BULLET_3 -> {
+ icon.setImageResource(R.drawable.icon_bullet_3)
+ firstMargin.visibility = visibility(true)
+ secondMargin.visibility = visibility(true)
+ }
+ else -> {
+ } // Ignore other cases
+ }
+ }
+}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatImageViewHolder.kt b/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatImageViewHolder.kt
index d1957b3c..bd9d39d0 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatImageViewHolder.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatImageViewHolder.kt
@@ -1,21 +1,22 @@
package com.maubis.scarlet.base.note.formats.recycler
import android.content.Context
-import android.support.v7.app.AppCompatActivity
import android.util.TypedValue
import android.view.View
import android.widget.ImageView
import android.widget.TextView
+import androidx.appcompat.app.AppCompatActivity
import com.github.bijoysingh.starter.util.ToastHelper
import com.github.bijoysingh.uibasics.views.UITextView
import com.maubis.scarlet.base.R
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppImageStorage
import com.maubis.scarlet.base.core.format.Format
import com.maubis.scarlet.base.core.note.ImageLoadCallback
-import com.maubis.scarlet.base.core.note.NoteImage
-import com.maubis.scarlet.base.main.sheets.AlertBottomSheet
import com.maubis.scarlet.base.main.sheets.openDeleteFormatDialog
import com.maubis.scarlet.base.note.creation.sheet.FormatActionBottomSheet
+import com.maubis.scarlet.base.support.sheets.openSheet
import com.maubis.scarlet.base.support.ui.visibility
+import com.maubis.scarlet.base.support.utils.maybeThrow
import pl.aprilapps.easyphotopicker.EasyImage
import java.io.File
@@ -54,20 +55,25 @@ class FormatImageViewHolder(context: Context, view: View) : FormatViewHolderBase
actionCamera.setOnClickListener {
try {
EasyImage.openCamera(context as AppCompatActivity, data.uid)
- } catch (e: Exception) {
+ } catch (exception: Exception) {
ToastHelper.show(context, "No camera app installed")
+ maybeThrow(context as AppCompatActivity, exception)
}
}
actionGallery.setOnClickListener {
try {
EasyImage.openGallery(context as AppCompatActivity, data.uid)
- } catch (e: Exception) {
+ } catch (exception: Exception) {
ToastHelper.show(context, "No photo picker app installed")
+ maybeThrow(context as AppCompatActivity, exception)
}
}
actionMove.setColorFilter(config.iconColor)
actionMove.setOnClickListener {
- FormatActionBottomSheet.openSheet(activity, config.noteUUID, data)
+ openSheet(activity, FormatActionBottomSheet().apply {
+ noteUUID = config.noteUUID
+ format = data
+ })
}
imageToolbar.visibility = visibility(config.editable)
@@ -76,22 +82,25 @@ class FormatImageViewHolder(context: Context, view: View) : FormatViewHolderBase
noImageMessage.setBackgroundColor(imageToolbarBg)
val fileName = data.text
- if (!fileName.isBlank()) {
- val file = NoteImage(context).getFile(config.noteUUID, data)
- when (file.exists()) {
- true -> populateFile(file)
- false -> {
- noImageMessage.setText(R.string.image_not_on_current_device)
- noImageMessage.visibility = visibility(config.editable)
- image.visibility = View.GONE
- imageToolbar.visibility = View.GONE
+ when {
+ fileName.isBlank() -> image.visibility = View.GONE
+ else -> {
+ val file = sAppImageStorage.getFile(config.noteUUID, data)
+ when (file.exists()) {
+ true -> populateFile(file)
+ false -> {
+ noImageMessage.setText(R.string.image_not_on_current_device)
+ noImageMessage.visibility = visibility(config.editable)
+ image.visibility = View.GONE
+ imageToolbar.visibility = View.GONE
+ }
}
}
}
}
fun populateFile(file: File) {
- NoteImage(context).loadPersistentFileToImageView(image, file, object : ImageLoadCallback {
+ sAppImageStorage.loadPersistentFileToImageView(image, file, object : ImageLoadCallback {
override fun onSuccess() {
noImageMessage.visibility = View.GONE
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatListViewHolder.kt b/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatListViewHolder.kt
index e3c1216d..83ee6cea 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatListViewHolder.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatListViewHolder.kt
@@ -9,19 +9,21 @@ import android.widget.ImageView
import com.maubis.scarlet.base.R
import com.maubis.scarlet.base.core.format.Format
import com.maubis.scarlet.base.core.format.FormatType
+import com.maubis.scarlet.base.support.ui.visibility
import com.maubis.scarlet.base.support.utils.getEditorActionListener
class FormatListViewHolder(context: Context, view: View) : FormatTextViewHolder(context, view) {
private val icon: ImageView = root.findViewById(R.id.icon)
+ private val close: ImageView = root.findViewById(R.id.close)
init {
edit.setOnEditorActionListener(getEditorActionListener(
- runnable = {
- activity.createOrChangeToNextFormat(format!!)
- true
- },
- preConditions = { format === null || !edit.isFocused }
+ runnable = {
+ activity.createOrChangeToNextFormat(format)
+ true
+ },
+ preConditions = { !edit.isFocused }
))
edit.imeOptions = EditorInfo.IME_ACTION_DONE
edit.setRawInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES or InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE)
@@ -40,16 +42,26 @@ class FormatListViewHolder(context: Context, view: View) : FormatTextViewHolder(
FormatType.CHECKLIST_UNCHECKED -> {
icon.setImageResource(R.drawable.ic_check_box_outline_blank_white_24dp)
text.paintFlags = text.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
- itemView.alpha = 1f
+ itemView.alpha = 0.8f
}
else -> {
} // Ignore other cases
}
+ close.visibility = visibility(config.editable)
+ close.setColorFilter(config.iconColor)
+ close.alpha = 0.8f
+ close.setOnClickListener {
+ activity.deleteFormat(format)
+ }
+
itemView.setOnClickListener {
if (!config.editable) {
activity.setFormatChecked(data, data.formatType != FormatType.CHECKLIST_CHECKED)
}
}
+ icon.setOnClickListener {
+ activity.setFormatChecked(data, data.formatType != FormatType.CHECKLIST_CHECKED)
+ }
}
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatSeparatorViewHolder.kt b/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatSeparatorViewHolder.kt
index 709c88ed..a0f6d847 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatSeparatorViewHolder.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatSeparatorViewHolder.kt
@@ -7,6 +7,7 @@ import com.maubis.scarlet.base.R
import com.maubis.scarlet.base.core.format.Format
import com.maubis.scarlet.base.note.creation.sheet.FormatActionBottomSheet
import com.maubis.scarlet.base.note.creation.sheet.sEditorMoveHandles
+import com.maubis.scarlet.base.support.sheets.openSheet
import com.maubis.scarlet.base.support.ui.visibility
class FormatSeparatorViewHolder(context: Context, view: View) : FormatViewHolderBase(context, view) {
@@ -21,7 +22,10 @@ class FormatSeparatorViewHolder(context: Context, view: View) : FormatViewHolder
actionMove.setColorFilter(config.iconColor)
actionMove.visibility = visibility(config.editable)
actionMove.setOnClickListener {
- FormatActionBottomSheet.openSheet(activity, config.noteUUID, data)
+ openSheet(activity, FormatActionBottomSheet().apply {
+ noteUUID = config.noteUUID
+ format = data
+ })
}
if (config.editable && !sEditorMoveHandles) {
actionMove.visibility = View.INVISIBLE
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatTextViewHolder.kt b/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatTextViewHolder.kt
index c9186c74..7c052104 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatTextViewHolder.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatTextViewHolder.kt
@@ -9,6 +9,7 @@ import android.view.View
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
+import androidx.appcompat.app.AppCompatActivity
import com.maubis.markdown.Markdown
import com.maubis.markdown.spannable.clearMarkdownSpans
import com.maubis.markdown.spannable.setFormats
@@ -19,7 +20,9 @@ import com.maubis.scarlet.base.core.format.MarkdownType
import com.maubis.scarlet.base.note.creation.sheet.FormatActionBottomSheet
import com.maubis.scarlet.base.note.creation.sheet.sEditorLiveMarkdown
import com.maubis.scarlet.base.note.creation.sheet.sEditorMoveHandles
+import com.maubis.scarlet.base.support.sheets.openSheet
import com.maubis.scarlet.base.support.ui.visibility
+import com.maubis.scarlet.base.support.utils.maybeThrow
open class FormatTextViewHolder(context: Context, view: View) : FormatViewHolderBase(context, view), TextWatcher {
@@ -27,16 +30,16 @@ open class FormatTextViewHolder(context: Context, view: View) : FormatViewHolder
protected val edit: EditText = root.findViewById(R.id.edit)
protected val actionMove: ImageView = root.findViewById(R.id.action_move_icon)
- protected var format: Format? = null
+ protected lateinit var format: Format
init {
edit.addTextChangedListener(this)
edit.onFocusChangeListener = View.OnFocusChangeListener { _, _ -> activity.focusedFormat = format }
edit.setRawInputType(
- InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
- or InputType.TYPE_TEXT_FLAG_MULTI_LINE
- or InputType.TYPE_CLASS_TEXT
- or InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE
+ InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
+ or InputType.TYPE_TEXT_FLAG_MULTI_LINE
+ or InputType.TYPE_CLASS_TEXT
+ or InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE
)
}
@@ -55,15 +58,17 @@ open class FormatTextViewHolder(context: Context, view: View) : FormatViewHolder
text.setBackgroundColor(config.backgroundColor)
text.setLinkTextColor(config.accentColor)
text.setTextIsSelectable(true)
+ text.setTypeface(config.typeface, config.typefaceStyle)
text.visibility = visibility(!config.editable)
edit.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSize)
edit.setTextColor(config.secondaryTextColor)
edit.setHintTextColor(config.hintTextColor)
edit.setBackgroundColor(config.backgroundColor)
+ edit.setTypeface(config.typeface, config.typefaceStyle)
edit.visibility = visibility(config.editable)
edit.isEnabled = config.editable
-
+ showHintWhenTextIsEmpty()
when {
config.editable -> edit.setText(data.text)
@@ -74,29 +79,43 @@ open class FormatTextViewHolder(context: Context, view: View) : FormatViewHolder
actionMove.setColorFilter(config.iconColor)
actionMove.visibility = visibility(config.editable)
actionMove.setOnClickListener {
- FormatActionBottomSheet.openSheet(activity, config.noteUUID, data)
+ openSheet(activity, FormatActionBottomSheet().apply {
+ noteUUID = config.noteUUID
+ format = data
+ })
}
if (config.editable && !sEditorMoveHandles) {
actionMove.visibility = View.INVISIBLE
}
}
- override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
+ override fun beforeTextChanged(text: CharSequence, start: Int, count: Int, after: Int) {
}
- override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
- if (format === null || !edit.isFocused) {
+ override fun onTextChanged(text: CharSequence, start: Int, before: Int, count: Int) {
+ if (!edit.isFocused) {
return
}
- format!!.text = s.toString()
- activity.setFormat(format!!)
+
+ format.text = text.toString()
+ activity.setFormat(format)
+ showHintWhenTextIsEmpty()
+ }
+
+ // Workaround to avoid this holder being higher than the text contained in it when hint text
+ // occupies more lines than the text inserted by the user
+ private fun showHintWhenTextIsEmpty() {
+ edit.hint = when {
+ format.text.isEmpty() -> format.getHint()
+ else -> ""
+ }
}
override fun afterTextChanged(text: Editable) {
text.clearMarkdownSpans()
if (sEditorLiveMarkdown) {
- text.setFormats(Markdown.getSpanInfo(format!!.text).spans)
+ text.setFormats(Markdown.getSpanInfo(format.text).spans)
}
}
@@ -126,8 +145,25 @@ open class FormatTextViewHolder(context: Context, view: View) : FormatViewHolder
try {
val additionTokenLength = (if (markdownType.requiresNewLine) 1 else 0) + markdownType.startToken.length
edit.setSelection(Math.min(startString.length + additionTokenLength, edit.text.length))
- } catch (_: Exception) {
- // Ignore the exception
+ } catch (exception: Exception) {
+ maybeThrow(context as AppCompatActivity, exception)
+ }
+ }
+
+ private fun Format.getHint(): String {
+ return when (formatType) {
+ FormatType.TEXT, FormatType.TAG -> context.getString(R.string.format_hint_text)
+ FormatType.HEADING,
+ FormatType.SUB_HEADING,
+ FormatType.HEADING_3
+ -> context.getString(R.string.format_hint_heading)
+ FormatType.NUMBERED_LIST,
+ FormatType.CHECKLIST_UNCHECKED,
+ FormatType.CHECKLIST_CHECKED
+ -> context.getString(R.string.format_hint_list)
+ FormatType.CODE -> context.getString(R.string.format_hint_code)
+ FormatType.QUOTE -> context.getString(R.string.format_hint_quote)
+ else -> ""
}
}
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatViewHolderBase.kt b/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatViewHolderBase.kt
index d6427ef9..794b046c 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatViewHolderBase.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/formats/recycler/FormatViewHolderBase.kt
@@ -1,21 +1,23 @@
package com.maubis.scarlet.base.note.formats.recycler
import android.content.Context
+import android.graphics.Typeface
import android.os.Bundle
-import android.support.v4.content.ContextCompat
import android.view.View
+import androidx.core.content.ContextCompat
import com.github.bijoysingh.starter.recyclerview.RecyclerViewHolder
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
import com.maubis.scarlet.base.core.format.Format
import com.maubis.scarlet.base.core.format.FormatType
import com.maubis.scarlet.base.note.creation.activity.INTENT_KEY_NOTE_ID
import com.maubis.scarlet.base.note.creation.activity.ViewAdvancedNoteActivity
+import com.maubis.scarlet.base.note.creation.sheet.sNoteDefaultColor
import com.maubis.scarlet.base.settings.sheet.STORE_KEY_TEXT_SIZE
import com.maubis.scarlet.base.settings.sheet.SettingsOptionsBottomSheet
import com.maubis.scarlet.base.settings.sheet.TEXT_SIZE_DEFAULT
-import com.maubis.scarlet.base.settings.sheet.UISettingsOptionsBottomSheet.Companion.useNoteColorAsBackground
-import com.maubis.scarlet.base.settings.sheet.sNoteDefaultColor
+import com.maubis.scarlet.base.settings.sheet.sUIUseNoteColorAsBackground
import com.maubis.scarlet.base.support.ui.ColorUtil
import com.maubis.scarlet.base.support.ui.Theme
import com.maubis.scarlet.base.support.ui.ThemeColorType
@@ -24,17 +26,18 @@ const val KEY_EDITABLE = "KEY_EDITABLE"
const val KEY_NOTE_COLOR = "KEY_NOTE_COLOR"
data class FormatViewHolderConfig(
- val editable: Boolean,
- val isMarkdownEnabled: Boolean,
- val fontSize: Float,
- val backgroundColor: Int,
- val secondaryTextColor: Int,
- val tertiaryTextColor: Int,
- val iconColor: Int,
- val hintTextColor: Int,
- val accentColor: Int,
- val noteUUID: String)
-
+ val editable: Boolean,
+ val isMarkdownEnabled: Boolean,
+ val fontSize: Float,
+ val backgroundColor: Int,
+ val secondaryTextColor: Int,
+ val tertiaryTextColor: Int,
+ val iconColor: Int,
+ val hintTextColor: Int,
+ val accentColor: Int,
+ val noteUUID: String,
+ val typeface: Typeface,
+ val typefaceStyle: Int)
abstract class FormatViewHolderBase(context: Context, view: View) : RecyclerViewHolder(context, view) {
@@ -46,55 +49,69 @@ abstract class FormatViewHolderBase(context: Context, view: View) : RecyclerView
val tertiaryTextColor: Int
val iconColor: Int
val hintTextColor: Int
- val theme = CoreConfig.instance.themeController()
val isLightBackground = ColorUtil.isLightColored(noteColor)
+ val linkColor: Int
when {
- !useNoteColorAsBackground -> {
- secondaryTextColor = theme.get(ThemeColorType.SECONDARY_TEXT)
- tertiaryTextColor = theme.get(ThemeColorType.TERTIARY_TEXT)
- iconColor = theme.get(ThemeColorType.TOOLBAR_ICON)
- hintTextColor = theme.get(ThemeColorType.HINT_TEXT)
+ !sUIUseNoteColorAsBackground -> {
+ secondaryTextColor = sAppTheme.get(ThemeColorType.SECONDARY_TEXT)
+ tertiaryTextColor = sAppTheme.get(ThemeColorType.TERTIARY_TEXT)
+ iconColor = sAppTheme.get(ThemeColorType.TOOLBAR_ICON)
+ hintTextColor = sAppTheme.get(ThemeColorType.HINT_TEXT)
+ linkColor = sAppTheme.get(ThemeColorType.ACCENT_TEXT)
}
isLightBackground -> {
- secondaryTextColor = theme.get(context, Theme.LIGHT, ThemeColorType.SECONDARY_TEXT)
- tertiaryTextColor = theme.get(context, Theme.LIGHT, ThemeColorType.TERTIARY_TEXT)
- iconColor = theme.get(context, Theme.LIGHT, ThemeColorType.TOOLBAR_ICON)
- hintTextColor = theme.get(context, Theme.LIGHT, ThemeColorType.HINT_TEXT)
+ secondaryTextColor = sAppTheme.get(context, Theme.LIGHT, ThemeColorType.SECONDARY_TEXT)
+ tertiaryTextColor = sAppTheme.get(context, Theme.LIGHT, ThemeColorType.TERTIARY_TEXT)
+ iconColor = sAppTheme.get(context, Theme.LIGHT, ThemeColorType.TOOLBAR_ICON)
+ hintTextColor = sAppTheme.get(context, Theme.LIGHT, ThemeColorType.HINT_TEXT)
+ linkColor = ContextCompat.getColor(context, R.color.colorAccentYellowLight)
}
else -> {
- secondaryTextColor = theme.get(context, Theme.DARK, ThemeColorType.SECONDARY_TEXT)
- tertiaryTextColor = theme.get(context, Theme.DARK, ThemeColorType.TERTIARY_TEXT)
- iconColor = theme.get(context, Theme.DARK, ThemeColorType.TOOLBAR_ICON)
- hintTextColor = theme.get(context, Theme.DARK, ThemeColorType.HINT_TEXT)
+ secondaryTextColor = sAppTheme.get(context, Theme.DARK, ThemeColorType.SECONDARY_TEXT)
+ tertiaryTextColor = sAppTheme.get(context, Theme.DARK, ThemeColorType.TERTIARY_TEXT)
+ iconColor = sAppTheme.get(context, Theme.DARK, ThemeColorType.TOOLBAR_ICON)
+ hintTextColor = sAppTheme.get(context, Theme.DARK, ThemeColorType.HINT_TEXT)
+ linkColor = ContextCompat.getColor(context, R.color.colorAccentYellowDark)
}
}
val
- config = FormatViewHolderConfig(
- editable = !(extra != null
- && extra.containsKey(KEY_EDITABLE)
- && !extra.getBoolean(KEY_EDITABLE)),
- isMarkdownEnabled = (extra == null
- || extra.getBoolean(SettingsOptionsBottomSheet.KEY_MARKDOWN_ENABLED, true)
- || data.forcedMarkdown),
- fontSize = {
- val fontSize = extra?.getInt(STORE_KEY_TEXT_SIZE, TEXT_SIZE_DEFAULT)
- ?: TEXT_SIZE_DEFAULT
- when (data.formatType) {
- FormatType.HEADING -> fontSize.toFloat() + 4
- FormatType.SUB_HEADING -> fontSize.toFloat() + 2
- else -> fontSize.toFloat()
- }
- }(),
- backgroundColor = when (data.formatType) {
- FormatType.CODE, FormatType.IMAGE -> CoreConfig.instance.themeController().get(context, R.color.code_light, R.color.code_dark)
- else -> ContextCompat.getColor(context, R.color.transparent)
- },
- secondaryTextColor = secondaryTextColor,
- tertiaryTextColor = tertiaryTextColor,
- iconColor = iconColor,
- hintTextColor = hintTextColor,
- accentColor = theme.get(ThemeColorType.ACCENT_TEXT),
- noteUUID = extra?.getString(INTENT_KEY_NOTE_ID) ?: "default")
+ config = FormatViewHolderConfig(
+ editable = !(extra != null
+ && extra.containsKey(KEY_EDITABLE)
+ && !extra.getBoolean(KEY_EDITABLE)),
+ isMarkdownEnabled = (extra == null
+ || extra.getBoolean(SettingsOptionsBottomSheet.KEY_MARKDOWN_ENABLED, true)
+ || data.forcedMarkdown) && (data.formatType != FormatType.CODE),
+ fontSize = {
+ val fontSize = extra?.getInt(STORE_KEY_TEXT_SIZE, TEXT_SIZE_DEFAULT)
+ ?: TEXT_SIZE_DEFAULT
+ when (data.formatType) {
+ FormatType.HEADING -> fontSize.toFloat() + 4
+ FormatType.SUB_HEADING -> fontSize.toFloat() + 2
+ else -> fontSize.toFloat()
+ }
+ }(),
+ backgroundColor = when (data.formatType) {
+ FormatType.CODE, FormatType.IMAGE -> sAppTheme.get(context, R.color.code_light, R.color.code_dark)
+ else -> ContextCompat.getColor(context, R.color.transparent)
+ },
+ secondaryTextColor = secondaryTextColor,
+ tertiaryTextColor = tertiaryTextColor,
+ iconColor = iconColor,
+ hintTextColor = hintTextColor,
+ accentColor = linkColor,
+ noteUUID = extra?.getString(INTENT_KEY_NOTE_ID) ?: "default",
+ typeface = when (data.formatType) {
+ FormatType.HEADING -> sAppTypeface.subHeading()
+ FormatType.SUB_HEADING -> sAppTypeface.title()
+ FormatType.HEADING_3 -> sAppTypeface.title()
+ FormatType.CODE -> sAppTypeface.code()
+ else -> sAppTypeface.text()
+ },
+ typefaceStyle = when (data.formatType) {
+ FormatType.HEADING, FormatType.SUB_HEADING, FormatType.HEADING_3 -> Typeface.BOLD
+ else -> Typeface.NORMAL
+ })
populate(data, config)
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteAppAdapter.kt b/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteAppAdapter.kt
index c9a98bae..03e4772f 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteAppAdapter.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteAppAdapter.kt
@@ -9,13 +9,17 @@ import com.maubis.scarlet.base.main.recycler.EmptyRecyclerHolder
import com.maubis.scarlet.base.main.recycler.InformationRecyclerHolder
import com.maubis.scarlet.base.main.recycler.ToolbarMainRecyclerHolder
import com.maubis.scarlet.base.note.folder.FolderRecyclerHolder
+import com.maubis.scarlet.base.note.folder.SelectorFolderRecyclerHolder
import com.maubis.scarlet.base.note.selection.recycler.SelectableNoteRecyclerViewHolder
import com.maubis.scarlet.base.support.recycler.RecyclerItem
import java.util.*
class NoteAppAdapter : MultiRecyclerViewAdapter {
- @JvmOverloads constructor(context: Context, staggered: Boolean = false, isTablet: Boolean = false) : super(context, getRecyclerItemControllerList(staggered, isTablet)) {}
+ @JvmOverloads
+ constructor(context: Context, staggered: Boolean = false, isTablet: Boolean = false) : super(
+ context, getRecyclerItemControllerList(staggered, isTablet)) {
+ }
constructor(context: Context, list: List>) : super(context, list) {}
@@ -25,35 +29,41 @@ class NoteAppAdapter : MultiRecyclerViewAdapter {
}
fun getRecyclerItemControllerList(
- staggered: Boolean,
- isTablet: Boolean): List> {
+ staggered: Boolean,
+ isTablet: Boolean): List> {
val list = ArrayList>()
- list.add(MultiRecyclerViewControllerItem.Builder()
+ list.add(
+ MultiRecyclerViewControllerItem.Builder()
.viewType(RecyclerItem.Type.NOTE.ordinal)
.layoutFile(if (staggered && !isTablet) R.layout.item_note_staggered else R.layout.item_note)
.holderClass(NoteRecyclerHolder::class.java)
.build())
- list.add(MultiRecyclerViewControllerItem.Builder()
+ list.add(
+ MultiRecyclerViewControllerItem.Builder()
.viewType(RecyclerItem.Type.EMPTY.ordinal)
.layoutFile(R.layout.item_no_notes)
.holderClass(EmptyRecyclerHolder::class.java)
.build())
- list.add(MultiRecyclerViewControllerItem.Builder()
+ list.add(
+ MultiRecyclerViewControllerItem.Builder()
.viewType(RecyclerItem.Type.INFORMATION.ordinal)
.layoutFile(R.layout.item_information)
.holderClass(InformationRecyclerHolder::class.java)
.build())
- list.add(MultiRecyclerViewControllerItem.Builder()
+ list.add(
+ MultiRecyclerViewControllerItem.Builder()
.viewType(RecyclerItem.Type.FILE.ordinal)
.layoutFile(R.layout.item_import_file)
.holderClass(FileImportViewHolder::class.java)
.build())
- list.add(MultiRecyclerViewControllerItem.Builder()
+ list.add(
+ MultiRecyclerViewControllerItem.Builder()
.viewType(RecyclerItem.Type.FOLDER.ordinal)
.layoutFile(R.layout.item_folder)
.holderClass(FolderRecyclerHolder::class.java)
.build())
- list.add(MultiRecyclerViewControllerItem.Builder()
+ list.add(
+ MultiRecyclerViewControllerItem.Builder()
.viewType(RecyclerItem.Type.TOOLBAR.ordinal)
.layoutFile(R.layout.toolbar_main)
.holderClass(ToolbarMainRecyclerHolder::class.java)
@@ -62,15 +72,23 @@ fun getRecyclerItemControllerList(
}
fun getSelectableRecyclerItemControllerList(
- staggered: Boolean,
- isTablet: Boolean): List> {
+ staggered: Boolean,
+ isTablet: Boolean): List> {
val list = ArrayList>()
- list.add(MultiRecyclerViewControllerItem.Builder()
+ list.add(
+ MultiRecyclerViewControllerItem.Builder()
.viewType(RecyclerItem.Type.NOTE.ordinal)
.layoutFile(if (staggered && !isTablet) R.layout.item_note_staggered else R.layout.item_note)
.holderClass(SelectableNoteRecyclerViewHolder::class.java)
.build())
- list.add(MultiRecyclerViewControllerItem.Builder()
+ list.add(
+ MultiRecyclerViewControllerItem.Builder()
+ .viewType(RecyclerItem.Type.FOLDER.ordinal)
+ .layoutFile(R.layout.item_selector_folder)
+ .holderClass(SelectorFolderRecyclerHolder::class.java)
+ .build())
+ list.add(
+ MultiRecyclerViewControllerItem.Builder()
.viewType(RecyclerItem.Type.EMPTY.ordinal)
.layoutFile(R.layout.item_no_notes)
.holderClass(EmptyRecyclerHolder::class.java)
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteRecyclerHolder.kt b/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteRecyclerHolder.kt
index 862035e6..ee7a8be5 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteRecyclerHolder.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteRecyclerHolder.kt
@@ -5,12 +5,12 @@ import android.os.Bundle
import android.view.View
import com.maubis.scarlet.base.MainActivity
import com.maubis.scarlet.base.database.room.note.Note
-import com.maubis.scarlet.base.main.sheets.EnterPincodeBottomSheet
import com.maubis.scarlet.base.note.actions.NoteOptionsBottomSheet
import com.maubis.scarlet.base.note.copy
+import com.maubis.scarlet.base.note.creation.activity.NoteIntentRouterActivity
import com.maubis.scarlet.base.note.edit
import com.maubis.scarlet.base.note.share
-import com.maubis.scarlet.base.note.view
+import com.maubis.scarlet.base.security.sheets.openUnlockSheet
import com.maubis.scarlet.base.support.ui.ThemedActivity
class NoteRecyclerHolder(context: Context, view: View) : NoteRecyclerViewHolderBase(context, view) {
@@ -47,17 +47,10 @@ class NoteRecyclerHolder(context: Context, view: View) : NoteRecyclerViewHolderB
private fun actionOrUnlockNote(data: Note, runnable: Runnable) {
if (context is ThemedActivity && data.locked) {
- EnterPincodeBottomSheet.openUnlockSheet(
- context as ThemedActivity,
- object : EnterPincodeBottomSheet.PincodeSuccessListener {
- override fun onFailure() {
- actionOrUnlockNote(data, runnable)
- }
-
- override fun onSuccess() {
- runnable.run()
- }
- })
+ openUnlockSheet(
+ activity = context as ThemedActivity,
+ onUnlockSuccess = { runnable.run() },
+ onUnlockFailure = { actionOrUnlockNote(data, runnable) })
return
} else if (data.locked) {
return
@@ -66,6 +59,6 @@ class NoteRecyclerHolder(context: Context, view: View) : NoteRecyclerViewHolderB
}
private fun openNote(data: Note) {
- data.view(context)
+ context.startActivity(NoteIntentRouterActivity.view(context, data))
}
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteRecyclerItem.kt b/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteRecyclerItem.kt
index 960a5af4..8ffee86b 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteRecyclerItem.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteRecyclerItem.kt
@@ -1,32 +1,28 @@
package com.maubis.scarlet.base.note.recycler
import android.content.Context
-import android.support.v4.content.ContextCompat
+import androidx.core.content.ContextCompat
import com.maubis.markdown.Markdown
import com.maubis.scarlet.base.R
import com.maubis.scarlet.base.core.note.getNoteState
import com.maubis.scarlet.base.core.note.getReminderV2
import com.maubis.scarlet.base.database.room.note.Note
-import com.maubis.scarlet.base.note.*
-import com.maubis.scarlet.base.note.creation.sheet.sEditorMarkdownEnabled
-import com.maubis.scarlet.base.settings.sheet.UISettingsOptionsBottomSheet.Companion.sMarkdownEnabledHome
+import com.maubis.scarlet.base.note.adjustedColor
+import com.maubis.scarlet.base.note.getDisplayTime
+import com.maubis.scarlet.base.note.getImageFile
+import com.maubis.scarlet.base.note.getLockedAwareTextForHomeList
+import com.maubis.scarlet.base.note.getTagString
import com.maubis.scarlet.base.settings.sheet.sNoteItemLineCount
import com.maubis.scarlet.base.support.recycler.RecyclerItem
import com.maubis.scarlet.base.support.ui.ColorUtil
class NoteRecyclerItem(context: Context, val note: Note) : RecyclerItem() {
- private val isLightShaded = ColorUtil.isLightColored(note.color)
- private val isMarkdownEnabled = sEditorMarkdownEnabled && sMarkdownEnabledHome
val lineCount = sNoteItemLineCount
+ val backgroundColor = note.adjustedColor()
+ val isLightShaded = ColorUtil.isLightColored(backgroundColor)
- val title = note.getMarkdownTitle(isMarkdownEnabled)
- val titleColor = when (isLightShaded) {
- true -> ContextCompat.getColor(context, R.color.dark_tertiary_text)
- false -> ContextCompat.getColor(context, R.color.light_primary_text)
- }
-
- val description = note.getLockedText(isMarkdownEnabled)
+ val description = note.getLockedAwareTextForHomeList()
val descriptionColor = when (isLightShaded) {
true -> ContextCompat.getColor(context, R.color.dark_tertiary_text)
false -> ContextCompat.getColor(context, R.color.light_primary_text)
@@ -60,5 +56,5 @@ class NoteRecyclerItem(context: Context, val note: Note) : RecyclerItem() {
val imageSource = note.getImageFile()
val disableBackup = note.disableBackup
- override val type = RecyclerItem.Type.NOTE
+ override val type = Type.NOTE
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteRecyclerViewHolderBase.kt b/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteRecyclerViewHolderBase.kt
index 29cb489c..2c00a1fe 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteRecyclerViewHolderBase.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/recycler/NoteRecyclerViewHolderBase.kt
@@ -1,19 +1,22 @@
package com.maubis.scarlet.base.note.recycler
import android.content.Context
+import android.graphics.Typeface
import android.os.Bundle
-import android.support.v7.widget.CardView
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.widget.ImageView
import android.widget.TextView
+import androidx.cardview.widget.CardView
import com.github.bijoysingh.starter.recyclerview.RecyclerViewHolder
import com.github.bijoysingh.starter.util.TextUtils
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.database.room.note.Note
-import com.maubis.scarlet.base.core.note.NoteImage
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppImageStorage
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTypeface
import com.maubis.scarlet.base.core.note.NoteState
+import com.maubis.scarlet.base.database.room.note.Note
+import com.maubis.scarlet.base.note.isNoteLockedButAppUnlocked
import com.maubis.scarlet.base.support.recycler.RecyclerItem
import com.maubis.scarlet.base.support.ui.visibility
import com.maubis.scarlet.base.support.utils.trim
@@ -23,7 +26,6 @@ open class NoteRecyclerViewHolderBase(context: Context, view: View) : RecyclerVi
protected val view: CardView
protected val tags: TextView
protected val image: ImageView
- protected val title: TextView
protected val description: TextView
protected val edit: ImageView
protected val share: ImageView
@@ -33,6 +35,7 @@ open class NoteRecyclerViewHolderBase(context: Context, view: View) : RecyclerVi
protected val bottomLayout: View
protected val pinIndicator: ImageView
+ protected val unlockIndicator: ImageView
protected val reminderIndicator: ImageView
protected val stateIndicator: ImageView
protected val backupIndicator: ImageView
@@ -41,13 +44,13 @@ open class NoteRecyclerViewHolderBase(context: Context, view: View) : RecyclerVi
this.view = view as CardView
tags = view.findViewById(R.id.tags)
image = view.findViewById(R.id.image)
- title = view.findViewById(R.id.title)
description = view.findViewById(R.id.description)
share = view.findViewById(R.id.share_button)
delete = view.findViewById(R.id.delete_button)
copy = view.findViewById(R.id.copy_button)
moreOptions = view.findViewById(R.id.options_button)
pinIndicator = view.findViewById(R.id.pin_icon)
+ unlockIndicator = view.findViewById(R.id.unlock_icon)
reminderIndicator = view.findViewById(R.id.reminder_icon)
edit = view.findViewById(R.id.edit_button)
bottomLayout = view.findViewById(R.id.bottom_toolbar_layout)
@@ -57,28 +60,23 @@ open class NoteRecyclerViewHolderBase(context: Context, view: View) : RecyclerVi
override fun populate(itemData: RecyclerItem, extra: Bundle?) {
val item = itemData as NoteRecyclerItem
- setTitle(item)
setDescription(item)
setImage(item)
setIndicators(item)
setMetaText(item)
+ view.alpha = if (item.note.isNoteLockedButAppUnlocked()) 0.7f else 1.0f
view.setOnClickListener { viewClick(item.note, extra) }
view.setOnLongClickListener {
viewLongClick(item.note, extra)
false
}
- view.setCardBackgroundColor(item.note.color)
+ view.setCardBackgroundColor(item.backgroundColor)
setActionBar(item, extra)
}
- private fun setTitle(note: NoteRecyclerItem) {
- title.text = note.title
- title.visibility = if (note.title.isEmpty()) View.GONE else View.VISIBLE
- title.setTextColor(note.titleColor)
- }
-
private fun setDescription(note: NoteRecyclerItem) {
+ description.setTypeface(sAppTypeface.text(), Typeface.NORMAL)
description.text = note.description
description.maxLines = note.lineCount
description.setTextColor(note.descriptionColor)
@@ -88,7 +86,7 @@ open class NoteRecyclerViewHolderBase(context: Context, view: View) : RecyclerVi
val isImageAvailable = !note.imageSource.isBlank()
image.visibility = visibility(isImageAvailable)
if (isImageAvailable) {
- NoteImage(context).loadThumbnailFileToImageView(note.note.uuid, note.imageSource, image)
+ sAppImageStorage.loadThumbnailFileToImageView(note.note.uuid, note.imageSource, image)
}
}
@@ -111,14 +109,17 @@ open class NoteRecyclerViewHolderBase(context: Context, view: View) : RecyclerVi
}
NoteState.DEFAULT -> stateIndicator.visibility = GONE
}
+ unlockIndicator.visibility = visibility(note.note.locked)
pinIndicator.setColorFilter(note.indicatorColor)
stateIndicator.setColorFilter(note.indicatorColor)
reminderIndicator.setColorFilter(note.indicatorColor)
backupIndicator.setColorFilter(note.indicatorColor)
+ unlockIndicator.setColorFilter(note.indicatorColor)
}
private fun setMetaText(note: NoteRecyclerItem) {
+ tags.typeface = sAppTypeface.text()
when {
!TextUtils.isNullOrEmpty(note.tagsSource) -> {
tags.setTextColor(note.tagsColor)
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/reminders/ReminderJob.kt b/base/src/main/java/com/maubis/scarlet/base/note/reminders/ReminderJob.kt
index 6435b733..24199ff5 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/reminders/ReminderJob.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/reminders/ReminderJob.kt
@@ -4,6 +4,7 @@ import com.evernote.android.job.Job
import com.evernote.android.job.JobManager
import com.evernote.android.job.JobRequest
import com.evernote.android.job.util.support.PersistableBundleCompat
+import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
import com.maubis.scarlet.base.core.note.Reminder
import com.maubis.scarlet.base.core.note.ReminderInterval
import com.maubis.scarlet.base.core.note.getReminderV2
@@ -12,11 +13,10 @@ import com.maubis.scarlet.base.note.saveWithoutSync
import com.maubis.scarlet.base.notification.NotificationConfig
import com.maubis.scarlet.base.notification.NotificationHandler
import com.maubis.scarlet.base.notification.REMINDER_NOTIFICATION_CHANNEL_ID
-import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
+import com.maubis.scarlet.base.support.utils.maybeThrow
import java.util.*
import java.util.concurrent.TimeUnit
-
class ReminderJob : Job() {
override fun onRunJob(params: Params): Job.Result {
@@ -33,9 +33,9 @@ class ReminderJob : Job() {
val reminder = note.getReminderV2()
if (reminder?.interval == ReminderInterval.DAILY) {
val reminderV2 = Reminder(
- 0,
- nextJobTimestamp(reminder.timestamp, System.currentTimeMillis()),
- ReminderInterval.DAILY)
+ 0,
+ nextJobTimestamp(reminder.timestamp, System.currentTimeMillis()),
+ ReminderInterval.DAILY)
reminderV2.uid = scheduleJob(note.uuid, reminderV2)
note.setReminderV2(reminderV2)
note.saveWithoutSync(context)
@@ -43,7 +43,8 @@ class ReminderJob : Job() {
note.meta = ""
note.saveWithoutSync(context)
}
- } catch (e: Exception) {
+ } catch (exception: Exception) {
+ maybeThrow(exception)
}
return Job.Result.SUCCESS
@@ -63,10 +64,10 @@ class ReminderJob : Job() {
}
return JobRequest.Builder(ReminderJob.TAG)
- .setExact(deltaTime)
- .setExtras(extras)
- .build()
- .schedule()
+ .setExact(deltaTime)
+ .setExtras(extras)
+ .build()
+ .schedule()
}
fun nextJobTimestamp(timestamp: Long, currentTimestamp: Long): Long {
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/reminders/ReminderJobCreator.kt b/base/src/main/java/com/maubis/scarlet/base/note/reminders/ReminderJobCreator.kt
index 07859f3d..ef055203 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/reminders/ReminderJobCreator.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/reminders/ReminderJobCreator.kt
@@ -1,6 +1,6 @@
package com.maubis.scarlet.base.note.reminders
-import android.support.annotation.Nullable
+import androidx.annotation.Nullable
import com.evernote.android.job.Job
import com.evernote.android.job.JobCreator
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/reminders/sheet/ReminderBottomSheet.kt b/base/src/main/java/com/maubis/scarlet/base/note/reminders/sheet/ReminderBottomSheet.kt
index 73a97869..85150181 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/reminders/sheet/ReminderBottomSheet.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/reminders/sheet/ReminderBottomSheet.kt
@@ -8,7 +8,7 @@ import android.widget.TextView
import com.github.bijoysingh.starter.util.DateFormatter
import com.github.bijoysingh.uibasics.views.UIActionView
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
import com.maubis.scarlet.base.core.note.Reminder
import com.maubis.scarlet.base.core.note.ReminderInterval
import com.maubis.scarlet.base.core.note.getReminderV2
@@ -21,16 +21,17 @@ import com.maubis.scarlet.base.support.sheets.LithoChooseOptionsItem
import com.maubis.scarlet.base.support.ui.ThemeColorType
import com.maubis.scarlet.base.support.ui.ThemedActivity
import com.maubis.scarlet.base.support.ui.ThemedBottomSheetFragment
+import com.maubis.scarlet.base.support.utils.sDateFormat
import java.util.*
-
+// TODO: Upgrade to Litho
class ReminderBottomSheet : ThemedBottomSheetFragment() {
var selectedNote: Note? = null
var reminder: Reminder = Reminder(
- 0,
- Calendar.getInstance().timeInMillis,
- ReminderInterval.ONCE)
+ 0,
+ Calendar.getInstance().timeInMillis,
+ ReminderInterval.ONCE)
override fun getBackgroundView(): Int {
return R.id.container_layout
@@ -49,9 +50,9 @@ class ReminderBottomSheet : ThemedBottomSheetFragment() {
val calendar = Calendar.getInstance()
reminder = note.getReminderV2() ?: Reminder(
- 0,
- calendar.timeInMillis,
- ReminderInterval.ONCE)
+ 0,
+ calendar.timeInMillis,
+ ReminderInterval.ONCE)
val isNewReminder = reminder.uid == 0
if (isNewReminder) {
@@ -70,9 +71,14 @@ class ReminderBottomSheet : ThemedBottomSheetFragment() {
}
fun setListeners(note: Note, isNewReminder: Boolean) {
- val reminderDate = dialog.findViewById(R.id.reminder_date)
- val reminderTime = dialog.findViewById(R.id.reminder_time)
- val reminderRepeat = dialog.findViewById(R.id.reminder_repeat)
+ val dlg = dialog
+ if (dlg === null) {
+ return
+ }
+
+ val reminderDate = dlg.findViewById(R.id.reminder_date)
+ val reminderTime = dlg.findViewById(R.id.reminder_time)
+ val reminderRepeat = dlg.findViewById(R.id.reminder_repeat)
reminderDate.setOnClickListener {
if (reminder.interval == ReminderInterval.ONCE) {
@@ -86,8 +92,8 @@ class ReminderBottomSheet : ThemedBottomSheetFragment() {
openFrequencyDialog()
}
- val removeAlarm = dialog.findViewById(R.id.remove_alarm)
- val setAlarm = dialog.findViewById(R.id.set_alarm)
+ val removeAlarm = dlg.findViewById(R.id.remove_alarm)
+ val setAlarm = dlg.findViewById(R.id.set_alarm)
if (isNewReminder) {
removeAlarm.visibility = GONE
}
@@ -130,87 +136,96 @@ class ReminderBottomSheet : ThemedBottomSheetFragment() {
fun openFrequencyDialog() {
val isSelected = fun(interval: ReminderInterval): Boolean = interval == reminder.interval
com.maubis.scarlet.base.support.sheets.openSheet(
- themedActivity() as ThemedActivity,
- GenericOptionsBottomSheet().apply {
- title = R.string.reminder_sheet_repeat
- options = arrayListOf(
- LithoChooseOptionsItem(
- title = getReminderIntervalLabel(ReminderInterval.ONCE),
- listener = {
- reminder.interval = ReminderInterval.ONCE
- setContent(reminder)
- },
- selected = isSelected(ReminderInterval.ONCE)
- ),
- LithoChooseOptionsItem(
- title = getReminderIntervalLabel(ReminderInterval.DAILY),
- listener = {
- reminder.interval = ReminderInterval.DAILY
- setContent(reminder)
- },
- selected = isSelected(ReminderInterval.DAILY)
- )
+ themedActivity() as ThemedActivity,
+ GenericOptionsBottomSheet().apply {
+ title = R.string.reminder_sheet_repeat
+ options = arrayListOf(
+ LithoChooseOptionsItem(
+ title = getReminderIntervalLabel(ReminderInterval.ONCE),
+ listener = {
+ reminder.interval = ReminderInterval.ONCE
+ setContent(reminder)
+ },
+ selected = isSelected(ReminderInterval.ONCE)
+ ),
+ LithoChooseOptionsItem(
+ title = getReminderIntervalLabel(ReminderInterval.DAILY),
+ listener = {
+ reminder.interval = ReminderInterval.DAILY
+ setContent(reminder)
+ },
+ selected = isSelected(ReminderInterval.DAILY)
)
- }
+ )
+ }
)
}
fun openDatePickerDialog() {
val calendar = reminder.toCalendar()
val dialog = DatePickerDialog(
- themedContext(),
- R.style.DialogTheme,
- DatePickerDialog.OnDateSetListener { _, year, month, day ->
- calendar.set(Calendar.YEAR, year)
- calendar.set(Calendar.MONTH, month)
- calendar.set(Calendar.DAY_OF_MONTH, day)
- reminder.timestamp = calendar.timeInMillis
- setContent(reminder)
- },
- calendar.get(Calendar.YEAR),
- calendar.get(Calendar.MONTH),
- calendar.get(Calendar.DAY_OF_MONTH))
+ themedContext(),
+ R.style.DialogTheme,
+ DatePickerDialog.OnDateSetListener { _, year, month, day ->
+ calendar.set(Calendar.YEAR, year)
+ calendar.set(Calendar.MONTH, month)
+ calendar.set(Calendar.DAY_OF_MONTH, day)
+ reminder.timestamp = calendar.timeInMillis
+ setContent(reminder)
+ },
+ calendar.get(Calendar.YEAR),
+ calendar.get(Calendar.MONTH),
+ calendar.get(Calendar.DAY_OF_MONTH))
dialog.show()
}
fun openTimePickerDialog() {
val calendar = reminder.toCalendar()
val dialog = TimePickerDialog(
- themedContext(),
- R.style.DialogTheme,
- TimePickerDialog.OnTimeSetListener { _, hourOfDay, minute ->
- calendar.set(Calendar.HOUR_OF_DAY, hourOfDay)
- calendar.set(Calendar.MINUTE, minute)
- calendar.set(Calendar.SECOND, 0)
- reminder.timestamp = calendar.timeInMillis
- setContent(reminder)
- },
- calendar.get(Calendar.HOUR_OF_DAY),
- calendar.get(Calendar.MINUTE),
- false)
+ themedContext(),
+ R.style.DialogTheme,
+ TimePickerDialog.OnTimeSetListener { _, hourOfDay, minute ->
+ calendar.set(Calendar.HOUR_OF_DAY, hourOfDay)
+ calendar.set(Calendar.MINUTE, minute)
+ calendar.set(Calendar.SECOND, 0)
+ reminder.timestamp = calendar.timeInMillis
+ setContent(reminder)
+ },
+ calendar.get(Calendar.HOUR_OF_DAY),
+ calendar.get(Calendar.MINUTE),
+ false)
dialog.show()
}
fun setContent(reminder: Reminder) {
- val reminderDate = dialog.findViewById(R.id.reminder_date)
- val reminderTime = dialog.findViewById(R.id.reminder_time)
- val reminderRepeat = dialog.findViewById(R.id.reminder_repeat)
+ val dlg = dialog
+ if (dlg === null) {
+ return
+ }
+
+ val reminderDate = dlg.findViewById(R.id.reminder_date)
+ val reminderTime = dlg.findViewById(R.id.reminder_time)
+ val reminderRepeat = dlg.findViewById(R.id.reminder_repeat)
- val date = Date(reminder.timestamp)
reminderRepeat.setSubtitle(getReminderIntervalLabel(reminder.interval))
- reminderTime.setSubtitle(DateFormatter.getDate(DateFormatter.Formats.HH_MM_A.format, date))
- reminderDate.setSubtitle(DateFormatter.getDate(DateFormatter.Formats.DD_MMM_YYYY.format, date))
+ reminderTime.setSubtitle(sDateFormat.readableTime(DateFormatter.Formats.HH_MM_A.format, reminder.timestamp))
+ reminderDate.setSubtitle(sDateFormat.readableTime(DateFormatter.Formats.DD_MMM_YYYY.format, reminder.timestamp))
reminderDate.alpha = if (reminder.interval == ReminderInterval.ONCE) 1.0f else 0.5f
}
fun setColors() {
- val reminderDate = dialog.findViewById(R.id.reminder_date)
- val reminderTime = dialog.findViewById(R.id.reminder_time)
- val reminderRepeat = dialog.findViewById(R.id.reminder_repeat)
+ val dlg = dialog
+ if (dlg === null) {
+ return
+ }
+
+ val reminderDate = dlg.findViewById(R.id.reminder_date)
+ val reminderTime = dlg.findViewById(R.id.reminder_time)
+ val reminderRepeat = dlg.findViewById(R.id.reminder_repeat)
- val iconColor = CoreConfig.instance.themeController().get(ThemeColorType.TOOLBAR_ICON)
- val textColor = CoreConfig.instance.themeController().get(ThemeColorType.TERTIARY_TEXT)
- val titleColor = CoreConfig.instance.themeController().get(ThemeColorType.SECTION_HEADER)
+ val iconColor = sAppTheme.get(ThemeColorType.TOOLBAR_ICON)
+ val textColor = sAppTheme.get(ThemeColorType.TERTIARY_TEXT)
+ val titleColor = sAppTheme.get(ThemeColorType.SECTION_HEADER)
reminderDate.setTitleColor(titleColor)
reminderDate.setSubtitleColor(textColor)
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/selection/activity/SelectNotesActivity.kt b/base/src/main/java/com/maubis/scarlet/base/note/selection/activity/SelectNotesActivity.kt
index 29af1e5b..83e73139 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/selection/activity/SelectNotesActivity.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/selection/activity/SelectNotesActivity.kt
@@ -1,16 +1,17 @@
package com.maubis.scarlet.base.note.selection.activity
import android.os.Bundle
-import android.support.design.widget.FloatingActionButton
-import android.support.v7.widget.RecyclerView
+import androidx.recyclerview.widget.RecyclerView
import com.github.bijoysingh.starter.util.IntentUtils
+import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.maubis.scarlet.base.R
+import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
import com.maubis.scarlet.base.database.room.note.Note
-import com.maubis.scarlet.base.main.HomeNavigationState
+import com.maubis.scarlet.base.main.HomeNavigationMode
import com.maubis.scarlet.base.note.getFullText
-import com.maubis.scarlet.base.note.selection.sheet.SelectedNoteOptionsBottomSheet
+import com.maubis.scarlet.base.note.selection.sheet.SelectedNotesOptionsBottomSheet
+import com.maubis.scarlet.base.support.sheets.openSheet
import com.maubis.scarlet.base.support.utils.bind
-import com.maubis.scarlet.base.config.CoreConfig.Companion.notesDb
const val KEY_SELECT_EXTRA_MODE = "KEY_SELECT_EXTRA_MODE"
const val KEY_SELECT_EXTRA_NOTE_ID = "KEY_SELECT_EXTRA_NOTE_ID"
@@ -48,13 +49,13 @@ class SelectNotesActivity : SelectableNotesActivityBase() {
primaryFab.setOnClickListener {
runTextFunction { text ->
IntentUtils.ShareBuilder(this)
- .setChooserText(getString(R.string.share_using))
- .setText(text)
- .share()
+ .setChooserText(getString(R.string.share_using))
+ .setText(text)
+ .share()
}
}
secondaryFab.setOnClickListener {
- SelectedNoteOptionsBottomSheet.openSheet(this)
+ openSheet(this, SelectedNotesOptionsBottomSheet())
}
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
@@ -142,12 +143,12 @@ class SelectNotesActivity : SelectableNotesActivityBase() {
return builder.toString()
}
- fun getMode(navigationState: String): Array {
- return when (navigationState) {
- HomeNavigationState.FAVOURITE.name -> arrayOf(HomeNavigationState.FAVOURITE.name)
- HomeNavigationState.ARCHIVED.name -> arrayOf(HomeNavigationState.ARCHIVED.name)
- HomeNavigationState.TRASH.name -> arrayOf(HomeNavigationState.TRASH.name)
- else -> arrayOf(HomeNavigationState.DEFAULT.name, HomeNavigationState.FAVOURITE.name)
+ fun getMode(navigationMode: String): Array {
+ return when (navigationMode) {
+ HomeNavigationMode.FAVOURITE.name -> arrayOf(HomeNavigationMode.FAVOURITE.name)
+ HomeNavigationMode.ARCHIVED.name -> arrayOf(HomeNavigationMode.ARCHIVED.name)
+ HomeNavigationMode.TRASH.name -> arrayOf(HomeNavigationMode.TRASH.name)
+ else -> arrayOf(HomeNavigationMode.DEFAULT.name, HomeNavigationMode.FAVOURITE.name)
}
}
}
diff --git a/base/src/main/java/com/maubis/scarlet/base/note/selection/activity/SelectableNotesActivityBase.kt b/base/src/main/java/com/maubis/scarlet/base/note/selection/activity/SelectableNotesActivityBase.kt
index ea3af1c1..faa3c3fc 100644
--- a/base/src/main/java/com/maubis/scarlet/base/note/selection/activity/SelectableNotesActivityBase.kt
+++ b/base/src/main/java/com/maubis/scarlet/base/note/selection/activity/SelectableNotesActivityBase.kt
@@ -1,28 +1,36 @@
package com.maubis.scarlet.base.note.selection.activity
import android.os.Bundle
-import android.support.v7.widget.LinearLayoutManager
-import android.support.v7.widget.RecyclerView
-import android.support.v7.widget.StaggeredGridLayoutManager
import android.view.View
import android.widget.GridLayout
import android.widget.ImageView
import android.widget.TextView
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.github.bijoysingh.starter.async.MultiAsyncTask
import com.github.bijoysingh.starter.recyclerview.RecyclerViewBuilder
import com.maubis.scarlet.base.R
-import com.maubis.scarlet.base.config.CoreConfig
-import com.maubis.scarlet.base.database.room.note.Note
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.instance
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppPreferences
+import com.maubis.scarlet.base.config.ApplicationBase.Companion.sAppTheme
import com.maubis.scarlet.base.core.note.sort
+import com.maubis.scarlet.base.database.room.note.Note
import com.maubis.scarlet.base.main.recycler.EmptyRecyclerItem
+import com.maubis.scarlet.base.note.folder.SelectorFolderRecyclerItem
import com.maubis.scarlet.base.note.recycler.NoteAppAdapter
import com.maubis.scarlet.base.note.recycler.NoteRecyclerItem
import com.maubis.scarlet.base.note.recycler.getSelectableRecyclerItemControllerList
-import com.maubis.scarlet.base.settings.sheet.*
+import com.maubis.scarlet.base.settings.sheet.STORE_KEY_LINE_COUNT
+import com.maubis.scarlet.base.settings.sheet.SettingsOptionsBottomSheet
+import com.maubis.scarlet.base.settings.sheet.SortingOptionsBottomSheet
+import com.maubis.scarlet.base.settings.sheet.sNoteItemLineCount
+import com.maubis.scarlet.base.settings.sheet.sUIUseGridView
+import com.maubis.scarlet.base.support.recycler.RecyclerItem
+import com.maubis.scarlet.base.support.ui.SecuredActivity
import com.maubis.scarlet.base.support.ui.ThemeColorType
-import com.maubis.scarlet.base.support.ui.ThemedActivity
-abstract class SelectableNotesActivityBase : ThemedActivity(), INoteSelectorActivity {
+abstract class SelectableNotesActivityBase : SecuredActivity(), INoteSelectorActivity {
lateinit var recyclerView: RecyclerView
lateinit var adapter: NoteAppAdapter
@@ -36,14 +44,34 @@ abstract class SelectableNotesActivityBase : ThemedActivity(), INoteSelectorActi
notifyThemeChange()
setupRecyclerView()
- MultiAsyncTask.execute(object : MultiAsyncTask.Task> {
- override fun run(): List {
+ MultiAsyncTask.execute(object : MultiAsyncTask.Task