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 {
release {
minifyEnabled = false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

View File

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

View File

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

View File

@@ -19,8 +19,6 @@
package com.kunzisoft.keepass.activities
import android.app.Activity
import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.content.Context
import android.content.Intent
import android.net.Uri
@@ -33,10 +31,8 @@ import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.AdapterView
import android.widget.DatePicker
import android.widget.ProgressBar
import android.widget.Spinner
import android.widget.TimePicker
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
@@ -48,16 +44,16 @@ import androidx.core.view.isVisible
import androidx.core.widget.NestedScrollView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.timepicker.MaterialTimePicker
import com.kunzisoft.keepass.R
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.FileTooBigDialogFragment
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.SetOTPDialogFragment
import com.kunzisoft.keepass.activities.dialogs.TimePickerFragment
import com.kunzisoft.keepass.activities.fragments.EntryEditFragment
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
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.AttachmentFileBinderManager
import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.getParcelableExtraCompat
import com.kunzisoft.keepass.utils.UriUtil.getDocumentFile
import com.kunzisoft.keepass.utils.getParcelableExtraCompat
import com.kunzisoft.keepass.view.ToolbarAction
import com.kunzisoft.keepass.view.asError
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.viewmodels.ColorPickerViewModel
import com.kunzisoft.keepass.viewmodels.EntryEditViewModel
import org.joda.time.DateTime
import java.util.UUID
class EntryEditActivity : DatabaseLockActivity(),
EntryCustomFieldDialogFragment.EntryCustomFieldListener,
SetOTPDialogFragment.CreateOtpListener,
DatePickerDialog.OnDateSetListener,
TimePickerDialog.OnTimeSetListener,
FileTooBigDialogFragment.ActionChooseListener,
ReplaceFileDialogFragment.ActionChooseListener {
@@ -291,14 +284,20 @@ class EntryEditActivity : DatabaseLockActivity(),
mEntryEditViewModel.requestDateTimeSelection.observe(this) { dateInstant ->
if (dateInstant.type == DateInstant.Type.TIME) {
// Launch the time picker
val dateTime = DateTime(dateInstant.date)
TimePickerFragment.getInstance(dateTime.hourOfDay, dateTime.minuteOfHour)
.show(supportFragmentManager, "TimePickerFragment")
MaterialTimePicker.Builder().build().apply {
addOnPositiveButtonClickListener {
mEntryEditViewModel.selectTime(this.hour, this.minute)
}
show(supportFragmentManager, "TimePickerFragment")
}
} else {
// Launch the date picker
val dateTime = DateTime(dateInstant.date)
DatePickerFragment.getInstance(dateTime.year, dateTime.monthOfYear - 1, dateTime.dayOfMonth)
.show(supportFragmentManager, "DatePickerFragment")
MaterialDatePicker.Builder.datePicker().build().apply {
addOnPositiveButtonClickListener {
mEntryEditViewModel.selectDate(it)
}
show(supportFragmentManager, "DatePickerFragment")
}
}
}
@@ -684,18 +683,6 @@ class EntryEditActivity : DatabaseLockActivity(),
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() {
onApprovedBackPressed {
super@EntryEditActivity.onBackPressed()

View File

@@ -19,9 +19,7 @@
package com.kunzisoft.keepass.activities
import android.app.Activity
import android.app.DatePickerDialog
import android.app.SearchManager
import android.app.TimePickerDialog
import android.content.ComponentName
import android.content.Context
import android.content.Intent
@@ -38,11 +36,9 @@ import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.DatePicker
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import android.widget.TimePicker
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.viewModels
@@ -59,13 +55,13 @@ import androidx.core.view.WindowInsetsControllerCompat
import androidx.core.view.isVisible
import androidx.drawerlayout.widget.DrawerLayout
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.activities.dialogs.DatePickerFragment
import com.kunzisoft.keepass.activities.dialogs.GroupDialogFragment
import com.kunzisoft.keepass.activities.dialogs.GroupEditDialogFragment
import com.kunzisoft.keepass.activities.dialogs.MainCredentialDialogFragment
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.helpers.EntrySelectionHelper
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.timeout.TimeoutHelper
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.getParcelableExtraCompat
import com.kunzisoft.keepass.utils.getParcelableList
import com.kunzisoft.keepass.utils.putParcelableList
import com.kunzisoft.keepass.utils.readParcelableCompat
import com.kunzisoft.keepass.utils.UriUtil.openUrl
import com.kunzisoft.keepass.view.AddNodeButtonView
import com.kunzisoft.keepass.view.NavigationDatabaseView
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.viewmodels.GroupEditViewModel
import com.kunzisoft.keepass.viewmodels.GroupViewModel
import org.joda.time.DateTime
class GroupActivity : DatabaseLockActivity(),
DatePickerDialog.OnDateSetListener,
TimePickerDialog.OnTimeSetListener,
GroupFragment.NodeClickListener,
GroupFragment.NodesActionMenuListener,
GroupFragment.OnScrollListener,
@@ -140,7 +133,6 @@ class GroupActivity : DatabaseLockActivity(),
private var databaseNameView: TextView? = null
private var searchView: SearchView? = null
private var searchFiltersView: SearchFiltersView? = null
private var toolbarBreadcrumb: Toolbar? = null
private var toolbarAction: ToolbarAction? = null
private var numberChildrenView: TextView? = null
private var addNodeButtonView: AddNodeButtonView? = null
@@ -277,7 +269,6 @@ class GroupActivity : DatabaseLockActivity(),
databaseColorView = findViewById(R.id.database_color)
databaseNameView = findViewById(R.id.database_name)
searchFiltersView = findViewById(R.id.search_filters)
toolbarBreadcrumb = findViewById(R.id.toolbar_breadcrumb)
breadcrumbListView = findViewById(R.id.breadcrumb_list)
toolbarAction = findViewById(R.id.toolbar_action)
lockView = findViewById(R.id.lock_button)
@@ -459,18 +450,20 @@ class GroupActivity : DatabaseLockActivity(),
mGroupEditViewModel.requestDateTimeSelection.observe(this) { dateInstant ->
if (dateInstant.type == DateInstant.Type.TIME) {
// Launch the time picker
val dateTime = DateTime(dateInstant.date)
TimePickerFragment.getInstance(dateTime.hourOfDay, dateTime.minuteOfHour)
.show(supportFragmentManager, "TimePickerFragment")
MaterialTimePicker.Builder().build().apply {
addOnPositiveButtonClickListener {
mGroupEditViewModel.selectTime(this.hour, this.minute)
}
show(supportFragmentManager, "TimePickerFragment")
}
} else {
// Launch the date picker
val dateTime = DateTime(dateInstant.date)
DatePickerFragment.getInstance(
dateTime.year,
dateTime.monthOfYear - 1,
dateTime.dayOfMonth
)
.show(supportFragmentManager, "DatePickerFragment")
MaterialDatePicker.Builder.datePicker().build().apply {
addOnPositiveButtonClickListener {
mGroupEditViewModel.selectDate(it)
}
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() {
actionNodeMode?.finish()
}
@@ -1228,11 +1209,11 @@ class GroupActivity : DatabaseLockActivity(),
}
}
if (it.isActionViewExpanded) {
toolbarBreadcrumb?.visibility = View.GONE
breadcrumbListView?.visibility = View.GONE
searchFiltersView?.visibility = View.VISIBLE
} else {
searchFiltersView?.visibility = View.GONE
toolbarBreadcrumb?.visibility = View.VISIBLE
breadcrumbListView?.visibility = View.VISIBLE
}
mLockSearchListeners = false
}

View File

@@ -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.MAIN_CREDENTIAL_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.SettingsAdvancedUnlockActivity
import com.kunzisoft.keepass.tasks.ActionRunnable
import com.kunzisoft.keepass.utils.BACK_PREVIOUS_KEYBOARD_ACTION
import com.kunzisoft.keepass.utils.MenuUtil
import com.kunzisoft.keepass.utils.UriUtil.getUri
import com.kunzisoft.keepass.utils.getParcelableCompat
import com.kunzisoft.keepass.utils.getParcelableExtraCompat
import com.kunzisoft.keepass.utils.UriUtil.getUri
import com.kunzisoft.keepass.view.MainCredentialView
import com.kunzisoft.keepass.view.asError
import com.kunzisoft.keepass.view.showActionErrorIfNeeded
@@ -88,6 +89,7 @@ class MainCredentialActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bu
// Views
private var toolbar: Toolbar? = null
private var filenameView: TextView? = null
private var logotypeButton: View? = null
private var advancedUnlockButton: View? = null
private var mainCredentialView: MainCredentialView? = null
private var confirmButtonView: Button? = null
@@ -128,7 +130,8 @@ class MainCredentialActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bu
supportActionBar?.setDisplayShowHomeEnabled(true)
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)
confirmButtonView = findViewById(R.id.activity_password_open_button)
infoContainerView = findViewById(R.id.activity_password_info_container)
@@ -157,10 +160,15 @@ class MainCredentialActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bu
// If is a view intent
getUriFromIntent(intent)
// Show appearance
logotypeButton?.setOnClickListener {
startActivity(Intent(this, AppearanceSettingsActivity::class.java))
}
// Init Biometric elements
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
advancedUnlockButton?.setOnClickListener {
startActivity(Intent(this, SettingsAdvancedUnlockActivity::class.java))
startActivity(Intent(this, AdvancedUnlockSettingsActivity::class.java))
}
}
advancedUnlockFragment = supportFragmentManager
@@ -647,7 +655,7 @@ class MainCredentialActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bu
startActivity(
Intent(
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.resetAppTimeoutWhenViewTouchedOrFocused
import com.kunzisoft.keepass.database.ContextualDatabase
import com.kunzisoft.keepass.icons.IconDrawableFactory
import com.kunzisoft.keepass.tasks.ActionRunnable
import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.viewmodels.DatabaseViewModel
@@ -16,8 +15,6 @@ abstract class DatabaseDialogFragment : DialogFragment(), DatabaseRetrieval {
private val mDatabaseViewModel: DatabaseViewModel by activityViewModels()
private var mDatabase: ContextualDatabase? = null
protected var mIconDrawableFactory: IconDrawableFactory? = null
override fun onCreate(savedInstanceState: Bundle?) {
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.model.GroupInfo
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.utils.getParcelableCompat
import com.kunzisoft.keepass.utils.TimeUtil.getDateTimeString
import com.kunzisoft.keepass.utils.UuidUtil
import com.kunzisoft.keepass.utils.getParcelableCompat
import com.kunzisoft.keepass.view.DateTimeFieldView
class GroupDialogFragment : DatabaseDialogFragment() {
@@ -65,7 +65,7 @@ class GroupDialogFragment : DatabaseDialogFragment() {
override fun onDatabaseRetrieved(database: ContextualDatabase?) {
super.onDatabaseRetrieved(database)
mPopulateIconMethod = { imageView, icon ->
mIconDrawableFactory?.assignDatabaseIcon(imageView, icon, mIconColor)
database?.iconDrawableFactory?.assignDatabaseIcon(imageView, icon, mIconColor)
}
mPopulateIconMethod?.invoke(iconView, mGroupInfo.icon)
@@ -108,7 +108,7 @@ class GroupDialogFragment : DatabaseDialogFragment() {
uuidReferenceView = root.findViewById(R.id.group_UUID_reference)
// 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)
ta.recycle()

View File

@@ -90,13 +90,11 @@ class GroupEditDialogFragment : DatabaseDialogFragment() {
mPopulateIconMethod?.invoke(iconButtonView, mGroupInfo.icon)
}
mGroupEditViewModel.onDateSelected.observe(this) { viewModelDate ->
mGroupEditViewModel.onDateSelected.observe(this) { dateMilliseconds ->
// Save the date
mGroupInfo.expiryTime = DateInstant(
DateTime(mGroupInfo.expiryTime.date)
.withYear(viewModelDate.year)
.withMonthOfYear(viewModelDate.month + 1)
.withDayOfMonth(viewModelDate.day)
.withMillis(dateMilliseconds)
.toDate())
expirationView.dateTime = mGroupInfo.expiryTime
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.activities.helpers.ExternalFileHelper
import com.kunzisoft.keepass.database.MainCredential
import com.kunzisoft.keepass.utils.getParcelableCompat
import com.kunzisoft.keepass.utils.UriUtil.getDocumentFile
import com.kunzisoft.keepass.utils.getParcelableCompat
import com.kunzisoft.keepass.view.MainCredentialView
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.OtpType
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.openUrl
import com.kunzisoft.keepass.utils.getParcelableCompat
import java.util.*
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.os.Build
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import androidx.appcompat.app.AlertDialog
import android.text.SpannableStringBuilder
import android.text.method.LinkMovementMethod
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.core.text.HtmlCompat
import androidx.fragment.app.DialogFragment
import com.kunzisoft.keepass.R
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.model.SearchInfo
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
private var mTypeMode: TypeMode = TypeMode.DEFAULT
private var mSpecialModeView: SpecialModeView? = null
private var mToolbarSpecial: ToolbarSpecial? = null
override fun onBackPressed() {
if (mSpecialMode != SpecialMode.DEFAULT)
@@ -113,8 +113,8 @@ abstract class DatabaseModeActivity : DatabaseActivity() {
?: EntrySelectionHelper.retrieveSearchInfoFromIntent(intent)
// To show the selection mode
mSpecialModeView = findViewById(R.id.special_mode_view)
mSpecialModeView?.apply {
mToolbarSpecial = findViewById(R.id.special_mode_view)
mToolbarSpecial?.apply {
// Populate title
val selectionModeStringId = when (mSpecialMode) {
SpecialMode.DEFAULT, // Not important because hidden

View File

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

View File

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

View File

@@ -23,12 +23,14 @@ import android.content.Context
import android.graphics.Color
import android.graphics.PorterDuff
import android.net.Uri
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.annotation.ColorInt
import android.widget.CompoundButton
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.SortedList
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 {
val view = inflater.inflate(R.layout.item_file_info, parent, false)
return FileDatabaseHistoryViewHolder(view)

View File

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

View File

@@ -221,8 +221,6 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
allowOpenBiometricPrompt = true
if (PreferencesUtil.isBiometricUnlockEnable(context)) {
mAdvancedUnlockInfoView?.setIconResource(R.drawable.fingerprint)
// biometric not supported (by API level or hardware) so keep option hidden
// or manually disable
val biometricCanAuthenticate = AdvancedUnlockManager.canAuthenticate(context)
@@ -241,7 +239,6 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
}
}
} else if (PreferencesUtil.isDeviceCredentialUnlockEnable(context)) {
mAdvancedUnlockInfoView?.setIconResource(R.drawable.bolt)
if (AdvancedUnlockManager.isDeviceSecure(context)) {
selectMode()
} else {
@@ -297,12 +294,12 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
private fun initNotAvailable() {
showViews(false)
mAdvancedUnlockInfoView?.setIconViewClickListener(false, null)
mAdvancedUnlockInfoView?.setIconViewClickListener(null)
}
@RequiresApi(Build.VERSION_CODES.M)
private fun openBiometricSetting() {
mAdvancedUnlockInfoView?.setIconViewClickListener(false) {
mAdvancedUnlockInfoView?.setIconViewClickListener {
try {
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> {
@@ -351,11 +348,11 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
@RequiresApi(Build.VERSION_CODES.M)
private fun initWaitData() {
showViews(true)
setAdvancedUnlockedTitleView(R.string.no_credentials_stored)
setAdvancedUnlockedTitleView(R.string.unavailable)
setAdvancedUnlockedMessageView("")
context?.let { context ->
mAdvancedUnlockInfoView?.setIconViewClickListener(false) {
mAdvancedUnlockInfoView?.setIconViewClickListener {
onAuthenticationError(BiometricPrompt.ERROR_UNABLE_TO_PROCESS,
context.getString(R.string.credential_before_click_advanced_unlock_button))
}
@@ -382,7 +379,7 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
@RequiresApi(Build.VERSION_CODES.M)
private fun initEncryptData() {
showViews(true)
setAdvancedUnlockedTitleView(R.string.open_advanced_unlock_prompt_store_credential)
setAdvancedUnlockedTitleView(R.string.unlock_and_link_biometric)
setAdvancedUnlockedMessageView("")
advancedUnlockManager?.initEncryptData { cryptoPrompt ->
@@ -396,7 +393,7 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
@RequiresApi(Build.VERSION_CODES.M)
private fun initDecryptData() {
showViews(true)
setAdvancedUnlockedTitleView(R.string.open_advanced_unlock_prompt_unlock_database)
setAdvancedUnlockedTitleView(R.string.unlock)
setAdvancedUnlockedMessageView("")
advancedUnlockManager?.let { unlockHelper ->
@@ -629,7 +626,7 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
@RequiresApi(Build.VERSION_CODES.M)
private fun setAdvancedUnlockedMessageView(text: CharSequence) {
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
import android.Manifest
import android.app.AlertDialog
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
@@ -38,6 +37,7 @@ import android.os.IBinder
import android.util.Log
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat.shouldShowRequestPermissionRationale
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
@@ -252,12 +252,10 @@ class DatabaseTaskProvider(
serviceConnection = object : ServiceConnection {
override fun onBindingDied(name: ComponentName?) {
stopDialog()
super.onBindingDied(name)
}
override fun onNullBinding(name: ComponentName?) {
stopDialog()
super.onNullBinding(name)
}
override fun onServiceConnected(name: ComponentName?, serviceBinder: IBinder?) {
@@ -372,7 +370,7 @@ class DatabaseTaskProvider(
// it's not the first time, so the user deliberately chooses not to display the notification
startService(bundle, actionTask)
} else {
AlertDialog.Builder(activity)
AlertDialog.Builder(context)
.setMessage(R.string.warning_database_notification_permission)
.setNegativeButton(R.string.later) { _, _ ->
// Refuses the notification, so start the service

View File

@@ -98,7 +98,7 @@ open class Education(val activity: Activity) {
}
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)
typedArray.recycle()
return colorControl
@@ -109,7 +109,7 @@ open class Education(val activity: Activity) {
}
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)
typedArray.recycle()
return colorControl

View File

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

View File

@@ -240,10 +240,10 @@ class AttachmentFileNotificationService: LockNotificationService() {
setOngoing(true)
}
AttachmentState.IN_PROGRESS -> {
if (attachmentNotification.entryAttachmentState.downloadProgression > 100) {
if (attachmentNotification.entryAttachmentState.downloadProgression > FILE_PROGRESSION_MAX) {
setContentText(getString(R.string.download_finalization))
} else {
setProgress(100,
setProgress(FILE_PROGRESSION_MAX,
attachmentNotification.entryAttachmentState.downloadProgression,
false)
setContentText(getString(R.string.download_progression,
@@ -446,7 +446,7 @@ class AttachmentFileNotificationService: LockNotificationService() {
if (downloadState != AttachmentState.CANCELED
&& downloadState != AttachmentState.ERROR) {
downloadState = AttachmentState.COMPLETE
downloadProgression = 100
downloadProgression = FILE_PROGRESSION_MAX
}
}
attachmentNotification.attachmentFileAction = null
@@ -495,6 +495,8 @@ class AttachmentFileNotificationService: LockNotificationService() {
const val FILE_URI_KEY = "FILE_URI_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
class SettingsAdvancedUnlockActivity : SettingsActivity() {
class AdvancedUnlockSettingsActivity : SettingsActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
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.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
import androidx.preference.TwoStatePreference
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.settings.preferencedialogfragment.AutofillBlocklistAppIdPreferenceDialogFragmentCompat
import com.kunzisoft.keepass.settings.preferencedialogfragment.AutofillBlocklistWebDomainPreferenceDialogFragmentCompat
@@ -35,7 +35,7 @@ class AutofillSettingsFragment : PreferenceFragmentCompat() {
// Load the preferences from an XML resource
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) {
autofillInlineSuggestionsPreference?.isVisible = false
}

View File

@@ -24,6 +24,7 @@ import android.os.Bundle
import android.view.View
import androidx.fragment.app.activityViewModels
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.viewmodels.DatabaseViewModel
@@ -60,6 +61,9 @@ class MainPreferenceFragment : PreferenceFragmentCompat() {
private fun checkDatabaseLoaded() {
findPreference<Preference>(getString(R.string.settings_database_key))
?.isEnabled = mDatabaseLoaded
findPreference<PreferenceCategory>(getString(R.string.settings_database_category_key))
?.isVisible = mDatabaseLoaded
}
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.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.SwitchPreference
import androidx.preference.TwoStatePreference
import com.kunzisoft.keepass.BuildConfig
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.ProFeatureDialogFragment
@@ -119,14 +119,14 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
activity?.let { activity ->
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)
if (autofillManager != null && autofillManager.hasEnabledAutofillServices())
autoFillEnablePreference?.isChecked = autofillManager.hasEnabledAutofillServices()
autoFillEnablePreference?.onPreferenceClickListener = object : Preference.OnPreferenceClickListener {
@RequiresApi(api = Build.VERSION_CODES.O)
override fun onPreferenceClick(preference: Preference): Boolean {
if ((preference as SwitchPreference).isChecked) {
if ((preference as TwoStatePreference).isChecked) {
try {
enableService()
} catch (e: ActivityNotFoundException) {
@@ -208,14 +208,13 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
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 ->
if (newValue as Boolean && context != null) {
val message = getString(R.string.allow_copy_password_warning) +
"\n\n" +
getString(R.string.clipboard_warning)
AlertDialog
.Builder(requireContext())
AlertDialog.Builder(requireContext())
.setMessage(message)
.create()
.apply {
@@ -240,10 +239,10 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
activity?.let { activity ->
val biometricUnlockEnablePreference: SwitchPreference? = findPreference(getString(R.string.biometric_unlock_enable_key))
val deviceCredentialUnlockEnablePreference: SwitchPreference? = findPreference(getString(R.string.device_credential_unlock_enable_key))
val autoOpenPromptPreference: SwitchPreference? = findPreference(getString(R.string.biometric_auto_open_prompt_key))
val tempAdvancedUnlockPreference: SwitchPreference? = findPreference(getString(R.string.temp_advanced_unlock_enable_key))
val biometricUnlockEnablePreference: TwoStatePreference? = findPreference(getString(R.string.biometric_unlock_enable_key))
val deviceCredentialUnlockEnablePreference: TwoStatePreference? = findPreference(getString(R.string.device_credential_unlock_enable_key))
val autoOpenPromptPreference: TwoStatePreference? = findPreference(getString(R.string.biometric_auto_open_prompt_key))
val tempAdvancedUnlockPreference: TwoStatePreference? = findPreference(getString(R.string.temp_advanced_unlock_enable_key))
val biometricUnlockSupported = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
AdvancedUnlockManager.biometricUnlockSupported(activity)
@@ -253,7 +252,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
if (!biometricUnlockSupported) {
isChecked = false
setOnPreferenceClickListener { preference ->
(preference as SwitchPreference).isChecked = false
(preference as TwoStatePreference).isChecked = false
UnavailableFeatureDialogFragment.getInstance(Build.VERSION_CODES.M)
.show(parentFragmentManager, "unavailableFeatureDialog")
false
@@ -300,7 +299,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
if (!deviceCredentialUnlockSupported) {
isChecked = false
setOnPreferenceClickListener { preference ->
(preference as SwitchPreference).isChecked = false
(preference as TwoStatePreference).isChecked = false
UnavailableFeatureDialogFragment.getInstance(Build.VERSION_CODES.M)
.show(parentFragmentManager, "unavailableFeatureDialog")
false
@@ -523,7 +522,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
super.onResume()
activity?.let { activity ->
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)
autoFillEnablePreference.isChecked = autofillManager != null
&& autofillManager.hasEnabledAutofillServices()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -23,14 +23,12 @@ import android.content.Context
import android.os.Build
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.annotation.StringRes
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.biometric.FingerPrintAnimatedVector
@RequiresApi(api = Build.VERSION_CODES.M)
class AdvancedUnlockInfoView @JvmOverloads constructor(context: Context,
@@ -38,83 +36,38 @@ class AdvancedUnlockInfoView @JvmOverloads constructor(context: Context,
defStyle: Int = 0)
: LinearLayout(context, attrs, defStyle) {
private val unlockContainerView: View
private var unlockAnimatedVector: FingerPrintAnimatedVector? = null
private var unlockTitleTextView: TextView? = null
private var unlockMessageTextView: TextView? = null
private var unlockIconImageView: ImageView? = null
private var biometricButtonView: Button? = null
init {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
inflater?.inflate(R.layout.view_advanced_unlock, this)
unlockContainerView = findViewById(R.id.fingerprint_container)
unlockTitleTextView = findViewById(R.id.biometric_title)
unlockMessageTextView = findViewById(R.id.biometric_message)
unlockIconImageView = findViewById(R.id.biometric_image)
biometricButtonView = findViewById(R.id.biometric_button)
}
private fun startIconViewAnimation() {
unlockAnimatedVector?.startScan()
}
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)
fun setIconViewClickListener(listener: OnClickListener?) {
biometricButtonView?.setOnClickListener(listener)
}
var title: CharSequence
get() {
return unlockTitleTextView?.text?.toString() ?: ""
return biometricButtonView?.text?.toString() ?: ""
}
set(value) {
unlockTitleTextView?.text = value
biometricButtonView?.text = value
}
fun setTitle(@StringRes textId: Int) {
title = context.getString(textId)
}
var message: CharSequence?
get() {
return unlockMessageTextView?.text?.toString() ?: ""
}
set(value) {
if (value == null || value.isEmpty()) {
unlockMessageTextView?.visibility = GONE
} else {
unlockMessageTextView?.visibility = VISIBLE
stopIconViewAnimation()
}
unlockMessageTextView?.text = value ?: ""
fun setMessage(text: CharSequence) {
if (text.isNotEmpty())
Toast.makeText(context, text, Toast.LENGTH_LONG).show()
}
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
mOnParametersChangeListener?.invoke(searchParameters)
}
searchNumbers.setOnClickListener(null)
}
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
setCurrentDateTimeSelection { instant ->
val newDateInstant = DateInstant(
DateTime(instant.date)
.withYear(date.year)
.withMonthOfYear(date.month + 1)
.withDayOfMonth(date.day)
.withMillis(dateMilliseconds)
.toDate(), instant.type)
if (instant.type == DateInstant.Type.DATE_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.appcompat.view.ActionMode
import androidx.appcompat.view.SupportMenuInflater
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
import com.google.android.material.appbar.MaterialToolbar
import com.kunzisoft.keepass.R
class ToolbarAction @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
defStyle: Int = androidx.appcompat.R.attr.toolbarStyle)
: Toolbar(context, attrs, defStyle) {
defStyle: Int = R.attr.toolbarActionStyle)
: MaterialToolbar(context, attrs, defStyle) {
private var mActionModeCallback: ActionMode.Callback? = null
private val actionMode = NodeActionMode(this)
@@ -47,7 +47,7 @@ class ToolbarAction @JvmOverloads constructor(context: Context,
init {
ContextCompat.getDrawable(context, R.drawable.ic_close_white_24dp)?.let { closeDrawable ->
val typedValue = TypedValue()
context.theme.resolveAttribute(R.attr.colorControlNormal, typedValue, true)
context.theme.resolveAttribute(R.attr.colorOnSurface, typedValue, true)
@ColorInt val colorControl = typedValue.data
closeDrawable.colorFilter = PorterDuffColorFilter(colorControl, PorterDuff.Mode.SRC_ATOP)
navigationIcon = closeDrawable

View File

@@ -26,14 +26,14 @@ import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import androidx.annotation.ColorInt
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
import com.google.android.material.appbar.MaterialToolbar
import com.kunzisoft.keepass.R
class SpecialModeView @JvmOverloads constructor(context: Context,
class ToolbarSpecial @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
defStyle: Int = androidx.appcompat.R.attr.toolbarStyle)
: Toolbar(context, attrs, defStyle) {
defStyle: Int = R.attr.toolbarSpecialStyle)
: MaterialToolbar(context, attrs, defStyle) {
init {
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 com.kunzisoft.keepass.database.element.DateInstant
import com.kunzisoft.keepass.database.element.icon.IconImage
import com.kunzisoft.keepass.view.DataDate
import com.kunzisoft.keepass.view.DataTime
abstract class NodeEditViewModel : ViewModel() {
@@ -24,8 +23,8 @@ abstract class NodeEditViewModel : ViewModel() {
val requestDateTimeSelection : LiveData<DateInstant> get() = _requestDateTimeSelection
private val _requestDateTimeSelection = SingleLiveEvent<DateInstant>()
val onDateSelected : LiveData<DataDate> get() = _onDateSelected
private val _onDateSelected = SingleLiveEvent<DataDate>()
val onDateSelected : LiveData<Long> get() = _onDateSelected
private val _onDateSelected = SingleLiveEvent<Long>()
val onTimeSelected : LiveData<DataTime> get() = _onTimeSelected
private val _onTimeSelected = SingleLiveEvent<DataTime>()
@@ -58,8 +57,8 @@ abstract class NodeEditViewModel : ViewModel() {
_requestDateTimeSelection.value = dateInstant
}
fun selectDate(year: Int, month: Int, day: Int) {
_onDateSelected.value = DataDate(year, month, day)
fun selectDate(dateMilliseconds: Long) {
_onDateSelected.value = dateMilliseconds
}
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"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="true" android:color="?attr/colorOnAccentColor"/>
<item android:color="?android:attr/textColorPrimary"/>
<item android:state_selected="true" android:color="?attr/colorOnSecondary"/>
<item android:color="?attr/colorOnSurface"/>
</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:top="12dp"
android:bottom="12dp"/>
<solid android:color="?attr/colorAccent"/>
<solid android:color="?attr/colorSecondary"/>
</shape>
</item>
</ripple>

View File

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

View File

@@ -1,13 +1,22 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:color="?android:attr/colorControlHighlight"
tools:targetApi="lollipop">
<item>
<selector>
<item android:state_selected="true">
<shape>
<solid android:color="?attr/colorAccentLight"/>
<corners android:radius="25dp" />
<solid android:color="?attr/colorSecondaryContainer"/>
</shape>
</item>
<item android:state_selected="false">
<shape>
<solid android:color="@color/transparent"/>
<corners android:radius="25dp" />
<solid android:color="?attr/colorSurfaceContainer"/>
</shape>
</item>
</selector>
</selector>
</item>
</ripple>

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">
<item android:state_selected="true">
<shape>
<solid android:color="@color/white_grey_darker"/>
<corners android:radius="25dp" />
<solid android:color="@color/grey_lighter"/>
</shape>
</item>
<item android:state_selected="false">
<shape>
<solid android:color="@color/transparent"/>
<corners android:radius="25dp" />
<solid android:color="@color/black_selection"/>
</shape>
</item>
</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">
<shape>
<corners
android:radius="8dp" />
android:radius="@dimen/dialog_radius" />
<padding
android:left="14dp"
android:right="14dp"
@@ -21,7 +21,7 @@
<item android:bottom="2dp" android:left="2dp">
<shape>
<corners
android:radius="8dp" />
android:radius="@dimen/dialog_radius" />
<padding
android:left="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:viewportHeight="24.0">
<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"/>
</vector>

View File

@@ -6,7 +6,8 @@
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:strokeWidth="2.28571415"
android:strokeColor="#000000"
android:strokeWidth="2"
android:strokeLineJoin="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" />

View File

@@ -17,56 +17,11 @@
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
-->
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<Button xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fingerprint_container"
android:layout_width="match_parent"
android:id="@+id/biometric_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:filterTouchesWhenObscured="true">
<androidx.appcompat.widget.AppCompatImageView
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>
style="@style/KeepassDXStyle.Button.Secondary"
app:icon="@drawable/ic_fingerprint_24"
android:text="@string/configure" />

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -40,9 +40,8 @@
<com.kunzisoft.keepass.view.ToolbarAction
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:theme="?attr/toolbarActionAppearance"
app:layout_constraintBottom_toTopOf="@+id/screenshot_mode_banner" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
@@ -52,7 +51,7 @@
android:layout_height="wrap_content"
android:contentDescription="@string/validate"
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_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View File

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

View File

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

View File

@@ -1,13 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
<com.kunzisoft.keepass.view.AdvancedUnlockInfoView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.kunzisoft.keepass.view.AdvancedUnlockInfoView
android:id="@+id/advanced_unlock_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="match_parent"
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_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<androidx.appcompat.widget.SwitchCompat
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_element"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="@string/enable"
android:background="@drawable/background_button_small"
android:textColor="?attr/colorOnAccentColor"
android:background="@drawable/background_switch"
android:backgroundTint="?attr/colorSecondary"
android:textColor="?attr/colorOnSecondary"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:minHeight="48dp"/>

View File

@@ -61,9 +61,8 @@
android:contentDescription="@string/menu_delete"
style="@style/KeepassDXStyle.ImageButton.Simple" />
<androidx.appcompat.widget.SwitchCompat
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/entry_custom_field_protection"
style="@style/KeepassDXStyle.TextAppearance.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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
android:layout_width="match_parent"
android:layout_height="68dp"
android:background="?attr/colorPrimary" />
android:background="?attr/colorSurface" />
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -44,8 +44,7 @@
android:layout_marginRight="@dimen/card_view_margin_horizontal"
android:layout_marginTop="@dimen/default_margin"
android:layout_marginBottom="@dimen/card_view_margin_vertical"
android:layout_gravity="bottom"
app:cardCornerRadius="4dp">
android:layout_gravity="bottom">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -114,10 +113,7 @@
android:stepSize="1"
android:value="@integer/passphrase_generator_word_count_default"
android:valueFrom="@integer/passphrase_generator_word_count_min"
android:valueTo="@integer/passphrase_generator_word_count_max"
app:thumbColor="?attr/chipFilterBackgroundColor"
app:trackColorActive="?attr/chipFilterBackgroundColor"
app:trackColorInactive="?attr/chipFilterBackgroundColorDisabled" />
android:valueTo="@integer/passphrase_generator_word_count_max" />
<EditText
android:id="@+id/word_count"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -17,8 +17,7 @@
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"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

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