Merge branch 'feature/Material_You_1469' into develop

This commit is contained in:
J-Jamet
2023-07-24 21:12:29 +02:00
202 changed files with 2808 additions and 3913 deletions

View File

@@ -33,7 +33,6 @@ android {
buildTypes { buildTypes {
release { release {
minifyEnabled = false minifyEnabled = false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} }
} }

View File

@@ -160,9 +160,11 @@
android:configChanges="keyboardHidden" android:configChanges="keyboardHidden"
android:excludeFromRecents="true"/> android:excludeFromRecents="true"/>
<activity <activity
android:name="com.kunzisoft.keepass.settings.SettingsAdvancedUnlockActivity" /> android:name="com.kunzisoft.keepass.settings.AdvancedUnlockSettingsActivity" />
<activity <activity
android:name="com.kunzisoft.keepass.settings.AutofillSettingsActivity" /> android:name="com.kunzisoft.keepass.settings.AutofillSettingsActivity" />
<activity
android:name="com.kunzisoft.keepass.settings.AppearanceSettingsActivity" />
<activity <activity
android:name="com.kunzisoft.keepass.hardware.HardwareKeyActivity" android:name="com.kunzisoft.keepass.hardware.HardwareKeyActivity"
android:theme="@style/Theme.Transparent" /> android:theme="@style/Theme.Transparent" />

View File

@@ -112,9 +112,9 @@ class EntryActivity : DatabaseLockActivity() {
} }
private var mIcon: IconImage? = null private var mIcon: IconImage? = null
private var mColorAccent: Int = 0 private var mColorSecondary: Int = 0
private var mControlColor: Int = 0 private var mColorSurface: Int = 0
private var mColorPrimary: Int = 0 private var mColorOnSurface: Int = 0
private var mColorBackground: Int = 0 private var mColorBackground: Int = 0
private var mBackgroundColor: Int? = null private var mBackgroundColor: Int? = null
private var mForegroundColor: Int? = null private var mForegroundColor: Int? = null
@@ -146,17 +146,17 @@ class EntryActivity : DatabaseLockActivity() {
toolbar?.title = " " toolbar?.title = " "
// Retrieve the textColor to tint the toolbar // Retrieve the textColor to tint the toolbar
val taColorAccent = theme.obtainStyledAttributes(intArrayOf(R.attr.colorAccent)) val taColorSecondary = theme.obtainStyledAttributes(intArrayOf(R.attr.colorSecondary))
val taControlColor = theme.obtainStyledAttributes(intArrayOf(R.attr.toolbarColorControl)) val taColorSurface = theme.obtainStyledAttributes(intArrayOf(R.attr.colorSurface))
val taColorPrimary = theme.obtainStyledAttributes(intArrayOf(R.attr.colorPrimary)) val taColorOnSurface = theme.obtainStyledAttributes(intArrayOf(R.attr.colorOnSurface))
val taColorBackground = theme.obtainStyledAttributes(intArrayOf(android.R.attr.windowBackground)) val taColorBackground = theme.obtainStyledAttributes(intArrayOf(android.R.attr.windowBackground))
mColorAccent = taColorAccent.getColor(0, Color.BLACK) mColorSecondary = taColorSecondary.getColor(0, Color.BLACK)
mControlColor = taControlColor.getColor(0, Color.BLACK) mColorSurface = taColorSurface.getColor(0, Color.BLACK)
mColorPrimary = taColorPrimary.getColor(0, Color.BLACK) mColorOnSurface = taColorOnSurface.getColor(0, Color.BLACK)
mColorBackground = taColorBackground.getColor(0, Color.BLACK) mColorBackground = taColorBackground.getColor(0, Color.BLACK)
taColorAccent.recycle() taColorSecondary.recycle()
taControlColor.recycle() taColorSurface.recycle()
taColorPrimary.recycle() taColorOnSurface.recycle()
taColorBackground.recycle() taColorBackground.recycle()
// Init Tags adapter // Init Tags adapter
@@ -225,10 +225,10 @@ class EntryActivity : DatabaseLockActivity() {
this.mEntryIsHistory = entryIsHistory this.mEntryIsHistory = entryIsHistory
// Assign history dedicated view // Assign history dedicated view
historyView?.visibility = if (entryIsHistory) View.VISIBLE else View.GONE historyView?.visibility = if (entryIsHistory) View.VISIBLE else View.GONE
// TODO History badge
/*
if (entryIsHistory) { if (entryIsHistory) {
collapsingToolbarLayout?.contentScrim = }*/
ColorDrawable(mColorAccent)
}
val entryInfo = entryInfoHistory.entryInfo val entryInfo = entryInfoHistory.entryInfo
// Manage entry copy to start notification if allowed (at the first start) // Manage entry copy to start notification if allowed (at the first start)
@@ -366,8 +366,8 @@ class EntryActivity : DatabaseLockActivity() {
} }
private fun applyToolbarColors() { private fun applyToolbarColors() {
appBarLayout?.setBackgroundColor(mBackgroundColor ?: mColorPrimary) collapsingToolbarLayout?.setBackgroundColor(mBackgroundColor ?: mColorSurface)
collapsingToolbarLayout?.contentScrim = ColorDrawable(mBackgroundColor ?: mColorPrimary) collapsingToolbarLayout?.contentScrim = ColorDrawable(mBackgroundColor ?: mColorSurface)
val backgroundDarker = if (mBackgroundColor != null) { val backgroundDarker = if (mBackgroundColor != null) {
ColorUtils.blendARGB(mBackgroundColor!!, Color.WHITE, 0.1f) ColorUtils.blendARGB(mBackgroundColor!!, Color.WHITE, 0.1f)
} else { } else {
@@ -380,12 +380,12 @@ class EntryActivity : DatabaseLockActivity() {
mDatabase?.iconDrawableFactory?.assignDatabaseIcon( mDatabase?.iconDrawableFactory?.assignDatabaseIcon(
iconView, iconView,
icon, icon,
mForegroundColor ?: mColorAccent mForegroundColor ?: mColorSecondary
) )
} }
} }
toolbar?.changeControlColor(mForegroundColor ?: mControlColor) toolbar?.changeControlColor(mForegroundColor ?: mColorOnSurface)
collapsingToolbarLayout?.changeTitleColor(mForegroundColor ?: mControlColor) collapsingToolbarLayout?.changeTitleColor(mForegroundColor ?: mColorOnSurface)
} }
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {

View File

@@ -19,8 +19,6 @@
package com.kunzisoft.keepass.activities package com.kunzisoft.keepass.activities
import android.app.Activity import android.app.Activity
import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
@@ -33,10 +31,8 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.DatePicker
import android.widget.ProgressBar import android.widget.ProgressBar
import android.widget.Spinner import android.widget.Spinner
import android.widget.TimePicker
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
@@ -48,16 +44,16 @@ import androidx.core.view.isVisible
import androidx.core.widget.NestedScrollView import androidx.core.widget.NestedScrollView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.google.android.material.timepicker.MaterialTimePicker
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.ColorPickerDialogFragment import com.kunzisoft.keepass.activities.dialogs.ColorPickerDialogFragment
import com.kunzisoft.keepass.activities.dialogs.DatePickerFragment
import com.kunzisoft.keepass.activities.dialogs.EntryCustomFieldDialogFragment import com.kunzisoft.keepass.activities.dialogs.EntryCustomFieldDialogFragment
import com.kunzisoft.keepass.activities.dialogs.FileTooBigDialogFragment import com.kunzisoft.keepass.activities.dialogs.FileTooBigDialogFragment
import com.kunzisoft.keepass.activities.dialogs.FileTooBigDialogFragment.Companion.MAX_WARNING_BINARY_FILE import com.kunzisoft.keepass.activities.dialogs.FileTooBigDialogFragment.Companion.MAX_WARNING_BINARY_FILE
import com.kunzisoft.keepass.activities.dialogs.ReplaceFileDialogFragment import com.kunzisoft.keepass.activities.dialogs.ReplaceFileDialogFragment
import com.kunzisoft.keepass.activities.dialogs.SetOTPDialogFragment import com.kunzisoft.keepass.activities.dialogs.SetOTPDialogFragment
import com.kunzisoft.keepass.activities.dialogs.TimePickerFragment
import com.kunzisoft.keepass.activities.fragments.EntryEditFragment import com.kunzisoft.keepass.activities.fragments.EntryEditFragment
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
@@ -90,8 +86,8 @@ import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.tasks.ActionRunnable import com.kunzisoft.keepass.tasks.ActionRunnable
import com.kunzisoft.keepass.tasks.AttachmentFileBinderManager import com.kunzisoft.keepass.tasks.AttachmentFileBinderManager
import com.kunzisoft.keepass.timeout.TimeoutHelper import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.getParcelableExtraCompat
import com.kunzisoft.keepass.utils.UriUtil.getDocumentFile import com.kunzisoft.keepass.utils.UriUtil.getDocumentFile
import com.kunzisoft.keepass.utils.getParcelableExtraCompat
import com.kunzisoft.keepass.view.ToolbarAction import com.kunzisoft.keepass.view.ToolbarAction
import com.kunzisoft.keepass.view.asError import com.kunzisoft.keepass.view.asError
import com.kunzisoft.keepass.view.hideByFading import com.kunzisoft.keepass.view.hideByFading
@@ -99,14 +95,11 @@ import com.kunzisoft.keepass.view.showActionErrorIfNeeded
import com.kunzisoft.keepass.view.updateLockPaddingLeft import com.kunzisoft.keepass.view.updateLockPaddingLeft
import com.kunzisoft.keepass.viewmodels.ColorPickerViewModel import com.kunzisoft.keepass.viewmodels.ColorPickerViewModel
import com.kunzisoft.keepass.viewmodels.EntryEditViewModel import com.kunzisoft.keepass.viewmodels.EntryEditViewModel
import org.joda.time.DateTime
import java.util.UUID import java.util.UUID
class EntryEditActivity : DatabaseLockActivity(), class EntryEditActivity : DatabaseLockActivity(),
EntryCustomFieldDialogFragment.EntryCustomFieldListener, EntryCustomFieldDialogFragment.EntryCustomFieldListener,
SetOTPDialogFragment.CreateOtpListener, SetOTPDialogFragment.CreateOtpListener,
DatePickerDialog.OnDateSetListener,
TimePickerDialog.OnTimeSetListener,
FileTooBigDialogFragment.ActionChooseListener, FileTooBigDialogFragment.ActionChooseListener,
ReplaceFileDialogFragment.ActionChooseListener { ReplaceFileDialogFragment.ActionChooseListener {
@@ -291,14 +284,20 @@ class EntryEditActivity : DatabaseLockActivity(),
mEntryEditViewModel.requestDateTimeSelection.observe(this) { dateInstant -> mEntryEditViewModel.requestDateTimeSelection.observe(this) { dateInstant ->
if (dateInstant.type == DateInstant.Type.TIME) { if (dateInstant.type == DateInstant.Type.TIME) {
// Launch the time picker // Launch the time picker
val dateTime = DateTime(dateInstant.date) MaterialTimePicker.Builder().build().apply {
TimePickerFragment.getInstance(dateTime.hourOfDay, dateTime.minuteOfHour) addOnPositiveButtonClickListener {
.show(supportFragmentManager, "TimePickerFragment") mEntryEditViewModel.selectTime(this.hour, this.minute)
}
show(supportFragmentManager, "TimePickerFragment")
}
} else { } else {
// Launch the date picker // Launch the date picker
val dateTime = DateTime(dateInstant.date) MaterialDatePicker.Builder.datePicker().build().apply {
DatePickerFragment.getInstance(dateTime.year, dateTime.monthOfYear - 1, dateTime.dayOfMonth) addOnPositiveButtonClickListener {
.show(supportFragmentManager, "DatePickerFragment") mEntryEditViewModel.selectDate(it)
}
show(supportFragmentManager, "DatePickerFragment")
}
} }
} }
@@ -684,18 +683,6 @@ class EntryEditActivity : DatabaseLockActivity(),
return super.onOptionsItemSelected(item) return super.onOptionsItemSelected(item)
} }
override fun onDateSet(datePicker: DatePicker?, year: Int, month: Int, day: Int) {
// To fix android 4.4 issue
// https://stackoverflow.com/questions/12436073/datepicker-ondatechangedlistener-called-twice
if (datePicker?.isShown == true) {
mEntryEditViewModel.selectDate(year, month, day)
}
}
override fun onTimeSet(timePicker: TimePicker?, hours: Int, minutes: Int) {
mEntryEditViewModel.selectTime(hours, minutes)
}
override fun onBackPressed() { override fun onBackPressed() {
onApprovedBackPressed { onApprovedBackPressed {
super@EntryEditActivity.onBackPressed() super@EntryEditActivity.onBackPressed()

View File

@@ -19,9 +19,7 @@
package com.kunzisoft.keepass.activities package com.kunzisoft.keepass.activities
import android.app.Activity import android.app.Activity
import android.app.DatePickerDialog
import android.app.SearchManager import android.app.SearchManager
import android.app.TimePickerDialog
import android.content.ComponentName import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@@ -38,11 +36,9 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.DatePicker
import android.widget.ImageView import android.widget.ImageView
import android.widget.ProgressBar import android.widget.ProgressBar
import android.widget.TextView import android.widget.TextView
import android.widget.TimePicker
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.viewModels import androidx.activity.viewModels
@@ -59,13 +55,13 @@ import androidx.core.view.WindowInsetsControllerCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.drawerlayout.widget.DrawerLayout import androidx.drawerlayout.widget.DrawerLayout
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.timepicker.MaterialTimePicker
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.DatePickerFragment
import com.kunzisoft.keepass.activities.dialogs.GroupDialogFragment import com.kunzisoft.keepass.activities.dialogs.GroupDialogFragment
import com.kunzisoft.keepass.activities.dialogs.GroupEditDialogFragment import com.kunzisoft.keepass.activities.dialogs.GroupEditDialogFragment
import com.kunzisoft.keepass.activities.dialogs.MainCredentialDialogFragment import com.kunzisoft.keepass.activities.dialogs.MainCredentialDialogFragment
import com.kunzisoft.keepass.activities.dialogs.SortDialogFragment import com.kunzisoft.keepass.activities.dialogs.SortDialogFragment
import com.kunzisoft.keepass.activities.dialogs.TimePickerFragment
import com.kunzisoft.keepass.activities.fragments.GroupFragment import com.kunzisoft.keepass.activities.fragments.GroupFragment
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
@@ -100,12 +96,12 @@ import com.kunzisoft.keepass.settings.SettingsActivity
import com.kunzisoft.keepass.tasks.ActionRunnable import com.kunzisoft.keepass.tasks.ActionRunnable
import com.kunzisoft.keepass.timeout.TimeoutHelper import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.BACK_PREVIOUS_KEYBOARD_ACTION import com.kunzisoft.keepass.utils.BACK_PREVIOUS_KEYBOARD_ACTION
import com.kunzisoft.keepass.utils.UriUtil.openUrl
import com.kunzisoft.keepass.utils.getParcelableCompat import com.kunzisoft.keepass.utils.getParcelableCompat
import com.kunzisoft.keepass.utils.getParcelableExtraCompat import com.kunzisoft.keepass.utils.getParcelableExtraCompat
import com.kunzisoft.keepass.utils.getParcelableList import com.kunzisoft.keepass.utils.getParcelableList
import com.kunzisoft.keepass.utils.putParcelableList import com.kunzisoft.keepass.utils.putParcelableList
import com.kunzisoft.keepass.utils.readParcelableCompat import com.kunzisoft.keepass.utils.readParcelableCompat
import com.kunzisoft.keepass.utils.UriUtil.openUrl
import com.kunzisoft.keepass.view.AddNodeButtonView import com.kunzisoft.keepass.view.AddNodeButtonView
import com.kunzisoft.keepass.view.NavigationDatabaseView import com.kunzisoft.keepass.view.NavigationDatabaseView
import com.kunzisoft.keepass.view.SearchFiltersView import com.kunzisoft.keepass.view.SearchFiltersView
@@ -115,12 +111,9 @@ import com.kunzisoft.keepass.view.showActionErrorIfNeeded
import com.kunzisoft.keepass.view.updateLockPaddingLeft import com.kunzisoft.keepass.view.updateLockPaddingLeft
import com.kunzisoft.keepass.viewmodels.GroupEditViewModel import com.kunzisoft.keepass.viewmodels.GroupEditViewModel
import com.kunzisoft.keepass.viewmodels.GroupViewModel import com.kunzisoft.keepass.viewmodels.GroupViewModel
import org.joda.time.DateTime
class GroupActivity : DatabaseLockActivity(), class GroupActivity : DatabaseLockActivity(),
DatePickerDialog.OnDateSetListener,
TimePickerDialog.OnTimeSetListener,
GroupFragment.NodeClickListener, GroupFragment.NodeClickListener,
GroupFragment.NodesActionMenuListener, GroupFragment.NodesActionMenuListener,
GroupFragment.OnScrollListener, GroupFragment.OnScrollListener,
@@ -140,7 +133,6 @@ class GroupActivity : DatabaseLockActivity(),
private var databaseNameView: TextView? = null private var databaseNameView: TextView? = null
private var searchView: SearchView? = null private var searchView: SearchView? = null
private var searchFiltersView: SearchFiltersView? = null private var searchFiltersView: SearchFiltersView? = null
private var toolbarBreadcrumb: Toolbar? = null
private var toolbarAction: ToolbarAction? = null private var toolbarAction: ToolbarAction? = null
private var numberChildrenView: TextView? = null private var numberChildrenView: TextView? = null
private var addNodeButtonView: AddNodeButtonView? = null private var addNodeButtonView: AddNodeButtonView? = null
@@ -277,7 +269,6 @@ class GroupActivity : DatabaseLockActivity(),
databaseColorView = findViewById(R.id.database_color) databaseColorView = findViewById(R.id.database_color)
databaseNameView = findViewById(R.id.database_name) databaseNameView = findViewById(R.id.database_name)
searchFiltersView = findViewById(R.id.search_filters) searchFiltersView = findViewById(R.id.search_filters)
toolbarBreadcrumb = findViewById(R.id.toolbar_breadcrumb)
breadcrumbListView = findViewById(R.id.breadcrumb_list) breadcrumbListView = findViewById(R.id.breadcrumb_list)
toolbarAction = findViewById(R.id.toolbar_action) toolbarAction = findViewById(R.id.toolbar_action)
lockView = findViewById(R.id.lock_button) lockView = findViewById(R.id.lock_button)
@@ -459,18 +450,20 @@ class GroupActivity : DatabaseLockActivity(),
mGroupEditViewModel.requestDateTimeSelection.observe(this) { dateInstant -> mGroupEditViewModel.requestDateTimeSelection.observe(this) { dateInstant ->
if (dateInstant.type == DateInstant.Type.TIME) { if (dateInstant.type == DateInstant.Type.TIME) {
// Launch the time picker // Launch the time picker
val dateTime = DateTime(dateInstant.date) MaterialTimePicker.Builder().build().apply {
TimePickerFragment.getInstance(dateTime.hourOfDay, dateTime.minuteOfHour) addOnPositiveButtonClickListener {
.show(supportFragmentManager, "TimePickerFragment") mGroupEditViewModel.selectTime(this.hour, this.minute)
}
show(supportFragmentManager, "TimePickerFragment")
}
} else { } else {
// Launch the date picker // Launch the date picker
val dateTime = DateTime(dateInstant.date) MaterialDatePicker.Builder.datePicker().build().apply {
DatePickerFragment.getInstance( addOnPositiveButtonClickListener {
dateTime.year, mGroupEditViewModel.selectDate(it)
dateTime.monthOfYear - 1, }
dateTime.dayOfMonth show(supportFragmentManager, "DatePickerFragment")
) }
.show(supportFragmentManager, "DatePickerFragment")
} }
} }
@@ -970,18 +963,6 @@ class GroupActivity : DatabaseLockActivity(),
} }
} }
override fun onDateSet(datePicker: DatePicker?, year: Int, month: Int, day: Int) {
// To fix android 4.4 issue
// https://stackoverflow.com/questions/12436073/datepicker-ondatechangedlistener-called-twice
if (datePicker?.isShown == true) {
mGroupEditViewModel.selectDate(year, month, day)
}
}
override fun onTimeSet(view: TimePicker?, hours: Int, minutes: Int) {
mGroupEditViewModel.selectTime(hours, minutes)
}
private fun finishNodeAction() { private fun finishNodeAction() {
actionNodeMode?.finish() actionNodeMode?.finish()
} }
@@ -1228,11 +1209,11 @@ class GroupActivity : DatabaseLockActivity(),
} }
} }
if (it.isActionViewExpanded) { if (it.isActionViewExpanded) {
toolbarBreadcrumb?.visibility = View.GONE breadcrumbListView?.visibility = View.GONE
searchFiltersView?.visibility = View.VISIBLE searchFiltersView?.visibility = View.VISIBLE
} else { } else {
searchFiltersView?.visibility = View.GONE searchFiltersView?.visibility = View.GONE
toolbarBreadcrumb?.visibility = View.VISIBLE breadcrumbListView?.visibility = View.VISIBLE
} }
mLockSearchListeners = false mLockSearchListeners = false
} }

View File

@@ -1,6 +1,6 @@
/* /*
* Copyright 2019 Jeremy Jamet / Kunzisoft. * Copyright 2019 Jeremy Jamet / Kunzisoft.
* *
* This file is part of KeePassDX. * This file is part of KeePassDX.
* *
* KeePassDX is free software: you can redistribute it and/or modify * KeePassDX is free software: you can redistribute it and/or modify
@@ -67,14 +67,15 @@ import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.DATABASE_URI_KEY import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.DATABASE_URI_KEY
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.MAIN_CREDENTIAL_KEY import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.MAIN_CREDENTIAL_KEY
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.READ_ONLY_KEY import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.READ_ONLY_KEY
import com.kunzisoft.keepass.settings.AdvancedUnlockSettingsActivity
import com.kunzisoft.keepass.settings.AppearanceSettingsActivity
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.settings.SettingsAdvancedUnlockActivity
import com.kunzisoft.keepass.tasks.ActionRunnable import com.kunzisoft.keepass.tasks.ActionRunnable
import com.kunzisoft.keepass.utils.BACK_PREVIOUS_KEYBOARD_ACTION import com.kunzisoft.keepass.utils.BACK_PREVIOUS_KEYBOARD_ACTION
import com.kunzisoft.keepass.utils.MenuUtil import com.kunzisoft.keepass.utils.MenuUtil
import com.kunzisoft.keepass.utils.UriUtil.getUri
import com.kunzisoft.keepass.utils.getParcelableCompat import com.kunzisoft.keepass.utils.getParcelableCompat
import com.kunzisoft.keepass.utils.getParcelableExtraCompat import com.kunzisoft.keepass.utils.getParcelableExtraCompat
import com.kunzisoft.keepass.utils.UriUtil.getUri
import com.kunzisoft.keepass.view.MainCredentialView import com.kunzisoft.keepass.view.MainCredentialView
import com.kunzisoft.keepass.view.asError import com.kunzisoft.keepass.view.asError
import com.kunzisoft.keepass.view.showActionErrorIfNeeded import com.kunzisoft.keepass.view.showActionErrorIfNeeded
@@ -88,6 +89,7 @@ class MainCredentialActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bu
// Views // Views
private var toolbar: Toolbar? = null private var toolbar: Toolbar? = null
private var filenameView: TextView? = null private var filenameView: TextView? = null
private var logotypeButton: View? = null
private var advancedUnlockButton: View? = null private var advancedUnlockButton: View? = null
private var mainCredentialView: MainCredentialView? = null private var mainCredentialView: MainCredentialView? = null
private var confirmButtonView: Button? = null private var confirmButtonView: Button? = null
@@ -128,7 +130,8 @@ class MainCredentialActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bu
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
filenameView = findViewById(R.id.filename) filenameView = findViewById(R.id.filename)
advancedUnlockButton = findViewById(R.id.activity_password_advanced_unlock_button) logotypeButton = findViewById(R.id.activity_password_logotype)
advancedUnlockButton = findViewById(R.id.fragment_advanced_unlock_container_view)
mainCredentialView = findViewById(R.id.activity_password_credentials) mainCredentialView = findViewById(R.id.activity_password_credentials)
confirmButtonView = findViewById(R.id.activity_password_open_button) confirmButtonView = findViewById(R.id.activity_password_open_button)
infoContainerView = findViewById(R.id.activity_password_info_container) infoContainerView = findViewById(R.id.activity_password_info_container)
@@ -157,10 +160,15 @@ class MainCredentialActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bu
// If is a view intent // If is a view intent
getUriFromIntent(intent) getUriFromIntent(intent)
// Show appearance
logotypeButton?.setOnClickListener {
startActivity(Intent(this, AppearanceSettingsActivity::class.java))
}
// Init Biometric elements // Init Biometric elements
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
advancedUnlockButton?.setOnClickListener { advancedUnlockButton?.setOnClickListener {
startActivity(Intent(this, SettingsAdvancedUnlockActivity::class.java)) startActivity(Intent(this, AdvancedUnlockSettingsActivity::class.java))
} }
} }
advancedUnlockFragment = supportFragmentManager advancedUnlockFragment = supportFragmentManager
@@ -647,7 +655,7 @@ class MainCredentialActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bu
startActivity( startActivity(
Intent( Intent(
this, this,
SettingsAdvancedUnlockActivity::class.java AdvancedUnlockSettingsActivity::class.java
) )
) )
}, },

View File

@@ -6,7 +6,6 @@ import androidx.fragment.app.activityViewModels
import com.kunzisoft.keepass.activities.legacy.DatabaseRetrieval import com.kunzisoft.keepass.activities.legacy.DatabaseRetrieval
import com.kunzisoft.keepass.activities.legacy.resetAppTimeoutWhenViewTouchedOrFocused import com.kunzisoft.keepass.activities.legacy.resetAppTimeoutWhenViewTouchedOrFocused
import com.kunzisoft.keepass.database.ContextualDatabase import com.kunzisoft.keepass.database.ContextualDatabase
import com.kunzisoft.keepass.icons.IconDrawableFactory
import com.kunzisoft.keepass.tasks.ActionRunnable import com.kunzisoft.keepass.tasks.ActionRunnable
import com.kunzisoft.keepass.timeout.TimeoutHelper import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.viewmodels.DatabaseViewModel import com.kunzisoft.keepass.viewmodels.DatabaseViewModel
@@ -16,8 +15,6 @@ abstract class DatabaseDialogFragment : DialogFragment(), DatabaseRetrieval {
private val mDatabaseViewModel: DatabaseViewModel by activityViewModels() private val mDatabaseViewModel: DatabaseViewModel by activityViewModels()
private var mDatabase: ContextualDatabase? = null private var mDatabase: ContextualDatabase? = null
protected var mIconDrawableFactory: IconDrawableFactory? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

View File

@@ -1,67 +0,0 @@
package com.kunzisoft.keepass.activities.dialogs
import android.app.DatePickerDialog
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import androidx.fragment.app.DialogFragment
// Not as DatabaseDialogFragment because crash on KitKat
class DatePickerFragment : DialogFragment() {
private var mDefaultYear: Int = 2000
private var mDefaultMonth: Int = 1
private var mDefaultDay: Int = 1
private var mListener: DatePickerDialog.OnDateSetListener? = null
override fun onAttach(context: Context) {
super.onAttach(context)
try {
mListener = context as DatePickerDialog.OnDateSetListener
} catch (e: ClassCastException) {
throw ClassCastException(context.toString()
+ " must implement " + DatePickerDialog.OnDateSetListener::class.java.name)
}
}
override fun onDetach() {
mListener = null
super.onDetach()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
// Create a new instance of DatePickerDialog and return it
return context?.let {
arguments?.apply {
if (containsKey(DEFAULT_YEAR_BUNDLE_KEY))
mDefaultYear = getInt(DEFAULT_YEAR_BUNDLE_KEY)
if (containsKey(DEFAULT_MONTH_BUNDLE_KEY))
mDefaultMonth = getInt(DEFAULT_MONTH_BUNDLE_KEY)
if (containsKey(DEFAULT_DAY_BUNDLE_KEY))
mDefaultDay = getInt(DEFAULT_DAY_BUNDLE_KEY)
}
DatePickerDialog(it, mListener, mDefaultYear, mDefaultMonth, mDefaultDay)
} ?: super.onCreateDialog(savedInstanceState)
}
companion object {
private const val DEFAULT_YEAR_BUNDLE_KEY = "DEFAULT_YEAR_BUNDLE_KEY"
private const val DEFAULT_MONTH_BUNDLE_KEY = "DEFAULT_MONTH_BUNDLE_KEY"
private const val DEFAULT_DAY_BUNDLE_KEY = "DEFAULT_DAY_BUNDLE_KEY"
fun getInstance(defaultYear: Int,
defaultMonth: Int,
defaultDay: Int): DatePickerFragment {
return DatePickerFragment().apply {
arguments = Bundle().apply {
putInt(DEFAULT_YEAR_BUNDLE_KEY, defaultYear)
putInt(DEFAULT_MONTH_BUNDLE_KEY, defaultMonth)
putInt(DEFAULT_DAY_BUNDLE_KEY, defaultDay)
}
}
}
}
}

View File

@@ -35,9 +35,9 @@ import com.kunzisoft.keepass.database.ContextualDatabase
import com.kunzisoft.keepass.database.element.icon.IconImage import com.kunzisoft.keepass.database.element.icon.IconImage
import com.kunzisoft.keepass.model.GroupInfo import com.kunzisoft.keepass.model.GroupInfo
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.utils.getParcelableCompat
import com.kunzisoft.keepass.utils.TimeUtil.getDateTimeString import com.kunzisoft.keepass.utils.TimeUtil.getDateTimeString
import com.kunzisoft.keepass.utils.UuidUtil import com.kunzisoft.keepass.utils.UuidUtil
import com.kunzisoft.keepass.utils.getParcelableCompat
import com.kunzisoft.keepass.view.DateTimeFieldView import com.kunzisoft.keepass.view.DateTimeFieldView
class GroupDialogFragment : DatabaseDialogFragment() { class GroupDialogFragment : DatabaseDialogFragment() {
@@ -65,7 +65,7 @@ class GroupDialogFragment : DatabaseDialogFragment() {
override fun onDatabaseRetrieved(database: ContextualDatabase?) { override fun onDatabaseRetrieved(database: ContextualDatabase?) {
super.onDatabaseRetrieved(database) super.onDatabaseRetrieved(database)
mPopulateIconMethod = { imageView, icon -> mPopulateIconMethod = { imageView, icon ->
mIconDrawableFactory?.assignDatabaseIcon(imageView, icon, mIconColor) database?.iconDrawableFactory?.assignDatabaseIcon(imageView, icon, mIconColor)
} }
mPopulateIconMethod?.invoke(iconView, mGroupInfo.icon) mPopulateIconMethod?.invoke(iconView, mGroupInfo.icon)
@@ -108,7 +108,7 @@ class GroupDialogFragment : DatabaseDialogFragment() {
uuidReferenceView = root.findViewById(R.id.group_UUID_reference) uuidReferenceView = root.findViewById(R.id.group_UUID_reference)
// Retrieve the textColor to tint the icon // Retrieve the textColor to tint the icon
val ta = activity.theme.obtainStyledAttributes(intArrayOf(R.attr.colorAccent)) val ta = activity.theme.obtainStyledAttributes(intArrayOf(R.attr.colorSecondary))
mIconColor = ta.getColor(0, Color.WHITE) mIconColor = ta.getColor(0, Color.WHITE)
ta.recycle() ta.recycle()

View File

@@ -90,13 +90,11 @@ class GroupEditDialogFragment : DatabaseDialogFragment() {
mPopulateIconMethod?.invoke(iconButtonView, mGroupInfo.icon) mPopulateIconMethod?.invoke(iconButtonView, mGroupInfo.icon)
} }
mGroupEditViewModel.onDateSelected.observe(this) { viewModelDate -> mGroupEditViewModel.onDateSelected.observe(this) { dateMilliseconds ->
// Save the date // Save the date
mGroupInfo.expiryTime = DateInstant( mGroupInfo.expiryTime = DateInstant(
DateTime(mGroupInfo.expiryTime.date) DateTime(mGroupInfo.expiryTime.date)
.withYear(viewModelDate.year) .withMillis(dateMilliseconds)
.withMonthOfYear(viewModelDate.month + 1)
.withDayOfMonth(viewModelDate.day)
.toDate()) .toDate())
expirationView.dateTime = mGroupInfo.expiryTime expirationView.dateTime = mGroupInfo.expiryTime
if (expirationView.dateTime.type == DateInstant.Type.DATE_TIME) { if (expirationView.dateTime.type == DateInstant.Type.DATE_TIME) {

View File

@@ -28,8 +28,8 @@ import androidx.appcompat.app.AlertDialog
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
import com.kunzisoft.keepass.database.MainCredential import com.kunzisoft.keepass.database.MainCredential
import com.kunzisoft.keepass.utils.getParcelableCompat
import com.kunzisoft.keepass.utils.UriUtil.getDocumentFile import com.kunzisoft.keepass.utils.UriUtil.getDocumentFile
import com.kunzisoft.keepass.utils.getParcelableCompat
import com.kunzisoft.keepass.view.MainCredentialView import com.kunzisoft.keepass.view.MainCredentialView
class MainCredentialDialogFragment : DatabaseDialogFragment() { class MainCredentialDialogFragment : DatabaseDialogFragment() {

View File

@@ -44,9 +44,9 @@ import com.kunzisoft.keepass.otp.OtpElement.Companion.MIN_TOTP_PERIOD
import com.kunzisoft.keepass.otp.OtpTokenType import com.kunzisoft.keepass.otp.OtpTokenType
import com.kunzisoft.keepass.otp.OtpType import com.kunzisoft.keepass.otp.OtpType
import com.kunzisoft.keepass.otp.TokenCalculator import com.kunzisoft.keepass.otp.TokenCalculator
import com.kunzisoft.keepass.utils.getParcelableCompat
import com.kunzisoft.keepass.utils.UriUtil.isContributingUser import com.kunzisoft.keepass.utils.UriUtil.isContributingUser
import com.kunzisoft.keepass.utils.UriUtil.openUrl import com.kunzisoft.keepass.utils.UriUtil.openUrl
import com.kunzisoft.keepass.utils.getParcelableCompat
import java.util.* import java.util.*
class SetOTPDialogFragment : DatabaseDialogFragment() { class SetOTPDialogFragment : DatabaseDialogFragment() {

View File

@@ -1,63 +0,0 @@
package com.kunzisoft.keepass.activities.dialogs
import android.app.DatePickerDialog
import android.app.Dialog
import android.app.TimePickerDialog
import android.content.Context
import android.os.Bundle
import android.text.format.DateFormat
import androidx.fragment.app.DialogFragment
// Not as DatabaseDialogFragment because crash on KitKat
class TimePickerFragment : DialogFragment() {
private var defaultHour: Int = 0
private var defaultMinute: Int = 0
private var mListener: TimePickerDialog.OnTimeSetListener? = null
override fun onAttach(context: Context) {
super.onAttach(context)
try {
mListener = context as TimePickerDialog.OnTimeSetListener
} catch (e: ClassCastException) {
throw ClassCastException(context.toString()
+ " must implement " + DatePickerDialog.OnDateSetListener::class.java.name)
}
}
override fun onDetach() {
mListener = null
super.onDetach()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
// Create a new instance of DatePickerDialog and return it
return context?.let {
arguments?.apply {
if (containsKey(DEFAULT_HOUR_BUNDLE_KEY))
defaultHour = getInt(DEFAULT_HOUR_BUNDLE_KEY)
if (containsKey(DEFAULT_MINUTE_BUNDLE_KEY))
defaultMinute = getInt(DEFAULT_MINUTE_BUNDLE_KEY)
}
TimePickerDialog(it, mListener, defaultHour, defaultMinute, DateFormat.is24HourFormat(activity))
} ?: super.onCreateDialog(savedInstanceState)
}
companion object {
private const val DEFAULT_HOUR_BUNDLE_KEY = "DEFAULT_HOUR_BUNDLE_KEY"
private const val DEFAULT_MINUTE_BUNDLE_KEY = "DEFAULT_MINUTE_BUNDLE_KEY"
fun getInstance(defaultHour: Int,
defaultMinute: Int): TimePickerFragment {
return TimePickerFragment().apply {
arguments = Bundle().apply {
putInt(DEFAULT_HOUR_BUNDLE_KEY, defaultHour)
putInt(DEFAULT_MINUTE_BUNDLE_KEY, defaultMinute)
}
}
}
}
}

View File

@@ -22,12 +22,12 @@ package com.kunzisoft.keepass.activities.dialogs
import android.app.Dialog import android.app.Dialog
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.DialogFragment
import androidx.appcompat.app.AlertDialog
import android.text.SpannableStringBuilder import android.text.SpannableStringBuilder
import android.text.method.LinkMovementMethod import android.text.method.LinkMovementMethod
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat
import androidx.fragment.app.DialogFragment
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
class UnavailableFeatureDialogFragment : DialogFragment() { class UnavailableFeatureDialogFragment : DialogFragment() {

View File

@@ -9,7 +9,7 @@ import com.kunzisoft.keepass.activities.helpers.SpecialMode
import com.kunzisoft.keepass.activities.helpers.TypeMode import com.kunzisoft.keepass.activities.helpers.TypeMode
import com.kunzisoft.keepass.model.SearchInfo import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.view.SpecialModeView import com.kunzisoft.keepass.view.ToolbarSpecial
/** /**
@@ -20,7 +20,7 @@ abstract class DatabaseModeActivity : DatabaseActivity() {
protected var mSpecialMode: SpecialMode = SpecialMode.DEFAULT protected var mSpecialMode: SpecialMode = SpecialMode.DEFAULT
private var mTypeMode: TypeMode = TypeMode.DEFAULT private var mTypeMode: TypeMode = TypeMode.DEFAULT
private var mSpecialModeView: SpecialModeView? = null private var mToolbarSpecial: ToolbarSpecial? = null
override fun onBackPressed() { override fun onBackPressed() {
if (mSpecialMode != SpecialMode.DEFAULT) if (mSpecialMode != SpecialMode.DEFAULT)
@@ -113,8 +113,8 @@ abstract class DatabaseModeActivity : DatabaseActivity() {
?: EntrySelectionHelper.retrieveSearchInfoFromIntent(intent) ?: EntrySelectionHelper.retrieveSearchInfoFromIntent(intent)
// To show the selection mode // To show the selection mode
mSpecialModeView = findViewById(R.id.special_mode_view) mToolbarSpecial = findViewById(R.id.special_mode_view)
mSpecialModeView?.apply { mToolbarSpecial?.apply {
// Populate title // Populate title
val selectionModeStringId = when (mSpecialMode) { val selectionModeStringId = when (mSpecialMode) {
SpecialMode.DEFAULT, // Not important because hidden SpecialMode.DEFAULT, // Not important because hidden

View File

@@ -39,10 +39,10 @@ class BreadcrumbAdapter(val context: Context)
mShowNumberEntries = PreferencesUtil.showNumberEntries(context) mShowNumberEntries = PreferencesUtil.showNumberEntries(context)
mShowUUID = PreferencesUtil.showUUID(context) mShowUUID = PreferencesUtil.showUUID(context)
// Retrieve the textColor to tint the icon // Retrieve the color to tint the icon
val taTextColor = context.theme.obtainStyledAttributes(intArrayOf(R.attr.textColorInverse)) val taIconColor = context.theme.obtainStyledAttributes(intArrayOf(R.attr.colorOnSurface))
mIconColor = taTextColor.getColor(0, Color.WHITE) mIconColor = taIconColor.getColor(0, Color.WHITE)
taTextColor.recycle() taIconColor.recycle()
} }
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
@@ -71,7 +71,7 @@ class BreadcrumbAdapter(val context: Context)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BreadcrumbGroupViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BreadcrumbGroupViewHolder {
return BreadcrumbGroupViewHolder(inflater.inflate( return BreadcrumbGroupViewHolder(inflater.inflate(
when (viewType) { when (viewType) {
0 -> R.layout.item_group 0 -> R.layout.item_breadcrumb_important
else -> R.layout.item_breadcrumb else -> R.layout.item_breadcrumb
}, parent, false) }, parent, false)
) )

View File

@@ -27,9 +27,9 @@ import android.util.TypedValue
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.progressindicator.CircularProgressIndicator
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.ImageViewerActivity import com.kunzisoft.keepass.activities.ImageViewerActivity
import com.kunzisoft.keepass.database.ContextualDatabase import com.kunzisoft.keepass.database.ContextualDatabase
@@ -38,6 +38,7 @@ import com.kunzisoft.keepass.database.helper.getLocalizedName
import com.kunzisoft.keepass.model.AttachmentState import com.kunzisoft.keepass.model.AttachmentState
import com.kunzisoft.keepass.model.EntryAttachmentState import com.kunzisoft.keepass.model.EntryAttachmentState
import com.kunzisoft.keepass.model.StreamDirection import com.kunzisoft.keepass.model.StreamDirection
import com.kunzisoft.keepass.services.AttachmentFileNotificationService.Companion.FILE_PROGRESSION_MAX
import com.kunzisoft.keepass.tasks.BinaryDatabaseManager import com.kunzisoft.keepass.tasks.BinaryDatabaseManager
import com.kunzisoft.keepass.view.expand import com.kunzisoft.keepass.view.expand
import kotlin.math.max import kotlin.math.max
@@ -138,6 +139,7 @@ class EntryAttachmentsItemsAdapter(context: Context)
visibility = View.GONE visibility = View.GONE
} }
} }
holder.binaryFileProgress.max = FILE_PROGRESSION_MAX
when (entryAttachmentState.streamDirection) { when (entryAttachmentState.streamDirection) {
StreamDirection.UPLOAD -> { StreamDirection.UPLOAD -> {
holder.binaryFileProgressIcon.isActivated = true holder.binaryFileProgressIcon.isActivated = true
@@ -182,7 +184,7 @@ class EntryAttachmentsItemsAdapter(context: Context)
AttachmentState.START, AttachmentState.START,
AttachmentState.IN_PROGRESS -> View.VISIBLE AttachmentState.IN_PROGRESS -> View.VISIBLE
} }
progress = entryAttachmentState.downloadProgression setProgressCompat(entryAttachmentState.downloadProgression, true)
} }
holder.binaryFileInfo.setOnClickListener { holder.binaryFileInfo.setOnClickListener {
onItemClickListener?.invoke(entryAttachmentState) onItemClickListener?.invoke(entryAttachmentState)
@@ -201,7 +203,7 @@ class EntryAttachmentsItemsAdapter(context: Context)
var binaryFileCompression: TextView = itemView.findViewById(R.id.item_attachment_compression) var binaryFileCompression: TextView = itemView.findViewById(R.id.item_attachment_compression)
var binaryFileProgressContainer: View = itemView.findViewById(R.id.item_attachment_progress_container) var binaryFileProgressContainer: View = itemView.findViewById(R.id.item_attachment_progress_container)
var binaryFileProgressIcon: ImageView = itemView.findViewById(R.id.item_attachment_icon) var binaryFileProgressIcon: ImageView = itemView.findViewById(R.id.item_attachment_icon)
var binaryFileProgress: ProgressBar = itemView.findViewById(R.id.item_attachment_progress) var binaryFileProgress: CircularProgressIndicator = itemView.findViewById(R.id.item_attachment_progress)
var binaryFileDeleteButton: View = itemView.findViewById(R.id.item_attachment_delete_button) var binaryFileDeleteButton: View = itemView.findViewById(R.id.item_attachment_delete_button)
} }
} }

View File

@@ -23,12 +23,14 @@ import android.content.Context
import android.graphics.Color import android.graphics.Color
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.net.Uri import android.net.Uri
import android.util.TypedValue
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.* import android.widget.CompoundButton
import androidx.annotation.ColorInt import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import android.widget.ViewSwitcher
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SortedList import androidx.recyclerview.widget.SortedList
import androidx.recyclerview.widget.SortedListAdapterCallback import androidx.recyclerview.widget.SortedListAdapterCallback
@@ -84,20 +86,6 @@ class FileDatabaseHistoryAdapter(context: Context)
} }
) )
@ColorInt
private val defaultColor: Int
@ColorInt
private val warningColor: Int
init {
val typedValue = TypedValue()
val theme = context.theme
theme.resolveAttribute(R.attr.colorAccent, typedValue, true)
warningColor = typedValue.data
theme.resolveAttribute(android.R.attr.textColorHintInverse, typedValue, true)
defaultColor = typedValue.data
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FileDatabaseHistoryViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FileDatabaseHistoryViewHolder {
val view = inflater.inflate(R.layout.item_file_info, parent, false) val view = inflater.inflate(R.layout.item_file_info, parent, false)
return FileDatabaseHistoryViewHolder(view) return FileDatabaseHistoryViewHolder(view)

View File

@@ -20,6 +20,7 @@
package com.kunzisoft.keepass.adapters package com.kunzisoft.keepass.adapters
import android.content.Context import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color import android.graphics.Color
import android.util.Log import android.util.Log
import android.util.TypedValue import android.util.TypedValue
@@ -29,6 +30,7 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SortedList import androidx.recyclerview.widget.SortedList
import androidx.recyclerview.widget.SortedListAdapterCallback import androidx.recyclerview.widget.SortedListAdapterCallback
@@ -88,6 +90,8 @@ class NodesAdapter (
private var mNodeClickCallback: NodeClickCallback? = null private var mNodeClickCallback: NodeClickCallback? = null
private var mClipboardHelper = ClipboardHelper(context) private var mClipboardHelper = ClipboardHelper(context)
@ColorInt
private val mColorSurfaceContainer: Int
@ColorInt @ColorInt
private val mTextColorPrimary: Int private val mTextColorPrimary: Int
@ColorInt @ColorInt
@@ -95,9 +99,9 @@ class NodesAdapter (
@ColorInt @ColorInt
private val mTextColorSecondary: Int private val mTextColorSecondary: Int
@ColorInt @ColorInt
private val mColorAccentLight: Int private val mColorSecondary: Int
@ColorInt @ColorInt
private val mColorOnAccentColor: Int private val mColorOnSecondary: Int
/** /**
* Determine if the adapter contains or not any element * Determine if the adapter contains or not any element
@@ -114,6 +118,9 @@ class NodesAdapter (
this.mNodeSortedListCallback = NodeSortedListCallback() this.mNodeSortedListCallback = NodeSortedListCallback()
this.mNodeSortedList = SortedList(Node::class.java, mNodeSortedListCallback) this.mNodeSortedList = SortedList(Node::class.java, mNodeSortedListCallback)
val taColorSurfaceContainer = context.theme.obtainStyledAttributes(intArrayOf(R.attr.colorSurfaceContainer))
this.mColorSurfaceContainer = taColorSurfaceContainer.getColor(0, Color.BLACK)
taColorSurfaceContainer.recycle()
// Retrieve the color to tint the icon // Retrieve the color to tint the icon
val taTextColorPrimary = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColorPrimary)) val taTextColorPrimary = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColorPrimary))
this.mTextColorPrimary = taTextColorPrimary.getColor(0, Color.BLACK) this.mTextColorPrimary = taTextColorPrimary.getColor(0, Color.BLACK)
@@ -127,13 +134,13 @@ class NodesAdapter (
this.mTextColorSecondary = taTextColorSecondary.getColor(0, Color.BLACK) this.mTextColorSecondary = taTextColorSecondary.getColor(0, Color.BLACK)
taTextColorSecondary.recycle() taTextColorSecondary.recycle()
// To get background color for selection // To get background color for selection
val taColorAccentLight = context.theme.obtainStyledAttributes(intArrayOf(R.attr.colorAccentLight)) val taColorSecondary = context.theme.obtainStyledAttributes(intArrayOf(R.attr.colorSecondary))
this.mColorAccentLight = taColorAccentLight.getColor(0, Color.GRAY) this.mColorSecondary = taColorSecondary.getColor(0, Color.GRAY)
taColorAccentLight.recycle() taColorSecondary.recycle()
// To get text color for selection // To get text color for selection
val taColorOnAccentColor = context.theme.obtainStyledAttributes(intArrayOf(R.attr.colorOnAccentColor)) val taColorOnSecondary = context.theme.obtainStyledAttributes(intArrayOf(R.attr.colorOnSecondary))
this.mColorOnAccentColor = taColorOnAccentColor.getColor(0, Color.WHITE) this.mColorOnSecondary = taColorOnSecondary.getColor(0, Color.WHITE)
taColorOnAccentColor.recycle() taColorOnSecondary.recycle()
} }
private fun assignPreferences() { private fun assignPreferences() {
@@ -380,10 +387,10 @@ class NodesAdapter (
// Assign icon colors // Assign icon colors
var iconColor = if (holder.container.isSelected) var iconColor = if (holder.container.isSelected)
mColorOnAccentColor mColorOnSecondary
else when (subNode.type) { else when (subNode.type) {
Type.GROUP -> mTextColorPrimary Type.GROUP -> mTextColor
Type.ENTRY -> mTextColor Type.ENTRY -> mColorSecondary
} }
// Specific elements for entry // Specific elements for entry
@@ -428,16 +435,8 @@ class NodesAdapter (
if (entry.containsAttachment()) View.VISIBLE else View.GONE if (entry.containsAttachment()) View.VISIBLE else View.GONE
// Assign colors // Assign colors
val backgroundColor = if (mShowEntryColors) entry.backgroundColor else null assignBackgroundColor(holder.container, entry)
if (!holder.container.isSelected) { assignBackgroundColor(holder.otpContainer, entry)
if (backgroundColor != null) {
holder.container.setBackgroundColor(backgroundColor)
} else {
holder.container.setBackgroundColor(Color.TRANSPARENT)
}
} else {
holder.container.setBackgroundColor(mColorAccentLight)
}
val foregroundColor = if (mShowEntryColors) entry.foregroundColor else null val foregroundColor = if (mShowEntryColors) entry.foregroundColor else null
if (!holder.container.isSelected) { if (!holder.container.isSelected) {
if (foregroundColor != null) { if (foregroundColor != null) {
@@ -457,12 +456,12 @@ class NodesAdapter (
holder.meta.setTextColor(mTextColor) holder.meta.setTextColor(mTextColor)
} }
} else { } else {
holder.text.setTextColor(mColorOnAccentColor) holder.text.setTextColor(mColorOnSecondary)
holder.subText?.setTextColor(mColorOnAccentColor) holder.subText?.setTextColor(mColorOnSecondary)
holder.otpToken?.setTextColor(mColorOnAccentColor) holder.otpToken?.setTextColor(mColorOnSecondary)
holder.otpProgress?.setIndicatorColor(mColorOnAccentColor) holder.otpProgress?.setIndicatorColor(mColorOnSecondary)
holder.attachmentIcon?.setColorFilter(mColorOnAccentColor) holder.attachmentIcon?.setColorFilter(mColorOnSecondary)
holder.meta.setTextColor(mColorOnAccentColor) holder.meta.setTextColor(mColorOnSecondary)
} }
database.stopManageEntry(entry) database.stopManageEntry(entry)
@@ -528,7 +527,8 @@ class NodesAdapter (
try { try {
mClipboardHelper.copyToClipboard( mClipboardHelper.copyToClipboard(
TemplateField.getLocalizedName(context, TemplateField.LABEL_TOKEN), TemplateField.getLocalizedName(context, TemplateField.LABEL_TOKEN),
token token,
true
) )
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Unable to copy the OTP token", e) Log.e(TAG, "Unable to copy the OTP token", e)
@@ -537,6 +537,22 @@ class NodesAdapter (
} }
} }
private fun assignBackgroundColor(view: View?, entry: Entry) {
view?.let {
ViewCompat.setBackgroundTintList(
view,
ColorStateList.valueOf(
if (!view.isSelected) {
(if (mShowEntryColors) entry.backgroundColor else null)
?: mColorSurfaceContainer
} else {
mColorSecondary
}
)
)
}
}
class OtpRunnable(val view: View?): Runnable { class OtpRunnable(val view: View?): Runnable {
var action: (() -> Unit)? = null var action: (() -> Unit)? = null

View File

@@ -221,8 +221,6 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
allowOpenBiometricPrompt = true allowOpenBiometricPrompt = true
if (PreferencesUtil.isBiometricUnlockEnable(context)) { if (PreferencesUtil.isBiometricUnlockEnable(context)) {
mAdvancedUnlockInfoView?.setIconResource(R.drawable.fingerprint)
// biometric not supported (by API level or hardware) so keep option hidden // biometric not supported (by API level or hardware) so keep option hidden
// or manually disable // or manually disable
val biometricCanAuthenticate = AdvancedUnlockManager.canAuthenticate(context) val biometricCanAuthenticate = AdvancedUnlockManager.canAuthenticate(context)
@@ -241,7 +239,6 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
} }
} }
} else if (PreferencesUtil.isDeviceCredentialUnlockEnable(context)) { } else if (PreferencesUtil.isDeviceCredentialUnlockEnable(context)) {
mAdvancedUnlockInfoView?.setIconResource(R.drawable.bolt)
if (AdvancedUnlockManager.isDeviceSecure(context)) { if (AdvancedUnlockManager.isDeviceSecure(context)) {
selectMode() selectMode()
} else { } else {
@@ -297,12 +294,12 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
private fun initNotAvailable() { private fun initNotAvailable() {
showViews(false) showViews(false)
mAdvancedUnlockInfoView?.setIconViewClickListener(false, null) mAdvancedUnlockInfoView?.setIconViewClickListener(null)
} }
@RequiresApi(Build.VERSION_CODES.M) @RequiresApi(Build.VERSION_CODES.M)
private fun openBiometricSetting() { private fun openBiometricSetting() {
mAdvancedUnlockInfoView?.setIconViewClickListener(false) { mAdvancedUnlockInfoView?.setIconViewClickListener {
try { try {
when { when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> { Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> {
@@ -351,11 +348,11 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
@RequiresApi(Build.VERSION_CODES.M) @RequiresApi(Build.VERSION_CODES.M)
private fun initWaitData() { private fun initWaitData() {
showViews(true) showViews(true)
setAdvancedUnlockedTitleView(R.string.no_credentials_stored) setAdvancedUnlockedTitleView(R.string.unavailable)
setAdvancedUnlockedMessageView("") setAdvancedUnlockedMessageView("")
context?.let { context -> context?.let { context ->
mAdvancedUnlockInfoView?.setIconViewClickListener(false) { mAdvancedUnlockInfoView?.setIconViewClickListener {
onAuthenticationError(BiometricPrompt.ERROR_UNABLE_TO_PROCESS, onAuthenticationError(BiometricPrompt.ERROR_UNABLE_TO_PROCESS,
context.getString(R.string.credential_before_click_advanced_unlock_button)) context.getString(R.string.credential_before_click_advanced_unlock_button))
} }
@@ -382,7 +379,7 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
@RequiresApi(Build.VERSION_CODES.M) @RequiresApi(Build.VERSION_CODES.M)
private fun initEncryptData() { private fun initEncryptData() {
showViews(true) showViews(true)
setAdvancedUnlockedTitleView(R.string.open_advanced_unlock_prompt_store_credential) setAdvancedUnlockedTitleView(R.string.unlock_and_link_biometric)
setAdvancedUnlockedMessageView("") setAdvancedUnlockedMessageView("")
advancedUnlockManager?.initEncryptData { cryptoPrompt -> advancedUnlockManager?.initEncryptData { cryptoPrompt ->
@@ -396,7 +393,7 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
@RequiresApi(Build.VERSION_CODES.M) @RequiresApi(Build.VERSION_CODES.M)
private fun initDecryptData() { private fun initDecryptData() {
showViews(true) showViews(true)
setAdvancedUnlockedTitleView(R.string.open_advanced_unlock_prompt_unlock_database) setAdvancedUnlockedTitleView(R.string.unlock)
setAdvancedUnlockedMessageView("") setAdvancedUnlockedMessageView("")
advancedUnlockManager?.let { unlockHelper -> advancedUnlockManager?.let { unlockHelper ->
@@ -629,7 +626,7 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
@RequiresApi(Build.VERSION_CODES.M) @RequiresApi(Build.VERSION_CODES.M)
private fun setAdvancedUnlockedMessageView(text: CharSequence) { private fun setAdvancedUnlockedMessageView(text: CharSequence) {
lifecycleScope.launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
mAdvancedUnlockInfoView?.message = text mAdvancedUnlockInfoView?.setMessage(text)
} }
} }

View File

@@ -1,63 +0,0 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePassDX.
*
* KeePassDX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePassDX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.biometric
import android.content.Context
import android.graphics.drawable.Drawable
import android.os.Build
import androidx.annotation.RequiresApi
import android.widget.ImageView
import androidx.vectordrawable.graphics.drawable.Animatable2Compat
import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
import com.kunzisoft.keepass.R
@RequiresApi(api = Build.VERSION_CODES.M)
class FingerPrintAnimatedVector(context: Context, imageView: ImageView) {
private val scanFingerprint: AnimatedVectorDrawableCompat? =
AnimatedVectorDrawableCompat.create(context, R.drawable.scan_fingerprint)
init {
imageView.setImageDrawable(scanFingerprint)
}
private var animationCallback = object : Animatable2Compat.AnimationCallback() {
override fun onAnimationEnd(drawable: Drawable) {
imageView.post {
scanFingerprint?.start()
}
}
}
fun startScan() {
scanFingerprint?.registerAnimationCallback(animationCallback)
if (scanFingerprint?.isRunning != true)
scanFingerprint?.start()
}
fun stopScan() {
scanFingerprint?.unregisterAnimationCallback(animationCallback)
if (scanFingerprint?.isRunning == true)
scanFingerprint.stop()
}
}

View File

@@ -20,7 +20,6 @@
package com.kunzisoft.keepass.database package com.kunzisoft.keepass.database
import android.Manifest import android.Manifest
import android.app.AlertDialog
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.ComponentName import android.content.ComponentName
import android.content.Context import android.content.Context
@@ -38,6 +37,7 @@ import android.os.IBinder
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat.shouldShowRequestPermissionRationale import androidx.core.app.ActivityCompat.shouldShowRequestPermissionRationale
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
@@ -107,7 +107,7 @@ class DatabaseTaskProvider(
// To show dialog only if context is an activity // To show dialog only if context is an activity
private var activity: FragmentActivity? = try { context as? FragmentActivity? } private var activity: FragmentActivity? = try { context as? FragmentActivity? }
catch (_: Exception) { null } catch (_: Exception) { null }
var onDatabaseRetrieved: ((database: ContextualDatabase?) -> Unit)? = null var onDatabaseRetrieved: ((database: ContextualDatabase?) -> Unit)? = null
@@ -252,12 +252,10 @@ class DatabaseTaskProvider(
serviceConnection = object : ServiceConnection { serviceConnection = object : ServiceConnection {
override fun onBindingDied(name: ComponentName?) { override fun onBindingDied(name: ComponentName?) {
stopDialog() stopDialog()
super.onBindingDied(name)
} }
override fun onNullBinding(name: ComponentName?) { override fun onNullBinding(name: ComponentName?) {
stopDialog() stopDialog()
super.onNullBinding(name)
} }
override fun onServiceConnected(name: ComponentName?, serviceBinder: IBinder?) { override fun onServiceConnected(name: ComponentName?, serviceBinder: IBinder?) {
@@ -323,10 +321,10 @@ class DatabaseTaskProvider(
} }
} }
context.registerReceiver(databaseTaskBroadcastReceiver, context.registerReceiver(databaseTaskBroadcastReceiver,
IntentFilter().apply { IntentFilter().apply {
addAction(DATABASE_START_TASK_ACTION) addAction(DATABASE_START_TASK_ACTION)
addAction(DATABASE_STOP_TASK_ACTION) addAction(DATABASE_STOP_TASK_ACTION)
} }
) )
// Check if a service is currently running else do nothing // Check if a service is currently running else do nothing
@@ -350,12 +348,12 @@ class DatabaseTaskProvider(
private val requestPermissionLauncher = activity?.registerForActivityResult( private val requestPermissionLauncher = activity?.registerForActivityResult(
ActivityResultContracts.RequestPermission() ActivityResultContracts.RequestPermission()
) { _ -> ) { _ ->
// Whether or not the user has accepted, the service can be started, // Whether or not the user has accepted, the service can be started,
// There just won't be any notification if it's not allowed. // There just won't be any notification if it's not allowed.
tempServiceParameters.removeFirstOrNull()?.let { tempServiceParameters.removeFirstOrNull()?.let {
startService(it.first, it.second) startService(it.first, it.second)
}
} }
}
private fun start(bundle: Bundle? = null, actionTask: String) { private fun start(bundle: Bundle? = null, actionTask: String) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
@@ -372,7 +370,7 @@ class DatabaseTaskProvider(
// it's not the first time, so the user deliberately chooses not to display the notification // it's not the first time, so the user deliberately chooses not to display the notification
startService(bundle, actionTask) startService(bundle, actionTask)
} else { } else {
AlertDialog.Builder(activity) AlertDialog.Builder(context)
.setMessage(R.string.warning_database_notification_permission) .setMessage(R.string.warning_database_notification_permission)
.setNegativeButton(R.string.later) { _, _ -> .setNegativeButton(R.string.later) { _, _ ->
// Refuses the notification, so start the service // Refuses the notification, so start the service
@@ -414,7 +412,7 @@ class DatabaseTaskProvider(
putParcelable(DatabaseTaskNotificationService.DATABASE_URI_KEY, databaseUri) putParcelable(DatabaseTaskNotificationService.DATABASE_URI_KEY, databaseUri)
putParcelable(DatabaseTaskNotificationService.MAIN_CREDENTIAL_KEY, mainCredential) putParcelable(DatabaseTaskNotificationService.MAIN_CREDENTIAL_KEY, mainCredential)
} }
, ACTION_DATABASE_CREATE_TASK) , ACTION_DATABASE_CREATE_TASK)
} }
fun startDatabaseLoad(databaseUri: Uri, fun startDatabaseLoad(databaseUri: Uri,
@@ -429,7 +427,7 @@ class DatabaseTaskProvider(
putParcelable(DatabaseTaskNotificationService.CIPHER_DATABASE_KEY, cipherEncryptDatabase) putParcelable(DatabaseTaskNotificationService.CIPHER_DATABASE_KEY, cipherEncryptDatabase)
putBoolean(DatabaseTaskNotificationService.FIX_DUPLICATE_UUID_KEY, fixDuplicateUuid) putBoolean(DatabaseTaskNotificationService.FIX_DUPLICATE_UUID_KEY, fixDuplicateUuid)
} }
, ACTION_DATABASE_LOAD_TASK) , ACTION_DATABASE_LOAD_TASK)
} }
fun startDatabaseMerge(save: Boolean, fun startDatabaseMerge(save: Boolean,
@@ -447,7 +445,7 @@ class DatabaseTaskProvider(
start(Bundle().apply { start(Bundle().apply {
putBoolean(DatabaseTaskNotificationService.FIX_DUPLICATE_UUID_KEY, fixDuplicateUuid) putBoolean(DatabaseTaskNotificationService.FIX_DUPLICATE_UUID_KEY, fixDuplicateUuid)
} }
, ACTION_DATABASE_RELOAD_TASK) , ACTION_DATABASE_RELOAD_TASK)
} }
fun askToStartDatabaseReload(conditionToAsk: Boolean, approved: () -> Unit) { fun askToStartDatabaseReload(conditionToAsk: Boolean, approved: () -> Unit) {
@@ -471,7 +469,7 @@ class DatabaseTaskProvider(
putParcelable(DatabaseTaskNotificationService.DATABASE_URI_KEY, databaseUri) putParcelable(DatabaseTaskNotificationService.DATABASE_URI_KEY, databaseUri)
putParcelable(DatabaseTaskNotificationService.MAIN_CREDENTIAL_KEY, mainCredential) putParcelable(DatabaseTaskNotificationService.MAIN_CREDENTIAL_KEY, mainCredential)
} }
, ACTION_DATABASE_ASSIGN_CREDENTIAL_TASK) , ACTION_DATABASE_ASSIGN_CREDENTIAL_TASK)
} }
/* /*
@@ -488,7 +486,7 @@ class DatabaseTaskProvider(
putParcelable(DatabaseTaskNotificationService.PARENT_ID_KEY, parent.nodeId) putParcelable(DatabaseTaskNotificationService.PARENT_ID_KEY, parent.nodeId)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_CREATE_GROUP_TASK) , ACTION_DATABASE_CREATE_GROUP_TASK)
} }
fun startDatabaseUpdateGroup(oldGroup: Group, fun startDatabaseUpdateGroup(oldGroup: Group,
@@ -499,7 +497,7 @@ class DatabaseTaskProvider(
putParcelable(DatabaseTaskNotificationService.GROUP_KEY, groupToUpdate) putParcelable(DatabaseTaskNotificationService.GROUP_KEY, groupToUpdate)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_UPDATE_GROUP_TASK) , ACTION_DATABASE_UPDATE_GROUP_TASK)
} }
fun startDatabaseCreateEntry(newEntry: Entry, fun startDatabaseCreateEntry(newEntry: Entry,
@@ -510,7 +508,7 @@ class DatabaseTaskProvider(
putParcelable(DatabaseTaskNotificationService.PARENT_ID_KEY, parent.nodeId) putParcelable(DatabaseTaskNotificationService.PARENT_ID_KEY, parent.nodeId)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_CREATE_ENTRY_TASK) , ACTION_DATABASE_CREATE_ENTRY_TASK)
} }
fun startDatabaseUpdateEntry(oldEntry: Entry, fun startDatabaseUpdateEntry(oldEntry: Entry,
@@ -521,7 +519,7 @@ class DatabaseTaskProvider(
putParcelable(DatabaseTaskNotificationService.ENTRY_KEY, entryToUpdate) putParcelable(DatabaseTaskNotificationService.ENTRY_KEY, entryToUpdate)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_UPDATE_ENTRY_TASK) , ACTION_DATABASE_UPDATE_ENTRY_TASK)
} }
private fun startDatabaseActionListNodes(actionTask: String, private fun startDatabaseActionListNodes(actionTask: String,
@@ -550,7 +548,7 @@ class DatabaseTaskProvider(
putParcelable(DatabaseTaskNotificationService.PARENT_ID_KEY, newParentId) putParcelable(DatabaseTaskNotificationService.PARENT_ID_KEY, newParentId)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, actionTask) , actionTask)
} }
fun startDatabaseCopyNodes(nodesToCopy: List<Node>, fun startDatabaseCopyNodes(nodesToCopy: List<Node>,
@@ -584,7 +582,7 @@ class DatabaseTaskProvider(
putInt(DatabaseTaskNotificationService.ENTRY_HISTORY_POSITION_KEY, entryHistoryPosition) putInt(DatabaseTaskNotificationService.ENTRY_HISTORY_POSITION_KEY, entryHistoryPosition)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_RESTORE_ENTRY_HISTORY) , ACTION_DATABASE_RESTORE_ENTRY_HISTORY)
} }
fun startDatabaseDeleteEntryHistory(mainEntryId: NodeId<UUID>, fun startDatabaseDeleteEntryHistory(mainEntryId: NodeId<UUID>,
@@ -595,7 +593,7 @@ class DatabaseTaskProvider(
putInt(DatabaseTaskNotificationService.ENTRY_HISTORY_POSITION_KEY, entryHistoryPosition) putInt(DatabaseTaskNotificationService.ENTRY_HISTORY_POSITION_KEY, entryHistoryPosition)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_DELETE_ENTRY_HISTORY) , ACTION_DATABASE_DELETE_ENTRY_HISTORY)
} }
/* /*
@@ -612,7 +610,7 @@ class DatabaseTaskProvider(
putString(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newName) putString(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newName)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_UPDATE_NAME_TASK) , ACTION_DATABASE_UPDATE_NAME_TASK)
} }
fun startDatabaseSaveDescription(oldDescription: String, fun startDatabaseSaveDescription(oldDescription: String,
@@ -623,7 +621,7 @@ class DatabaseTaskProvider(
putString(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newDescription) putString(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newDescription)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_UPDATE_DESCRIPTION_TASK) , ACTION_DATABASE_UPDATE_DESCRIPTION_TASK)
} }
fun startDatabaseSaveDefaultUsername(oldDefaultUsername: String, fun startDatabaseSaveDefaultUsername(oldDefaultUsername: String,
@@ -634,7 +632,7 @@ class DatabaseTaskProvider(
putString(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newDefaultUsername) putString(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newDefaultUsername)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_UPDATE_DEFAULT_USERNAME_TASK) , ACTION_DATABASE_UPDATE_DEFAULT_USERNAME_TASK)
} }
fun startDatabaseSaveColor(oldColor: String, fun startDatabaseSaveColor(oldColor: String,
@@ -645,7 +643,7 @@ class DatabaseTaskProvider(
putString(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newColor) putString(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newColor)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_UPDATE_COLOR_TASK) , ACTION_DATABASE_UPDATE_COLOR_TASK)
} }
fun startDatabaseSaveCompression(oldCompression: CompressionAlgorithm, fun startDatabaseSaveCompression(oldCompression: CompressionAlgorithm,
@@ -656,14 +654,14 @@ class DatabaseTaskProvider(
putSerializable(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newCompression) putSerializable(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newCompression)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_UPDATE_COMPRESSION_TASK) , ACTION_DATABASE_UPDATE_COMPRESSION_TASK)
} }
fun startDatabaseRemoveUnlinkedData(save: Boolean) { fun startDatabaseRemoveUnlinkedData(save: Boolean) {
start(Bundle().apply { start(Bundle().apply {
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_REMOVE_UNLINKED_DATA_TASK) , ACTION_DATABASE_REMOVE_UNLINKED_DATA_TASK)
} }
fun startDatabaseSaveRecycleBin(oldRecycleBin: Group?, fun startDatabaseSaveRecycleBin(oldRecycleBin: Group?,
@@ -696,7 +694,7 @@ class DatabaseTaskProvider(
putInt(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newMaxHistoryItems) putInt(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newMaxHistoryItems)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_UPDATE_MAX_HISTORY_ITEMS_TASK) , ACTION_DATABASE_UPDATE_MAX_HISTORY_ITEMS_TASK)
} }
fun startDatabaseSaveMaxHistorySize(oldMaxHistorySize: Long, fun startDatabaseSaveMaxHistorySize(oldMaxHistorySize: Long,
@@ -707,7 +705,7 @@ class DatabaseTaskProvider(
putLong(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newMaxHistorySize) putLong(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newMaxHistorySize)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_UPDATE_MAX_HISTORY_SIZE_TASK) , ACTION_DATABASE_UPDATE_MAX_HISTORY_SIZE_TASK)
} }
/* /*
@@ -724,7 +722,7 @@ class DatabaseTaskProvider(
putSerializable(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newEncryption) putSerializable(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newEncryption)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_UPDATE_ENCRYPTION_TASK) , ACTION_DATABASE_UPDATE_ENCRYPTION_TASK)
} }
fun startDatabaseSaveKeyDerivation(oldKeyDerivation: KdfEngine, fun startDatabaseSaveKeyDerivation(oldKeyDerivation: KdfEngine,
@@ -735,7 +733,7 @@ class DatabaseTaskProvider(
putSerializable(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newKeyDerivation) putSerializable(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newKeyDerivation)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_UPDATE_KEY_DERIVATION_TASK) , ACTION_DATABASE_UPDATE_KEY_DERIVATION_TASK)
} }
fun startDatabaseSaveIterations(oldIterations: Long, fun startDatabaseSaveIterations(oldIterations: Long,
@@ -746,7 +744,7 @@ class DatabaseTaskProvider(
putLong(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newIterations) putLong(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newIterations)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_UPDATE_ITERATIONS_TASK) , ACTION_DATABASE_UPDATE_ITERATIONS_TASK)
} }
fun startDatabaseSaveMemoryUsage(oldMemoryUsage: Long, fun startDatabaseSaveMemoryUsage(oldMemoryUsage: Long,
@@ -757,7 +755,7 @@ class DatabaseTaskProvider(
putLong(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newMemoryUsage) putLong(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newMemoryUsage)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_UPDATE_MEMORY_USAGE_TASK) , ACTION_DATABASE_UPDATE_MEMORY_USAGE_TASK)
} }
fun startDatabaseSaveParallelism(oldParallelism: Long, fun startDatabaseSaveParallelism(oldParallelism: Long,
@@ -768,7 +766,7 @@ class DatabaseTaskProvider(
putLong(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newParallelism) putLong(DatabaseTaskNotificationService.NEW_ELEMENT_KEY, newParallelism)
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
} }
, ACTION_DATABASE_UPDATE_PARALLELISM_TASK) , ACTION_DATABASE_UPDATE_PARALLELISM_TASK)
} }
/** /**
@@ -779,14 +777,14 @@ class DatabaseTaskProvider(
putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save) putBoolean(DatabaseTaskNotificationService.SAVE_DATABASE_KEY, save)
putParcelable(DatabaseTaskNotificationService.DATABASE_URI_KEY, saveToUri) putParcelable(DatabaseTaskNotificationService.DATABASE_URI_KEY, saveToUri)
} }
, ACTION_DATABASE_SAVE) , ACTION_DATABASE_SAVE)
} }
fun startChallengeResponded(response: ByteArray?) { fun startChallengeResponded(response: ByteArray?) {
start(Bundle().apply { start(Bundle().apply {
putByteArray(DatabaseTaskNotificationService.DATA_BYTES, response) putByteArray(DatabaseTaskNotificationService.DATA_BYTES, response)
} }
, ACTION_CHALLENGE_RESPONDED) , ACTION_CHALLENGE_RESPONDED)
} }
companion object { companion object {

View File

@@ -98,7 +98,7 @@ open class Education(val activity: Activity) {
} }
protected fun getCircleColor(): Int { protected fun getCircleColor(): Int {
val typedArray = activity.obtainStyledAttributes(intArrayOf(R.attr.educationCircleColor)) val typedArray = activity.obtainStyledAttributes(intArrayOf(R.attr.colorPrimaryContainer))
val colorControl = typedArray.getColor(0, Color.GREEN) val colorControl = typedArray.getColor(0, Color.GREEN)
typedArray.recycle() typedArray.recycle()
return colorControl return colorControl
@@ -109,7 +109,7 @@ open class Education(val activity: Activity) {
} }
protected fun getTextColor(): Int { protected fun getTextColor(): Int {
val typedArray = activity.obtainStyledAttributes(intArrayOf(R.attr.educationTextColor)) val typedArray = activity.obtainStyledAttributes(intArrayOf(R.attr.colorOnPrimaryContainer))
val colorControl = typedArray.getColor(0, Color.WHITE) val colorControl = typedArray.getColor(0, Color.WHITE)
typedArray.recycle() typedArray.recycle()
return colorControl return colorControl

View File

@@ -93,8 +93,9 @@ class PasswordActivityEducation(activity: Activity)
activity.getString(R.string.education_advanced_unlock_summary)) activity.getString(R.string.education_advanced_unlock_summary))
.outerCircleColorInt(getCircleColor()) .outerCircleColorInt(getCircleColor())
.outerCircleAlpha(getCircleAlpha()) .outerCircleAlpha(getCircleAlpha())
.icon(ContextCompat.getDrawable(activity, R.drawable.ic_fingerprint_24))
.textColorInt(getTextColor()) .textColorInt(getTextColor())
.tintTarget(false) .tintTarget(true)
.cancelable(true), .cancelable(true),
object : TapTargetView.Listener() { object : TapTargetView.Listener() {
override fun onTargetClick(view: TapTargetView) { override fun onTargetClick(view: TapTargetView) {

View File

@@ -240,10 +240,10 @@ class AttachmentFileNotificationService: LockNotificationService() {
setOngoing(true) setOngoing(true)
} }
AttachmentState.IN_PROGRESS -> { AttachmentState.IN_PROGRESS -> {
if (attachmentNotification.entryAttachmentState.downloadProgression > 100) { if (attachmentNotification.entryAttachmentState.downloadProgression > FILE_PROGRESSION_MAX) {
setContentText(getString(R.string.download_finalization)) setContentText(getString(R.string.download_finalization))
} else { } else {
setProgress(100, setProgress(FILE_PROGRESSION_MAX,
attachmentNotification.entryAttachmentState.downloadProgression, attachmentNotification.entryAttachmentState.downloadProgression,
false) false)
setContentText(getString(R.string.download_progression, setContentText(getString(R.string.download_progression,
@@ -446,7 +446,7 @@ class AttachmentFileNotificationService: LockNotificationService() {
if (downloadState != AttachmentState.CANCELED if (downloadState != AttachmentState.CANCELED
&& downloadState != AttachmentState.ERROR) { && downloadState != AttachmentState.ERROR) {
downloadState = AttachmentState.COMPLETE downloadState = AttachmentState.COMPLETE
downloadProgression = 100 downloadProgression = FILE_PROGRESSION_MAX
} }
} }
attachmentNotification.attachmentFileAction = null attachmentNotification.attachmentFileAction = null
@@ -495,6 +495,8 @@ class AttachmentFileNotificationService: LockNotificationService() {
const val FILE_URI_KEY = "FILE_URI_KEY" const val FILE_URI_KEY = "FILE_URI_KEY"
const val ATTACHMENT_KEY = "ATTACHMENT_KEY" const val ATTACHMENT_KEY = "ATTACHMENT_KEY"
const val FILE_PROGRESSION_MAX = 100
} }
} }

View File

@@ -23,7 +23,7 @@ import android.os.Bundle
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
class SettingsAdvancedUnlockActivity : SettingsActivity() { class AdvancedUnlockSettingsActivity : SettingsActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePassDX.
*
* KeePassDX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePassDX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings
import android.os.Bundle
import android.view.MenuItem
import androidx.fragment.app.Fragment
class AppearanceSettingsActivity : SettingsActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mTimeoutEnable = false
setTitle(NestedSettingsFragment.Screen.APPEARANCE)
}
override fun retrieveMainFragment(): Fragment {
return NestedSettingsFragment.newInstance(NestedSettingsFragment.Screen.APPEARANCE)
}
}

View File

@@ -24,7 +24,7 @@ import android.os.Bundle
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference import androidx.preference.TwoStatePreference
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.settings.preferencedialogfragment.AutofillBlocklistAppIdPreferenceDialogFragmentCompat import com.kunzisoft.keepass.settings.preferencedialogfragment.AutofillBlocklistAppIdPreferenceDialogFragmentCompat
import com.kunzisoft.keepass.settings.preferencedialogfragment.AutofillBlocklistWebDomainPreferenceDialogFragmentCompat import com.kunzisoft.keepass.settings.preferencedialogfragment.AutofillBlocklistWebDomainPreferenceDialogFragmentCompat
@@ -35,7 +35,7 @@ class AutofillSettingsFragment : PreferenceFragmentCompat() {
// Load the preferences from an XML resource // Load the preferences from an XML resource
setPreferencesFromResource(R.xml.preferences_autofill, rootKey) setPreferencesFromResource(R.xml.preferences_autofill, rootKey)
val autofillInlineSuggestionsPreference: SwitchPreference? = findPreference(getString(R.string.autofill_inline_suggestions_key)) val autofillInlineSuggestionsPreference: TwoStatePreference? = findPreference(getString(R.string.autofill_inline_suggestions_key))
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
autofillInlineSuggestionsPreference?.isVisible = false autofillInlineSuggestionsPreference?.isVisible = false
} }

View File

@@ -24,6 +24,7 @@ import android.os.Bundle
import android.view.View import android.view.View
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.viewmodels.DatabaseViewModel import com.kunzisoft.keepass.viewmodels.DatabaseViewModel
@@ -60,6 +61,9 @@ class MainPreferenceFragment : PreferenceFragmentCompat() {
private fun checkDatabaseLoaded() { private fun checkDatabaseLoaded() {
findPreference<Preference>(getString(R.string.settings_database_key)) findPreference<Preference>(getString(R.string.settings_database_key))
?.isEnabled = mDatabaseLoaded ?.isEnabled = mDatabaseLoaded
findPreference<PreferenceCategory>(getString(R.string.settings_database_category_key))
?.isVisible = mDatabaseLoaded
} }
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {

View File

@@ -34,7 +34,7 @@ import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.preference.ListPreference import androidx.preference.ListPreference
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.SwitchPreference import androidx.preference.TwoStatePreference
import com.kunzisoft.keepass.BuildConfig import com.kunzisoft.keepass.BuildConfig
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.ProFeatureDialogFragment import com.kunzisoft.keepass.activities.dialogs.ProFeatureDialogFragment
@@ -119,14 +119,14 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
activity?.let { activity -> activity?.let { activity ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val autoFillEnablePreference: SwitchPreference? = findPreference(getString(R.string.settings_autofill_enable_key)) val autoFillEnablePreference: TwoStatePreference? = findPreference(getString(R.string.settings_autofill_enable_key))
val autofillManager = activity.getSystemService(AutofillManager::class.java) val autofillManager = activity.getSystemService(AutofillManager::class.java)
if (autofillManager != null && autofillManager.hasEnabledAutofillServices()) if (autofillManager != null && autofillManager.hasEnabledAutofillServices())
autoFillEnablePreference?.isChecked = autofillManager.hasEnabledAutofillServices() autoFillEnablePreference?.isChecked = autofillManager.hasEnabledAutofillServices()
autoFillEnablePreference?.onPreferenceClickListener = object : Preference.OnPreferenceClickListener { autoFillEnablePreference?.onPreferenceClickListener = object : Preference.OnPreferenceClickListener {
@RequiresApi(api = Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.O)
override fun onPreferenceClick(preference: Preference): Boolean { override fun onPreferenceClick(preference: Preference): Boolean {
if ((preference as SwitchPreference).isChecked) { if ((preference as TwoStatePreference).isChecked) {
try { try {
enableService() enableService()
} catch (e: ActivityNotFoundException) { } catch (e: ActivityNotFoundException) {
@@ -208,14 +208,13 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
false false
} }
val copyPasswordPreference: SwitchPreference? = findPreference(getString(R.string.allow_copy_password_key)) val copyPasswordPreference: TwoStatePreference? = findPreference(getString(R.string.allow_copy_password_key))
copyPasswordPreference?.setOnPreferenceChangeListener { _, newValue -> copyPasswordPreference?.setOnPreferenceChangeListener { _, newValue ->
if (newValue as Boolean && context != null) { if (newValue as Boolean && context != null) {
val message = getString(R.string.allow_copy_password_warning) + val message = getString(R.string.allow_copy_password_warning) +
"\n\n" + "\n\n" +
getString(R.string.clipboard_warning) getString(R.string.clipboard_warning)
AlertDialog AlertDialog.Builder(requireContext())
.Builder(requireContext())
.setMessage(message) .setMessage(message)
.create() .create()
.apply { .apply {
@@ -240,10 +239,10 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
activity?.let { activity -> activity?.let { activity ->
val biometricUnlockEnablePreference: SwitchPreference? = findPreference(getString(R.string.biometric_unlock_enable_key)) val biometricUnlockEnablePreference: TwoStatePreference? = findPreference(getString(R.string.biometric_unlock_enable_key))
val deviceCredentialUnlockEnablePreference: SwitchPreference? = findPreference(getString(R.string.device_credential_unlock_enable_key)) val deviceCredentialUnlockEnablePreference: TwoStatePreference? = findPreference(getString(R.string.device_credential_unlock_enable_key))
val autoOpenPromptPreference: SwitchPreference? = findPreference(getString(R.string.biometric_auto_open_prompt_key)) val autoOpenPromptPreference: TwoStatePreference? = findPreference(getString(R.string.biometric_auto_open_prompt_key))
val tempAdvancedUnlockPreference: SwitchPreference? = findPreference(getString(R.string.temp_advanced_unlock_enable_key)) val tempAdvancedUnlockPreference: TwoStatePreference? = findPreference(getString(R.string.temp_advanced_unlock_enable_key))
val biometricUnlockSupported = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { val biometricUnlockSupported = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
AdvancedUnlockManager.biometricUnlockSupported(activity) AdvancedUnlockManager.biometricUnlockSupported(activity)
@@ -253,7 +252,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
if (!biometricUnlockSupported) { if (!biometricUnlockSupported) {
isChecked = false isChecked = false
setOnPreferenceClickListener { preference -> setOnPreferenceClickListener { preference ->
(preference as SwitchPreference).isChecked = false (preference as TwoStatePreference).isChecked = false
UnavailableFeatureDialogFragment.getInstance(Build.VERSION_CODES.M) UnavailableFeatureDialogFragment.getInstance(Build.VERSION_CODES.M)
.show(parentFragmentManager, "unavailableFeatureDialog") .show(parentFragmentManager, "unavailableFeatureDialog")
false false
@@ -300,7 +299,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
if (!deviceCredentialUnlockSupported) { if (!deviceCredentialUnlockSupported) {
isChecked = false isChecked = false
setOnPreferenceClickListener { preference -> setOnPreferenceClickListener { preference ->
(preference as SwitchPreference).isChecked = false (preference as TwoStatePreference).isChecked = false
UnavailableFeatureDialogFragment.getInstance(Build.VERSION_CODES.M) UnavailableFeatureDialogFragment.getInstance(Build.VERSION_CODES.M)
.show(parentFragmentManager, "unavailableFeatureDialog") .show(parentFragmentManager, "unavailableFeatureDialog")
false false
@@ -523,7 +522,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
super.onResume() super.onResume()
activity?.let { activity -> activity?.let { activity ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
findPreference<SwitchPreference?>(getString(R.string.settings_autofill_enable_key))?.let { autoFillEnablePreference -> findPreference<TwoStatePreference?>(getString(R.string.settings_autofill_enable_key))?.let { autoFillEnablePreference ->
val autofillManager = activity.getSystemService(AutofillManager::class.java) val autofillManager = activity.getSystemService(AutofillManager::class.java)
autoFillEnablePreference.isChecked = autofillManager != null autoFillEnablePreference.isChecked = autofillManager != null
&& autofillManager.hasEnabledAutofillServices() && autofillManager.hasEnabledAutofillServices()

View File

@@ -28,7 +28,7 @@ import androidx.fragment.app.DialogFragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceCategory import androidx.preference.PreferenceCategory
import androidx.preference.SwitchPreference import androidx.preference.TwoStatePreference
import com.kunzisoft.androidclearchroma.ChromaUtil import com.kunzisoft.androidclearchroma.ChromaUtil
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.SetMainCredentialDialogFragment import com.kunzisoft.keepass.activities.dialogs.SetMainCredentialDialogFragment
@@ -253,7 +253,7 @@ class NestedDatabaseSettingsFragment : NestedSettingsFragment(), DatabaseRetriev
// Recycle bin // Recycle bin
if (database.allowConfigurableRecycleBin) { if (database.allowConfigurableRecycleBin) {
val recycleBinEnablePref: SwitchPreference? = findPreference(getString(R.string.recycle_bin_enable_key)) val recycleBinEnablePref: TwoStatePreference? = findPreference(getString(R.string.recycle_bin_enable_key))
recycleBinEnablePref?.apply { recycleBinEnablePref?.apply {
isChecked = database.isRecycleBinEnabled isChecked = database.isRecycleBinEnabled
isEnabled = if (!mDatabaseReadOnly) { isEnabled = if (!mDatabaseReadOnly) {
@@ -286,7 +286,7 @@ class NestedDatabaseSettingsFragment : NestedSettingsFragment(), DatabaseRetriev
val templatesGroupPrefCategory: PreferenceCategory? = findPreference(getString(R.string.database_category_templates_key)) val templatesGroupPrefCategory: PreferenceCategory? = findPreference(getString(R.string.database_category_templates_key))
templatesGroupPref = findPreference(getString(R.string.templates_group_uuid_key)) templatesGroupPref = findPreference(getString(R.string.templates_group_uuid_key))
if (database.allowTemplatesGroup) { if (database.allowTemplatesGroup) {
val templatesEnablePref: SwitchPreference? = findPreference(getString(R.string.templates_group_enable_key)) val templatesEnablePref: TwoStatePreference? = findPreference(getString(R.string.templates_group_enable_key))
templatesEnablePref?.apply { templatesEnablePref?.apply {
isChecked = database.isTemplatesEnabled isChecked = database.isTemplatesEnabled
isEnabled = if (!mDatabaseReadOnly) { isEnabled = if (!mDatabaseReadOnly) {

View File

@@ -23,7 +23,7 @@ import android.content.res.Resources
import android.os.Bundle import android.os.Bundle
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference import androidx.preference.TwoStatePreference
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.UnderDevelopmentFeatureDialogFragment import com.kunzisoft.keepass.activities.dialogs.UnderDevelopmentFeatureDialogFragment
@@ -49,7 +49,7 @@ abstract class NestedSettingsFragment : PreferenceFragmentCompat() {
protected fun preferenceInDevelopment(preferenceInDev: Preference) { protected fun preferenceInDevelopment(preferenceInDev: Preference) {
preferenceInDev.setOnPreferenceClickListener { preference -> preferenceInDev.setOnPreferenceClickListener { preference ->
try { // don't check if we can try { // don't check if we can
(preference as SwitchPreference).isChecked = false (preference as TwoStatePreference).isChecked = false
} catch (ignored: Exception) { } catch (ignored: Exception) {
} }
UnderDevelopmentFeatureDialogFragment().show(parentFragmentManager, "underDevFeatureDialog") UnderDevelopmentFeatureDialogFragment().show(parentFragmentManager, "underDevFeatureDialog")

View File

@@ -70,7 +70,7 @@ abstract class InputPreferenceDialogFragmentCompat : PreferenceDialogFragmentCom
get() = textUnitView?.text?.toString() ?: "" get() = textUnitView?.text?.toString() ?: ""
set(unitText) { set(unitText) {
textUnitView?.apply { textUnitView?.apply {
if (unitText != null && unitText.isNotEmpty()) { if (!unitText.isNullOrEmpty()) {
text = unitText text = unitText
visibility = View.VISIBLE visibility = View.VISIBLE
} else { } else {
@@ -88,7 +88,7 @@ abstract class InputPreferenceDialogFragmentCompat : PreferenceDialogFragmentCom
get() = textExplanationView?.text?.toString() ?: "" get() = textExplanationView?.text?.toString() ?: ""
set(explanationText) { set(explanationText) {
textExplanationView?.apply { textExplanationView?.apply {
if (explanationText != null && explanationText.isNotEmpty()) { if (!explanationText.isNullOrEmpty()) {
text = explanationText text = explanationText
visibility = View.VISIBLE visibility = View.VISIBLE
} else { } else {
@@ -107,7 +107,7 @@ abstract class InputPreferenceDialogFragmentCompat : PreferenceDialogFragmentCom
fun setExplanationButton(explanationButtonText: String?, clickListener: View.OnClickListener) { fun setExplanationButton(explanationButtonText: String?, clickListener: View.OnClickListener) {
explanationButton?.apply { explanationButton?.apply {
if (explanationButtonText != null && explanationButtonText.isNotEmpty()) { if (!explanationButtonText.isNullOrEmpty()) {
text = explanationButtonText text = explanationButtonText
visibility = View.VISIBLE visibility = View.VISIBLE
setOnClickListener(clickListener) setOnClickListener(clickListener)

View File

@@ -34,7 +34,8 @@ import android.widget.Toast
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.settings.PreferencesUtil
import java.util.* import java.util.Timer
import java.util.TimerTask
class ClipboardHelper(context: Context) { class ClipboardHelper(context: Context) {

View File

@@ -43,7 +43,9 @@ class AddNodeButtonView @JvmOverloads constructor(context: Context,
var addButtonView: FloatingActionButton? = null var addButtonView: FloatingActionButton? = null
private lateinit var addEntryView: View private lateinit var addEntryView: View
private lateinit var fabAddEntryView: View
private lateinit var addGroupView: View private lateinit var addGroupView: View
private lateinit var fabAddGroupView: View
private var addEntryEnable: Boolean = false private var addEntryEnable: Boolean = false
private var addGroupEnable: Boolean = false private var addGroupEnable: Boolean = false
@@ -77,7 +79,9 @@ class AddNodeButtonView @JvmOverloads constructor(context: Context,
addButtonView = findViewById(R.id.add_button) addButtonView = findViewById(R.id.add_button)
addEntryView = findViewById(R.id.container_add_entry) addEntryView = findViewById(R.id.container_add_entry)
fabAddEntryView = findViewById(R.id.fab_add_entry)
addGroupView = findViewById(R.id.container_add_group) addGroupView = findViewById(R.id.container_add_group)
fabAddGroupView = findViewById(R.id.fab_add_group)
animationDuration = 300L animationDuration = 300L
@@ -189,24 +193,21 @@ class AddNodeButtonView @JvmOverloads constructor(context: Context,
} }
} }
private fun onButtonClickListener(onClickListener: OnClickListener) =
OnClickListener { view ->
onClickListener.onClick(view)
closeButtonIfOpen()
}
fun setAddGroupClickListener(onClickListener: OnClickListener) { fun setAddGroupClickListener(onClickListener: OnClickListener) {
if (addGroupEnable) if (addGroupEnable) {
addGroupView.setOnClickListener { view -> fabAddGroupView.setOnClickListener(onButtonClickListener(onClickListener))
onClickListener.onClick(view) }
closeButtonIfOpen()
}
} }
fun setAddEntryClickListener(onClickListener: OnClickListener) { fun setAddEntryClickListener(onClickListener: OnClickListener) {
if (addEntryEnable) { if (addEntryEnable) {
addEntryView.setOnClickListener { view -> fabAddEntryView.setOnClickListener(onButtonClickListener(onClickListener))
onClickListener.onClick(view)
closeButtonIfOpen()
}
addEntryView.setOnClickListener { view ->
onClickListener.onClick(view)
closeButtonIfOpen()
}
} }
} }

View File

@@ -23,14 +23,12 @@ import android.content.Context
import android.os.Build import android.os.Build
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.widget.Button
import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.Toast
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.annotation.StringRes import androidx.annotation.StringRes
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.biometric.FingerPrintAnimatedVector
@RequiresApi(api = Build.VERSION_CODES.M) @RequiresApi(api = Build.VERSION_CODES.M)
class AdvancedUnlockInfoView @JvmOverloads constructor(context: Context, class AdvancedUnlockInfoView @JvmOverloads constructor(context: Context,
@@ -38,83 +36,38 @@ class AdvancedUnlockInfoView @JvmOverloads constructor(context: Context,
defStyle: Int = 0) defStyle: Int = 0)
: LinearLayout(context, attrs, defStyle) { : LinearLayout(context, attrs, defStyle) {
private val unlockContainerView: View private var biometricButtonView: Button? = null
private var unlockAnimatedVector: FingerPrintAnimatedVector? = null
private var unlockTitleTextView: TextView? = null
private var unlockMessageTextView: TextView? = null
private var unlockIconImageView: ImageView? = null
init { init {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater? val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
inflater?.inflate(R.layout.view_advanced_unlock, this) inflater?.inflate(R.layout.view_advanced_unlock, this)
unlockContainerView = findViewById(R.id.fingerprint_container) biometricButtonView = findViewById(R.id.biometric_button)
unlockTitleTextView = findViewById(R.id.biometric_title)
unlockMessageTextView = findViewById(R.id.biometric_message)
unlockIconImageView = findViewById(R.id.biometric_image)
} }
private fun startIconViewAnimation() { fun setIconViewClickListener(listener: OnClickListener?) {
unlockAnimatedVector?.startScan() biometricButtonView?.setOnClickListener(listener)
}
private fun stopIconViewAnimation() {
unlockAnimatedVector?.stopScan()
}
fun setIconResource(iconId: Int) {
unlockIconImageView?.setImageResource(iconId)
// Init the fingerprint animation
unlockAnimatedVector = when (iconId) {
R.drawable.fingerprint -> FingerPrintAnimatedVector(context, unlockIconImageView!!)
else -> null
}
}
fun setIconViewClickListener(animation: Boolean = true,
listener: ((view: View)->Unit)?) {
var animateButton = animation
if (listener == null)
animateButton = false
if (animateButton) {
startIconViewAnimation()
unlockContainerView.alpha = 1f
} else {
stopIconViewAnimation()
unlockContainerView.alpha = 0.8f
}
unlockIconImageView?.setOnClickListener(listener)
} }
var title: CharSequence var title: CharSequence
get() { get() {
return unlockTitleTextView?.text?.toString() ?: "" return biometricButtonView?.text?.toString() ?: ""
} }
set(value) { set(value) {
unlockTitleTextView?.text = value biometricButtonView?.text = value
} }
fun setTitle(@StringRes textId: Int) { fun setTitle(@StringRes textId: Int) {
title = context.getString(textId) title = context.getString(textId)
} }
var message: CharSequence? fun setMessage(text: CharSequence) {
get() { if (text.isNotEmpty())
return unlockMessageTextView?.text?.toString() ?: "" Toast.makeText(context, text, Toast.LENGTH_LONG).show()
} }
set(value) {
if (value == null || value.isEmpty()) {
unlockMessageTextView?.visibility = GONE
} else {
unlockMessageTextView?.visibility = VISIBLE
stopIconViewAnimation()
}
unlockMessageTextView?.text = value ?: ""
}
fun setMessage(@StringRes textId: Int) { fun setMessage(@StringRes textId: Int) {
message = context.getString(textId) Toast.makeText(context, textId, Toast.LENGTH_LONG).show()
} }
} }

View File

@@ -1,3 +0,0 @@
package com.kunzisoft.keepass.view
data class DataDate(val year: Int, val month: Int, val day: Int)

View File

@@ -189,6 +189,8 @@ class SearchFiltersView @JvmOverloads constructor(context: Context,
searchParameters.searchInTemplates = isChecked searchParameters.searchInTemplates = isChecked
mOnParametersChangeListener?.invoke(searchParameters) mOnParametersChangeListener?.invoke(searchParameters)
} }
searchNumbers.setOnClickListener(null)
} }
fun setNumbers(numbers: Int) { fun setNumbers(numbers: Int) {

View File

@@ -217,14 +217,12 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
} }
} }
fun setCurrentDateTimeValue(date: DataDate) { fun setCurrentDateTimeValue(dateMilliseconds: Long) {
// Save the date // Save the date
setCurrentDateTimeSelection { instant -> setCurrentDateTimeSelection { instant ->
val newDateInstant = DateInstant( val newDateInstant = DateInstant(
DateTime(instant.date) DateTime(instant.date)
.withYear(date.year) .withMillis(dateMilliseconds)
.withMonthOfYear(date.month + 1)
.withDayOfMonth(date.day)
.toDate(), instant.type) .toDate(), instant.type)
if (instant.type == DateInstant.Type.DATE_TIME) { if (instant.type == DateInstant.Type.DATE_TIME) {
val instantTime = DateInstant(instant.date, DateInstant.Type.TIME) val instantTime = DateInstant(instant.date, DateInstant.Type.TIME)

View File

@@ -31,14 +31,14 @@ import android.view.View
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.appcompat.view.SupportMenuInflater import androidx.appcompat.view.SupportMenuInflater
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.google.android.material.appbar.MaterialToolbar
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
class ToolbarAction @JvmOverloads constructor(context: Context, class ToolbarAction @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
defStyle: Int = androidx.appcompat.R.attr.toolbarStyle) defStyle: Int = R.attr.toolbarActionStyle)
: Toolbar(context, attrs, defStyle) { : MaterialToolbar(context, attrs, defStyle) {
private var mActionModeCallback: ActionMode.Callback? = null private var mActionModeCallback: ActionMode.Callback? = null
private val actionMode = NodeActionMode(this) private val actionMode = NodeActionMode(this)
@@ -47,7 +47,7 @@ class ToolbarAction @JvmOverloads constructor(context: Context,
init { init {
ContextCompat.getDrawable(context, R.drawable.ic_close_white_24dp)?.let { closeDrawable -> ContextCompat.getDrawable(context, R.drawable.ic_close_white_24dp)?.let { closeDrawable ->
val typedValue = TypedValue() val typedValue = TypedValue()
context.theme.resolveAttribute(R.attr.colorControlNormal, typedValue, true) context.theme.resolveAttribute(R.attr.colorOnSurface, typedValue, true)
@ColorInt val colorControl = typedValue.data @ColorInt val colorControl = typedValue.data
closeDrawable.colorFilter = PorterDuffColorFilter(colorControl, PorterDuff.Mode.SRC_ATOP) closeDrawable.colorFilter = PorterDuffColorFilter(colorControl, PorterDuff.Mode.SRC_ATOP)
navigationIcon = closeDrawable navigationIcon = closeDrawable

View File

@@ -26,14 +26,14 @@ import android.util.AttributeSet
import android.util.TypedValue import android.util.TypedValue
import android.view.View import android.view.View
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.google.android.material.appbar.MaterialToolbar
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
class SpecialModeView @JvmOverloads constructor(context: Context, class ToolbarSpecial @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
defStyle: Int = androidx.appcompat.R.attr.toolbarStyle) defStyle: Int = R.attr.toolbarSpecialStyle)
: Toolbar(context, attrs, defStyle) { : MaterialToolbar(context, attrs, defStyle) {
init { init {
ContextCompat.getDrawable(context, R.drawable.ic_arrow_back_white_24dp)?.let { closeDrawable -> ContextCompat.getDrawable(context, R.drawable.ic_arrow_back_white_24dp)?.let { closeDrawable ->

View File

@@ -4,7 +4,6 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.kunzisoft.keepass.database.element.DateInstant import com.kunzisoft.keepass.database.element.DateInstant
import com.kunzisoft.keepass.database.element.icon.IconImage import com.kunzisoft.keepass.database.element.icon.IconImage
import com.kunzisoft.keepass.view.DataDate
import com.kunzisoft.keepass.view.DataTime import com.kunzisoft.keepass.view.DataTime
abstract class NodeEditViewModel : ViewModel() { abstract class NodeEditViewModel : ViewModel() {
@@ -24,8 +23,8 @@ abstract class NodeEditViewModel : ViewModel() {
val requestDateTimeSelection : LiveData<DateInstant> get() = _requestDateTimeSelection val requestDateTimeSelection : LiveData<DateInstant> get() = _requestDateTimeSelection
private val _requestDateTimeSelection = SingleLiveEvent<DateInstant>() private val _requestDateTimeSelection = SingleLiveEvent<DateInstant>()
val onDateSelected : LiveData<DataDate> get() = _onDateSelected val onDateSelected : LiveData<Long> get() = _onDateSelected
private val _onDateSelected = SingleLiveEvent<DataDate>() private val _onDateSelected = SingleLiveEvent<Long>()
val onTimeSelected : LiveData<DataTime> get() = _onTimeSelected val onTimeSelected : LiveData<DataTime> get() = _onTimeSelected
private val _onTimeSelected = SingleLiveEvent<DataTime>() private val _onTimeSelected = SingleLiveEvent<DataTime>()
@@ -58,8 +57,8 @@ abstract class NodeEditViewModel : ViewModel() {
_requestDateTimeSelection.value = dateInstant _requestDateTimeSelection.value = dateInstant
} }
fun selectDate(year: Int, month: Int, day: Int) { fun selectDate(dateMilliseconds: Long) {
_onDateSelected.value = DataDate(year, month, day) _onDateSelected.value = dateMilliseconds
} }
fun selectTime(hours: Int, minutes: Int) { fun selectTime(hours: Int, minutes: Int) {

View File

@@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<objectAnimator
android:propertyName="pathData"
android:valueFrom="@string/clip_path_scan_top"
android:valueTo="@string/clip_path_scan_bottom"
android:valueType="pathType"
android:duration="800"
android:interpolator="@android:interpolator/fast_out_slow_in" />
<objectAnimator
android:propertyName="pathData"
android:valueFrom="@string/clip_path_scan_bottom"
android:valueTo="@string/clip_path_scan_top"
android:valueType="pathType"
android:startOffset="50"
android:duration="500"
android:interpolator="@android:interpolator/fast_out_slow_in" />
</set>

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorAccent" />
</selector>

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorAccentLight" android:state_pressed="true" />
<item android:color="@color/white_grey" android:state_activated="true" />
<item android:color="@color/white_grey_darker" android:state_enabled="false" />
<item android:color="?attr/colorAccent" android:state_enabled="true" />
</selector>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorPrimaryDark" android:state_pressed="true" />
<item android:color="@color/white_grey_darker" android:state_enabled="false" />
<item android:color="?attr/colorPrimary" android:state_enabled="true" />
</selector>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/white_grey" android:state_activated="true" />
<item android:color="@color/white_grey_darker" android:state_enabled="false" />
<item android:color="?android:attr/textColorSecondaryInverse" android:state_enabled="true" />
</selector>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="0.97" android:color="?attr/chipFilterBackgroundColorDisabled" android:state_enabled="false" />
<item android:alpha="1.00" android:color="?attr/chipFilterBackgroundColor" android:state_checked="true" />
<item android:alpha="0.98" android:color="?attr/chipFilterBackgroundColor" />
</selector>

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2021 Jeremy Jamet / Kunzisoft.
This file is part of KeePassDX.
KeePassDX is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
KeePassDX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorAccent" android:state_focused="true"/>
<item android:alpha="0.46" android:color="?attr/colorOnSurface" android:state_hovered="true"/>
<item android:alpha="0.38" android:color="?attr/colorOnSurface" android:state_enabled="false"/>
<item android:alpha="0.42" android:color="?attr/colorOnSurface"/>
</selector>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="true" android:color="@color/white"/>
<item android:color="?android:attr/textColor"/>
</selector>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="true" android:color="@color/white"/>
<item android:color="@color/grey"/>
</selector>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:alpha="0.46" android:color="?attr/colorOnSurface" android:state_hovered="true"/>
<item android:alpha="0.38" android:color="?attr/colorOnSurface" android:state_enabled="false"/>
<item android:alpha="1.00" android:color="?attr/colorOnSurface"/>
</selector>

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/white_dark" />
</selector>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/white_grey" android:state_enabled="false" />
<item android:color="?attr/colorOnAccentColor" android:state_enabled="true" />
</selector>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_enabled="false" android:color="@color/white_grey_dark"/>
<item android:color="@color/grey_light"/>
</selector>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_enabled="false" android:color="@color/grey"/>
<item android:color="@color/white"/>
</selector>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_enabled="false" android:color="@color/white_grey_dark"/>
<item android:color="@color/grey_lighter"/>
</selector>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_enabled="false" android:color="@color/grey"/>
<item android:color="@color/white_grey_darker"/>
</selector>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" > <selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="true" android:color="?attr/colorOnAccentColor"/> <item android:state_selected="true" android:color="?attr/colorOnSecondary"/>
<item android:color="?android:attr/textColorPrimary"/> <item android:color="?attr/colorOnSurface"/>
</selector> </selector>

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="@color/white"
tools:targetApi="lollipop">
<item>
<shape>
<corners
android:radius="0dp" />
<padding
android:left="8dp"
android:right="8dp"
android:top="12dp"
android:bottom="12dp"/>
<solid android:color="?attr/colorAccent"/>
</shape>
</item>
</ripple>

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="@color/white"
tools:targetApi="lollipop">
<item>
<layer-list>
<item android:bottom="2dp" android:left="2dp">
<shape>
<corners
android:radius="8dp" />
<padding
android:left="14dp"
android:right="14dp"
android:top="4dp"
android:bottom="8dp"/>
<solid android:color="?attr/colorAccent"/>
</shape>
</item>
</layer-list>
</item>
</ripple>

View File

@@ -11,7 +11,7 @@
android:right="12dp" android:right="12dp"
android:top="12dp" android:top="12dp"
android:bottom="12dp"/> android:bottom="12dp"/>
<solid android:color="?attr/colorAccent"/> <solid android:color="?attr/colorSecondary"/>
</shape> </shape>
</item> </item>
</ripple> </ripple>

View File

@@ -6,7 +6,7 @@
<item> <item>
<shape <shape
android:shape="oval"> android:shape="oval">
<stroke android:color="?attr/colorAccent" android:width="1dp"/> <stroke android:color="?attr/colorSecondary" android:width="1dp"/>
<padding <padding
android:left="12dp" android:left="12dp"
android:right="12dp" android:right="12dp"

View File

@@ -1,13 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <ripple xmlns:android="http://schemas.android.com/apk/res/android"
<item android:state_selected="true"> xmlns:tools="http://schemas.android.com/tools"
<shape> android:color="?android:attr/colorControlHighlight"
<solid android:color="?attr/colorAccentLight"/> tools:targetApi="lollipop">
</shape> <item>
<selector>
<item android:state_selected="true">
<shape>
<corners android:radius="25dp" />
<solid android:color="?attr/colorSecondaryContainer"/>
</shape>
</item>
<item android:state_selected="false">
<shape>
<corners android:radius="25dp" />
<solid android:color="?attr/colorSurfaceContainer"/>
</shape>
</item>
</selector>
</item> </item>
<item android:state_selected="false"> </ripple>
<shape>
<solid android:color="@color/transparent"/>
</shape>
</item>
</selector>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/advanced_unlock_size"
android:height="@dimen/advanced_unlock_size"
android:viewportWidth="24"
android:viewportHeight="24">
<group>
<path
android:fillColor="#fffbfb"
android:strokeWidth="1"
android:pathData="M 13 4 L 8 13 L 11.777344 13 L 11 20 L 16 11 L 12.222656 11 L 13 4 z" />
</group>
</vector>

View File

@@ -1,65 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/advanced_unlock_size"
android:height="@dimen/advanced_unlock_size"
android:viewportWidth="@integer/fingerprint_viewport_width"
android:viewportHeight="@integer/fingerprint_viewport_height">
<group
android:name="fingerprint"
android:pivotX="@integer/fingerprint_viewport_center"
android:pivotY="@integer/fingerprint_viewport_center">
<path
android:name="ridge_1"
android:pathData="@string/path_ridge_1"
android:strokeColor="@color/fingerprint_ridge"
android:strokeLineCap="round"
android:strokeWidth="@integer/fingerprint_stroke_width" />
<path
android:name="ridge_2"
android:pathData="@string/path_ridge_2"
android:strokeColor="@color/fingerprint_ridge"
android:strokeLineCap="round"
android:strokeWidth="@integer/fingerprint_stroke_width" />
<path
android:name="ridge_3"
android:pathData="@string/path_ridge_3"
android:strokeColor="@color/fingerprint_ridge"
android:strokeLineCap="round"
android:strokeWidth="@integer/fingerprint_stroke_width" />
<path
android:name="ridge_4"
android:pathData="@string/path_ridge_4"
android:strokeColor="@color/fingerprint_ridge"
android:strokeLineCap="round"
android:strokeWidth="@integer/fingerprint_stroke_width" />
<path
android:name="ridge_5"
android:pathData="@string/path_ridge_5"
android:strokeColor="@color/fingerprint_ridge"
android:strokeLineCap="round"
android:strokeWidth="@integer/fingerprint_stroke_width" />
</group>
</vector>

View File

@@ -1,109 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/advanced_unlock_size"
android:height="@dimen/advanced_unlock_size"
android:viewportWidth="@integer/fingerprint_viewport_width"
android:viewportHeight="@integer/fingerprint_viewport_height">
<group
android:name="fingerprint">
<path
android:name="ridge_1"
android:pathData="@string/path_ridge_1"
android:strokeColor="@color/fingerprint_ridge"
android:strokeLineCap="round"
android:strokeWidth="@integer/fingerprint_stroke_width" />
<path
android:name="ridge_2"
android:pathData="@string/path_ridge_2"
android:strokeColor="@color/fingerprint_ridge"
android:strokeLineCap="round"
android:strokeWidth="@integer/fingerprint_stroke_width" />
<path
android:name="ridge_3"
android:pathData="@string/path_ridge_3"
android:strokeColor="@color/fingerprint_ridge"
android:strokeLineCap="round"
android:strokeWidth="@integer/fingerprint_stroke_width" />
<path
android:name="ridge_4"
android:pathData="@string/path_ridge_4"
android:strokeColor="@color/fingerprint_ridge"
android:strokeLineCap="round"
android:strokeWidth="@integer/fingerprint_stroke_width" />
<path
android:name="ridge_5"
android:pathData="@string/path_ridge_5"
android:strokeColor="@color/fingerprint_ridge"
android:strokeLineCap="round"
android:strokeWidth="@integer/fingerprint_stroke_width" />
</group>
<!-- we overlay the above with a duplicate of the fingerprint which is colored differently
and uses a clip to only reveal portions at a time. -->
<group
android:name="fingerprint_scan">
<clip-path
android:name="scan_clip"
android:pathData="@string/clip_path_scan_top" />
<path
android:name="ridge_1"
android:pathData="@string/path_ridge_1"
android:strokeColor="@color/fingerprint_ridge_scan"
android:strokeLineCap="round"
android:strokeWidth="@integer/fingerprint_stroke_width" />
<path
android:name="ridge_2"
android:pathData="@string/path_ridge_2"
android:strokeColor="@color/fingerprint_ridge_scan"
android:strokeLineCap="round"
android:strokeWidth="@integer/fingerprint_stroke_width" />
<path
android:name="ridge_3"
android:pathData="@string/path_ridge_3"
android:strokeColor="@color/fingerprint_ridge_scan"
android:strokeLineCap="round"
android:strokeWidth="@integer/fingerprint_stroke_width" />
<path
android:name="ridge_4"
android:pathData="@string/path_ridge_4"
android:strokeColor="@color/fingerprint_ridge_scan"
android:strokeLineCap="round"
android:strokeWidth="@integer/fingerprint_stroke_width" />
<path
android:name="ridge_5"
android:pathData="@string/path_ridge_5"
android:strokeColor="@color/fingerprint_ridge_scan"
android:strokeLineCap="round"
android:strokeWidth="@integer/fingerprint_stroke_width" />
</group>
</vector>

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/fingerprint_scan">
<target
android:name="scan_clip"
android:animation="@animator/scan" />
</animated-vector>

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape>
<corners
android:radius="0dp" />
<padding
android:left="8dp"
android:right="8dp"
android:top="12dp"
android:bottom="12dp"/>
<solid android:color="@color/orange_lighter"/>
</shape>
</item>
<item>
<shape>
<corners
android:radius="0dp" />
<padding
android:left="8dp"
android:right="8dp"
android:top="12dp"
android:bottom="12dp"/>
<solid android:color="@color/orange"/>
</shape>
</item>
</selector>

View File

@@ -2,12 +2,14 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"> <item android:state_selected="true">
<shape> <shape>
<solid android:color="@color/white_grey_darker"/> <corners android:radius="25dp" />
<solid android:color="@color/grey_lighter"/>
</shape> </shape>
</item> </item>
<item android:state_selected="false"> <item android:state_selected="false">
<shape> <shape>
<solid android:color="@color/transparent"/> <corners android:radius="25dp" />
<solid android:color="@color/black_selection"/>
</shape> </shape>
</item> </item>
</selector> </selector>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<padding
android:bottom="-2dp"
android:left="-2dp"
android:right="-2dp"
android:top="-2dp" />
<stroke
android:width="1.5dp"
android:color="@color/white_grey_darker"/>
</shape >

View File

@@ -5,7 +5,7 @@
<item android:bottom="2dp" android:left="2dp"> <item android:bottom="2dp" android:left="2dp">
<shape> <shape>
<corners <corners
android:radius="8dp" /> android:radius="@dimen/dialog_radius" />
<padding <padding
android:left="14dp" android:left="14dp"
android:right="14dp" android:right="14dp"
@@ -21,7 +21,7 @@
<item android:bottom="2dp" android:left="2dp"> <item android:bottom="2dp" android:left="2dp">
<shape> <shape>
<corners <corners
android:radius="8dp" /> android:radius="@dimen/dialog_radius" />
<padding <padding
android:left="14dp" android:left="14dp"
android:right="14dp" android:right="14dp"

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="270"
android:toDegrees="270">
<shape
android:shape="ring"
android:innerRadiusRatio="2.5"
android:thickness="2dp"
android:useLevel="true">
<solid android:color="@color/progress_color" />
</shape>
</rotate>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="270"
android:toDegrees="270">
<shape
android:shape="ring"
android:innerRadiusRatio="2.5"
android:thickness="2dp"
android:useLevel="true">
<solid android:color="@color/list_secondary_color" />
</shape>
</rotate>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M17.81,4.47c-0.08,0 -0.16,-0.02 -0.23,-0.06C15.66,3.42 14,3 12.01,3c-1.98,0 -3.86,0.47 -5.57,1.41 -0.24,0.13 -0.54,0.04 -0.68,-0.2 -0.13,-0.24 -0.04,-0.55 0.2,-0.68C7.82,2.52 9.86,2 12.01,2c2.13,0 3.99,0.47 6.03,1.52 0.25,0.13 0.34,0.43 0.21,0.67 -0.09,0.18 -0.26,0.28 -0.44,0.28zM3.5,9.72c-0.1,0 -0.2,-0.03 -0.29,-0.09 -0.23,-0.16 -0.28,-0.47 -0.12,-0.7 0.99,-1.4 2.25,-2.5 3.75,-3.27C9.98,4.04 14,4.03 17.15,5.65c1.5,0.77 2.76,1.86 3.75,3.25 0.16,0.22 0.11,0.54 -0.12,0.7 -0.23,0.16 -0.54,0.11 -0.7,-0.12 -0.9,-1.26 -2.04,-2.25 -3.39,-2.94 -2.87,-1.47 -6.54,-1.47 -9.4,0.01 -1.36,0.7 -2.5,1.7 -3.4,2.96 -0.08,0.14 -0.23,0.21 -0.39,0.21zM9.75,21.79c-0.13,0 -0.26,-0.05 -0.35,-0.15 -0.87,-0.87 -1.34,-1.43 -2.01,-2.64 -0.69,-1.23 -1.05,-2.73 -1.05,-4.34 0,-2.97 2.54,-5.39 5.66,-5.39s5.66,2.42 5.66,5.39c0,0.28 -0.22,0.5 -0.5,0.5s-0.5,-0.22 -0.5,-0.5c0,-2.42 -2.09,-4.39 -4.66,-4.39 -2.57,0 -4.66,1.97 -4.66,4.39 0,1.44 0.32,2.77 0.93,3.85 0.64,1.15 1.08,1.64 1.85,2.42 0.19,0.2 0.19,0.51 0,0.71 -0.11,0.1 -0.24,0.15 -0.37,0.15zM16.92,19.94c-1.19,0 -2.24,-0.3 -3.1,-0.89 -1.49,-1.01 -2.38,-2.65 -2.38,-4.39 0,-0.28 0.22,-0.5 0.5,-0.5s0.5,0.22 0.5,0.5c0,1.41 0.72,2.74 1.94,3.56 0.71,0.48 1.54,0.71 2.54,0.71 0.24,0 0.64,-0.03 1.04,-0.1 0.27,-0.05 0.53,0.13 0.58,0.41 0.05,0.27 -0.13,0.53 -0.41,0.58 -0.57,0.11 -1.07,0.12 -1.21,0.12zM14.91,22c-0.04,0 -0.09,-0.01 -0.13,-0.02 -1.59,-0.44 -2.63,-1.03 -3.72,-2.1 -1.4,-1.39 -2.17,-3.24 -2.17,-5.22 0,-1.62 1.38,-2.94 3.08,-2.94 1.7,0 3.08,1.32 3.08,2.94 0,1.07 0.93,1.94 2.08,1.94s2.08,-0.87 2.08,-1.94c0,-3.77 -3.25,-6.83 -7.25,-6.83 -2.84,0 -5.44,1.58 -6.61,4.03 -0.39,0.81 -0.59,1.76 -0.59,2.8 0,0.78 0.07,2.01 0.67,3.61 0.1,0.26 -0.03,0.55 -0.29,0.64 -0.26,0.1 -0.55,-0.04 -0.64,-0.29 -0.49,-1.31 -0.73,-2.61 -0.73,-3.96 0,-1.2 0.23,-2.29 0.68,-3.24 1.33,-2.79 4.28,-4.6 7.51,-4.6 4.55,0 8.25,3.51 8.25,7.83 0,1.62 -1.38,2.94 -3.08,2.94s-3.08,-1.32 -3.08,-2.94c0,-1.07 -0.93,-1.94 -2.08,-1.94s-2.08,0.87 -2.08,1.94c0,1.71 0.66,3.31 1.87,4.51 0.95,0.94 1.86,1.46 3.27,1.85 0.27,0.07 0.42,0.35 0.35,0.61 -0.05,0.23 -0.26,0.38 -0.47,0.38z"/>
</vector>

View File

@@ -4,6 +4,6 @@
android:viewportWidth="24.0" android:viewportWidth="24.0"
android:viewportHeight="24.0"> android:viewportHeight="24.0">
<path <path
android:fillColor="@color/background_button_color_secondary" android:fillColor="@color/black"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/> android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/>
</vector> </vector>

View File

@@ -6,7 +6,8 @@
android:viewportHeight="24"> android:viewportHeight="24">
<path <path
android:fillColor="#ffffff" android:fillColor="#ffffff"
android:strokeWidth="2.28571415" android:strokeColor="#000000"
android:strokeWidth="2"
android:strokeLineJoin="round" android:strokeLineJoin="round"
android:strokeLineCap="round" android:strokeLineCap="round"
android:pathData="M 12 8 C 14.2091389993 8 16 9.79086100068 16 12 C 16 14.2091389993 14.2091389993 16 12 16 C 9.79086100068 16 8 14.2091389993 8 12 C 8 9.79086100068 9.79086100068 8 12 8 Z" /> android:pathData="M 12 8 C 14.2091389993 8 16 9.79086100068 16 12 C 16 14.2091389993 14.2091389993 16 12 16 C 9.79086100068 16 8 14.2091389993 8 12 C 8 9.79086100068 9.79086100068 8 12 8 Z" />

View File

@@ -17,56 +17,11 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
--> -->
<androidx.constraintlayout.widget.ConstraintLayout <Button xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/biometric_button"
android:id="@+id/fingerprint_container" android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:filterTouchesWhenObscured="true"> style="@style/KeepassDXStyle.Button.Secondary"
app:icon="@drawable/ic_fingerprint_24"
<androidx.appcompat.widget.AppCompatImageView android:text="@string/configure" />
android:id="@+id/biometric_image"
android:layout_width="48dp"
android:layout_height="48dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="12dp"
android:elevation="8dp"
android:src="@drawable/fingerprint"
android:background="@drawable/background_image"
android:backgroundTint="?attr/colorAccent" />
<TextView
android:id="@+id/biometric_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/biometric_image"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/biometric_message"
tools:text="@string/advanced_unlock_prompt_store_credential_title"
style="@style/KeepassDXStyle.TextAppearance.Secondary.TextOnPrimary"
android:gravity="center" />
<TextView
android:id="@+id/biometric_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:orientation="vertical"
android:layout_marginBottom="8dp"
app:layout_constraintTop_toBottomOf="@+id/biometric_title"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="Sample error"
style="@style/KeepassDXStyle.TextAppearance.Warning.TextOnPrimary"
android:gravity="center" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -110,9 +110,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/about" android:text="@string/info"
android:textStyle="bold" style="@style/KeepassDXStyle.Title"/>
style="@style/KeepassDXStyle.TextAppearance.Title"/>
<TextView <TextView
android:id="@+id/activity_about_licence_text" android:id="@+id/activity_about_licence_text"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
@@ -135,8 +134,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/contact" android:text="@string/contact"
android:textStyle="bold" style="@style/KeepassDXStyle.Title"/>
style="@style/KeepassDXStyle.TextAppearance.Title"/>
<TextView <TextView
android:id="@+id/activity_about_homepage_subtitle" android:id="@+id/activity_about_homepage_subtitle"
@@ -144,7 +142,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:text="@string/homepage" android:text="@string/homepage"
style="@style/KeepassDXStyle.TextAppearance.SmallTitle"/> style="@style/KeepassDXStyle.SubTitle"/>
<TextView <TextView
android:id="@+id/activity_about_homepage_link" android:id="@+id/activity_about_homepage_link"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -158,7 +156,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:text="@string/feedback" android:text="@string/feedback"
style="@style/KeepassDXStyle.TextAppearance.SmallTitle"/> style="@style/KeepassDXStyle.SubTitle"/>
<TextView <TextView
android:id="@+id/activity_about_feedback_link" android:id="@+id/activity_about_feedback_link"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -172,7 +170,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:text="@string/contribution" android:text="@string/contribution"
style="@style/KeepassDXStyle.TextAppearance.SmallTitle"/> style="@style/KeepassDXStyle.SubTitle"/>
<TextView <TextView
android:id="@+id/activity_about_contribution_link" android:id="@+id/activity_about_contribution_link"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@@ -36,14 +36,12 @@
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar" android:id="@+id/app_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_parallax_height" android:layout_height="wrap_content">
android:background="?attr/colorPrimary">
<com.google.android.material.appbar.CollapsingToolbarLayout <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar_layout" android:id="@+id/toolbar_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="center_horizontal|bottom" app:expandedTitleGravity="center_horizontal|bottom"
app:expandedTitleMarginStart="@dimen/default_margin" app:expandedTitleMarginStart="@dimen/default_margin"
app:expandedTitleMarginEnd="@dimen/default_margin" app:expandedTitleMarginEnd="@dimen/default_margin"
@@ -54,12 +52,12 @@
android:id="@+id/title_block" android:id="@+id/title_block"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:minHeight="160dp"
app:layout_collapseMode="parallax" app:layout_collapseMode="parallax"
android:orientation="vertical" android:orientation="vertical"
android:background="@drawable/background_repeat" android:background="@drawable/background_repeat"
android:gravity="center" android:gravity="center"
android:paddingBottom="12dp" android:paddingBottom="12dp">
style="@style/KeepassDXStyle.TextAppearance.Default">
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/entry_icon" android:id="@+id/entry_icon"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -69,20 +67,18 @@
style="@style/KeepassDXStyle.Icon" style="@style/KeepassDXStyle.Icon"
android:layout_gravity="center"/> android:layout_gravity="center"/>
</FrameLayout> </FrameLayout>
<androidx.appcompat.widget.Toolbar <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="wrap_content"
android:theme="?attr/toolbarAppearance" style="@style/KeepassDXStyle.Toolbar.Transparent"
app:layout_collapseMode="pin" app:layout_collapseMode="pin" />
tools:targetApi="lollipop">
</androidx.appcompat.widget.Toolbar>
<com.google.android.material.progressindicator.LinearProgressIndicator <com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/entry_progress" android:id="@+id/entry_progress"
android:visibility="gone" android:visibility="gone"
android:indeterminate="false" android:indeterminate="false"
app:indicatorColor="?attr/colorAccent" app:indicatorColor="?attr/colorSecondary"
android:progress="10" android:progress="10"
android:max="30" android:max="30"
android:layout_gravity="bottom" android:layout_gravity="bottom"
@@ -109,9 +105,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
android:visibility="gone" android:visibility="gone"
android:background="?attr/colorAccent" android:background="?attr/colorSecondary"
android:padding="12dp" android:padding="12dp"
android:textColor="?attr/colorOnAccentColor" android:textColor="?attr/colorOnSecondary"
android:text="@string/entry_history"/> android:text="@string/entry_history"/>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
@@ -147,10 +143,8 @@
android:id="@+id/entry_content_tab" android:id="@+id/entry_content_tab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minWidth="120dp" android:minWidth="180dp"
android:layout_gravity="bottom|center_horizontal" android:layout_gravity="bottom|center_horizontal"
android:background="?attr/cardBackgroundTransparentColor"
app:tabIconTint="?android:attr/textColor"
app:tabMode="fixed"> app:tabMode="fixed">
<com.google.android.material.tabs.TabItem <com.google.android.material.tabs.TabItem

View File

@@ -39,11 +39,10 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fitsSystemWindows="true"> android:fitsSystemWindows="true">
<com.kunzisoft.keepass.view.SpecialModeView <com.kunzisoft.keepass.view.ToolbarSpecial
android:id="@+id/special_mode_view" android:id="@+id/special_mode_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="wrap_content"
android:theme="?attr/toolbarSpecialAppearance"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
@@ -59,7 +58,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:paddingTop="@dimen/card_view_margin_vertical" android:paddingTop="@dimen/card_view_margin_vertical"
android:paddingBottom="@dimen/card_view_margin_vertical"> android:paddingBottom="@dimen/card_view_margin_vertical">
<Spinner <androidx.appcompat.widget.AppCompatSpinner
android:id="@+id/entry_edit_template_selector" android:id="@+id/entry_edit_template_selector"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -81,8 +80,7 @@
<com.kunzisoft.keepass.view.ToolbarAction <com.kunzisoft.keepass.view.ToolbarAction
android:id="@+id/entry_edit_bottom_bar" android:id="@+id/entry_edit_bottom_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="wrap_content"
android:theme="?attr/toolbarActionAppearance"
android:layout_gravity="bottom" android:layout_gravity="bottom"
app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner" /> app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner" />
@@ -93,8 +91,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@string/validate" android:contentDescription="@string/validate"
android:src="@drawable/ic_check_white_24dp" android:src="@drawable/ic_check_white_24dp"
android:tint="?attr/colorOnAccentColor" app:fabCustomSize="@dimen/button_small_size"
app:fabSize="mini"
app:layout_constraintTop_toTopOf="@+id/entry_edit_bottom_bar" app:layout_constraintTop_toTopOf="@+id/entry_edit_bottom_bar"
app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner" app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"

View File

@@ -27,11 +27,10 @@
android:importantForAutofill="noExcludeDescendants" android:importantForAutofill="noExcludeDescendants"
tools:targetApi="o"> tools:targetApi="o">
<com.kunzisoft.keepass.view.SpecialModeView <com.kunzisoft.keepass.view.ToolbarSpecial
android:id="@+id/special_mode_view" android:id="@+id/special_mode_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="?attr/toolbarSpecialAppearance"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<androidx.coordinatorlayout.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
@@ -46,7 +45,7 @@
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar" android:id="@+id/app_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_parallax_height"> android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar_layout" android:id="@+id/toolbar_layout"
@@ -56,16 +55,13 @@
<LinearLayout <LinearLayout
android:id="@+id/file_selection_title_container" android:id="@+id/file_selection_title_container"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_collapseMode="parallax" app:layout_collapseMode="parallax"
android:layout_gravity="center_horizontal|bottom" android:layout_gravity="center_horizontal|bottom"
android:gravity="center"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingLeft="24dp" android:paddingBottom="36dp">
android:paddingStart="24dp"
android:paddingRight="24dp"
android:paddingEnd="24dp"
android:paddingBottom="48dp">
<TextView <TextView
android:id="@+id/file_selection_title_part_1" android:id="@+id/file_selection_title_part_1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -77,7 +73,7 @@
android:shadowDy="2" android:shadowDy="2"
android:shadowRadius="4" android:shadowRadius="4"
android:paddingTop="?attr/actionBarSize" android:paddingTop="?attr/actionBarSize"
android:textColor="?attr/textColorInverse" android:textColor="@color/green_light"
android:gravity="center" android:gravity="center"
android:text="@string/app_name_part1"/> android:text="@string/app_name_part1"/>
<TextView <TextView
@@ -93,15 +89,16 @@
android:shadowDy="2" android:shadowDy="2"
android:shadowRadius="4" android:shadowRadius="4"
android:paddingTop="?attr/actionBarSize" android:paddingTop="?attr/actionBarSize"
android:textColor="?attr/colorAccent" android:textColor="@color/orange"
android:gravity="center" android:gravity="center"
android:text="@string/app_name_part2"/> android:text="@string/app_name_part2"/>
<TextView <TextView
android:id="@+id/file_selection_title_part_3" android:id="@+id/file_selection_title_part_3"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="12dp" android:layout_marginStart="8dp"
android:layout_marginLeft="12dp" android:layout_marginLeft="8dp"
android:paddingHorizontal="4dp"
android:textSize="32sp" android:textSize="32sp"
android:textStyle="bold" android:textStyle="bold"
android:visibility="gone" android:visibility="gone"
@@ -110,26 +107,19 @@
android:shadowDy="2" android:shadowDy="2"
android:shadowRadius="4" android:shadowRadius="4"
android:paddingTop="?attr/actionBarSize" android:paddingTop="?attr/actionBarSize"
android:textColor="?android:attr/textColorHintInverse" android:textColor="@color/green_lightest"
android:gravity="center" android:gravity="center"
android:text="@string/app_name_part3"/> android:text="@string/app_name_part3"/>
</LinearLayout> </LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
android:background="?attr/colorPrimary" />
<androidx.appcompat.widget.Toolbar <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="@drawable/ic_info_white_24dp" app:navigationIcon="@drawable/ic_info_white_24dp"
app:navigationContentDescription="@string/about" app:navigationContentDescription="@string/about"
android:elevation="4dp" app:layout_collapseMode="pin"/>
app:layout_collapseMode="pin"
android:theme="?attr/toolbarHomeAppearance" />
</com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
@@ -142,57 +132,49 @@
app:layout_behavior="@string/appbar_scrolling_view_behavior"/> app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
<FrameLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/file_selection_buttons_container" android:id="@+id/file_selection_buttons_container"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner" app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner"
app:layout_constraintEnd_toEndOf="parent" android:background="?attr/colorSurface">
app:layout_constraintStart_toStartOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.Guideline
android:id="@+id/database_buttons_container" android:id="@+id/guideline_buttons"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<Button
android:id="@+id/create_database_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:icon="@drawable/ic_database_plus_white_24dp"
app:iconGravity="start"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline_buttons"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:focusable="true"
style="@style/KeepassDXStyle.Button.Secondary"
android:text="@string/create_keepass_file"/>
<Button
android:id="@+id/open_database_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/select_database_file"
app:icon="@drawable/ic_folder_white_24dp"
app:iconGravity="start"
app:layout_constraintStart_toEndOf="@+id/create_database_button"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"> app:layout_constraintHorizontal_bias="0.5"
<View app:layout_constraintTop_toTopOf="parent"
android:layout_width="match_parent" app:layout_constraintBottom_toBottomOf="parent"
android:layout_height="1dp" android:focusable="true"
android:layout_gravity="top" style="@style/KeepassDXStyle.Button.Primary"/>
app:layout_constraintBottom_toTopOf="@+id/open_database_button" </androidx.constraintlayout.widget.ConstraintLayout>
android:background="?attr/colorPrimaryDark"/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/open_database_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/select_database_file"
android:drawableRight="@drawable/ic_folder_white_24dp"
android:drawableEnd="@drawable/ic_folder_white_24dp"
style="@style/KeepassDXStyle.Button.Primary"
android:focusable="true"
android:paddingLeft="32dp"
android:paddingStart="32dp"
android:paddingRight="24dp"
android:paddingEnd="24dp"
app:layout_constraintBottom_toTopOf="@+id/create_database_button"/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/create_database_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
app:layout_constraintBottom_toBottomOf="parent"
android:drawableRight="@drawable/ic_database_plus_white_24dp"
android:drawableEnd="@drawable/ic_database_plus_white_24dp"
android:paddingLeft="24dp"
android:paddingStart="24dp"
android:paddingRight="24dp"
android:paddingEnd="24dp"
android:text="@string/create_keepass_file"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
<include layout="@layout/view_screenshot_mode_banner" /> <include layout="@layout/view_screenshot_mode_banner" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -24,27 +24,23 @@
android:id="@+id/drawer_layout" android:id="@+id/drawer_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:filterTouchesWhenObscured="true" android:filterTouchesWhenObscured="true">
android:fitsSystemWindows="true">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/activity_group_container_view" android:id="@+id/activity_group_container_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<com.kunzisoft.keepass.view.SpecialModeView <com.kunzisoft.keepass.view.ToolbarSpecial
android:id="@+id/special_mode_view" android:id="@+id/special_mode_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="?attr/toolbarSpecialAppearance"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.Toolbar <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="?attr/toolbarAppearance"
android:title="@string/app_name" android:title="@string/app_name"
app:layout_constraintTop_toBottomOf="@+id/special_mode_view"> app:layout_constraintTop_toBottomOf="@+id/special_mode_view">
<FrameLayout <FrameLayout
@@ -58,19 +54,19 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
tools:text="Database" tools:text="Database"
style="@style/KeepassDXStyle.TextAppearance.Title.TextOnPrimary" /> style="@style/KeepassDXStyle.Title.OnSurface" />
</FrameLayout> </FrameLayout>
</androidx.appcompat.widget.Toolbar> </com.google.android.material.appbar.MaterialToolbar>
<FrameLayout <FrameLayout
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="?attr/actionBarSize" android:layout_height="wrap_content"
android:layout_marginStart="50dp" android:layout_marginStart="41dp"
android:layout_marginLeft="50dp" android:layout_marginLeft="41dp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/special_mode_view"> app:layout_constraintTop_toBottomOf="@+id/special_mode_view"
app:layout_constraintBottom_toTopOf="@+id/group_coordinator">
<ImageView <ImageView
android:id="@+id/database_color" android:id="@+id/database_color"
android:layout_width="12dp" android:layout_width="12dp"
android:layout_height="12dp" android:layout_height="12dp"
@@ -82,12 +78,9 @@
android:id="@+id/database_modified" android:id="@+id/database_modified"
android:layout_width="12dp" android:layout_width="12dp"
android:layout_height="12dp" android:layout_height="12dp"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:layout_gravity="center_vertical|start" android:layout_gravity="center_vertical|start"
android:visibility="gone" android:visibility="gone"
android:src="@drawable/ic_modified_white_12dp" android:src="@drawable/ic_modified_white_12dp"
android:tint="?attr/textColorInverse"
android:contentDescription="@string/save"/> android:contentDescription="@string/save"/>
</FrameLayout> </FrameLayout>
@@ -102,7 +95,6 @@
android:id="@+id/app_bar" android:id="@+id/app_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:targetApi="lollipop"
android:fitsSystemWindows="true"> android:fitsSystemWindows="true">
<FrameLayout <FrameLayout
@@ -110,25 +102,18 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|snap|enterAlways"> app:layout_scrollFlags="scroll|snap|enterAlways">
<androidx.appcompat.widget.Toolbar <androidx.recyclerview.widget.RecyclerView
android:id="@+id/toolbar_breadcrumb" android:id="@+id/breadcrumb_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="64dp"
android:background="?attr/colorPrimary" android:paddingHorizontal="12dp"
android:theme="?attr/toolbarAppearance" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:targetApi="lollipop"> android:orientation="horizontal" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/breadcrumb_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="horizontal" />
</androidx.appcompat.widget.Toolbar>
<com.kunzisoft.keepass.view.SearchFiltersView <com.kunzisoft.keepass.view.SearchFiltersView
android:id="@+id/search_filters" android:id="@+id/search_filters"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"/>
</FrameLayout> </FrameLayout>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
@@ -145,6 +130,7 @@
android:id="@+id/nodes_list_fragment_container" android:id="@+id/nodes_list_fragment_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:paddingTop="@dimen/selectable_margin_vertical"
android:background="?android:attr/windowBackground" /> android:background="?android:attr/windowBackground" />
</RelativeLayout> </RelativeLayout>
@@ -159,9 +145,8 @@
<com.kunzisoft.keepass.view.ToolbarAction <com.kunzisoft.keepass.view.ToolbarAction
android:id="@+id/toolbar_action" android:id="@+id/toolbar_action"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="64dp"
android:visibility="gone" android:visibility="gone"
android:theme="?attr/toolbarActionAppearance"
app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner" /> app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner" />
<FrameLayout <FrameLayout
@@ -190,8 +175,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="start" android:layout_gravity="start"
app:itemTextColor="?android:attr/textColor" style="@style/Widget.Material3.NavigationView"
app:subheaderColor="?attr/colorAccent"
android:fitsSystemWindows="true" /> android:fitsSystemWindows="true" />
</androidx.drawerlayout.widget.DrawerLayout> </androidx.drawerlayout.widget.DrawerLayout>

View File

@@ -40,9 +40,8 @@
<com.kunzisoft.keepass.view.ToolbarAction <com.kunzisoft.keepass.view.ToolbarAction
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:theme="?attr/toolbarActionAppearance"
app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner" /> app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
@@ -52,7 +51,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@string/validate" android:contentDescription="@string/validate"
android:src="@drawable/ic_file_upload_white_24dp" android:src="@drawable/ic_file_upload_white_24dp"
app:fabSize="mini" app:fabCustomSize="@dimen/button_small_size"
app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner" app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View File

@@ -40,9 +40,8 @@
<com.kunzisoft.keepass.view.ToolbarAction <com.kunzisoft.keepass.view.ToolbarAction
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:theme="?attr/toolbarActionAppearance"
app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner" /> app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
@@ -52,8 +51,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@string/validate" android:contentDescription="@string/validate"
android:src="@drawable/ic_check_white_24dp" android:src="@drawable/ic_check_white_24dp"
android:tint="?attr/colorOnAccentColor" app:fabCustomSize="@dimen/button_small_size"
app:fabSize="mini"
app:layout_constraintTop_toTopOf="@+id/toolbar" app:layout_constraintTop_toTopOf="@+id/toolbar"
app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner" app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"

View File

@@ -24,15 +24,13 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:filterTouchesWhenObscured="true" android:filterTouchesWhenObscured="true"
android:background="?android:attr/windowBackground"
tools:targetApi="o"> tools:targetApi="o">
<com.kunzisoft.keepass.view.SpecialModeView <com.kunzisoft.keepass.view.ToolbarSpecial
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
android:id="@+id/special_mode_view" android:id="@+id/special_mode_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content" />
android:theme="?attr/toolbarSpecialAppearance" />
<androidx.coordinatorlayout.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/activity_password_coordinator_layout" android:id="@+id/activity_password_coordinator_layout"
@@ -46,68 +44,44 @@
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar" android:id="@+id/app_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:background="?attr/colorPrimary">
<com.google.android.material.appbar.CollapsingToolbarLayout <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar_layout" android:id="@+id/toolbar_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:titleEnabled="false"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"> app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:minHeight="144dp" app:layout_collapseMode="parallax"
android:layout_marginTop="?attr/actionBarSize" android:layout_gravity="center_horizontal|bottom"
android:background="?attr/colorPrimary"> android:gravity="center_horizontal"
<LinearLayout android:paddingTop="?attr/actionBarSize">
android:orientation="vertical" <androidx.appcompat.widget.AppCompatImageView
android:layout_width="match_parent" android:id="@+id/activity_password_logotype"
android:layout_height="wrap_content" android:layout_width="48dp"
android:layout_gravity="center"> android:layout_height="48dp"
<androidx.appcompat.widget.AppCompatImageView android:layout_gravity="center"
android:id="@+id/activity_password_advanced_unlock_button" android:layout_margin="12dp"
android:layout_width="48dp" android:contentDescription="@string/about"
android:layout_height="48dp" android:elevation="4dp"
android:layout_gravity="center" android:src="@drawable/ic_app_white_24dp"
android:layout_marginTop="12dp" android:background="@drawable/background_image"
android:contentDescription="@string/about" android:backgroundTint="@color/green"/>
android:elevation="8dp"
android:src="@drawable/ic_app_white_24dp"
android:background="@drawable/background_image"
android:backgroundTint="@color/green_light"/>
<TextView
android:id="@+id/activity_password_advanced_unlock_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:orientation="vertical"
android:text="@string/education_unlock_title"
style="@style/KeepassDXStyle.TextAppearance.Secondary.TextOnPrimary"
android:gravity="center" />
</LinearLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_advanced_unlock_container_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout> </FrameLayout>
<androidx.appcompat.widget.Toolbar <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="wrap_content"
android:background="?attr/colorPrimary" android:elevation="0dp"
android:theme="?attr/toolbarAppearance" app:elevation="0dp"
app:layout_collapseMode="pin" app:layout_collapseMode="pin">
tools:targetApi="lollipop">
<TextView <TextView
android:id="@+id/filename" android:id="@+id/filename"
style="@style/KeepassDXStyle.TextAppearance.Title.TextOnPrimary" style="@style/KeepassDXStyle.Title.OnSurface"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
@@ -116,7 +90,7 @@
android:marqueeRepeatLimit="marquee_forever" android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true" android:scrollHorizontally="true"
android:singleLine="true"/> android:singleLine="true"/>
</androidx.appcompat.widget.Toolbar> </com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
@@ -135,16 +109,24 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="12dp" android:layout_marginBottom="12dp"
android:elevation="4dp"
app:layout_constraintWidth_percent="@dimen/content_percent" app:layout_constraintWidth_percent="@dimen/content_percent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"> app:layout_constraintEnd_toEndOf="parent">
<com.kunzisoft.keepass.view.MainCredentialView <View
android:id="@+id/activity_password_credentials"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="116dp"
android:background="?attr/colorSurface" />
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?android:attr/windowBackground" /> style="@style/KeepassDXStyle.Cardview.SurfaceContainer"
android:layout_margin="16dp">
<com.kunzisoft.keepass.view.MainCredentialView
android:id="@+id/activity_password_credentials"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.card.MaterialCardView>
</FrameLayout> </FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
@@ -174,24 +156,39 @@
android:paddingLeft="24dp" android:paddingLeft="24dp"
android:paddingEnd="24dp" android:paddingEnd="24dp"
android:paddingRight="24dp" android:paddingRight="24dp"
style="@style/KeepassDXStyle.TextAppearance.Tiny" style="@style/KeepassDXStyle.Text.Tiny"
android:text="@string/warning_database_link_revoked" android:text="@string/warning_database_link_revoked"
android:textColor="?attr/textColorInverse" android:textColor="?attr/colorOnSecondary"
android:background="?attr/colorAccent" android:background="?attr/colorSecondary"
app:layout_constraintBottom_toTopOf="@+id/activity_password_info_delimiter" app:layout_constraintBottom_toTopOf="@+id/activity_password_info_delimiter"
android:layout_gravity="bottom"/> android:layout_gravity="bottom"/>
<View
android:id="@+id/activity_password_info_delimiter"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/colorAccentLight"/>
</LinearLayout> </LinearLayout>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/activity_password_open_button" <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:focusable="true" android:background="?attr/colorSurface">
android:text="@string/menu_open" /> <androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_advanced_unlock_container_view"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/activity_password_open_button"
app:layout_constraintBottom_toBottomOf="parent"/>
<Button
android:id="@+id/activity_password_open_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:text="@string/unlock"
style="@style/KeepassDXStyle.Button.Primary"
app:icon="@drawable/ic_lock_open_white_24dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@+id/fragment_advanced_unlock_container_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout> </LinearLayout>
<include layout="@layout/view_screenshot_mode_banner" /> <include layout="@layout/view_screenshot_mode_banner" />

View File

@@ -1,13 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout <com.kunzisoft.keepass.view.AdvancedUnlockInfoView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/advanced_unlock_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
<com.kunzisoft.keepass.view.AdvancedUnlockInfoView android:layout_gravity="center"
android:id="@+id/advanced_unlock_view" android:visibility="gone"/>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="?attr/colorPrimary"
android:visibility="gone"/>
</FrameLayout>

View File

@@ -36,14 +36,15 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />
<androidx.appcompat.widget.SwitchCompat <com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_element" android:id="@+id/switch_element"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="20dp" android:layout_margin="20dp"
android:text="@string/enable" android:text="@string/enable"
android:background="@drawable/background_button_small" android:background="@drawable/background_switch"
android:textColor="?attr/colorOnAccentColor" android:backgroundTint="?attr/colorSecondary"
android:textColor="?attr/colorOnSecondary"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
android:minHeight="48dp"/> android:minHeight="48dp"/>

View File

@@ -61,9 +61,8 @@
android:contentDescription="@string/menu_delete" android:contentDescription="@string/menu_delete"
style="@style/KeepassDXStyle.ImageButton.Simple" /> style="@style/KeepassDXStyle.ImageButton.Simple" />
<androidx.appcompat.widget.SwitchCompat <com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/entry_custom_field_protection" android:id="@+id/entry_custom_field_protection"
style="@style/KeepassDXStyle.TextAppearance.Small"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="48dp" android:minHeight="48dp"

View File

@@ -1,86 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 Jeremy Jamet / Kunzisoft.
This file is part of KeePassDX.
KeePassDX is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
KeePassDX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/default_margin">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/file_filename"
android:layout_margin="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/KeepassDXStyle.TextAppearance.LargeTitle"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/file_path"
android:textIsSelectable="true"
android:layout_margin="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:textStyle="italic"/>
<LinearLayout
android:id="@+id/file_modification_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/file_modification_label"
android:layout_margin="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/entry_modified"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/file_modification"
android:layout_margin="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end" />
</LinearLayout>
<RelativeLayout
android:id="@+id/file_size_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/file_size"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/file_size_unit"
android:layout_toStartOf="@+id/file_size_unit"
android:gravity="end" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/file_size_unit"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="21 MB"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
</LinearLayout>

View File

@@ -34,7 +34,7 @@
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="68dp" android:layout_height="68dp"
android:background="?attr/colorPrimary" /> android:background="?attr/colorSurface" />
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -44,8 +44,7 @@
android:layout_marginRight="@dimen/card_view_margin_horizontal" android:layout_marginRight="@dimen/card_view_margin_horizontal"
android:layout_marginTop="@dimen/default_margin" android:layout_marginTop="@dimen/default_margin"
android:layout_marginBottom="@dimen/card_view_margin_vertical" android:layout_marginBottom="@dimen/card_view_margin_vertical"
android:layout_gravity="bottom" android:layout_gravity="bottom">
app:cardCornerRadius="4dp">
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -114,10 +113,7 @@
android:stepSize="1" android:stepSize="1"
android:value="@integer/passphrase_generator_word_count_default" android:value="@integer/passphrase_generator_word_count_default"
android:valueFrom="@integer/passphrase_generator_word_count_min" android:valueFrom="@integer/passphrase_generator_word_count_min"
android:valueTo="@integer/passphrase_generator_word_count_max" android:valueTo="@integer/passphrase_generator_word_count_max" />
app:thumbColor="?attr/chipFilterBackgroundColor"
app:trackColorActive="?attr/chipFilterBackgroundColor"
app:trackColorInactive="?attr/chipFilterBackgroundColorDisabled" />
<EditText <EditText
android:id="@+id/word_count" android:id="@+id/word_count"

View File

@@ -34,7 +34,7 @@
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="68dp" android:layout_height="68dp"
android:background="?attr/colorPrimary" /> android:background="?attr/colorSurface" />
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -44,8 +44,7 @@
android:layout_marginRight="@dimen/card_view_margin_horizontal" android:layout_marginRight="@dimen/card_view_margin_horizontal"
android:layout_marginTop="@dimen/default_margin" android:layout_marginTop="@dimen/default_margin"
android:layout_marginBottom="@dimen/card_view_margin_vertical" android:layout_marginBottom="@dimen/card_view_margin_vertical"
android:layout_gravity="bottom" android:layout_gravity="bottom">
app:cardCornerRadius="4dp">
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -112,10 +111,7 @@
android:stepSize="1" android:stepSize="1"
android:value="@integer/password_generator_length_default" android:value="@integer/password_generator_length_default"
android:valueFrom="@integer/password_generator_length_min" android:valueFrom="@integer/password_generator_length_min"
android:valueTo="@integer/password_generator_length_max" android:valueTo="@integer/password_generator_length_max" />
app:thumbColor="?attr/chipFilterBackgroundColor"
app:trackColorActive="?attr/chipFilterBackgroundColor"
app:trackColorInactive="?attr/chipFilterBackgroundColorDisabled" />
<EditText <EditText
android:id="@+id/length" android:id="@+id/length"
@@ -208,6 +204,7 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/consider_chars_filter_layout" android:id="@+id/consider_chars_filter_layout"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/ignore_chars_filter_layout" app:layout_constraintEnd_toStartOf="@+id/ignore_chars_filter_layout"
android:layout_width="0dp" android:layout_width="0dp"
@@ -220,6 +217,7 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/ignore_chars_filter_layout" android:id="@+id/ignore_chars_filter_layout"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@+id/consider_chars_filter_layout" app:layout_constraintStart_toEndOf="@+id/consider_chars_filter_layout"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
android:layout_width="0dp" android:layout_width="0dp"

View File

@@ -32,7 +32,7 @@
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/colorPrimary"> android:background="?attr/colorSurface">
<LinearLayout <LinearLayout
android:id="@+id/title_block" android:id="@+id/title_block"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -40,8 +40,7 @@
android:orientation="vertical" android:orientation="vertical"
android:padding="@dimen/default_margin" android:padding="@dimen/default_margin"
android:background="@drawable/background_repeat" android:background="@drawable/background_repeat"
android:gravity="center" android:gravity="center">
style="@style/KeepassDXStyle.TextAppearance.Default">
<!-- Icon --> <!-- Icon -->
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
@@ -59,7 +58,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
style="@style/KeepassDXStyle.Expanded.Title" /> style="@style/KeepassDXStyle.Title.Large.OnSurface" />
</LinearLayout> </LinearLayout>
</FrameLayout> </FrameLayout>

View File

@@ -40,7 +40,7 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
android:text="@string/database" android:text="@string/database"
style="@style/KeepassDXStyle.TextAppearance.Large"/> style="@style/KeepassDXStyle.Title"/>
<com.kunzisoft.keepass.view.MainCredentialView <com.kunzisoft.keepass.view.MainCredentialView
android:id="@+id/main_credential_view" android:id="@+id/main_credential_view"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@@ -29,7 +29,6 @@
android:scrollbarStyle="insideOverlay" android:scrollbarStyle="insideOverlay"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?android:attr/windowBackground"
android:paddingBottom="?attr/actionBarSize" android:paddingBottom="?attr/actionBarSize"
android:clipToPadding="false" /> android:clipToPadding="false" />
<LinearLayout <LinearLayout

View File

@@ -27,53 +27,51 @@
android:id="@+id/progress_dialog_title" android:id="@+id/progress_dialog_title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:layout_marginTop="18dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="32dp"
android:layout_marginRight="20dp" android:layout_marginRight="32dp"
android:layout_marginStart="20dp" android:layout_marginStart="32dp"
android:layout_marginEnd="20dp" android:layout_marginEnd="32dp"
style="@style/KeepassDXStyle.TextAppearance.Title" style="@style/KeepassDXStyle.Title"/>
android:textStyle="bold"
android:textColor="?android:attr/textColor"/>
<TextView <TextView
android:id="@+id/progress_dialog_message" android:id="@+id/progress_dialog_message"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:layout_marginTop="18dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="32dp"
android:layout_marginRight="20dp" android:layout_marginRight="32dp"
android:layout_marginStart="20dp" android:layout_marginStart="32dp"
android:layout_marginEnd="20dp" android:layout_marginEnd="32dp"
style="@style/KeepassDXStyle.TextAppearance.SmallTitle"/> style="@style/KeepassDXStyle.SubTitle"/>
<TextView <TextView
android:id="@+id/progress_dialog_warning" android:id="@+id/progress_dialog_warning"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:layout_marginTop="18dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="32dp"
android:layout_marginRight="20dp" android:layout_marginRight="32dp"
android:layout_marginStart="20dp" android:layout_marginStart="32dp"
android:layout_marginEnd="20dp" android:layout_marginEnd="32dp"
style="@style/KeepassDXStyle.TextAppearance.Warning"/> style="@style/KeepassDXStyle.Text"/>
<Button <Button
android:id="@+id/progress_dialog_cancel" android:id="@+id/progress_dialog_cancel"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end" android:layout_gravity="end"
android:layout_marginTop="20dp" android:layout_marginTop="18dp"
android:layout_marginRight="20dp" android:layout_marginRight="32dp"
android:layout_marginEnd="20dp" android:layout_marginEnd="32dp"
android:text="@string/entry_cancel" /> android:text="@string/entry_cancel" />
<com.google.android.material.progressindicator.LinearProgressIndicator <com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progress_dialog_bar" android:id="@+id/progress_dialog_bar"
app:indicatorColor="?attr/colorAccent" app:indicatorColor="?attr/colorSecondary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:layout_marginTop="18dp"
android:indeterminate="true" android:indeterminate="true"
android:max="100"/> android:max="100"/>

View File

@@ -41,7 +41,7 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/credentials_information" app:layout_constraintEnd_toStartOf="@+id/credentials_information"
android:text="@string/assign_master_key" android:text="@string/assign_master_key"
style="@style/KeepassDXStyle.TextAppearance.Large"/> style="@style/KeepassDXStyle.Title"/>
<ImageView <ImageView
android:id="@+id/credentials_information" android:id="@+id/credentials_information"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -65,7 +65,7 @@
android:layout_margin="@dimen/default_margin" android:layout_margin="@dimen/default_margin"
android:orientation="vertical"> android:orientation="vertical">
<androidx.appcompat.widget.SwitchCompat <com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/password_checkbox" android:id="@+id/password_checkbox"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -85,7 +85,7 @@
android:importantForAutofill="no" android:importantForAutofill="no"
android:contentDescription="@string/content_description_repeat_toggle_password_visibility" android:contentDescription="@string/content_description_repeat_toggle_password_visibility"
app:endIconMode="password_toggle" app:endIconMode="password_toggle"
app:endIconTint="?attr/colorAccent"> app:endIconTint="?attr/colorSecondary">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/password_confirmation" android:id="@+id/password_confirmation"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -115,7 +115,7 @@
android:layout_margin="@dimen/default_margin" android:layout_margin="@dimen/default_margin"
android:orientation="vertical"> android:orientation="vertical">
<androidx.appcompat.widget.SwitchCompat <com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/keyfile_checkbox" android:id="@+id/keyfile_checkbox"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -145,7 +145,7 @@
android:layout_margin="@dimen/default_margin" android:layout_margin="@dimen/default_margin"
android:orientation="vertical"> android:orientation="vertical">
<androidx.appcompat.widget.SwitchCompat <com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/hardware_key_checkbox" android:id="@+id/hardware_key_checkbox"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@@ -42,7 +42,7 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/otp_information" app:layout_constraintEnd_toStartOf="@+id/otp_information"
android:text="@string/entry_setup_otp" android:text="@string/entry_setup_otp"
style="@style/KeepassDXStyle.TextAppearance.Large"/> style="@style/KeepassDXStyle.Title"/>
<ImageView <ImageView
android:id="@+id/otp_information" android:id="@+id/otp_information"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -63,7 +63,7 @@
android:layout_marginEnd="@dimen/card_view_margin_horizontal" android:layout_marginEnd="@dimen/card_view_margin_horizontal"
android:layout_marginRight="@dimen/card_view_margin_horizontal" android:layout_marginRight="@dimen/card_view_margin_horizontal"
android:text="@string/error_otp_type" android:text="@string/error_otp_type"
style="@style/KeepassDXStyle.TextAppearance.Warning"/> android:textColor="?attr/colorSecondary"/>
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/card_view_otp_selection" android:id="@+id/card_view_otp_selection"
@@ -114,7 +114,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:endIconMode="password_toggle" app:endIconMode="password_toggle"
app:endIconTint="?attr/colorAccent"> app:endIconTint="?attr/colorSecondary">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/setup_otp_secret" android:id="@+id/setup_otp_secret"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@@ -17,8 +17,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
--> -->
<LinearLayout <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">

Some files were not shown because too many files have changed in this diff Show More