Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
f3f0daf7e7
17 changed files with 634 additions and 23 deletions
2
.github/workflows/beta.yml
vendored
2
.github/workflows/beta.yml
vendored
|
@ -108,7 +108,7 @@ jobs:
|
|||
|
||||
#Telegram
|
||||
curl -F "chat_id=${{ secrets.TELEGRAM_CHANNEL_ID }}" \
|
||||
-F "document=@app/build/outputs/apk/google/alpha/app-google-universal-alpha.apk" \
|
||||
-F "document=@app/build/outputs/apk/google/alpha/app-google-alpha.apk" \
|
||||
-F "caption=Alpha-Build: ${VERSION}: ${commit_messages}" \
|
||||
https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendDocument
|
||||
|
||||
|
|
|
@ -101,6 +101,8 @@ dependencies {
|
|||
implementation 'androidx.preference:preference-ktx:1.2.1'
|
||||
implementation 'androidx.webkit:webkit:1.11.0'
|
||||
implementation "com.anggrayudi:storage:1.5.5"
|
||||
implementation "androidx.biometric:biometric:1.1.0"
|
||||
|
||||
|
||||
// Glide
|
||||
ext.glide_version = '4.16.0'
|
||||
|
|
|
@ -16,6 +16,8 @@ import ani.dantotsu.navBarHeight
|
|||
import ani.dantotsu.profile.User
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.toast
|
||||
import ani.dantotsu.util.Logger
|
||||
|
||||
class StatusActivity : AppCompatActivity(), StoriesCallback {
|
||||
private lateinit var activity: ArrayList<User>
|
||||
|
@ -44,10 +46,14 @@ class StatusActivity : AppCompatActivity(), StoriesCallback {
|
|||
|
||||
val key = "activities"
|
||||
val watchedActivity = PrefManager.getCustomVal<Set<Int>>(key, setOf())
|
||||
val startFrom = findFirstNonMatch(watchedActivity, activity[position].activity )
|
||||
val startIndex = if ( startFrom > 0) startFrom else 0
|
||||
binding.stories.setStoriesList(activity[position].activity, this, startIndex + 1)
|
||||
|
||||
if (activity.getOrNull(position) != null) {
|
||||
val startFrom = findFirstNonMatch(watchedActivity, activity[position].activity )
|
||||
val startIndex = if ( startFrom > 0) startFrom else 0
|
||||
binding.stories.setStoriesList(activity[position].activity, this, startIndex + 1)
|
||||
} else {
|
||||
Logger.log("index out of bounds for position $position of size ${activity.size}")
|
||||
finish()
|
||||
}
|
||||
|
||||
}
|
||||
private fun findFirstNonMatch(watchedActivity: Set<Int>, activity: List<Activity>): Int {
|
||||
|
@ -58,13 +64,16 @@ class StatusActivity : AppCompatActivity(), StoriesCallback {
|
|||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
binding.stories.pause()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
binding.stories.resume()
|
||||
if (hasWindowFocus())
|
||||
binding.stories.resume()
|
||||
}
|
||||
|
||||
override fun onWindowFocusChanged(hasFocus: Boolean) {
|
||||
|
|
|
@ -424,7 +424,8 @@ class MediaDetailsActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedLi
|
|||
}
|
||||
|
||||
override fun onResume() {
|
||||
navBar.selectTabAt(selected)
|
||||
if (::navBar.isInitialized)
|
||||
navBar.selectTabAt(selected)
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.content.Intent
|
|||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.core.view.updateLayoutParams
|
||||
|
@ -24,7 +25,10 @@ class CrashActivity : AppCompatActivity() {
|
|||
ThemeManager(this).applyTheme()
|
||||
initActivity(this)
|
||||
binding = ActivityCrashBinding.inflate(layoutInflater)
|
||||
|
||||
window.setFlags(
|
||||
WindowManager.LayoutParams.FLAG_SECURE,
|
||||
WindowManager.LayoutParams.FLAG_SECURE
|
||||
)
|
||||
setContentView(binding.root)
|
||||
binding.root.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = statusBarHeight
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package ani.dantotsu.others.calc
|
||||
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.biometric.BiometricPrompt
|
||||
import androidx.core.content.ContextCompat
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.util.Logger
|
||||
|
||||
object BiometricPromptUtils {
|
||||
private const val TAG = "BiometricPromptUtils"
|
||||
|
||||
/**
|
||||
* Create a BiometricPrompt instance
|
||||
* @param activity: AppCompatActivity
|
||||
* @param processSuccess: success callback
|
||||
*/
|
||||
fun createBiometricPrompt(
|
||||
activity: AppCompatActivity,
|
||||
processSuccess: (BiometricPrompt.AuthenticationResult) -> Unit
|
||||
): BiometricPrompt {
|
||||
val executor = ContextCompat.getMainExecutor(activity)
|
||||
|
||||
val callback = object : BiometricPrompt.AuthenticationCallback() {
|
||||
|
||||
override fun onAuthenticationError(errCode: Int, errString: CharSequence) {
|
||||
super.onAuthenticationError(errCode, errString)
|
||||
Logger.log("$TAG errCode is $errCode and errString is: $errString")
|
||||
}
|
||||
|
||||
override fun onAuthenticationFailed() {
|
||||
super.onAuthenticationFailed()
|
||||
Logger.log("$TAG User biometric rejected.")
|
||||
}
|
||||
|
||||
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
||||
super.onAuthenticationSucceeded(result)
|
||||
Log.d(TAG, "Authentication was successful")
|
||||
processSuccess(result)
|
||||
}
|
||||
}
|
||||
return BiometricPrompt(activity, executor, callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a BiometricPrompt.PromptInfo instance
|
||||
* @param activity: AppCompatActivity
|
||||
* @return BiometricPrompt.PromptInfo: instance
|
||||
*/
|
||||
fun createPromptInfo(activity: AppCompatActivity): BiometricPrompt.PromptInfo =
|
||||
BiometricPrompt.PromptInfo.Builder().apply {
|
||||
setTitle(activity.getString(R.string.bio_prompt_info_title))
|
||||
setDescription(activity.getString(R.string.bio_prompt_info_desc))
|
||||
setConfirmationRequired(false)
|
||||
setNegativeButtonText(activity.getString(R.string.cancel))
|
||||
}.build()
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
package ani.dantotsu.others.calc
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.view.MotionEvent
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
|
@ -16,6 +20,8 @@ import ani.dantotsu.databinding.ActivityCalcBinding
|
|||
import ani.dantotsu.getThemeColor
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import ani.dantotsu.util.NumberConverter.Companion.toBinary
|
||||
|
@ -24,7 +30,13 @@ import ani.dantotsu.util.NumberConverter.Companion.toHex
|
|||
class CalcActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityCalcBinding
|
||||
private lateinit var code: String
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private val runnable = Runnable {
|
||||
success()
|
||||
}
|
||||
private val stack = CalcStack()
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeManager(this).applyTheme()
|
||||
|
@ -73,6 +85,29 @@ class CalcActivity : AppCompatActivity() {
|
|||
binding.displayHex.text = ""
|
||||
binding.display.text = "0"
|
||||
}
|
||||
if (PrefManager.getVal(PrefName.OverridePassword, false)) {
|
||||
buttonClear.setOnTouchListener { v, event ->
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
handler.postDelayed(runnable, 10000)
|
||||
true
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_UP -> {
|
||||
v.performClick()
|
||||
handler.removeCallbacks(runnable)
|
||||
true
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_CANCEL -> {
|
||||
handler.removeCallbacks(runnable)
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
buttonBackspace.setOnClickListener {
|
||||
stack.remove()
|
||||
updateDisplay()
|
||||
|
@ -81,6 +116,20 @@ class CalcActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (hasPermission) {
|
||||
success()
|
||||
}
|
||||
if (PrefManager.getVal(PrefName.BiometricToken, "").isNotEmpty()) {
|
||||
val bioMetricPrompt = BiometricPromptUtils.createBiometricPrompt(this) {
|
||||
success()
|
||||
}
|
||||
val promptInfo = BiometricPromptUtils.createPromptInfo(this)
|
||||
bioMetricPrompt.authenticate(promptInfo)
|
||||
}
|
||||
}
|
||||
|
||||
private fun success() {
|
||||
hasPermission = true
|
||||
ContextCompat.startActivity(
|
||||
|
|
|
@ -43,6 +43,7 @@ import kotlinx.coroutines.CoroutineScope
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.util.Locale
|
||||
|
||||
class ExtensionsActivity : AppCompatActivity() {
|
||||
lateinit var binding: ActivityExtensionsBinding
|
||||
|
@ -173,8 +174,11 @@ class ExtensionsActivity : AppCompatActivity() {
|
|||
initActivity(this)
|
||||
binding.languageselect.setOnClickListener {
|
||||
val languageOptions =
|
||||
LanguageMapper.Companion.Language.entries.map { it.name }.toTypedArray()
|
||||
val builder = AlertDialog.Builder(currContext(), R.style.MyPopup)
|
||||
LanguageMapper.Companion.Language.entries.map { entry ->
|
||||
entry.name.lowercase().replace("_", " ")
|
||||
.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.ROOT) else it.toString() }
|
||||
}.toTypedArray()
|
||||
val builder = AlertDialog.Builder(this, R.style.MyPopup)
|
||||
val listOrder: String = PrefManager.getVal(PrefName.LangSort)
|
||||
val index = LanguageMapper.Companion.Language.entries.toTypedArray()
|
||||
.indexOfFirst { it.code == listOrder }
|
||||
|
|
|
@ -6,6 +6,7 @@ import androidx.core.app.NotificationCompat
|
|||
import ani.dantotsu.R
|
||||
import ani.dantotsu.connections.crashlytics.CrashlyticsInterface
|
||||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.util.Logger
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.extension.InstallStep
|
||||
import uy.kohesive.injekt.Injekt
|
||||
|
@ -30,6 +31,7 @@ class InstallerSteps(
|
|||
|
||||
fun onError(error: Throwable, extra: () -> Unit) {
|
||||
Injekt.get<CrashlyticsInterface>().logException(error)
|
||||
Logger.log(error)
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_ERROR
|
||||
|
|
|
@ -8,9 +8,12 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.CheckBox
|
||||
import android.widget.EditText
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.biometric.BiometricManager
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
|
@ -21,6 +24,7 @@ import ani.dantotsu.databinding.DialogUserAgentBinding
|
|||
import ani.dantotsu.download.DownloadsManager
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.others.calc.BiometricPromptUtils
|
||||
import ani.dantotsu.restartApp
|
||||
import ani.dantotsu.savePrefsToDownloads
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
|
@ -39,6 +43,7 @@ import kotlinx.coroutines.GlobalScope
|
|||
import kotlinx.coroutines.launch
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.util.UUID
|
||||
|
||||
|
||||
class SettingsCommonActivity : AppCompatActivity() {
|
||||
|
@ -183,14 +188,47 @@ class SettingsCommonActivity : AppCompatActivity() {
|
|||
(dialog as AlertDialog).findViewById<EditText>(R.id.passwordInput)
|
||||
val confirmPasswordInput =
|
||||
dialog.findViewById<EditText>(R.id.confirmPasswordInput)
|
||||
val forgotPasswordCheckbox =
|
||||
dialog.findViewById<CheckBox>(R.id.forgotPasswordCheckbox)
|
||||
if (forgotPasswordCheckbox?.isChecked == true) {
|
||||
PrefManager.setVal(PrefName.OverridePassword, true)
|
||||
}
|
||||
|
||||
val password = passwordInput?.text.toString()
|
||||
val confirmPassword = confirmPasswordInput?.text.toString()
|
||||
|
||||
if (password == confirmPassword && password.isNotEmpty()) {
|
||||
PrefManager.setVal(PrefName.AppPassword, password)
|
||||
toast(R.string.success)
|
||||
dialog.dismiss()
|
||||
if (dialog.findViewById<CheckBox>(R.id.biometricCheckbox)?.isChecked == true) {
|
||||
val canBiometricPrompt =
|
||||
BiometricManager.from(applicationContext)
|
||||
.canAuthenticate(
|
||||
BiometricManager.Authenticators.BIOMETRIC_WEAK
|
||||
) == BiometricManager.BIOMETRIC_SUCCESS
|
||||
if (canBiometricPrompt) {
|
||||
val biometricPrompt =
|
||||
BiometricPromptUtils.createBiometricPrompt(
|
||||
this@SettingsCommonActivity
|
||||
) { _ ->
|
||||
val token = UUID.randomUUID().toString()
|
||||
PrefManager.setVal(
|
||||
PrefName.BiometricToken,
|
||||
token
|
||||
)
|
||||
toast(R.string.success)
|
||||
dialog.dismiss()
|
||||
}
|
||||
val promptInfo =
|
||||
BiometricPromptUtils.createPromptInfo(
|
||||
this@SettingsCommonActivity
|
||||
)
|
||||
biometricPrompt.authenticate(promptInfo)
|
||||
}
|
||||
} else {
|
||||
PrefManager.setVal(PrefName.BiometricToken, "")
|
||||
toast(R.string.success)
|
||||
dialog.dismiss()
|
||||
}
|
||||
} else {
|
||||
toast(R.string.password_mismatch)
|
||||
}
|
||||
|
@ -200,6 +238,8 @@ class SettingsCommonActivity : AppCompatActivity() {
|
|||
}
|
||||
.setNeutralButton(R.string.remove) { dialog, _ ->
|
||||
PrefManager.setVal(PrefName.AppPassword, "")
|
||||
PrefManager.setVal(PrefName.BiometricToken, "")
|
||||
PrefManager.setVal(PrefName.OverridePassword, false)
|
||||
toast(R.string.success)
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
@ -209,6 +249,19 @@ class SettingsCommonActivity : AppCompatActivity() {
|
|||
passwordDialog.setOnShowListener {
|
||||
passwordDialog.findViewById<EditText>(R.id.passwordInput)
|
||||
?.requestFocus()
|
||||
val biometricCheckbox =
|
||||
passwordDialog.findViewById<CheckBox>(R.id.biometricCheckbox)
|
||||
val forgotPasswordCheckbox =
|
||||
passwordDialog.findViewById<CheckBox>(R.id.forgotPasswordCheckbox)
|
||||
val canAuthenticate =
|
||||
BiometricManager.from(applicationContext).canAuthenticate(
|
||||
BiometricManager.Authenticators.BIOMETRIC_WEAK
|
||||
) == BiometricManager.BIOMETRIC_SUCCESS
|
||||
biometricCheckbox?.isVisible = canAuthenticate
|
||||
biometricCheckbox?.isChecked =
|
||||
PrefManager.getVal(PrefName.BiometricToken, "").isNotEmpty()
|
||||
forgotPasswordCheckbox?.isChecked =
|
||||
PrefManager.getVal(PrefName.OverridePassword)
|
||||
}
|
||||
passwordDialog.show()
|
||||
}
|
||||
|
|
|
@ -202,4 +202,6 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
|
|||
MALCodeChallenge(Pref(Location.Protected, String::class, "")),
|
||||
MALToken(Pref(Location.Protected, MAL.ResponseToken::class, "")),
|
||||
AppPassword(Pref(Location.Protected, String::class, "")),
|
||||
BiometricToken(Pref(Location.Protected, String::class, "")),
|
||||
OverridePassword(Pref(Location.Protected, Boolean::class, false)),
|
||||
}
|
390
app/src/main/res/layout-land/activity_calc.xml
Normal file
390
app/src/main/res/layout-land/activity_calc.xml
Normal file
|
@ -0,0 +1,390 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout 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:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/bg">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/mainContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:background="@color/bg"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/displayContainer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:layout_marginTop="16dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/display"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:background="@drawable/rounded_top_corners"
|
||||
android:gravity="end"
|
||||
android:maxLines="2"
|
||||
app:autoSizeMaxTextSize="48sp"
|
||||
app:autoSizeMinTextSize="10sp"
|
||||
app:autoSizeStepGranularity="2sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
android:textSize="48sp"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/displayBinary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:background="?attr/colorSurfaceVariant"
|
||||
android:gravity="end"
|
||||
android:maxLines="2"
|
||||
app:autoSizeMaxTextSize="48sp"
|
||||
app:autoSizeMinTextSize="10sp"
|
||||
app:autoSizeStepGranularity="2sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
android:textSize="28sp"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/displayHex"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:background="@drawable/rounded_bottom_corners"
|
||||
android:gravity="end"
|
||||
android:maxLines="2"
|
||||
app:autoSizeMaxTextSize="48sp"
|
||||
app:autoSizeMinTextSize="10sp"
|
||||
app:autoSizeStepGranularity="2sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
android:textSize="28sp"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/buttonContainer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button7"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:backgroundTint="?attr/colorSurfaceVariant"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="7"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button8"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:backgroundTint="?attr/colorSurfaceVariant"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="8"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button9"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:backgroundTint="?attr/colorSurfaceVariant"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="9"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonDivide"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginStart="16dp"
|
||||
android:backgroundTint="?attr/colorPrimary"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="÷"
|
||||
android:textColor="?attr/colorOnPrimary"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button4"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:backgroundTint="?attr/colorSurfaceVariant"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="4"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button5"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:backgroundTint="?attr/colorSurfaceVariant"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="5"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button6"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:backgroundTint="?attr/colorSurfaceVariant"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="6"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonMultiply"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginStart="16dp"
|
||||
android:backgroundTint="?attr/colorPrimary"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="×"
|
||||
android:textColor="?attr/colorOnPrimary"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button1"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:backgroundTint="?attr/colorSurfaceVariant"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="1"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button2"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:backgroundTint="?attr/colorSurfaceVariant"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="2"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button3"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:backgroundTint="?attr/colorSurfaceVariant"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="3"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonSubtract"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginStart="16dp"
|
||||
android:backgroundTint="?attr/colorPrimary"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="−"
|
||||
android:textColor="?attr/colorOnPrimary"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button0"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:backgroundTint="?attr/colorSurfaceVariant"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="0"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonDot"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:backgroundTint="?attr/colorSurfaceVariant"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="."
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonBackspace"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:backgroundTint="?attr/colorSurfaceVariant"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="⌫"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonAdd"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginStart="16dp"
|
||||
android:backgroundTint="?attr/colorPrimary"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="+"
|
||||
android:textColor="?attr/colorOnPrimary"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonClear"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:backgroundTint="?attr/colorPrimary"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="C"
|
||||
android:textColor="?attr/colorOnPrimary"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonEquals"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginTop="16dp"
|
||||
android:backgroundTint="?attr/colorPrimary"
|
||||
android:elegantTextHeight="true"
|
||||
android:text="="
|
||||
android:textColor="?attr/colorOnPrimary"
|
||||
app:cornerRadius="16dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
|
@ -33,6 +33,10 @@
|
|||
android:background="@drawable/rounded_top_corners"
|
||||
android:gravity="end"
|
||||
android:maxLines="1"
|
||||
app:autoSizeMaxTextSize="48sp"
|
||||
app:autoSizeMinTextSize="10sp"
|
||||
app:autoSizeStepGranularity="2sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
android:textSize="48sp"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
@ -46,7 +50,11 @@
|
|||
android:layout_marginEnd="32dp"
|
||||
android:background="?attr/colorSurfaceVariant"
|
||||
android:gravity="end"
|
||||
android:maxLines="1"
|
||||
android:maxLines="2"
|
||||
app:autoSizeMaxTextSize="48sp"
|
||||
app:autoSizeMinTextSize="10sp"
|
||||
app:autoSizeStepGranularity="2sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
android:textSize="28sp"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
@ -60,7 +68,11 @@
|
|||
android:layout_marginEnd="32dp"
|
||||
android:background="@drawable/rounded_bottom_corners"
|
||||
android:gravity="end"
|
||||
android:maxLines="1"
|
||||
android:maxLines="2"
|
||||
app:autoSizeMaxTextSize="48sp"
|
||||
app:autoSizeMinTextSize="10sp"
|
||||
app:autoSizeStepGranularity="2sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
android:textSize="28sp"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout 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:layout_width="match_parent"
|
||||
|
@ -54,11 +54,14 @@
|
|||
<EditText
|
||||
android:id="@+id/editText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_margin="16dp"
|
||||
android:fontFamily="@font/poppins"
|
||||
android:inputType="textMultiLine"
|
||||
android:padding="16dp"
|
||||
android:nestedScrollingEnabled="true"
|
||||
android:gravity="top|start"
|
||||
android:textColor="?attr/colorOnBackground"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="12sp"
|
||||
|
@ -101,4 +104,4 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</LinearLayout>
|
|
@ -10,16 +10,34 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/enter_password"
|
||||
android:maxLength="32"
|
||||
android:inputType="numberPassword" />
|
||||
android:inputType="numberPassword"
|
||||
android:maxLength="32" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/confirmPasswordInput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:hint="@string/confirm_password"
|
||||
android:inputType="numberPassword"
|
||||
android:maxLength="32"
|
||||
android:layout_marginTop="16dp" />
|
||||
android:maxLength="32" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/biometricCheckbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:fontFamily="@font/poppins"
|
||||
android:text="@string/enable_biometric"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/forgotPasswordCheckbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:fontFamily="@font/poppins"
|
||||
android:text="@string/enable_forgot_password"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
android:src="@drawable/linear_gradient_bg"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<LinearLayout
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/textActivityContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -47,7 +47,7 @@
|
|||
android:textSize="18sp"
|
||||
android:visibility="gone"
|
||||
tools:ignore="HardcodedText" />
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/leftTouchPanel"
|
||||
|
|
|
@ -1024,4 +1024,9 @@ Non quae tempore quo provident laudantium qui illo dolor vel quia dolor et exerc
|
|||
<string name="app_lock_desc">Lock the app with a password\n( ͡° ͜ʖ ͡°)</string>
|
||||
<string name="confirm_password">Confirm Password</string>
|
||||
<string name="password_mismatch">Passwords do not match or are empty!</string>
|
||||
<string name="enable_biometric">Enable Biometric</string>
|
||||
<string name="bio_prompt_info_title">Biometric Authentication</string>
|
||||
<string name="bio_prompt_info_desc">Use your fingerprint or face to unlock the app</string>
|
||||
<string name="enable_forgot_password">Enable Forgot Password (hold clear button for 10 seconds)</string>
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue