diff --git a/app/src/main/kotlin/com/simplemobiletools/notes/pro/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/notes/pro/activities/MainActivity.kt index f7282627..14c0c5f0 100644 --- a/app/src/main/kotlin/com/simplemobiletools/notes/pro/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/notes/pro/activities/MainActivity.kt @@ -42,6 +42,7 @@ import com.simplemobiletools.notes.pro.dialogs.* import com.simplemobiletools.notes.pro.extensions.* import com.simplemobiletools.notes.pro.fragments.TextFragment import com.simplemobiletools.notes.pro.helpers.* +import com.simplemobiletools.notes.pro.helpers.NotesImporter.ImportResult import com.simplemobiletools.notes.pro.models.Note import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.item_checklist.* @@ -290,7 +291,7 @@ class MainActivity : SimpleActivity() { val outputStream = contentResolver.openOutputStream(resultData.data!!) exportNotesTo(outputStream) } else if (requestCode == PICK_IMPORT_NOTES_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) { - importNotesFrom(resultData.data!!) + tryImportingAsJson(resultData.data!!) } } @@ -729,23 +730,29 @@ class MainActivity : SimpleActivity() { } private fun importUri(uri: Uri) { - when (uri.scheme) { - "file" -> openPath(uri.path!!) - "content" -> { - val realPath = getRealPathFromURI(uri) - if (hasPermission(PERMISSION_READ_STORAGE)) { - if (realPath != null) { - openPath(realPath) + tryImportingAsJson(uri, force = true, showToasts = false) { success -> + if (success) { + return@tryImportingAsJson + } + + when (uri.scheme) { + "file" -> openPath(uri.path!!) + "content" -> { + val realPath = getRealPathFromURI(uri) + if (hasPermission(PERMISSION_READ_STORAGE)) { + if (realPath != null) { + openPath(realPath) + } else { + R.string.unknown_error_occurred + } + } else if (realPath != null && realPath != "") { + checkFile(realPath, false) { + addNoteFromUri(uri, realPath.getFilenameFromPath()) + } } else { - R.string.unknown_error_occurred - } - } else if (realPath != null && realPath != "") { - checkFile(realPath, false) { - addNoteFromUri(uri, realPath.getFilenameFromPath()) - } - } else { - checkUri(uri) { - addNoteFromUri(uri) + checkUri(uri) { + addNoteFromUri(uri) + } } } } @@ -954,43 +961,66 @@ class MainActivity : SimpleActivity() { } } - private fun importNotes(path: String, filename: String) { - toast(R.string.importing) - ensureBackgroundThread { - NotesImporter(this).importNotes(path, filename) { - toast( - when (it) { - NotesImporter.ImportResult.IMPORT_OK -> R.string.importing_successful - NotesImporter.ImportResult.IMPORT_PARTIAL -> R.string.importing_some_entries_failed - else -> R.string.no_new_items - } - ) - initViewPager() - } - } - } - - private fun importNotesFrom(uri: Uri) { + private fun tryImportingAsJson(uri: Uri, force: Boolean = false, showToasts: Boolean = true, callback: ((success: Boolean) -> Unit)? = null) { + val path: String + val filename: String when (uri.scheme) { - "file" -> importNotes(uri.path!!, uri.path!!.getFilenameFromPath()) + "file" -> { + path = uri.path!! + filename = path.getFilenameFromPath() + } "content" -> { val tempFile = getTempFile("messages", "backup.txt") if (tempFile == null) { - toast(R.string.unknown_error_occurred) + maybeToast(R.string.unknown_error_occurred, showToasts) + callback?.invoke(false) return } try { - val filename = getFilenameFromUri(uri) + filename = getFilenameFromUri(uri) val inputStream = contentResolver.openInputStream(uri) val out = FileOutputStream(tempFile) inputStream!!.copyTo(out) - importNotes(tempFile.absolutePath, filename) + path = tempFile.absolutePath } catch (e: Exception) { showErrorToast(e) + callback?.invoke(false) + return } } - else -> toast(R.string.invalid_file_format) + else -> { + maybeToast(R.string.invalid_file_format, showToasts) + callback?.invoke(false) + return + } + } + + maybeToast(R.string.importing, showToasts) + ensureBackgroundThread { + NotesImporter(this).importNotes(path, filename, force) { importResult -> + if (importResult == ImportResult.IMPORT_FAIL) { + maybeToast(R.string.no_new_items, showToasts) + runOnUiThread { callback?.invoke(false) } + return@importNotes + } + + toast( + when (importResult) { + ImportResult.IMPORT_OK -> R.string.importing_successful + ImportResult.IMPORT_PARTIAL -> R.string.importing_some_entries_failed + else -> R.string.no_new_items + } + ) + initViewPager() + runOnUiThread { callback?.invoke(true) } + } + } + } + + private fun maybeToast(id: Int, show: Boolean) { + if (show) { + toast(id) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/notes/pro/helpers/NotesImporter.kt b/app/src/main/kotlin/com/simplemobiletools/notes/pro/helpers/NotesImporter.kt index 3a3e03e0..8ec4fca0 100644 --- a/app/src/main/kotlin/com/simplemobiletools/notes/pro/helpers/NotesImporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/notes/pro/helpers/NotesImporter.kt @@ -19,8 +19,9 @@ class NotesImporter(private val context: Context) { private val gson = Gson() private var notesImported = 0 private var notesFailed = 0 + private var notesSkipped = 0 - fun importNotes(path: String, filename: String, callback: (result: ImportResult) -> Unit) { + fun importNotes(path: String, filename: String, force: Boolean = false, callback: (result: ImportResult) -> Unit) { ensureBackgroundThread { try { val inputStream = if (path.contains("/")) { @@ -33,9 +34,9 @@ class NotesImporter(private val context: Context) { val json = reader.readText() val type = object : TypeToken>() {}.type val notes = gson.fromJson>(json, type) - val totalNotes = notes.size + val totalNotes = notes?.size ?: 0 if (totalNotes <= 0) { - callback.invoke(ImportResult.IMPORT_NOTHING_NEW) + callback.invoke(ImportResult.IMPORT_FAIL) return@ensureBackgroundThread } @@ -44,10 +45,17 @@ class NotesImporter(private val context: Context) { if (!exists) { context.notesDB.insertOrUpdate(note) notesImported++ + } else { + notesSkipped++ } } } } catch (e: JsonSyntaxException) { + if (force) { + callback(ImportResult.IMPORT_FAIL) + return@ensureBackgroundThread + } + // Import notes expects a json with note name, content etc, but lets be more flexible and accept the basic files with note content only too val inputStream = if (path.contains("/")) { File(path).inputStream() @@ -82,6 +90,7 @@ class NotesImporter(private val context: Context) { callback.invoke( when { + notesSkipped > 0 && notesImported == 0 -> ImportResult.IMPORT_NOTHING_NEW notesImported == 0 -> ImportResult.IMPORT_FAIL notesFailed > 0 -> ImportResult.IMPORT_PARTIAL else -> ImportResult.IMPORT_OK