mirror of
https://github.com/afollestad/nock-nock.git
synced 2025-08-09 17:38:47 +00:00
Re-organize some UI, hook up SSL certificate selection, etc. Resolves #42.
This commit is contained in:
parent
909e5420ad
commit
26d6d9abf8
14 changed files with 238 additions and 62 deletions
|
@ -16,13 +16,20 @@
|
|||
package com.afollestad.nocknock.ui.addsite
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.content.Intent.ACTION_OPEN_DOCUMENT
|
||||
import android.content.Intent.CATEGORY_OPENABLE
|
||||
import android.os.Bundle
|
||||
import android.widget.ArrayAdapter
|
||||
import androidx.lifecycle.Observer
|
||||
import com.afollestad.nocknock.R
|
||||
import com.afollestad.nocknock.data.model.Site
|
||||
import com.afollestad.nocknock.data.model.ValidationMode
|
||||
import com.afollestad.nocknock.ui.DarkModeSwitchActivity
|
||||
import com.afollestad.nocknock.ui.viewsite.KEY_SITE
|
||||
import com.afollestad.nocknock.utilities.ext.onTextChanged
|
||||
import com.afollestad.nocknock.utilities.ext.toUri
|
||||
import com.afollestad.nocknock.utilities.livedata.distinct
|
||||
import com.afollestad.nocknock.viewcomponents.ext.dimenFloat
|
||||
import com.afollestad.nocknock.viewcomponents.ext.onScroll
|
||||
import com.afollestad.nocknock.viewcomponents.livedata.attachLiveData
|
||||
|
@ -41,6 +48,8 @@ import kotlinx.android.synthetic.main.activity_addsite.responseValidationSearchT
|
|||
import kotlinx.android.synthetic.main.activity_addsite.retryPolicyLayout
|
||||
import kotlinx.android.synthetic.main.activity_addsite.scriptInputLayout
|
||||
import kotlinx.android.synthetic.main.activity_addsite.scrollView
|
||||
import kotlinx.android.synthetic.main.activity_addsite.sslCertificateBrowse
|
||||
import kotlinx.android.synthetic.main.activity_addsite.sslCertificateInput
|
||||
import kotlinx.android.synthetic.main.activity_addsite.textUrlWarning
|
||||
import kotlinx.android.synthetic.main.activity_addsite.validationModeDescription
|
||||
import kotlinx.android.synthetic.main.include_app_bar.toolbar
|
||||
|
@ -50,6 +59,9 @@ import kotlinx.android.synthetic.main.include_app_bar.toolbar_title as toolbarTi
|
|||
|
||||
/** @author Aidan Follestad (@afollestad) */
|
||||
class AddSiteActivity : DarkModeSwitchActivity() {
|
||||
companion object {
|
||||
private const val SELECT_CERT_FILE_RQ = 23
|
||||
}
|
||||
|
||||
private val viewModel by viewModel<AddSiteViewModel>()
|
||||
|
||||
|
@ -165,5 +177,38 @@ class AddSiteActivity : DarkModeSwitchActivity() {
|
|||
0f
|
||||
}
|
||||
}
|
||||
|
||||
// SSL certificate
|
||||
sslCertificateInput.onTextChanged { viewModel.certificateUri.value = it.toUri() }
|
||||
viewModel.certificateUri.distinct()
|
||||
.observe(this, Observer { sslCertificateInput.setText(it.toString()) })
|
||||
sslCertificateBrowse.setOnClickListener {
|
||||
val intent = Intent(ACTION_OPEN_DOCUMENT).apply {
|
||||
addCategory(CATEGORY_OPENABLE)
|
||||
type = "*/*"
|
||||
}
|
||||
startActivityForResult(intent, SELECT_CERT_FILE_RQ)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
appToolbar.elevation =
|
||||
if (scrollView.scrollY > appToolbar.measuredHeight / 2) {
|
||||
appToolbar.dimenFloat(R.dimen.default_elevation)
|
||||
} else {
|
||||
0f
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(
|
||||
requestCode: Int,
|
||||
resultCode: Int,
|
||||
resultData: Intent?
|
||||
) {
|
||||
super.onActivityResult(requestCode, resultCode, resultData)
|
||||
if (requestCode == SELECT_CERT_FILE_RQ && resultCode == RESULT_OK) {
|
||||
sslCertificateInput.setText(resultData?.data?.toString() ?: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package com.afollestad.nocknock.ui.addsite
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.annotation.CheckResult
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.annotation.VisibleForTesting.PRIVATE
|
||||
|
@ -68,6 +69,7 @@ class AddSiteViewModel(
|
|||
val retryPolicyTimes = MutableLiveData<Int>()
|
||||
val retryPolicyMinutes = MutableLiveData<Int>()
|
||||
val headers = MutableLiveData<List<Header>>()
|
||||
val certificateUri = MutableLiveData<Uri>()
|
||||
|
||||
@OnLifecycleEvent(ON_START)
|
||||
fun setDefaults() {
|
||||
|
@ -237,7 +239,8 @@ class AddSiteViewModel(
|
|||
validationMode = validationMode.value!!,
|
||||
validationArgs = getValidationArgs(),
|
||||
networkTimeout = timeout,
|
||||
disabled = false
|
||||
disabled = false,
|
||||
certificate = certificateUri.value.toString()
|
||||
)
|
||||
|
||||
val newLastResult = ValidationResult(
|
||||
|
|
|
@ -17,6 +17,8 @@ package com.afollestad.nocknock.ui.viewsite
|
|||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.content.Intent.ACTION_OPEN_DOCUMENT
|
||||
import android.content.Intent.CATEGORY_OPENABLE
|
||||
import android.os.Bundle
|
||||
import android.widget.ArrayAdapter
|
||||
import androidx.lifecycle.Observer
|
||||
|
@ -25,6 +27,9 @@ import com.afollestad.nocknock.broadcasts.StatusUpdateIntentReceiver
|
|||
import com.afollestad.nocknock.data.model.Site
|
||||
import com.afollestad.nocknock.data.model.ValidationMode
|
||||
import com.afollestad.nocknock.ui.DarkModeSwitchActivity
|
||||
import com.afollestad.nocknock.utilities.ext.onTextChanged
|
||||
import com.afollestad.nocknock.utilities.ext.toUri
|
||||
import com.afollestad.nocknock.utilities.livedata.distinct
|
||||
import com.afollestad.nocknock.utilities.providers.IntentProvider
|
||||
import com.afollestad.nocknock.viewcomponents.ext.dimenFloat
|
||||
import com.afollestad.nocknock.viewcomponents.ext.onScroll
|
||||
|
@ -45,18 +50,23 @@ import kotlinx.android.synthetic.main.activity_viewsite.responseValidationSearch
|
|||
import kotlinx.android.synthetic.main.activity_viewsite.retryPolicyLayout
|
||||
import kotlinx.android.synthetic.main.activity_viewsite.scriptInputLayout
|
||||
import kotlinx.android.synthetic.main.activity_viewsite.scrollView
|
||||
import kotlinx.android.synthetic.main.activity_viewsite.sslCertificateBrowse
|
||||
import kotlinx.android.synthetic.main.activity_viewsite.sslCertificateInput
|
||||
import kotlinx.android.synthetic.main.activity_viewsite.textLastCheckResult
|
||||
import kotlinx.android.synthetic.main.activity_viewsite.textNextCheck
|
||||
import kotlinx.android.synthetic.main.activity_viewsite.textUrlWarning
|
||||
import kotlinx.android.synthetic.main.activity_viewsite.validationModeDescription
|
||||
import kotlinx.android.synthetic.main.include_app_bar.app_toolbar as appToolbar
|
||||
import kotlinx.android.synthetic.main.include_app_bar.toolbar
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import kotlinx.android.synthetic.main.include_app_bar.app_toolbar as appToolbar
|
||||
import kotlinx.android.synthetic.main.include_app_bar.toolbar_title as toolbarTitle
|
||||
|
||||
/** @author Aidan Follestad (@afollestad) */
|
||||
class ViewSiteActivity : DarkModeSwitchActivity() {
|
||||
companion object {
|
||||
private const val SELECT_CERT_FILE_RQ = 23
|
||||
}
|
||||
|
||||
internal val viewModel by viewModel<ViewSiteViewModel>()
|
||||
|
||||
|
@ -210,6 +220,39 @@ class ViewSiteActivity : DarkModeSwitchActivity() {
|
|||
toolbar.menu.findItem(R.id.commit)
|
||||
.setTitle(it)
|
||||
})
|
||||
|
||||
// SSL certificate
|
||||
sslCertificateInput.onTextChanged { viewModel.certificateUri.value = it.toUri() }
|
||||
viewModel.certificateUri.distinct()
|
||||
.observe(this, Observer { sslCertificateInput.setText(it.toString()) })
|
||||
sslCertificateBrowse.setOnClickListener {
|
||||
val intent = Intent(ACTION_OPEN_DOCUMENT).apply {
|
||||
addCategory(CATEGORY_OPENABLE)
|
||||
type = "*/*"
|
||||
}
|
||||
startActivityForResult(intent, SELECT_CERT_FILE_RQ)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
appToolbar.elevation =
|
||||
if (scrollView.scrollY > appToolbar.measuredHeight / 2) {
|
||||
appToolbar.dimenFloat(R.dimen.default_elevation)
|
||||
} else {
|
||||
0f
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(
|
||||
requestCode: Int,
|
||||
resultCode: Int,
|
||||
resultData: Intent?
|
||||
) {
|
||||
super.onActivityResult(requestCode, resultCode, resultData)
|
||||
if (requestCode == SELECT_CERT_FILE_RQ && resultCode == RESULT_OK) {
|
||||
sslCertificateInput.setText(resultData?.data?.toString() ?: "")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package com.afollestad.nocknock.ui.viewsite
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.annotation.CheckResult
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.annotation.VisibleForTesting.PRIVATE
|
||||
|
@ -76,6 +77,7 @@ class ViewSiteViewModel(
|
|||
val retryPolicyTimes = MutableLiveData<Int>()
|
||||
val retryPolicyMinutes = MutableLiveData<Int>()
|
||||
val headers = MutableLiveData<List<Header>>()
|
||||
val certificateUri = MutableLiveData<Uri>()
|
||||
internal val disabled = MutableLiveData<Boolean>()
|
||||
internal val lastResult = MutableLiveData<ValidationResult?>()
|
||||
|
||||
|
@ -316,7 +318,8 @@ class ViewSiteViewModel(
|
|||
validationMode = validationMode.value!!,
|
||||
validationArgs = getValidationArgs(),
|
||||
networkTimeout = timeout,
|
||||
disabled = false
|
||||
disabled = false,
|
||||
certificate = certificateUri.value.toString()
|
||||
)
|
||||
|
||||
val retryPolicyTimes = retryPolicyTimes.value ?: 0
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.afollestad.nocknock.utilities.ext.DAY
|
|||
import com.afollestad.nocknock.utilities.ext.HOUR
|
||||
import com.afollestad.nocknock.utilities.ext.MINUTE
|
||||
import com.afollestad.nocknock.utilities.ext.WEEK
|
||||
import com.afollestad.nocknock.utilities.ext.toUri
|
||||
import kotlin.math.ceil
|
||||
|
||||
fun ViewSiteViewModel.setModel(site: Site) {
|
||||
|
@ -55,6 +56,9 @@ fun ViewSiteViewModel.setModel(site: Site) {
|
|||
setCheckInterval(settings.validationIntervalMs)
|
||||
setRetryPolicy(site.retryPolicy)
|
||||
headers.value = site.headers
|
||||
if (settings.certificate != null) {
|
||||
certificateUri.value = settings.certificate!!.toUri()
|
||||
}
|
||||
|
||||
this.disabled.value = settings.disabled
|
||||
this.lastResult.value = site.lastResult
|
||||
|
|
|
@ -91,20 +91,6 @@
|
|||
android:layout_marginTop="@dimen/content_inset"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:text="@string/response_timeout"
|
||||
style="@style/InputForm.Header"
|
||||
/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/responseTimeoutInput"
|
||||
android:hint="@string/response_timeout_default"
|
||||
android:inputType="number"
|
||||
android:maxLength="8"
|
||||
tools:ignore="Autofill"
|
||||
style="@style/InputForm.Field"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/responseValidationLabel"
|
||||
android:text="@string/response_validation_mode"
|
||||
|
@ -159,6 +145,59 @@
|
|||
android:layout_marginTop="@dimen/content_inset_more"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_marginTop="@dimen/content_inset"
|
||||
android:text="@string/response_timeout"
|
||||
style="@style/InputForm.Header"
|
||||
/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/responseTimeoutInput"
|
||||
android:hint="@string/response_timeout_default"
|
||||
android:inputType="number"
|
||||
android:maxLength="8"
|
||||
tools:ignore="Autofill"
|
||||
style="@style/InputForm.Field"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/content_inset"
|
||||
android:text="@string/ssl_certificate"
|
||||
style="@style/NockText.SectionHeader"
|
||||
/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/sslCertificateInput"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:layout_marginStart="-4dp"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/ssl_certificate_automatic"
|
||||
android:inputType="textUri"
|
||||
tools:ignore="Autofill,HardcodedText,LabelFor"
|
||||
style="@style/NockText.Body"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/sslCertificateBrowse"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:text="@string/ssl_certificate_browse"
|
||||
style="@style/AccentTextButton"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/include_divider"/>
|
||||
|
||||
<com.afollestad.nocknock.viewcomponents.headers.HeaderStackLayout
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/content_inset"
|
||||
android:paddingBottom="@dimen/content_inset_double"
|
||||
android:paddingLeft="@dimen/content_inset"
|
||||
android:paddingRight="@dimen/content_inset"
|
||||
android:paddingTop="@dimen/content_inset_less"
|
||||
|
@ -126,35 +126,6 @@
|
|||
android:layout_marginTop="@dimen/content_inset"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/content_inset_less"
|
||||
android:text="@string/response_timeout"
|
||||
style="@style/NockText.SectionHeader"
|
||||
/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/responseTimeoutInput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="-4dp"
|
||||
android:layout_marginStart="-4dp"
|
||||
android:layout_marginTop="@dimen/content_inset_quarter"
|
||||
android:hint="@string/response_timeout_default"
|
||||
android:inputType="number"
|
||||
android:maxLength="8"
|
||||
tools:ignore="Autofill,HardcodedText,LabelFor"
|
||||
style="@style/NockText.Body"
|
||||
/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="@dimen/content_inset_less"
|
||||
android:background="?dividerColor"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/responseValidationLabel"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -217,6 +188,66 @@
|
|||
android:layout_marginTop="@dimen/content_inset"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/content_inset"
|
||||
android:text="@string/response_timeout"
|
||||
style="@style/NockText.SectionHeader"
|
||||
/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/responseTimeoutInput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="-4dp"
|
||||
android:layout_marginStart="-4dp"
|
||||
android:layout_marginTop="@dimen/content_inset_quarter"
|
||||
android:hint="@string/response_timeout_default"
|
||||
android:inputType="number"
|
||||
android:maxLength="8"
|
||||
tools:ignore="Autofill,HardcodedText,LabelFor"
|
||||
style="@style/NockText.Body"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/content_inset"
|
||||
android:text="@string/ssl_certificate"
|
||||
style="@style/NockText.SectionHeader"
|
||||
/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/sslCertificateInput"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:layout_marginStart="-4dp"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/ssl_certificate_automatic"
|
||||
android:inputType="textUri"
|
||||
tools:ignore="Autofill,HardcodedText,LabelFor"
|
||||
style="@style/NockText.Body"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/sslCertificateBrowse"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:text="@string/ssl_certificate_browse"
|
||||
style="@style/AccentTextButton"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/include_divider"/>
|
||||
|
||||
<com.afollestad.nocknock.viewcomponents.headers.HeaderStackLayout
|
||||
|
|
|
@ -59,6 +59,10 @@
|
|||
<string name="response_timeout">Network Response Timeout (ms)</string>
|
||||
<string name="response_timeout_default">10000</string>
|
||||
|
||||
<string name="ssl_certificate">SSL Certificate</string>
|
||||
<string name="ssl_certificate_automatic">(Automatic)</string>
|
||||
<string name="ssl_certificate_browse">Browse</string>
|
||||
|
||||
<string name="refresh_status">Refresh Status</string>
|
||||
|
||||
<string name="warning_http_url">
|
||||
|
|
|
@ -4,20 +4,10 @@
|
|||
|
||||
<style name="AppTheme.Dark" parent="AppThemeParent.Dark"/>
|
||||
|
||||
<style name="AccentButton" parent="Widget.MaterialComponents.Button">
|
||||
<item name="android:textColor">#fff</item>
|
||||
<item name="backgroundTint">@color/colorAccent</item>
|
||||
<item name="android:fontFamily">@font/lato</item>
|
||||
</style>
|
||||
|
||||
<style name="PrimaryDarkButton" parent="Widget.MaterialComponents.Button">
|
||||
<item name="android:textColor">#fff</item>
|
||||
<item name="backgroundTint">@color/lighterGray</item>
|
||||
<item name="android:fontFamily">@font/lato</item>
|
||||
</style>
|
||||
|
||||
<style name="AccentTextButton" parent="Widget.MaterialComponents.Button.TextButton">
|
||||
<item name="android:fontFamily">@font/lato</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -66,6 +66,6 @@ class Database3to4Migration : Migration(3, 4) {
|
|||
class Database4to5Migration : Migration(4, 5) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE `site_settings` ADD COLUMN certificatePath TEXT")
|
||||
database.execSQL("ALTER TABLE `site_settings` ADD COLUMN certificate TEXT")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,10 @@ class RealSslManager(
|
|||
log("Loaded successfully!")
|
||||
return client.newBuilder()
|
||||
.sslSocketFactory(sslContext.socketFactory, trustManager)
|
||||
.hostnameVerifier { hostname, _ ->
|
||||
log("Verifying hostname $hostname")
|
||||
hostname == host
|
||||
}
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
android:id="@+id/label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/check_interval"
|
||||
android:text="@string/validation_interval"
|
||||
style="@style/NockText.SectionHeader"
|
||||
/>
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
|||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/check_interval_every"
|
||||
android:text="@string/validation_interval_every"
|
||||
style="@style/NockText.Body"
|
||||
/>
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<string name="function_declaration">function validate(response) {</string>
|
||||
<string name="function_end">}</string>
|
||||
|
||||
<string name="check_interval">Check Interval</string>
|
||||
<string name="check_interval_every">Every</string>
|
||||
<string name="validation_interval">Validation Interval</string>
|
||||
<string name="validation_interval_every">Every</string>
|
||||
|
||||
<string name="retry_policy">Retry Policy</string>
|
||||
<string name="retry_policy_retry">Retry</string>
|
||||
|
|
|
@ -52,4 +52,14 @@
|
|||
<item name="android:textColor">@color/md_red</item>
|
||||
</style>
|
||||
|
||||
<style name="AccentButton" parent="Widget.MaterialComponents.Button">
|
||||
<item name="android:textColor">#fff</item>
|
||||
<item name="backgroundTint">?colorAccent</item>
|
||||
<item name="android:fontFamily">@font/lato</item>
|
||||
</style>
|
||||
|
||||
<style name="AccentTextButton" parent="Widget.MaterialComponents.Button.TextButton">
|
||||
<item name="android:fontFamily">@font/lato</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue