diff --git a/README.md b/README.md index 3aac5044..6dc53088 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -*Please use the issues tab only for bug reports* +*Please use the pull requests tab only for translations or bug reports* ### Background Although there are many notes apps out there, they're all hideous, glitchy, low quality or all 3 at the same time. @@ -23,7 +23,7 @@ Well, Notally is none of these things. It's extremely light, minimalistic and el * APK size of 1.5 MB (1.9 MB Uncompressed) * Add labels to your notes for quick organisation * Archive notes to keep them around, but out of your way -* Export notes as plain text, HTML or PDF files with formatting +* Export notes as plain text, XML, HTML or PDF files with formatting * Create rich text notes with support for bold, italics, mono space and strike-through * Add clickable links to notes with support for phone numbers, email addresses and web urls diff --git a/app/build.gradle b/app/build.gradle index ddbb1874..41e189b0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,9 +13,9 @@ android { applicationId "com.omgodse.notally" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 33 - versionName "3.8" - resConfigs "en", "ca", "cs", "de", "es", "fr", "hu", "in", "it", "ja", "nb", "nl", "pl", "pt-rBR", "ru", "sv", "tl", "tr", "uk" + versionCode 34 + versionName "3.9" + resConfigs "en", "ca", "cs", "de", "es", "fr", "hu", "in", "it", "ja", "nb", "nl", "pl", "pt-rBR", "ru", "sk", "sv", "tl", "tr", "uk" vectorDrawables.generatedDensities = [] } @@ -56,7 +56,7 @@ dependencies { implementation "androidx.navigation:navigation-fragment-ktx:$navVersion" implementation "org.ocpsoft.prettytime:prettytime:4.0.6.Final" - implementation "com.google.android.material:material:1.3.0" + implementation "com.google.android.material:material:1.4.0" implementation project(":Post") } \ No newline at end of file diff --git a/app/src/main/java/com/omgodse/notally/fragments/NotallyFragment.kt b/app/src/main/java/com/omgodse/notally/fragments/NotallyFragment.kt index 046cfe65..08517645 100644 --- a/app/src/main/java/com/omgodse/notally/fragments/NotallyFragment.kt +++ b/app/src/main/java/com/omgodse/notally/fragments/NotallyFragment.kt @@ -11,6 +11,7 @@ import android.view.ViewGroup import android.widget.LinearLayout import android.widget.Toast import androidx.core.content.FileProvider +import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.LiveData @@ -140,10 +141,7 @@ abstract class NotallyFragment : Fragment(), OperationsParent, ItemListener { private fun setupObserver() { getObservable()?.observe(viewLifecycleOwner, { list -> adapter?.submitList(list) - - if (list.isNotEmpty()) { - binding?.RecyclerView?.visibility = View.VISIBLE - } else binding?.RecyclerView?.visibility = View.GONE + binding?.RecyclerView?.isVisible = list.isNotEmpty() }) } @@ -176,6 +174,7 @@ abstract class NotallyFragment : Fragment(), OperationsParent, ItemListener { MenuDialog(mContext) .addItem(Operation(R.string.pdf, R.drawable.pdf) { exportBaseNoteToPDF(baseNote) }) .addItem(Operation(R.string.txt, R.drawable.txt) { exportBaseNoteToTXT(baseNote) }) + .addItem(Operation(R.string.xml, R.drawable.xml) { exportBaseNoteToXML(baseNote) }) .addItem(Operation(R.string.html, R.drawable.html) { exportBaseNoteToHTML(baseNote) }) .show() } @@ -196,7 +195,7 @@ abstract class NotallyFragment : Fragment(), OperationsParent, ItemListener { } override fun onFailure(message: String?) { - Toast.makeText(context, R.string.something_went_wrong, Toast.LENGTH_SHORT).show() + Toast.makeText(mContext, R.string.something_went_wrong, Toast.LENGTH_SHORT).show() } }) } @@ -208,6 +207,13 @@ abstract class NotallyFragment : Fragment(), OperationsParent, ItemListener { } } + private fun exportBaseNoteToXML(baseNote: BaseNote) { + lifecycleScope.launch { + val file = model.getXMLFile(baseNote) + showFileOptionsDialog(file, "text/xml") + } + } + private fun exportBaseNoteToHTML(baseNote: BaseNote) { lifecycleScope.launch { val file = model.getHTMLFile(baseNote, settingsHelper.getShowDateCreated()) @@ -227,29 +233,29 @@ abstract class NotallyFragment : Fragment(), OperationsParent, ItemListener { private fun viewFile(uri: Uri, mimeType: String) { - val intent = Intent(Intent.ACTION_VIEW).apply { - setDataAndType(uri, mimeType) - flags = Intent.FLAG_GRANT_READ_URI_PERMISSION - } + val intent = Intent(Intent.ACTION_VIEW) + intent.setDataAndType(uri, mimeType) + intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION + val chooser = Intent.createChooser(intent, mContext.getString(R.string.view_note)) startActivity(chooser) } private fun shareFile(uri: Uri, mimeType: String) { - val intent = Intent(Intent.ACTION_SEND).apply { - type = mimeType - putExtra(Intent.EXTRA_STREAM, uri) - } + val intent = Intent(Intent.ACTION_SEND) + intent.type = mimeType + intent.putExtra(Intent.EXTRA_STREAM, uri) + val chooser = Intent.createChooser(intent, mContext.getString(R.string.share_note)) startActivity(chooser) } private fun saveFileToDevice(file: File, mimeType: String) { - val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply { - type = mimeType - addCategory(Intent.CATEGORY_OPENABLE) - putExtra(Intent.EXTRA_TITLE, file.nameWithoutExtension) - } + val intent = Intent(Intent.ACTION_CREATE_DOCUMENT) + intent.type = mimeType + intent.addCategory(Intent.CATEGORY_OPENABLE) + intent.putExtra(Intent.EXTRA_TITLE, file.nameWithoutExtension) + model.currentFile = file startActivityForResult(intent, Constants.RequestCodeExportFile) } diff --git a/app/src/main/java/com/omgodse/notally/viewmodels/BaseNoteModel.kt b/app/src/main/java/com/omgodse/notally/viewmodels/BaseNoteModel.kt index fe029dbd..287a4f2f 100644 --- a/app/src/main/java/com/omgodse/notally/viewmodels/BaseNoteModel.kt +++ b/app/src/main/java/com/omgodse/notally/viewmodels/BaseNoteModel.kt @@ -132,6 +132,15 @@ class BaseNoteModel(private val app: Application) : AndroidViewModel(app) { } + suspend fun getXMLFile(baseNote: BaseNote) = withContext(Dispatchers.IO) { + val fileName = getFileName(baseNote) + val file = File(getExportedPath(), "$fileName.xml") + val outputStream = FileOutputStream(file) + XMLUtils.writeBaseNoteToStream(baseNote, outputStream) + outputStream.close() + file + } + suspend fun getTXTFile(baseNote: BaseNote, showDateCreated: Boolean) = withContext(Dispatchers.IO) { val fileName = getFileName(baseNote) val file = File(getExportedPath(), "$fileName.txt") @@ -233,6 +242,7 @@ class BaseNoteModel(private val app: Application) : AndroidViewModel(app) { private fun getHTML(baseNote: BaseNote, showDateCreated: Boolean) = buildString { val date = formatter.format(baseNote.timestamp) + append("") append("") append("

${Html.escapeHtml(baseNote.title)}

") @@ -243,7 +253,7 @@ class BaseNoteModel(private val app: Application) : AndroidViewModel(app) { when (baseNote.type) { Type.NOTE -> { val body = baseNote.body.applySpans(baseNote.spans).toHtml() - append("

$body

") + append(body) } Type.LIST -> { append("
    ") diff --git a/app/src/main/java/com/omgodse/notally/xml/XMLUtils.kt b/app/src/main/java/com/omgodse/notally/xml/XMLUtils.kt index db98b4b5..99320abc 100644 --- a/app/src/main/java/com/omgodse/notally/xml/XMLUtils.kt +++ b/app/src/main/java/com/omgodse/notally/xml/XMLUtils.kt @@ -113,6 +113,22 @@ object XMLUtils { xmlSerializer.endDocument() } + fun writeBaseNoteToStream(baseNote: BaseNote, stream: OutputStream) { + val xmlSerializer = Xml.newSerializer() + + xmlSerializer.setOutput(stream, null) + xmlSerializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true) + xmlSerializer.startDocument("UTF-8", true) + + when (baseNote.type) { + Type.NOTE -> appendNote(baseNote, xmlSerializer) + Type.LIST -> appendList(baseNote, xmlSerializer) + } + + xmlSerializer.endDocument() + } + + private fun appendNote(note: BaseNote, xmlSerializer: XmlSerializer) { xmlSerializer.startTag(null, XMLTags.Note) diff --git a/app/src/main/res/drawable/html.xml b/app/src/main/res/drawable/html.xml index c6010a53..57ab66ac 100644 --- a/app/src/main/res/drawable/html.xml +++ b/app/src/main/res/drawable/html.xml @@ -5,5 +5,5 @@ android:viewportHeight="24"> + android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM18.92,8h-2.95c-0.32,-1.25 -0.78,-2.45 -1.38,-3.56 1.84,0.63 3.37,1.91 4.33,3.56zM12,4.04c0.83,1.2 1.48,2.53 1.91,3.96h-3.82c0.43,-1.43 1.08,-2.76 1.91,-3.96zM4.26,14C4.1,13.36 4,12.69 4,12s0.1,-1.36 0.26,-2h3.38c-0.08,0.66 -0.14,1.32 -0.14,2s0.06,1.34 0.14,2L4.26,14zM5.08,16h2.95c0.32,1.25 0.78,2.45 1.38,3.56 -1.84,-0.63 -3.37,-1.9 -4.33,-3.56zM8.03,8L5.08,8c0.96,-1.66 2.49,-2.93 4.33,-3.56C8.81,5.55 8.35,6.75 8.03,8zM12,19.96c-0.83,-1.2 -1.48,-2.53 -1.91,-3.96h3.82c-0.43,1.43 -1.08,2.76 -1.91,3.96zM14.34,14L9.66,14c-0.09,-0.66 -0.16,-1.32 -0.16,-2s0.07,-1.35 0.16,-2h4.68c0.09,0.65 0.16,1.32 0.16,2s-0.07,1.34 -0.16,2zM14.59,19.56c0.6,-1.11 1.06,-2.31 1.38,-3.56h2.95c-0.96,1.65 -2.49,2.93 -4.33,3.56zM16.36,14c0.08,-0.66 0.14,-1.32 0.14,-2s-0.06,-1.34 -0.14,-2h3.38c0.16,0.64 0.26,1.31 0.26,2s-0.1,1.36 -0.26,2h-3.38z" /> \ No newline at end of file diff --git a/app/src/main/res/drawable/xml.xml b/app/src/main/res/drawable/xml.xml new file mode 100644 index 00000000..c6010a53 --- /dev/null +++ b/app/src/main/res/drawable/xml.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ffc005b4..46e3119a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -37,6 +37,7 @@ Export PDF TXT + XML HTML Save to device Edit label diff --git a/build.gradle b/build.gradle index 74194774..fa4627cd 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { minSdkVersion = 21 targetSdkVersion = 30 compileSdkVersion = 30 - kotlinVersion = "1.5.10" + kotlinVersion = "1.5.21" buildToolsVersion = "30.0.3" } @@ -14,7 +14,7 @@ buildscript { } dependencies { - classpath "com.android.tools.build:gradle:4.2.1" + classpath "com.android.tools.build:gradle:4.2.2" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" } } diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index 1bcdb0d6..ddbd51ea 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -13,6 +13,7 @@ Add clickable links to notes with support for phone numbers, email addresses and • PDF • TXT +• XML • HTML Convenience diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png index 60ac685f..8ab2492b 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png index 348958e2..dc7930d8 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png index b677b21e..95d4b9b1 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png differ