diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c72c9272..e99875af 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -27,7 +27,35 @@ android { versionCode = project.findProperty("app.versionCode").toString().toInt() versionName = project.findProperty("app.versionName").toString() resourceConfigurations += listOf( - "en", "ca", "cs", "da", "de", "el", "es", "fr", "hu", "in", "it", "ja", "my", "nb", "nl", "nn", "pl", "pt-rBR", "pt-rPT", "ro", "ru", "sk", "sv", "tl", "tr", "uk", "vi", "zh-rCN", "zh-rTW" + "en", + "ca", + "cs", + "da", + "de", + "el", + "es", + "fr", + "hu", + "in", + "it", + "ja", + "my", + "nb", + "nl", + "nn", + "pl", + "pt-rBR", + "pt-rPT", + "ro", + "ru", + "sk", + "sv", + "tl", + "tr", + "uk", + "vi", + "zh-rCN", + "zh-rTW" ) vectorDrawables.generatedDensities?.clear() ndk { @@ -64,7 +92,7 @@ android { ) signingConfig = signingConfigs.getByName("release") } - create("beta"){ + create("beta") { initWith(getByName("release")) applicationIdSuffix = ".beta" versionNameSuffix = "-BETA" @@ -82,10 +110,15 @@ android { if (buildType.isMinifyEnabled) { // Function to copy proguard mapping.txt file fun copyMapping(suffix: String) { - val mappingFile = layout.buildDirectory.file("outputs/mapping/${buildType.name}/mapping.txt").get().asFile + val mappingFile = + layout.buildDirectory.file("outputs/mapping/${buildType.name}/mapping.txt") + .get().asFile if (mappingFile.exists()) { val target = - File(project.projectDir, "obfuscation/mapping-${buildType.name}-$suffix.txt") + File( + project.projectDir, + "obfuscation/mapping-${buildType.name}-$suffix.txt" + ) target.parentFile.mkdirs() mappingFile.copyTo(target, overwrite = true) println("Copied mapping to: ${target.absolutePath}") @@ -100,7 +133,7 @@ android { tasks.matching { it.name == "bundle${name.capitalize()}" } .forEach { bundleTask -> bundleTask.doLast { - copyMapping( "bundle") + copyMapping("bundle") } } @@ -118,13 +151,17 @@ android { return@doLast } // Target zip file - val outputZip = File(project.projectDir, "obfuscation/${buildType.name}-debug-symbols.zip") + val outputZip = File( + project.projectDir, + "obfuscation/${buildType.name}-debug-symbols.zip" + ) outputZip.parentFile.mkdirs() ZipOutputStream(outputZip.outputStream()).use { zipOut -> nativeLibsDir.walkTopDown().forEach { file -> if (file.isFile) { // Preserve "lib/ABI/..." folder structure in the zip - val relativePath = nativeLibsDir.toPath().relativize(file.toPath()).toString() + val relativePath = + nativeLibsDir.toPath().relativize(file.toPath()).toString() zipOut.putNextEntry(ZipEntry(relativePath)) file.inputStream().use { it.copyTo(zipOut) } zipOut.closeEntry() diff --git a/app/src/main/java/com/philkes/notallyx/data/model/Folder.kt b/app/src/main/java/com/philkes/notallyx/data/model/Folder.kt index 2de9bdca..8b5490db 100644 --- a/app/src/main/java/com/philkes/notallyx/data/model/Folder.kt +++ b/app/src/main/java/com/philkes/notallyx/data/model/Folder.kt @@ -5,6 +5,7 @@ import java.io.Serializable enum class Folder : Serializable { NOTES, DELETED, + HIDDEN, ARCHIVED; companion object { diff --git a/app/src/main/java/com/philkes/notallyx/presentation/UiExtensions.kt b/app/src/main/java/com/philkes/notallyx/presentation/UiExtensions.kt index 316cc6ff..820e3a53 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/UiExtensions.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/UiExtensions.kt @@ -402,6 +402,7 @@ fun Folder.movedToResId(): Int { Folder.DELETED -> R.plurals.deleted_selected_notes Folder.ARCHIVED -> R.plurals.archived_selected_notes Folder.NOTES -> R.plurals.restored_selected_notes + Folder.HIDDEN -> R.plurals.hidden_selected_notes } } diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/MainActivity.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/MainActivity.kt index d187a93f..56926ff4 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/MainActivity.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/MainActivity.kt @@ -295,10 +295,13 @@ class MainActivity : LockedActivity() { add(2, R.id.Archived, CATEGORY_SYSTEM + 2, R.string.archived) .setCheckable(true) .setIcon(R.drawable.archive) - add(3, R.id.Reminders, CATEGORY_SYSTEM + 3, R.string.reminders) + add(2, R.id.Hidden, CATEGORY_SYSTEM + 3, R.string.hiddens) + .setCheckable(true) + .setIcon(R.drawable.hidden) + add(3, R.id.Reminders, CATEGORY_SYSTEM + 4, R.string.reminders) .setCheckable(true) .setIcon(R.drawable.notifications) - add(3, R.id.Settings, CATEGORY_SYSTEM + 4, R.string.settings) + add(4, R.id.Settings, CATEGORY_SYSTEM + 5, R.string.settings) .setCheckable(true) .setIcon(R.drawable.settings) } @@ -580,6 +583,7 @@ class MainActivity : LockedActivity() { } true } + else -> super.onOptionsItemSelected(item) } } diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/ModelFolderObserver.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/ModelFolderObserver.kt index d418109a..458deb5d 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/ModelFolderObserver.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/ModelFolderObserver.kt @@ -53,6 +53,7 @@ class ModelFolderObserver( Folder.NOTES -> initNotesFolderMenu() Folder.ARCHIVED -> initArchivedFolderMenu() Folder.DELETED -> initDeletedFolderMenu() + Folder.HIDDEN -> initHiddenFolderMenu() } } @@ -64,6 +65,7 @@ class ModelFolderObserver( baseModel.duplicateSelectedBaseNotes() } menu.add(R.string.archive, R.drawable.archive) { moveNotes(Folder.ARCHIVED) } + menu.add(R.string.hidden, R.drawable.hidden) { moveNotes(Folder.HIDDEN) } menu.addChangeColor() val pinnedToStatus = menu.addPinnedToStatus() val share = menu.addShare() @@ -100,6 +102,23 @@ class ModelFolderObserver( model.actionMode.count.observeCount(activity, share) } + private fun initHiddenFolderMenu() { + menu.add( + R.string.unhidden, + R.drawable.unhidden, + MenuItem.SHOW_AS_ACTION_ALWAYS, + ) { + moveNotes(Folder.NOTES) + } + menu.addDelete(MenuItem.SHOW_AS_ACTION_ALWAYS) + menu.addLabels(MenuItem.SHOW_AS_ACTION_ALWAYS) + menu.addExportMenu() + menu.addChangeColor() + val share = menu.add(R.string.share, R.drawable.share) { share() } + model.actionMode.count.observeCount(activity, share) + + } + private fun Menu.addPinned(showAsAction: Int = MenuItem.SHOW_AS_ACTION_IF_ROOM): MenuItem { return add(R.string.pin, R.drawable.pin, showAsAction) {} } @@ -238,10 +257,10 @@ class ModelFolderObserver( val ids = baseModel.moveBaseNotes(folderTo) { baseModel.actionMode.loading.postValue(false) } Snackbar.make( - activity.findViewById(R.id.DrawerLayout), - activity.getQuantityString(folderTo.movedToResId(), ids.size), - Snackbar.LENGTH_SHORT, - ) + activity.findViewById(R.id.DrawerLayout), + activity.getQuantityString(folderTo.movedToResId(), ids.size), + Snackbar.LENGTH_SHORT, + ) .apply { setAction(R.string.undo) { baseModel.moveBaseNotes(ids, folderFrom) } } .show() } catch (_: Exception) { @@ -262,13 +281,13 @@ class ModelFolderObserver( activity.lifecycleScope.launch { val deletedNotes = baseModel.deleteSelectedBaseNotes() Snackbar.make( - activity.findViewById(R.id.DrawerLayout), - activity.getQuantityString( - R.plurals.deleted_selected_notes, - removedNotes.size, - ), - Snackbar.LENGTH_SHORT, - ) + activity.findViewById(R.id.DrawerLayout), + activity.getQuantityString( + R.plurals.deleted_selected_notes, + removedNotes.size, + ), + Snackbar.LENGTH_SHORT, + ) .apply { setAction(R.string.undo) { baseModel.saveNotes(removedNotes) } addCallback( diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/HiddenFragment.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/HiddenFragment.kt new file mode 100644 index 00000000..1ebc243c --- /dev/null +++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/HiddenFragment.kt @@ -0,0 +1,51 @@ +package com.philkes.notallyx.presentation.activity.main.fragment + +import android.os.Bundle +import android.view.View +import android.view.View.INVISIBLE +import android.view.View.VISIBLE +import android.view.WindowManager +import androidx.lifecycle.LiveData +import androidx.navigation.fragment.findNavController +import com.philkes.notallyx.R +import com.philkes.notallyx.data.model.Folder +import com.philkes.notallyx.data.model.Item +import com.philkes.notallyx.utils.security.showBiometricOrPinPromptHidden + +open class HiddenFragment : NotallyFragment() { + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + model.folder.value = Folder.HIDDEN + requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_SECURE) + } + + override fun onDestroyView() { + super.onDestroyView() + requireActivity().window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE) + } + + override fun getBackground() = R.drawable.label_off + + override fun getObservable(): LiveData> { + return model.hiddenNotes!! + } + + override fun onStart() { + super.onStart() + hide() + showBiometricOrPinPromptHidden( + this, + R.string.hidden_lock_title, + onSuccess = { show() }, + onFailure = { findNavController().popBackStack() }, + ) + } + + protected fun show() { + binding?.root?.visibility = VISIBLE + } + + protected fun hide() { + binding?.root?.visibility = INVISIBLE + } +} diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/SearchFragment.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/SearchFragment.kt index db5c7f7d..ec86e623 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/SearchFragment.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/SearchFragment.kt @@ -26,12 +26,13 @@ class SearchFragment : NotallyFragment() { val initialLabel = arguments?.getString(EXTRA_INITIAL_LABEL) model.currentLabel = initialLabel - if (initialLabel?.isEmpty() == true) { + if (initialLabel?.isEmpty() == true && model.folder.value != Folder.HIDDEN) { val checked = when (initialFolder ?: model.folder.value) { Folder.NOTES -> R.id.Notes Folder.DELETED -> R.id.Deleted Folder.ARCHIVED -> R.id.Archived + Folder.HIDDEN -> R.id.Hidden } binding?.ChipGroup?.apply { @@ -40,6 +41,7 @@ class SearchFragment : NotallyFragment() { R.id.Notes -> model.folder.value = Folder.NOTES R.id.Deleted -> model.folder.value = Folder.DELETED R.id.Archived -> model.folder.value = Folder.ARCHIVED + R.id.Hidden -> model.folder.value = Folder.HIDDEN } } check(checked) diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt index ee152270..a0ad9c3e 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt @@ -1,5 +1,6 @@ package com.philkes.notallyx.presentation.activity.note +import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.content.res.ColorStateList @@ -12,6 +13,7 @@ import android.os.Looper import android.text.Editable import android.text.Spanned import android.text.style.URLSpan +import android.util.AttributeSet import android.util.Log import android.view.MenuItem import android.view.View @@ -19,6 +21,7 @@ import android.view.View.GONE import android.view.ViewGroup import android.view.ViewGroup.LayoutParams import android.view.ViewGroup.VISIBLE +import android.view.WindowManager import android.view.inputmethod.InputMethodManager import androidx.activity.viewModels import androidx.annotation.ColorInt @@ -34,6 +37,7 @@ import androidx.recyclerview.widget.PagerSnapHelper import androidx.recyclerview.widget.RecyclerView import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.philkes.notallyx.R +import com.philkes.notallyx.data.model.Folder import com.philkes.notallyx.data.model.NoteViewMode import com.philkes.notallyx.data.model.Type import com.philkes.notallyx.data.model.generateBaseNote @@ -124,6 +128,27 @@ abstract class EditActivity(private val type: Type) : LockedActivity handleSharedNote() + else -> intent.getStringExtra(EXTRA_DISPLAYED_LABEL)?.let { notallyModel.setLabels(listOf(it)) @@ -478,6 +504,7 @@ abstract class EditActivity(private val type: Type) : LockedActivity (manualSize ?: binding.EnterBody.lineCount) > (if (isInLandscapeMode) 30 else 75) + Type.LIST -> (manualSize ?: notallyModel.items.size) > (if (isInLandscapeMode) 15 else 25) @@ -647,6 +674,7 @@ abstract class EditActivity(private val type: Type) : LockedActivity notallyModel.title = text.trim().toString() } + val textMaxLengthFilter = application.textMaxLengthFilter() binding.EnterTitle.filters = textMaxLengthFilter binding.EnterBody.filters = textMaxLengthFilter @@ -688,6 +716,7 @@ abstract class EditActivity(private val type: Type) : LockedActivity Pair(notallyModel.timestamp, R.string.creation_date) NotesSortBy.MODIFIED_DATE -> Pair(notallyModel.modifiedTimestamp, R.string.modified_date) + else -> Pair(null, null) } binding.Date.apply { @@ -943,6 +972,7 @@ abstract class EditActivity(private val type: Type) : LockedActivity { binding.EnterBody.visibility = GONE binding.CheckedListView.visibility = diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/NoteActionHandler.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/NoteActionHandler.kt index 3522e03d..b499ec19 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/NoteActionHandler.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/NoteActionHandler.kt @@ -239,9 +239,11 @@ class NoteActionHandler( ExportBottomSheet(activity.colorInt, ::export) .show(activity.supportFragmentManager, ExportBottomSheet.TAG) } + EditAction.SHARE -> share() EditAction.DELETE -> delete() EditAction.ARCHIVE -> archive() + EditAction.HIDDEN -> hidden() EditAction.TOGGLE_VIEW_MODE -> toggleViewMode() EditAction.CONVERT -> convertTo() EditAction.DELETE_FOREVER -> deleteForever() @@ -361,6 +363,14 @@ class NoteActionHandler( } } + private fun hidden() { + if (notallyModel.folder == Folder.HIDDEN) { + restore() + } else { + moveNote(Folder.HIDDEN) + } + } + private fun moveNote(toFolder: Folder) { if (toFolder != Folder.NOTES) { this.activity.cancelPinAndReminders(notallyModel.id, notallyModel.reminders.value) diff --git a/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/BaseNoteModel.kt b/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/BaseNoteModel.kt index 2f0cbceb..2915e0cb 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/BaseNoteModel.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/BaseNoteModel.kt @@ -113,6 +113,8 @@ class BaseNoteModel(private val app: Application) : AndroidViewModel(app) { var baseNotes: Content? = Content(MutableLiveData(), ::transform) var deletedNotes: Content? = Content(MutableLiveData(), ::transform) var archivedNotes: Content? = Content(MutableLiveData(), ::transform) + + var hiddenNotes: Content? = Content(MutableLiveData(), ::transform) var reminderNotes: Content? = Content(MutableLiveData(), ::transform) val folder = NotNullLiveData(Folder.NOTES) @@ -187,6 +189,12 @@ class BaseNoteModel(private val app: Application) : AndroidViewModel(app) { archivedNotes!!.setObserver(baseNoteDao.getFrom(Folder.ARCHIVED)) } + if (hiddenNotes == null) { + hiddenNotes = Content(baseNoteDao.getFrom(Folder.HIDDEN), ::transform) + } else { + hiddenNotes!!.setObserver(baseNoteDao.getFrom(Folder.HIDDEN)) + } + if (reminderNotes == null) { reminderNotes = Content(baseNoteDao.getAllBaseNotesWithReminders(), ::transform) } else { diff --git a/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/Preference.kt b/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/Preference.kt index 97a65662..8ca79d9c 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/Preference.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/Preference.kt @@ -468,6 +468,7 @@ fun ListItemSort.callback(adapterChecked: CheckedListItemAdapter) = when (this) { ListItemSort.AUTO_SORT_BY_CHECKED_TIMESTAMP -> ListItemCheckedTimestampSortCallback(adapterChecked) + else -> ListItemParentSortCallback(adapterChecked) } @@ -503,6 +504,7 @@ enum class EditAction(override val textResId: Int, val drawableResId: Int) : Sta SHARE(R.string.share, R.drawable.share), DELETE(R.string.delete, R.drawable.delete), ARCHIVE(R.string.archive, R.drawable.archive), + HIDDEN(R.string.hidden, R.drawable.hidden), TOGGLE_VIEW_MODE(R.string.edit, R.drawable.visibility), CONVERT(R.string.convert_to_list_note, R.drawable.convert_to_text), DELETE_FOREVER(R.string.delete_forever, R.drawable.delete), @@ -523,11 +525,15 @@ enum class EditAction(override val textResId: Int, val drawableResId: Int) : Sta if (isPinnedToStatus) R.drawable.pinboard_filled else R.drawable.pinboard ARCHIVE -> if (folder == Folder.ARCHIVED) R.drawable.unarchive else R.drawable.archive + RESTORE -> if (folder == Folder.ARCHIVED) R.drawable.unarchive else R.drawable.restore + + HIDDEN -> if (folder == Folder.HIDDEN) R.drawable.unhidden else R.drawable.hidden TOGGLE_VIEW_MODE -> if (viewMode == NoteViewMode.READ_ONLY) R.drawable.edit else R.drawable.visibility + else -> drawableResId } val title = @@ -537,12 +543,15 @@ enum class EditAction(override val textResId: Int, val drawableResId: Int) : Sta if (isPinnedToStatus) R.string.unpin_from_status_bar else R.string.pin_to_status_bar ARCHIVE -> if (folder == Folder.ARCHIVED) R.string.unarchive else R.string.archive + HIDDEN -> if (folder == Folder.HIDDEN) R.string.unhidden else R.string.hidden RESTORE -> if (folder == Folder.ARCHIVED) R.string.unarchive else R.string.restore TOGGLE_VIEW_MODE -> if (viewMode == NoteViewMode.READ_ONLY) R.string.edit else R.string.read_only + CONVERT -> if (type == Type.LIST) R.string.convert_to_text_note else R.string.convert_to_list_note + else -> textResId } return title to icon diff --git a/app/src/main/java/com/philkes/notallyx/utils/security/LockUtils.kt b/app/src/main/java/com/philkes/notallyx/utils/security/LockUtils.kt index fd695f4d..f14f7005 100644 --- a/app/src/main/java/com/philkes/notallyx/utils/security/LockUtils.kt +++ b/app/src/main/java/com/philkes/notallyx/utils/security/LockUtils.kt @@ -12,6 +12,7 @@ import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import com.philkes.notallyx.R +import com.philkes.notallyx.utils.canAuthenticateWithBiometrics import javax.crypto.Cipher fun Activity.showBiometricOrPinPrompt( @@ -56,6 +57,81 @@ fun Fragment.showBiometricOrPinPrompt( ) } +fun showBiometricOrPinPromptHidden( + fragment: Fragment, + titleResId: Int, + onSuccess: () -> Unit, + onFailure: (errorCode: Int?) -> Unit, +) { + when { + Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> { + if ( + BiometricManager.BIOMETRIC_SUCCESS != + BiometricManager.from(fragment.requireContext()) + .canAuthenticate( + BiometricManager.Authenticators.DEVICE_CREDENTIAL or + BiometricManager.Authenticators.BIOMETRIC_STRONG + ) + ) { + onSuccess.invoke() + return + } + val promptInfo = + BiometricPrompt.PromptInfo.Builder() + .apply { + setTitle(fragment.getString(titleResId)) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + setAllowedAuthenticators( + BiometricManager.Authenticators.BIOMETRIC_STRONG or + BiometricManager.Authenticators.DEVICE_CREDENTIAL + ) + } else { + setNegativeButtonText(fragment.getString(R.string.cancel)) + setAllowedAuthenticators( + BiometricManager.Authenticators.BIOMETRIC_STRONG + ) + } + } + .build() + val authCallback = + object : BiometricPrompt.AuthenticationCallback() { + override fun onAuthenticationSucceeded( + result: BiometricPrompt.AuthenticationResult + ) { + super.onAuthenticationSucceeded(result) + onSuccess.invoke() + } + + override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { + super.onAuthenticationError(errorCode, errString) + onFailure.invoke(errorCode) + } + } + val prompt = + BiometricPrompt( + fragment, + ContextCompat.getMainExecutor(fragment.requireContext()), + authCallback, + ) + + prompt.authenticate(promptInfo) + } + + else -> { + if ( + fragment.requireContext().canAuthenticateWithBiometrics() != + android.hardware.biometrics.BiometricManager.BIOMETRIC_SUCCESS + ) { + onSuccess.invoke() + return + } + // API 21-22: No biometric support, fallback to PIN/Password + promptPinAuthentication(fragment.requireContext(), null, titleResId, onFailure) + onSuccess.invoke() + } + } +} + private fun showBiometricOrPinPrompt( isForDecrypt: Boolean, context: FragmentActivity, @@ -103,11 +179,6 @@ private fun showBiometricOrPinPrompt( onSuccess.invoke(result.cryptoObject!!.cipher!!) } - override fun onAuthenticationFailed() { - super.onAuthenticationFailed() - onFailure.invoke(null) - } - override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { super.onAuthenticationError(errorCode, errString) onFailure.invoke(errorCode) @@ -127,7 +198,7 @@ private fun showBiometricOrPinPrompt( private fun promptPinAuthentication( context: Context, - activityResultLauncher: ActivityResultLauncher, + activityResultLauncher: ActivityResultLauncher?, titleResId: Int, onFailure: (errorCode: Int?) -> Unit, ) { @@ -141,7 +212,7 @@ private fun promptPinAuthentication( null, ) if (intent != null) { - activityResultLauncher.launch(intent) + activityResultLauncher?.launch(intent) } else { onFailure.invoke(null) } @@ -157,7 +228,7 @@ private fun promptPinAuthentication( null, ) if (intent != null) { - activityResultLauncher.launch(intent) + activityResultLauncher?.launch(intent) } else { onFailure.invoke(null) } diff --git a/app/src/main/res/drawable/hidden.xml b/app/src/main/res/drawable/hidden.xml new file mode 100644 index 00000000..969639d4 --- /dev/null +++ b/app/src/main/res/drawable/hidden.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/unhidden.xml b/app/src/main/res/drawable/unhidden.xml new file mode 100644 index 00000000..7a314497 --- /dev/null +++ b/app/src/main/res/drawable/unhidden.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/fragment_notes.xml b/app/src/main/res/layout/fragment_notes.xml index b73e7302..fd5df878 100644 --- a/app/src/main/res/layout/fragment_notes.xml +++ b/app/src/main/res/layout/fragment_notes.xml @@ -5,62 +5,62 @@ android:layout_height="match_parent"> + android:id="@+id/EnterSearchKeywordLayout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingStart="8dp" + android:paddingEnd="8dp" + android:paddingBottom="4dp" + android:paddingTop="4dp" + android:visibility="gone" + app:layout_constraintTop_toTopOf="parent" + style="@style/RoundedTextInput"> + + android:id="@+id/EnterSearchKeyword" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@null" + app:boxStrokeWidth="0dp" + android:hint="@string/search" + android:inputType="textFilter" + android:paddingTop="10dp" + android:paddingBottom="10dp" + android:textAppearance="?attr/textAppearanceBodyLarge" /> + android:id="@+id/ChipGroup" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layout_constraintTop_toBottomOf="@id/EnterSearchKeywordLayout" + android:background="?attr/colorSurface" + android:paddingStart="12dp" + android:paddingEnd="12dp" + android:visibility="gone" + app:selectionRequired="true" + app:singleSelection="true"> + android:id="@+id/Notes" + style="@style/FilterChip" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/notes" /> + android:id="@+id/Deleted" + style="@style/FilterChip" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/deleted" /> + android:id="@+id/Archived" + style="@style/FilterChip" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/archived" /> @@ -74,8 +74,7 @@ app:layout_constraintTop_toBottomOf="@id/ChipGroup" app:layout_constraintBottom_toTopOf="@id/MainListView" android:visibility="gone" - android:paddingHorizontal="4dp" - > + android:paddingHorizontal="4dp"> + + + app:fastScrollVerticalThumbDrawable="@drawable/scroll_thumb"> + + android:id="@+id/ImageView" + android:layout_width="96dp" + android:layout_height="96dp" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + android:contentDescription="Background" + app:tint="?attr/colorPrimary" /> + android:label="@string/deleted"> + android:id="@+id/DeletedToSearch" + app:destination="@id/Search" + app:enterAnim="@anim/nav_default_enter_anim" + app:exitAnim="@anim/nav_default_exit_anim" + app:popEnterAnim="@anim/nav_default_pop_enter_anim" + app:popExitAnim="@anim/nav_default_pop_exit_anim" /> + android:label="@string/archived"> + android:id="@+id/ArchivedToSearch" + app:destination="@id/Search" + app:enterAnim="@anim/nav_default_enter_anim" + app:exitAnim="@anim/nav_default_exit_anim" + app:popEnterAnim="@anim/nav_default_pop_enter_anim" + app:popExitAnim="@anim/nav_default_pop_exit_anim" /> - + android:id="@+id/Reminders" + android:name="com.philkes.notallyx.presentation.activity.main.fragment.RemindersFragment" + android:label="@string/reminders"> + android:name="initialFolder" + app:argType="com.philkes.notallyx.data.model.Folder" /> + + \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index ca6c2d4a..96cfa7c9 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -272,7 +272,7 @@ %1$s notas son demasiado grandes para guardarlas, han sido truncadas a %2$s caracteres %1$s de mes - Último %1$s de mes + Último %1$s del mes Abrir enlace Abrir nota Otros @@ -379,4 +379,12 @@ Anual Años Tus notas asociadas con esta etiqueta no serán eliminadas + Ocultas + Ocultar + Desocultar + + %1$d nota oculta + %1$d notas ocultas + + Mostrar ocultas diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 084ea00c..f7b263dd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -18,6 +18,10 @@ Archived %1$d note Archived %1$d notes + + Hidden %1$d note + Hidden %1$d notes + Ascending Attach file @@ -405,4 +409,8 @@ Yearly Years Your notes attached to this label will not be deleted + Hidden + Hidden + Unhidden + Show hidden diff --git a/app/translations.xlsx b/app/translations.xlsx index e5c1b854..34cefffd 100644 Binary files a/app/translations.xlsx and b/app/translations.xlsx differ