Improve Pi-hole interactions

This commit is contained in:
William Brawner 2020-02-05 07:55:29 -06:00
parent 9479c5b40e
commit fdbd55cdf8
8 changed files with 56 additions and 34 deletions

View file

@ -15,6 +15,7 @@ android {
}
buildTypes {
release {
debuggable true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
@ -33,17 +34,17 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.2.0-alpha02'
implementation 'com.google.android.material:material:1.2.0-alpha04'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.security:security-crypto:1.0.0-alpha02'
implementation 'androidx.preference:preference:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
def navigation_version = '2.1.0'
def navigation_version = '2.2.0'
implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"
def lifecycle_version = '2.1.0'
def lifecycle_version = '2.2.0'
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
def acraVersion = '5.1.3'

View file

@ -44,28 +44,35 @@ class MainFragment : Fragment(), CoroutineScope {
}
viewModel.monitorSummary()
}
viewModel.summary.observe(this, Observer { summary ->
viewModel.status.observe(this, Observer {
showProgress(false)
val (statusColor, statusText) = if (
summary.status == Status.DISABLED
) {
enableButton?.visibility = View.VISIBLE
disableButtons?.visibility = View.GONE
Pair(R.color.colorDisabled, R.string.status_disabled)
} else {
enableButton?.visibility = View.GONE
disableButtons?.visibility = View.VISIBLE
Pair(R.color.colorEnabled, R.string.status_enabled)
val (statusColor, statusText) = when (it) {
Status.DISABLED -> {
enableButton?.visibility = View.VISIBLE
disableButtons?.visibility = View.GONE
Pair(R.color.colorDisabled, R.string.status_disabled)
}
Status.ENABLED -> {
enableButton?.visibility = View.GONE
disableButtons?.visibility = View.VISIBLE
Pair(R.color.colorEnabled, R.string.status_enabled)
}
else -> {
enableButton?.visibility = View.GONE
disableButtons?.visibility = View.GONE
Pair(R.color.colorUnknown, R.string.status_unknown)
}
}
status?.let {
status?.let { textView ->
val status = getString(statusText)
val statusLabel = getString(R.string.label_status, status)
val start = statusLabel.indexOf(status)
val end = start + status.length
val statusSpan = SpannableString(statusLabel)
statusSpan[start, end] = StyleSpan(Typeface.BOLD)
statusSpan[start, end] = ForegroundColorSpan(getColor(it.context, statusColor))
it.text = statusSpan
statusSpan[start, end] =
ForegroundColorSpan(getColor(textView.context, statusColor))
textView.text = statusSpan
}
})
}
@ -124,7 +131,7 @@ class MainFragment : Fragment(), CoroutineScope {
}
disableCustomTimeButton?.setOnClickListener {
val dialogView = LayoutInflater.from(it.context)
.inflate(R.layout.dialog_disable_custom_time, null, false)
.inflate(R.layout.dialog_disable_custom_time, view as ViewGroup, false)
AlertDialog.Builder(it.context)
.setTitle(R.string.action_disable_custom)
.setNegativeButton(android.R.string.cancel) { _, _ -> }

View file

@ -3,23 +3,27 @@ package com.wbrawner.pihelper
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.wbrawner.piholeclient.PiHoleApiService
import com.wbrawner.piholeclient.Summary
import kotlinx.coroutines.NonCancellable.isActive
import com.wbrawner.piholeclient.Status
import com.wbrawner.piholeclient.StatusProvider
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.yield
import java.lang.Exception
import kotlin.coroutines.coroutineContext
class PiHelperViewModel(
private val apiService: PiHoleApiService
) : ViewModel() {
val summary = MutableLiveData<Summary>()
val status = MutableLiveData<Status>()
private var action: (suspend () -> StatusProvider)? = null
get() = field ?: defaultAction
private var defaultAction = suspend {
apiService.getSummary()
}
suspend fun monitorSummary() {
while (coroutineContext.isActive) {
try {
loadSummary()
status.postValue(action!!.invoke().status)
action = null
} catch (ignored: Exception) {
break
}
@ -27,15 +31,15 @@ class PiHelperViewModel(
}
}
suspend fun loadSummary() {
summary.postValue(apiService.getSummary())
}
suspend fun enablePiHole() {
apiService.enable()
action = {
apiService.enable()
}
}
suspend fun disablePiHole(duration: Long? = null) {
apiService.disable(duration)
action = {
apiService.disable(duration)
}
}
}

View file

@ -27,6 +27,7 @@ class RetrieveApiKeyFragment : Fragment(), CoroutineScope {
sharedElementEnterTransition = TransitionInflater.from(context)
.inflateTransition(android.R.transition.move)
viewModel.authenticated.observe(this, Observer {
if (!it) return@Observer
findNavController().navigate(R.id.action_retrieveApiKeyFragment_to_mainFragment)
})
}

View file

@ -4,4 +4,5 @@
<color name="colorOnSurface">#f1f1f1</color>
<color name="colorEnabled">@color/colorGreenLight</color>
<color name="colorDisabled">@color/colorRedLight</color>
<color name="colorButtonSecondary">#999999</color>
</resources>

View file

@ -10,6 +10,7 @@
<color name="colorOnSurface">#000000</color>
<color name="colorWhite">#ffffff</color>
<color name="colorEnabled">@color/colorGreenDark</color>
<color name="colorUnknown">@color/colorButtonSecondary</color>
<color name="colorDisabled">@color/colorRedDark</color>
<color name="colorSurface">@color/colorWhite</color>
<color name="colorTransparent">#00000000</color>

View file

@ -30,4 +30,5 @@
<string name="title_crash_notification">Pi-Helper Crashed!</string>
<string name="text_crash_notification">Would you please consider sending the crash report to me?</string>
<string name="channel_crash_notification">Crash Reports</string>
<string name="status_unknown">Unknown</string>
</resources>

View file

@ -1,5 +1,6 @@
package com.wbrawner.piholeclient
import androidx.annotation.Keep
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@ -35,13 +36,14 @@ data class Summary(
val ipReplies: String?,
@Json(name = "privacy_level")
val privacyLevel: String,
val status: Status,
override val status: Status,
@Json(name = "gravity_last_updated")
val gravity: Gravity?,
val type: String?,
val version: Int?
)
) : StatusProvider
@Keep
enum class Status {
@Json(name = "enabled")
ENABLED,
@ -69,11 +71,15 @@ data class VersionResponse(val version: Int)
@JsonClass(generateAdapter = true)
data class TopItemsResponse(
@Json(name = "top_queries") val topQueries: List<String>,
@Json(name = "top_queries") val topQueries: Map<String, String>,
@Json(name = "top_ads") val topAds: List<String>
)
@JsonClass(generateAdapter = true)
data class StatusResponse(
override val status: Status
) : StatusProvider
interface StatusProvider {
val status: Status
)
}