Various fixes and behavioral tweaks

This commit is contained in:
Aidan Follestad 2018-11-30 10:45:22 -08:00
commit c7a8148d3c
6 changed files with 611 additions and 538 deletions

View file

@ -38,6 +38,7 @@ import com.afollestad.nocknock.utilities.ext.textAsLong
import com.afollestad.nocknock.utilities.ext.trimmedText import com.afollestad.nocknock.utilities.ext.trimmedText
import kotlinx.android.synthetic.main.activity_addsite.checkIntervalInput import kotlinx.android.synthetic.main.activity_addsite.checkIntervalInput
import kotlinx.android.synthetic.main.activity_addsite.checkIntervalSpinner import kotlinx.android.synthetic.main.activity_addsite.checkIntervalSpinner
import kotlinx.android.synthetic.main.activity_addsite.content_loading_progress
import kotlinx.android.synthetic.main.activity_addsite.doneBtn import kotlinx.android.synthetic.main.activity_addsite.doneBtn
import kotlinx.android.synthetic.main.activity_addsite.inputName import kotlinx.android.synthetic.main.activity_addsite.inputName
import kotlinx.android.synthetic.main.activity_addsite.inputUrl import kotlinx.android.synthetic.main.activity_addsite.inputUrl
@ -199,7 +200,6 @@ class AddSiteActivity : AppCompatActivity(), View.OnClickListener {
// Done button // Done button
override fun onClick(view: View) { override fun onClick(view: View) {
isClosing = true isClosing = true
var model = ServerModel( var model = ServerModel(
name = inputName.trimmedText(), name = inputName.trimmedText(),
url = inputUrl.trimmedText(), url = inputUrl.trimmedText(),
@ -259,13 +259,20 @@ class AddSiteActivity : AppCompatActivity(), View.OnClickListener {
validationContent = responseValidationScriptInput.trimmedText() validationContent = responseValidationScriptInput.trimmedText()
) )
} }
else -> {
throw IllegalStateException(
"Unexpected validation mode index: ${responseValidationMode.selectedItemPosition}"
)
}
} }
rootView.scopeWhileAttached(Main) { rootView.scopeWhileAttached(Main) {
launch(coroutineContext) { launch(coroutineContext) {
content_loading_progress.show()
val storedModel = async(IO) { serverModelStore.put(model) }.await() val storedModel = async(IO) { serverModelStore.put(model) }.await()
checkStatusManager.cancelCheck(storedModel) checkStatusManager.cancelCheck(storedModel)
checkStatusManager.scheduleCheck(storedModel, rightNow = true) checkStatusManager.scheduleCheck(storedModel, rightNow = true)
content_loading_progress.hide()
setResult(RESULT_OK) setResult(RESULT_OK)
finish() finish()

View file

@ -85,6 +85,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
when (intent.action) { when (intent.action) {
ACTION_STATUS_UPDATE -> { ACTION_STATUS_UPDATE -> {
val model = intent.getSerializableExtra(KEY_UPDATE_MODEL) as? ServerModel ?: return val model = intent.getSerializableExtra(KEY_UPDATE_MODEL) as? ServerModel ?: return
log("Received model update: $model")
list.post { adapter.update(model) } list.post { adapter.update(model) }
} }
else -> throw IllegalStateException("Unexpected intent: ${intent.action}") else -> throw IllegalStateException("Unexpected intent: ${intent.action}")

View file

@ -24,6 +24,7 @@ import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.nocknock.BuildConfig import com.afollestad.nocknock.BuildConfig
import com.afollestad.nocknock.R import com.afollestad.nocknock.R
import com.afollestad.nocknock.data.ServerModel import com.afollestad.nocknock.data.ServerModel
import com.afollestad.nocknock.data.ServerStatus.CHECKING
import com.afollestad.nocknock.data.ServerStatus.WAITING import com.afollestad.nocknock.data.ServerStatus.WAITING
import com.afollestad.nocknock.data.ValidationMode.JAVASCRIPT import com.afollestad.nocknock.data.ValidationMode.JAVASCRIPT
import com.afollestad.nocknock.data.ValidationMode.STATUS_CODE import com.afollestad.nocknock.data.ValidationMode.STATUS_CODE
@ -42,6 +43,8 @@ import com.afollestad.nocknock.utilities.ext.hide
import com.afollestad.nocknock.utilities.ext.injector import com.afollestad.nocknock.utilities.ext.injector
import com.afollestad.nocknock.utilities.ext.isHttpOrHttps import com.afollestad.nocknock.utilities.ext.isHttpOrHttps
import com.afollestad.nocknock.utilities.ext.onItemSelected import com.afollestad.nocknock.utilities.ext.onItemSelected
import com.afollestad.nocknock.utilities.ext.safeRegisterReceiver
import com.afollestad.nocknock.utilities.ext.safeUnregisterReceiver
import com.afollestad.nocknock.utilities.ext.scopeWhileAttached import com.afollestad.nocknock.utilities.ext.scopeWhileAttached
import com.afollestad.nocknock.utilities.ext.show import com.afollestad.nocknock.utilities.ext.show
import com.afollestad.nocknock.utilities.ext.showOrHide import com.afollestad.nocknock.utilities.ext.showOrHide
@ -49,6 +52,7 @@ import com.afollestad.nocknock.utilities.ext.textAsLong
import com.afollestad.nocknock.utilities.ext.trimmedText import com.afollestad.nocknock.utilities.ext.trimmedText
import kotlinx.android.synthetic.main.activity_viewsite.checkIntervalInput import kotlinx.android.synthetic.main.activity_viewsite.checkIntervalInput
import kotlinx.android.synthetic.main.activity_viewsite.checkIntervalSpinner import kotlinx.android.synthetic.main.activity_viewsite.checkIntervalSpinner
import kotlinx.android.synthetic.main.activity_viewsite.content_loading_progress
import kotlinx.android.synthetic.main.activity_viewsite.doneBtn import kotlinx.android.synthetic.main.activity_viewsite.doneBtn
import kotlinx.android.synthetic.main.activity_viewsite.iconStatus import kotlinx.android.synthetic.main.activity_viewsite.iconStatus
import kotlinx.android.synthetic.main.activity_viewsite.inputName import kotlinx.android.synthetic.main.activity_viewsite.inputName
@ -106,7 +110,8 @@ class ViewSiteActivity : AppCompatActivity(),
val model = intent.getSerializableExtra(KEY_VIEW_MODEL) as? ServerModel val model = intent.getSerializableExtra(KEY_VIEW_MODEL) as? ServerModel
if (model != null) { if (model != null) {
this@ViewSiteActivity.currentModel = model this@ViewSiteActivity.currentModel = model
update() log("Received model update: $currentModel")
displayCurrentModel()
} }
} }
} }
@ -177,19 +182,19 @@ class ViewSiteActivity : AppCompatActivity(),
} }
currentModel = intent.getSerializableExtra(KEY_VIEW_MODEL) as ServerModel currentModel = intent.getSerializableExtra(KEY_VIEW_MODEL) as ServerModel
update() displayCurrentModel()
} }
override fun onNewIntent(intent: Intent?) { override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent) super.onNewIntent(intent)
if (intent != null && intent.hasExtra(KEY_VIEW_MODEL)) { if (intent != null && intent.hasExtra(KEY_VIEW_MODEL)) {
currentModel = intent.getSerializableExtra(KEY_VIEW_MODEL) as ServerModel currentModel = intent.getSerializableExtra(KEY_VIEW_MODEL) as ServerModel
update() displayCurrentModel()
} }
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private fun update() = with(currentModel) { private fun displayCurrentModel() = with(currentModel) {
iconStatus.setStatus(this.status) iconStatus.setStatus(this.status)
inputName.setText(this.name) inputName.setText(this.name)
inputUrl.setText(this.url) inputUrl.setText(this.url)
@ -260,27 +265,20 @@ class ViewSiteActivity : AppCompatActivity(),
} }
doneBtn.setOnClickListener(this@ViewSiteActivity) doneBtn.setOnClickListener(this@ViewSiteActivity)
invalidateMenuForStatus()
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
try { val filter = IntentFilter().apply {
val filter = IntentFilter() addAction(ACTION_STATUS_UPDATE)
filter.addAction(ACTION_STATUS_UPDATE)
// filter.addAction(CheckService.ACTION_JOB_RUNNING);
registerReceiver(intentReceiver, filter)
} catch (t: Throwable) {
t.printStackTrace()
} }
safeRegisterReceiver(intentReceiver, filter)
} }
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
try { safeUnregisterReceiver(intentReceiver)
unregisterReceiver(intentReceiver)
} catch (t: Throwable) {
t.printStackTrace()
}
} }
private fun updateModelFromInput(withValidation: Boolean) { private fun updateModelFromInput(withValidation: Boolean) {
@ -345,6 +343,11 @@ class ViewSiteActivity : AppCompatActivity(),
validationContent = responseValidationScriptInput.trimmedText() validationContent = responseValidationScriptInput.trimmedText()
) )
} }
else -> {
throw IllegalStateException(
"Unexpected response validation mode index: ${responseValidationMode.selectedItemPosition}"
)
}
} }
} }
@ -352,8 +355,14 @@ class ViewSiteActivity : AppCompatActivity(),
override fun onClick(view: View) { override fun onClick(view: View) {
rootView.scopeWhileAttached(Main) { rootView.scopeWhileAttached(Main) {
launch(coroutineContext) { launch(coroutineContext) {
content_loading_progress.show()
updateModelFromInput(true) updateModelFromInput(true)
async(IO) { serverModelStore.update(currentModel) }.await() async(IO) { serverModelStore.update(currentModel) }.await()
checkStatusManager.cancelCheck(currentModel)
checkStatusManager.scheduleCheck(currentModel, rightNow = true)
content_loading_progress.hide()
setResult(RESULT_OK) setResult(RESULT_OK)
finish() finish()
} }
@ -365,26 +374,29 @@ class ViewSiteActivity : AppCompatActivity(),
R.id.refresh -> { R.id.refresh -> {
rootView.scopeWhileAttached(Main) { rootView.scopeWhileAttached(Main) {
launch(coroutineContext) { launch(coroutineContext) {
content_loading_progress.show()
updateModelFromInput(false) updateModelFromInput(false)
currentModel = currentModel.copy(status = WAITING)
displayCurrentModel()
async(IO) { serverModelStore.update(currentModel) }.await() async(IO) { serverModelStore.update(currentModel) }.await()
checkStatusManager.cancelCheck(currentModel) checkStatusManager.cancelCheck(currentModel)
checkStatusManager.scheduleCheck(currentModel, rightNow = true) checkStatusManager.scheduleCheck(currentModel, rightNow = true)
content_loading_progress.hide()
} }
} }
return true return true
} }
R.id.remove -> { R.id.remove -> {
maybeRemoveSite(currentModel) { finish() } maybeRemoveSite(currentModel)
return true return true
} }
} }
return false return false
} }
private fun maybeRemoveSite( private fun maybeRemoveSite(model: ServerModel) {
model: ServerModel,
onRemoved: (() -> Unit)?
) {
MaterialDialog(this).show { MaterialDialog(this).show {
title(R.string.remove_site) title(R.string.remove_site)
message( message(
@ -396,21 +408,25 @@ class ViewSiteActivity : AppCompatActivity(),
positiveButton(R.string.remove) { positiveButton(R.string.remove) {
checkStatusManager.cancelCheck(model) checkStatusManager.cancelCheck(model)
notificationManager.cancelStatusNotifications() notificationManager.cancelStatusNotifications()
performRemoveSite(model, onRemoved) performRemoveSite(model)
} }
negativeButton(android.R.string.cancel) negativeButton(android.R.string.cancel)
} }
} }
private fun performRemoveSite( private fun performRemoveSite(model: ServerModel) {
model: ServerModel,
onRemoved: (() -> Unit)?
) {
rootView.scopeWhileAttached(Main) { rootView.scopeWhileAttached(Main) {
launch(coroutineContext) { launch(coroutineContext) {
content_loading_progress.show()
async(IO) { serverModelStore.delete(model) }.await() async(IO) { serverModelStore.delete(model) }.await()
onRemoved?.invoke() content_loading_progress.hide()
finish()
} }
} }
} }
private fun invalidateMenuForStatus() {
val item = toolbar.menu.findItem(R.id.refresh)
item.isEnabled = currentModel.status != CHECKING && currentModel.status != WAITING
}
} }

View file

@ -1,270 +1,294 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rootView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?colorPrimary"
android:orientation="vertical"
> >
<androidx.appcompat.widget.Toolbar <LinearLayout
android:id="@+id/toolbar" android:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:navigationIcon="@drawable/ic_action_close"
app:title="@string/add_site"
app:titleTextColor="?android:textColorPrimary"
/>
<ScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?colorPrimary"
android:orientation="vertical"
> >
<LinearLayout <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" app:navigationIcon="@drawable/ic_action_close"
android:paddingBottom="@dimen/content_inset" app:title="@string/add_site"
android:paddingLeft="@dimen/content_inset" app:titleTextColor="?android:textColorPrimary"
android:paddingRight="@dimen/content_inset" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
> >
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/nameTiLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="-4dp"
android:layout_marginRight="-4dp"
android:layout_marginTop="@dimen/content_inset"
>
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/inputName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:hint="@string/site_name"
android:inputType="textPersonName|textCapWords|textAutoCorrect"
android:textColor="?android:textColorPrimary"
android:textColorHint="?android:textColorSecondary"
android:textSize="@dimen/body_font_size"
/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/urlTiLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="-4dp"
android:layout_marginRight="-4dp"
android:layout_marginTop="@dimen/content_inset_half"
>
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/inputUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:hint="@string/site_url"
android:inputType="textUri"
android:textColor="?android:textColorPrimary"
android:textColorHint="?android:textColorSecondary"
android:textSize="@dimen/body_font_size"
/>
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/textUrlWarning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_text_spacing"
android:fontFamily="sans-serif-light"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/caption_font_size"
android:visibility="gone"
tools:text="Warning: this app checks for server availability with HTTP requests. It's recommended that you use an HTTP URL."
/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="@dimen/content_inset"
android:background="@color/dividerColorDark"
/>
<TextView
android:id="@+id/checkIntervalLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_inset"
android:fontFamily="sans-serif"
android:text="@string/check_interval"
android:textColor="?colorAccent"
android:textSize="@dimen/caption_font_size"
/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="vertical"
android:weightSum="2" android:paddingBottom="@dimen/content_inset"
android:paddingLeft="@dimen/content_inset"
android:paddingRight="@dimen/content_inset"
> >
<EditText <com.google.android.material.textfield.TextInputLayout
android:id="@+id/checkIntervalInput" android:id="@+id/nameTiLayout"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical" android:layout_marginLeft="-4dp"
android:layout_marginEnd="@dimen/content_inset_half" android:layout_marginRight="-4dp"
android:layout_marginStart="-4dp" android:layout_marginTop="@dimen/content_inset"
android:layout_weight="1"
android:fontFamily="sans-serif-light"
android:hint="0"
android:inputType="number"
android:textSize="@dimen/body_font_size"
tools:ignore="HardcodedText,LabelFor"
/>
<Spinner
android:id="@+id/checkIntervalSpinner"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:layout_marginEnd="-4dp"
android:layout_weight="1"
/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="@dimen/content_inset"
android:background="@color/dividerColorDark"
/>
<TextView
android:id="@+id/responseValidation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_inset"
android:fontFamily="sans-serif"
android:text="@string/response_validation_mode"
android:textColor="?colorAccent"
android:textSize="@dimen/caption_font_size"
/>
<Spinner
android:id="@+id/responseValidationMode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<EditText
android:id="@+id/responseValidationSearchTerm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_inset_less"
android:layout_marginLeft="-4dp"
android:layout_marginRight="-4dp"
android:layout_marginTop="-4dp"
android:fontFamily="sans-serif-light"
android:hint="@string/search_term"
android:textSize="@dimen/body_font_size"
android:visibility="gone"
tools:ignore="Autofill"
/>
<HorizontalScrollView
android:id="@+id/responseValidationScript"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_inset"
android:layout_marginTop="@dimen/content_inset_half"
android:background="@color/colorPrimaryDark"
android:elevation="@dimen/fab_elevation"
android:padding="@dimen/content_inset_half"
android:scrollbars="none"
tools:ignore="UnusedAttribute"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
> >
<TextView <com.google.android.material.textfield.TextInputEditText
android:layout_width="wrap_content" android:id="@+id/inputName"
android:layout_height="wrap_content"
android:fontFamily="serif-monospace"
android:lineSpacingMultiplier="1.4"
android:singleLine="true"
android:text="@string/function_declaration"
android:textSize="@dimen/code_font_size"
/>
<EditText
android:id="@+id/responseValidationScriptInput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:fontFamily="serif-monospace"
android:gravity="top"
android:hint="@string/default_js"
android:inputType="textMultiLine"
android:lineSpacingMultiplier="1.4"
android:paddingBottom="@dimen/content_inset_less"
android:paddingEnd="@dimen/content_inset_more"
android:paddingStart="@dimen/content_inset_more"
android:paddingTop="@dimen/content_inset_less"
android:scrollHorizontally="true"
android:textSize="@dimen/code_font_size"
tools:ignore="Autofill,LabelFor,RtlSymmetry"
/>
<TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="serif-monospace" android:fontFamily="sans-serif-light"
android:text="@string/function_end" android:hint="@string/site_name"
android:textSize="@dimen/code_font_size" android:inputType="textPersonName|textCapWords|textAutoCorrect"
android:textColor="?android:textColorPrimary"
android:textColorHint="?android:textColorSecondary"
android:textSize="@dimen/body_font_size"
/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/urlTiLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="-4dp"
android:layout_marginRight="-4dp"
android:layout_marginTop="@dimen/content_inset_half"
>
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/inputUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:hint="@string/site_url"
android:inputType="textUri"
android:textColor="?android:textColorPrimary"
android:textColorHint="?android:textColorSecondary"
android:textSize="@dimen/body_font_size"
/>
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/textUrlWarning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_text_spacing"
android:fontFamily="sans-serif-light"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/caption_font_size"
android:visibility="gone"
tools:text="Warning: this app checks for server availability with HTTP requests. It's recommended that you use an HTTP URL."
/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="@dimen/content_inset"
android:background="@color/dividerColorDark"
/>
<TextView
android:id="@+id/checkIntervalLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_inset"
android:fontFamily="sans-serif"
android:text="@string/check_interval"
android:textColor="?colorAccent"
android:textSize="@dimen/caption_font_size"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2"
>
<EditText
android:id="@+id/checkIntervalInput"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:layout_marginEnd="@dimen/content_inset_half"
android:layout_marginStart="-4dp"
android:layout_weight="1"
android:fontFamily="sans-serif-light"
android:hint="0"
android:inputType="number"
android:textSize="@dimen/body_font_size"
tools:ignore="HardcodedText,LabelFor"
/>
<Spinner
android:id="@+id/checkIntervalSpinner"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:layout_marginEnd="-4dp"
android:layout_weight="1"
/> />
</LinearLayout> </LinearLayout>
</HorizontalScrollView> <View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="@dimen/content_inset"
android:background="@color/dividerColorDark"
/>
<TextView <TextView
android:id="@+id/validationModeDescription" android:id="@+id/responseValidation"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_inset_half" android:layout_marginTop="@dimen/content_inset"
android:fontFamily="sans-serif-light" android:fontFamily="sans-serif"
android:lineSpacingMultiplier="1.2" android:text="@string/response_validation_mode"
android:text="@string/validation_mode_status_desc" android:textColor="?colorAccent"
android:textSize="@dimen/body_font_size" android:textSize="@dimen/caption_font_size"
/> />
<Button <Spinner
android:id="@+id/doneBtn" android:id="@+id/responseValidationMode"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="-4dp" />
android:layout_marginRight="-4dp"
android:layout_marginTop="@dimen/content_inset"
android:text="@string/done"
android:textColor="#fff"
/>
</LinearLayout> <EditText
android:id="@+id/responseValidationSearchTerm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_inset_less"
android:layout_marginLeft="-4dp"
android:layout_marginRight="-4dp"
android:layout_marginTop="-4dp"
android:fontFamily="sans-serif-light"
android:hint="@string/search_term"
android:textSize="@dimen/body_font_size"
android:visibility="gone"
tools:ignore="Autofill"
/>
</ScrollView> <HorizontalScrollView
android:id="@+id/responseValidationScript"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_inset"
android:layout_marginTop="@dimen/content_inset_half"
android:background="@color/colorPrimaryDark"
android:elevation="@dimen/fab_elevation"
android:padding="@dimen/content_inset_half"
android:scrollbars="none"
tools:ignore="UnusedAttribute"
>
</LinearLayout> <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="serif-monospace"
android:lineSpacingMultiplier="1.4"
android:singleLine="true"
android:text="@string/function_declaration"
android:textSize="@dimen/code_font_size"
/>
<EditText
android:id="@+id/responseValidationScriptInput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:fontFamily="serif-monospace"
android:gravity="top"
android:hint="@string/default_js"
android:inputType="textMultiLine"
android:lineSpacingMultiplier="1.4"
android:paddingBottom="@dimen/content_inset_less"
android:paddingEnd="@dimen/content_inset_more"
android:paddingStart="@dimen/content_inset_more"
android:paddingTop="@dimen/content_inset_less"
android:scrollHorizontally="true"
android:textSize="@dimen/code_font_size"
tools:ignore="Autofill,LabelFor,RtlSymmetry"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="serif-monospace"
android:text="@string/function_end"
android:textSize="@dimen/code_font_size"
/>
</LinearLayout>
</HorizontalScrollView>
<TextView
android:id="@+id/validationModeDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_inset_half"
android:fontFamily="sans-serif-light"
android:lineSpacingMultiplier="1.2"
android:text="@string/validation_mode_status_desc"
android:textSize="@dimen/body_font_size"
/>
<Button
android:id="@+id/doneBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="-4dp"
android:layout_marginRight="-4dp"
android:layout_marginTop="@dimen/content_inset"
android:text="@string/done"
android:textColor="#fff"
/>
</LinearLayout>
</ScrollView>
</LinearLayout>
<FrameLayout
android:id="@+id/content_loading_progress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#40000000"
android:visibility="gone"
>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="?android:progressBarStyleLarge"
/>
</FrameLayout>
</FrameLayout>

View file

@ -1,329 +1,354 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rootView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?colorPrimary"
android:orientation="vertical"
> >
<androidx.appcompat.widget.Toolbar <LinearLayout
android:id="@+id/toolbar" android:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:navigationIcon="@drawable/ic_action_close"
app:title="@string/view_site"
app:titleTextColor="?android:textColorPrimary"
/>
<ScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?colorPrimary"
android:orientation="vertical"
> >
<LinearLayout <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" app:navigationIcon="@drawable/ic_action_close"
android:paddingBottom="@dimen/content_inset" app:title="@string/view_site"
android:paddingLeft="@dimen/content_inset" app:titleTextColor="?android:textColorPrimary"
android:paddingRight="@dimen/content_inset" />
android:paddingTop="@dimen/content_inset_half"
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
> >
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="vertical"
android:paddingBottom="@dimen/content_inset"
android:paddingLeft="@dimen/content_inset"
android:paddingRight="@dimen/content_inset"
android:paddingTop="@dimen/content_inset_half"
> >
<com.afollestad.nocknock.views.StatusImageView <LinearLayout
android:id="@+id/iconStatus" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<com.afollestad.nocknock.views.StatusImageView
android:id="@+id/iconStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/content_inset"
android:scaleType="centerInside"
android:transitionName="status_image_view"
tools:ignore="ContentDescription,UnusedAttribute"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<EditText
android:id="@+id/inputName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:hint="@string/site_name"
android:inputType="textPersonName|textCapWords|textAutoCorrect"
android:singleLine="true"
android:textColor="?android:textColorPrimary"
android:textColorHint="?android:textColorSecondary"
android:textSize="@dimen/body_font_size"
android:transitionName="site_name"
tools:ignore="UnusedAttribute"
/>
<EditText
android:id="@+id/inputUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:hint="@string/site_url"
android:inputType="textUri"
android:singleLine="true"
android:textColor="?android:textColorPrimary"
android:textColorHint="?android:textColorSecondary"
android:textSize="@dimen/body_font_size"
android:transitionName="site_url"
tools:ignore="UnusedAttribute"
/>
<TextView
android:id="@+id/textUrlWarning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:layout_marginStart="4dp"
android:layout_marginTop="@dimen/list_text_spacing"
android:fontFamily="sans-serif-light"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/caption_font_size"
android:visibility="gone"
tools:text="Warning: this app checks for server availability with HTTP requests. It's recommended that you use an HTTP URL."
/>
</LinearLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="@dimen/content_inset_less"
android:background="@color/dividerColorDark"
/>
<TextView
android:id="@+id/checkIntervalLabel"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_marginTop="@dimen/content_inset"
android:layout_marginEnd="@dimen/content_inset" android:fontFamily="sans-serif"
android:scaleType="centerInside" android:text="@string/check_interval"
android:transitionName="status_image_view" android:textColor="?colorAccent"
tools:ignore="ContentDescription,UnusedAttribute" android:textSize="@dimen/caption_font_size"
/> />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="horizontal"
android:weightSum="2"
> >
<EditText <EditText
android:id="@+id/inputName" android:id="@+id/checkIntervalInput"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:layout_marginEnd="@dimen/content_inset_half"
android:layout_marginStart="-4dp"
android:layout_weight="1"
android:fontFamily="sans-serif-light" android:fontFamily="sans-serif-light"
android:hint="@string/site_name" android:hint="0"
android:inputType="textPersonName|textCapWords|textAutoCorrect" android:inputType="number"
android:singleLine="true"
android:textColor="?android:textColorPrimary"
android:textColorHint="?android:textColorSecondary"
android:textSize="@dimen/body_font_size" android:textSize="@dimen/body_font_size"
android:transitionName="site_name" tools:ignore="HardcodedText,LabelFor"
tools:ignore="UnusedAttribute"
/> />
<EditText <Spinner
android:id="@+id/inputUrl" android:id="@+id/checkIntervalSpinner"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="sans-serif-light" android:layout_gravity="end|center_vertical"
android:hint="@string/site_url" android:layout_marginEnd="-4dp"
android:inputType="textUri" android:layout_weight="1"
android:singleLine="true"
android:textColor="?android:textColorPrimary"
android:textColorHint="?android:textColorSecondary"
android:textSize="@dimen/body_font_size"
android:transitionName="site_url"
tools:ignore="UnusedAttribute"
/>
<TextView
android:id="@+id/textUrlWarning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:layout_marginStart="4dp"
android:layout_marginTop="@dimen/list_text_spacing"
android:fontFamily="sans-serif-light"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/caption_font_size"
android:visibility="gone"
tools:text="Warning: this app checks for server availability with HTTP requests. It's recommended that you use an HTTP URL."
/> />
</LinearLayout> </LinearLayout>
</LinearLayout> <View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="@dimen/content_inset_less"
android:background="@color/dividerColorDark"
/>
<View <TextView
android:layout_width="match_parent" android:id="@+id/responseValidation"
android:layout_height="1dp" android:layout_width="wrap_content"
android:layout_marginTop="@dimen/content_inset_less"
android:background="@color/dividerColorDark"
/>
<TextView
android:id="@+id/checkIntervalLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_inset"
android:fontFamily="sans-serif"
android:text="@string/check_interval"
android:textColor="?colorAccent"
android:textSize="@dimen/caption_font_size"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2"
>
<EditText
android:id="@+id/checkIntervalInput"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical" android:layout_marginTop="@dimen/content_inset"
android:layout_marginEnd="@dimen/content_inset_half" android:fontFamily="sans-serif"
android:layout_marginStart="-4dp" android:text="@string/response_validation_mode"
android:layout_weight="1" android:textColor="?colorAccent"
android:fontFamily="sans-serif-light" android:textSize="@dimen/caption_font_size"
android:hint="0"
android:inputType="number"
android:textSize="@dimen/body_font_size"
tools:ignore="HardcodedText,LabelFor"
/> />
<Spinner <Spinner
android:id="@+id/checkIntervalSpinner" android:id="@+id/responseValidationMode"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical" />
android:layout_marginEnd="-4dp"
android:layout_weight="1" <EditText
android:id="@+id/responseValidationSearchTerm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_inset_less"
android:layout_marginLeft="-4dp"
android:layout_marginRight="-4dp"
android:layout_marginTop="-4dp"
android:fontFamily="sans-serif-light"
android:hint="@string/search_term"
android:textSize="@dimen/body_font_size"
android:visibility="gone"
/>
<HorizontalScrollView
android:id="@+id/responseValidationScript"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_inset"
android:layout_marginTop="@dimen/content_inset_half"
android:background="@color/colorPrimaryDark"
android:elevation="@dimen/fab_elevation"
android:padding="@dimen/content_inset_half"
android:scrollbars="none"
tools:ignore="UnusedAttribute"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="serif-monospace"
android:lineSpacingMultiplier="1.4"
android:singleLine="true"
android:text="@string/function_declaration"
android:textSize="@dimen/code_font_size"
/>
<EditText
android:id="@+id/responseValidationScriptInput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:fontFamily="serif-monospace"
android:gravity="top"
android:inputType="textMultiLine"
android:lineSpacingMultiplier="1.4"
android:paddingBottom="@dimen/content_inset_less"
android:paddingEnd="@dimen/content_inset_more"
android:paddingStart="@dimen/content_inset_more"
android:paddingTop="@dimen/content_inset_less"
android:scrollHorizontally="true"
android:text="@string/default_js"
android:textSize="@dimen/code_font_size"
tools:ignore="Autofill,LabelFor"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="serif-monospace"
android:text="@string/function_end"
android:textSize="@dimen/code_font_size"
/>
</LinearLayout>
</HorizontalScrollView>
<TextView
android:id="@+id/validationModeDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_inset_half"
android:fontFamily="sans-serif-light"
android:lineSpacingMultiplier="1.2"
android:text="@string/validation_mode_status_desc"
android:textSize="@dimen/body_font_size"
/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="@dimen/content_inset"
android:background="@color/dividerColorDark"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_inset"
android:text="@string/last_check_result"
android:textColor="?colorAccent"
android:textSize="@dimen/caption_font_size"
/>
<TextView
android:id="@+id/textLastCheckResult"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_text_spacing"
android:fontFamily="sans-serif"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/medium_text_size"
tools:text="Everything checks out!"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_inset"
android:text="@string/next_check"
android:textColor="?colorAccent"
android:textSize="@dimen/caption_font_size"
/>
<TextView
android:id="@+id/textNextCheck"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_text_spacing"
android:fontFamily="sans-serif"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/medium_text_size"
tools:text="In 2 hours"
/>
<Button
android:id="@+id/doneBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="-4dp"
android:layout_marginRight="-4dp"
android:layout_marginTop="@dimen/content_inset_more"
android:text="@string/save"
android:textColor="#fff"
/> />
</LinearLayout> </LinearLayout>
<View </ScrollView>
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="@dimen/content_inset_less"
android:background="@color/dividerColorDark"
/>
<TextView </LinearLayout>
android:id="@+id/responseValidation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_inset"
android:fontFamily="sans-serif"
android:text="@string/response_validation_mode"
android:textColor="?colorAccent"
android:textSize="@dimen/caption_font_size"
/>
<Spinner <FrameLayout
android:id="@+id/responseValidationMode" android:id="@+id/content_loading_progress"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
/> android:background="#40000000"
android:visibility="gone"
>
<EditText <ProgressBar
android:id="@+id/responseValidationSearchTerm" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_gravity="center"
android:layout_marginBottom="@dimen/content_inset_less" style="?android:progressBarStyleLarge"
android:layout_marginLeft="-4dp" />
android:layout_marginRight="-4dp"
android:layout_marginTop="-4dp"
android:fontFamily="sans-serif-light"
android:hint="@string/search_term"
android:textSize="@dimen/body_font_size"
android:visibility="gone"
/>
<HorizontalScrollView </FrameLayout>
android:id="@+id/responseValidationScript"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_inset"
android:layout_marginTop="@dimen/content_inset_half"
android:background="@color/colorPrimaryDark"
android:elevation="@dimen/fab_elevation"
android:padding="@dimen/content_inset_half"
android:scrollbars="none"
tools:ignore="UnusedAttribute"
>
<LinearLayout </FrameLayout>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="serif-monospace"
android:lineSpacingMultiplier="1.4"
android:singleLine="true"
android:text="@string/function_declaration"
android:textSize="@dimen/code_font_size"
/>
<EditText
android:id="@+id/responseValidationScriptInput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:fontFamily="serif-monospace"
android:gravity="top"
android:hint="@string/default_js"
android:inputType="textMultiLine"
android:lineSpacingMultiplier="1.4"
android:paddingBottom="@dimen/content_inset_less"
android:paddingEnd="@dimen/content_inset_more"
android:paddingStart="@dimen/content_inset_more"
android:paddingTop="@dimen/content_inset_less"
android:scrollHorizontally="true"
android:textSize="@dimen/code_font_size"
tools:ignore="Autofill,LabelFor,RtlSymmetry"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="serif-monospace"
android:text="@string/function_end"
android:textSize="@dimen/code_font_size"
/>
</LinearLayout>
</HorizontalScrollView>
<TextView
android:id="@+id/validationModeDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_inset_half"
android:fontFamily="sans-serif-light"
android:lineSpacingMultiplier="1.2"
android:text="@string/validation_mode_status_desc"
android:textSize="@dimen/body_font_size"
/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="@dimen/content_inset"
android:background="@color/dividerColorDark"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_inset"
android:text="@string/last_check_result"
android:textColor="?colorAccent"
android:textSize="@dimen/caption_font_size"
/>
<TextView
android:id="@+id/textLastCheckResult"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_text_spacing"
android:fontFamily="sans-serif"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/medium_text_size"
tools:text="Everything checks out!"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_inset"
android:text="@string/next_check"
android:textColor="?colorAccent"
android:textSize="@dimen/caption_font_size"
/>
<TextView
android:id="@+id/textNextCheck"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_text_spacing"
android:fontFamily="sans-serif"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/medium_text_size"
tools:text="In 2 hours"
/>
<Button
android:id="@+id/doneBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="-4dp"
android:layout_marginRight="-4dp"
android:layout_marginTop="@dimen/content_inset_more"
android:text="@string/save"
android:textColor="#fff"
/>
</LinearLayout>
</ScrollView>
</LinearLayout>

View file

@ -160,7 +160,7 @@ class CheckStatusJob : JobService() {
modelStore.update(newSiteModel) modelStore.update(newSiteModel)
withContext(Main) { withContext(Main) {
sendBroadcast(Intent(ACTION_STATUS_UPDATE).apply { putExtra(KEY_UPDATE_MODEL, site) }) sendBroadcast(Intent(ACTION_STATUS_UPDATE).apply { putExtra(KEY_UPDATE_MODEL, newSiteModel) })
} }
return newSiteModel return newSiteModel
} }