mirror of
https://github.com/afollestad/nock-nock.git
synced 2025-08-06 16:08:39 +00:00
Begin to modularize reused view layouts, switch to Material Components theme
This commit is contained in:
parent
c7096e8746
commit
6dfff5bb12
41 changed files with 502 additions and 365 deletions
1
.idea/modules.xml
generated
1
.idea/modules.xml
generated
|
@ -8,6 +8,7 @@
|
||||||
<module fileurl="file://$PROJECT_DIR$/nock-nock.iml" filepath="$PROJECT_DIR$/nock-nock.iml" />
|
<module fileurl="file://$PROJECT_DIR$/nock-nock.iml" filepath="$PROJECT_DIR$/nock-nock.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/notifications/notifications.iml" filepath="$PROJECT_DIR$/notifications/notifications.iml" />
|
<module fileurl="file://$PROJECT_DIR$/notifications/notifications.iml" filepath="$PROJECT_DIR$/notifications/notifications.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/utilities/utilities.iml" filepath="$PROJECT_DIR$/utilities/utilities.iml" />
|
<module fileurl="file://$PROJECT_DIR$/utilities/utilities.iml" filepath="$PROJECT_DIR$/utilities/utilities.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/viewcomponents/viewcomponents.iml" filepath="$PROJECT_DIR$/viewcomponents/viewcomponents.iml" />
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -22,6 +22,7 @@ dependencies {
|
||||||
implementation project(':utilities')
|
implementation project(':utilities')
|
||||||
implementation project(':engine')
|
implementation project(':engine')
|
||||||
implementation project(':notifications')
|
implementation project(':notifications')
|
||||||
|
implementation project(':viewcomponents')
|
||||||
|
|
||||||
implementation 'androidx.appcompat:appcompat:' + versions.androidx
|
implementation 'androidx.appcompat:appcompat:' + versions.androidx
|
||||||
implementation 'androidx.recyclerview:recyclerview:' + versions.androidx
|
implementation 'androidx.recyclerview:recyclerview:' + versions.androidx
|
||||||
|
|
|
@ -25,33 +25,30 @@ import com.afollestad.nocknock.data.ValidationMode.STATUS_CODE
|
||||||
import com.afollestad.nocknock.data.ValidationMode.TERM_SEARCH
|
import com.afollestad.nocknock.data.ValidationMode.TERM_SEARCH
|
||||||
import com.afollestad.nocknock.engine.db.ServerModelStore
|
import com.afollestad.nocknock.engine.db.ServerModelStore
|
||||||
import com.afollestad.nocknock.engine.statuscheck.CheckStatusManager
|
import com.afollestad.nocknock.engine.statuscheck.CheckStatusManager
|
||||||
import com.afollestad.nocknock.utilities.ext.conceal
|
|
||||||
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.onEnd
|
import com.afollestad.nocknock.utilities.ext.onEnd
|
||||||
import com.afollestad.nocknock.utilities.ext.onItemSelected
|
|
||||||
import com.afollestad.nocknock.utilities.ext.onLayout
|
|
||||||
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.viewcomponents.ext.conceal
|
||||||
import com.afollestad.nocknock.utilities.ext.showOrHide
|
import com.afollestad.nocknock.viewcomponents.ext.hide
|
||||||
import com.afollestad.nocknock.utilities.ext.textAsLong
|
import com.afollestad.nocknock.viewcomponents.ext.onItemSelected
|
||||||
import com.afollestad.nocknock.utilities.ext.trimmedText
|
import com.afollestad.nocknock.viewcomponents.ext.onLayout
|
||||||
import kotlinx.android.synthetic.main.activity_addsite.checkIntervalInput
|
import com.afollestad.nocknock.viewcomponents.ext.show
|
||||||
import kotlinx.android.synthetic.main.activity_addsite.checkIntervalSpinner
|
import com.afollestad.nocknock.viewcomponents.ext.showOrHide
|
||||||
import kotlinx.android.synthetic.main.activity_addsite.content_loading_progress
|
import com.afollestad.nocknock.viewcomponents.ext.trimmedText
|
||||||
|
import kotlinx.android.synthetic.main.activity_addsite.checkIntervalLayout
|
||||||
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
|
||||||
|
import kotlinx.android.synthetic.main.activity_addsite.loadingProgress
|
||||||
import kotlinx.android.synthetic.main.activity_addsite.nameTiLayout
|
import kotlinx.android.synthetic.main.activity_addsite.nameTiLayout
|
||||||
import kotlinx.android.synthetic.main.activity_addsite.responseValidationMode
|
import kotlinx.android.synthetic.main.activity_addsite.responseValidationMode
|
||||||
import kotlinx.android.synthetic.main.activity_addsite.responseValidationSearchTerm
|
import kotlinx.android.synthetic.main.activity_addsite.responseValidationSearchTerm
|
||||||
import kotlinx.android.synthetic.main.activity_addsite.rootView
|
import kotlinx.android.synthetic.main.activity_addsite.rootView
|
||||||
|
import kotlinx.android.synthetic.main.activity_addsite.scriptInputLayout
|
||||||
import kotlinx.android.synthetic.main.activity_addsite.textUrlWarning
|
import kotlinx.android.synthetic.main.activity_addsite.textUrlWarning
|
||||||
import kotlinx.android.synthetic.main.activity_addsite.toolbar
|
import kotlinx.android.synthetic.main.activity_addsite.toolbar
|
||||||
import kotlinx.android.synthetic.main.activity_addsite.urlTiLayout
|
import kotlinx.android.synthetic.main.activity_addsite.urlTiLayout
|
||||||
import kotlinx.android.synthetic.main.activity_addsite.validationModeDescription
|
import kotlinx.android.synthetic.main.activity_addsite.validationModeDescription
|
||||||
import kotlinx.android.synthetic.main.include_script_input.responseValidationScript
|
|
||||||
import kotlinx.android.synthetic.main.include_script_input.responseValidationScriptInput
|
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.Dispatchers.Main
|
import kotlinx.coroutines.Dispatchers.Main
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
|
@ -97,14 +94,6 @@ class AddSiteActivity : AppCompatActivity(), View.OnClickListener {
|
||||||
rootView.onLayout { circularRevealActivity() }
|
rootView.onLayout { circularRevealActivity() }
|
||||||
}
|
}
|
||||||
|
|
||||||
val intervalOptionsAdapter = ArrayAdapter(
|
|
||||||
this,
|
|
||||||
R.layout.list_item_spinner,
|
|
||||||
resources.getStringArray(R.array.interval_options)
|
|
||||||
)
|
|
||||||
intervalOptionsAdapter.setDropDownViewResource(R.layout.list_item_spinner_dropdown)
|
|
||||||
checkIntervalSpinner.adapter = intervalOptionsAdapter
|
|
||||||
|
|
||||||
inputUrl.setOnFocusChangeListener { _, hasFocus ->
|
inputUrl.setOnFocusChangeListener { _, hasFocus ->
|
||||||
if (!hasFocus) {
|
if (!hasFocus) {
|
||||||
val inputStr = inputUrl.text
|
val inputStr = inputUrl.text
|
||||||
|
@ -137,7 +126,7 @@ class AddSiteActivity : AppCompatActivity(), View.OnClickListener {
|
||||||
responseValidationMode.adapter = validationOptionsAdapter
|
responseValidationMode.adapter = validationOptionsAdapter
|
||||||
responseValidationMode.onItemSelected { pos ->
|
responseValidationMode.onItemSelected { pos ->
|
||||||
responseValidationSearchTerm.showOrHide(pos == 1)
|
responseValidationSearchTerm.showOrHide(pos == 1)
|
||||||
responseValidationScript.showOrHide(pos == 2)
|
scriptInputLayout.showOrHide(pos == 2)
|
||||||
|
|
||||||
validationModeDescription.setText(
|
validationModeDescription.setText(
|
||||||
when (pos) {
|
when (pos) {
|
||||||
|
@ -200,14 +189,14 @@ 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 newModel = ServerModel(
|
||||||
name = inputName.trimmedText(),
|
name = inputName.trimmedText(),
|
||||||
url = inputUrl.trimmedText(),
|
url = inputUrl.trimmedText(),
|
||||||
status = WAITING,
|
status = WAITING,
|
||||||
validationMode = STATUS_CODE
|
validationMode = STATUS_CODE
|
||||||
)
|
)
|
||||||
|
|
||||||
if (model.name.isEmpty()) {
|
if (newModel.name.isEmpty()) {
|
||||||
nameTiLayout.error = getString(R.string.please_enter_name)
|
nameTiLayout.error = getString(R.string.please_enter_name)
|
||||||
isClosing = false
|
isClosing = false
|
||||||
return
|
return
|
||||||
|
@ -215,42 +204,42 @@ class AddSiteActivity : AppCompatActivity(), View.OnClickListener {
|
||||||
nameTiLayout.error = null
|
nameTiLayout.error = null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model.url.isEmpty()) {
|
if (newModel.url.isEmpty()) {
|
||||||
urlTiLayout.error = getString(R.string.please_enter_url)
|
urlTiLayout.error = getString(R.string.please_enter_url)
|
||||||
isClosing = false
|
isClosing = false
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
urlTiLayout.error = null
|
urlTiLayout.error = null
|
||||||
if (!WEB_URL.matcher(model.url).find()) {
|
if (!WEB_URL.matcher(newModel.url).find()) {
|
||||||
urlTiLayout.error = getString(R.string.please_enter_valid_url)
|
urlTiLayout.error = getString(R.string.please_enter_valid_url)
|
||||||
isClosing = false
|
isClosing = false
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
val uri = Uri.parse(model.url)
|
val uri = Uri.parse(newModel.url)
|
||||||
if (uri.scheme == null) {
|
if (uri.scheme == null) {
|
||||||
model = model.copy(url = "http://${model.url}")
|
newModel = newModel.copy(url = "http://${newModel.url}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val parsedCheckInterval = getParsedCheckInterval()
|
val selectedCheckInterval = checkIntervalLayout.getSelectedCheckInterval()
|
||||||
val selectedValidationMode = getSelectedValidationMode()
|
val selectedValidationMode = getSelectedValidationMode()
|
||||||
val selectedValidationContent = getSelectedValidationContent()
|
val selectedValidationContent = getSelectedValidationContent()
|
||||||
|
|
||||||
model = model.copy(
|
newModel = newModel.copy(
|
||||||
checkInterval = parsedCheckInterval,
|
checkInterval = selectedCheckInterval,
|
||||||
lastCheck = currentTimeMillis() - parsedCheckInterval,
|
lastCheck = currentTimeMillis() - selectedCheckInterval,
|
||||||
validationMode = selectedValidationMode,
|
validationMode = selectedValidationMode,
|
||||||
validationContent = selectedValidationContent
|
validationContent = selectedValidationContent
|
||||||
)
|
)
|
||||||
|
|
||||||
rootView.scopeWhileAttached(Main) {
|
rootView.scopeWhileAttached(Main) {
|
||||||
launch(coroutineContext) {
|
launch(coroutineContext) {
|
||||||
content_loading_progress.show()
|
loadingProgress.setLoading()
|
||||||
val storedModel = async(IO) { serverModelStore.put(model) }.await()
|
val storedModel = async(IO) { serverModelStore.put(newModel) }.await()
|
||||||
checkStatusManager.cancelCheck(storedModel)
|
checkStatusManager.cancelCheck(storedModel)
|
||||||
checkStatusManager.scheduleCheck(storedModel, rightNow = true)
|
checkStatusManager.scheduleCheck(storedModel, rightNow = true)
|
||||||
content_loading_progress.hide()
|
loadingProgress.setDone()
|
||||||
|
|
||||||
setResult(RESULT_OK)
|
setResult(RESULT_OK)
|
||||||
finish()
|
finish()
|
||||||
|
@ -261,16 +250,6 @@ class AddSiteActivity : AppCompatActivity(), View.OnClickListener {
|
||||||
|
|
||||||
override fun onBackPressed() = closeActivityWithReveal()
|
override fun onBackPressed() = closeActivityWithReveal()
|
||||||
|
|
||||||
private fun getParsedCheckInterval(): Long {
|
|
||||||
val intervalInput = checkIntervalInput.textAsLong()
|
|
||||||
return when (checkIntervalSpinner.selectedItemPosition) {
|
|
||||||
0 -> intervalInput * (60 * 1000)
|
|
||||||
1 -> intervalInput * (60 * 60 * 1000)
|
|
||||||
2 -> intervalInput * (60 * 60 * 24 * 1000)
|
|
||||||
else -> intervalInput * (60 * 60 * 24 * 7 * 1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getSelectedValidationMode() = when (responseValidationMode.selectedItemPosition) {
|
private fun getSelectedValidationMode() = when (responseValidationMode.selectedItemPosition) {
|
||||||
0 -> STATUS_CODE
|
0 -> STATUS_CODE
|
||||||
1 -> TERM_SEARCH
|
1 -> TERM_SEARCH
|
||||||
|
@ -285,7 +264,7 @@ class AddSiteActivity : AppCompatActivity(), View.OnClickListener {
|
||||||
private fun getSelectedValidationContent() = when (responseValidationMode.selectedItemPosition) {
|
private fun getSelectedValidationContent() = when (responseValidationMode.selectedItemPosition) {
|
||||||
0 -> null
|
0 -> null
|
||||||
1 -> responseValidationSearchTerm.trimmedText()
|
1 -> responseValidationSearchTerm.trimmedText()
|
||||||
2 -> responseValidationScriptInput.trimmedText()
|
2 -> scriptInputLayout.getCode()
|
||||||
else -> {
|
else -> {
|
||||||
throw IllegalStateException(
|
throw IllegalStateException(
|
||||||
"Unexpected validation mode index: ${responseValidationMode.selectedItemPosition}"
|
"Unexpected validation mode index: ${responseValidationMode.selectedItemPosition}"
|
||||||
|
|
|
@ -44,8 +44,8 @@ import com.afollestad.nocknock.utilities.ext.onEnd
|
||||||
import com.afollestad.nocknock.utilities.ext.safeRegisterReceiver
|
import com.afollestad.nocknock.utilities.ext.safeRegisterReceiver
|
||||||
import com.afollestad.nocknock.utilities.ext.safeUnregisterReceiver
|
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.viewcomponents.ext.show
|
||||||
import com.afollestad.nocknock.utilities.ext.showOrHide
|
import com.afollestad.nocknock.viewcomponents.ext.showOrHide
|
||||||
import com.afollestad.nocknock.utilities.util.MathUtil.bezierCurve
|
import com.afollestad.nocknock.utilities.util.MathUtil.bezierCurve
|
||||||
import kotlinx.android.synthetic.main.activity_main.emptyText
|
import kotlinx.android.synthetic.main.activity_main.emptyText
|
||||||
import kotlinx.android.synthetic.main.activity_main.fab
|
import kotlinx.android.synthetic.main.activity_main.fab
|
||||||
|
|
|
@ -35,46 +35,38 @@ import com.afollestad.nocknock.engine.db.ServerModelStore
|
||||||
import com.afollestad.nocknock.engine.statuscheck.CheckStatusJob.Companion.ACTION_STATUS_UPDATE
|
import com.afollestad.nocknock.engine.statuscheck.CheckStatusJob.Companion.ACTION_STATUS_UPDATE
|
||||||
import com.afollestad.nocknock.engine.statuscheck.CheckStatusManager
|
import com.afollestad.nocknock.engine.statuscheck.CheckStatusManager
|
||||||
import com.afollestad.nocknock.notifications.NockNotificationManager
|
import com.afollestad.nocknock.notifications.NockNotificationManager
|
||||||
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.formatDate
|
import com.afollestad.nocknock.utilities.ext.formatDate
|
||||||
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.safeRegisterReceiver
|
import com.afollestad.nocknock.utilities.ext.safeRegisterReceiver
|
||||||
import com.afollestad.nocknock.utilities.ext.safeUnregisterReceiver
|
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.viewcomponents.ext.hide
|
||||||
import com.afollestad.nocknock.utilities.ext.showOrHide
|
import com.afollestad.nocknock.viewcomponents.ext.onItemSelected
|
||||||
import com.afollestad.nocknock.utilities.ext.textAsLong
|
import com.afollestad.nocknock.viewcomponents.ext.show
|
||||||
import com.afollestad.nocknock.utilities.ext.trimmedText
|
import com.afollestad.nocknock.viewcomponents.ext.showOrHide
|
||||||
import kotlinx.android.synthetic.main.activity_viewsite.checkIntervalInput
|
import com.afollestad.nocknock.viewcomponents.ext.trimmedText
|
||||||
import kotlinx.android.synthetic.main.activity_viewsite.checkIntervalSpinner
|
import kotlinx.android.synthetic.main.activity_viewsite.checkIntervalLayout
|
||||||
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
|
||||||
import kotlinx.android.synthetic.main.activity_viewsite.inputUrl
|
import kotlinx.android.synthetic.main.activity_viewsite.inputUrl
|
||||||
|
import kotlinx.android.synthetic.main.activity_viewsite.loadingProgress
|
||||||
import kotlinx.android.synthetic.main.activity_viewsite.responseValidationMode
|
import kotlinx.android.synthetic.main.activity_viewsite.responseValidationMode
|
||||||
import kotlinx.android.synthetic.main.activity_viewsite.responseValidationSearchTerm
|
import kotlinx.android.synthetic.main.activity_viewsite.responseValidationSearchTerm
|
||||||
import kotlinx.android.synthetic.main.activity_viewsite.rootView
|
import kotlinx.android.synthetic.main.activity_viewsite.rootView
|
||||||
|
import kotlinx.android.synthetic.main.activity_viewsite.scriptInputLayout
|
||||||
import kotlinx.android.synthetic.main.activity_viewsite.textLastCheckResult
|
import kotlinx.android.synthetic.main.activity_viewsite.textLastCheckResult
|
||||||
import kotlinx.android.synthetic.main.activity_viewsite.textNextCheck
|
import kotlinx.android.synthetic.main.activity_viewsite.textNextCheck
|
||||||
import kotlinx.android.synthetic.main.activity_viewsite.textUrlWarning
|
import kotlinx.android.synthetic.main.activity_viewsite.textUrlWarning
|
||||||
import kotlinx.android.synthetic.main.activity_viewsite.toolbar
|
import kotlinx.android.synthetic.main.activity_viewsite.toolbar
|
||||||
import kotlinx.android.synthetic.main.activity_viewsite.validationModeDescription
|
import kotlinx.android.synthetic.main.activity_viewsite.validationModeDescription
|
||||||
import kotlinx.android.synthetic.main.include_script_input.responseValidationScript
|
|
||||||
import kotlinx.android.synthetic.main.include_script_input.responseValidationScriptInput
|
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.Dispatchers.Main
|
import kotlinx.coroutines.Dispatchers.Main
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.lang.System.currentTimeMillis
|
import java.lang.System.currentTimeMillis
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.math.ceil
|
|
||||||
|
|
||||||
private const val KEY_VIEW_MODEL = "site_model"
|
private const val KEY_VIEW_MODEL = "site_model"
|
||||||
|
|
||||||
|
@ -130,14 +122,6 @@ class ViewSiteActivity : AppCompatActivity(),
|
||||||
setOnMenuItemClickListener(this@ViewSiteActivity)
|
setOnMenuItemClickListener(this@ViewSiteActivity)
|
||||||
}
|
}
|
||||||
|
|
||||||
val intervalOptionsAdapter = ArrayAdapter(
|
|
||||||
this,
|
|
||||||
R.layout.list_item_spinner,
|
|
||||||
resources.getStringArray(R.array.interval_options)
|
|
||||||
)
|
|
||||||
intervalOptionsAdapter.setDropDownViewResource(R.layout.list_item_spinner_dropdown)
|
|
||||||
checkIntervalSpinner.adapter = intervalOptionsAdapter
|
|
||||||
|
|
||||||
inputUrl.setOnFocusChangeListener { _, hasFocus ->
|
inputUrl.setOnFocusChangeListener { _, hasFocus ->
|
||||||
if (!hasFocus) {
|
if (!hasFocus) {
|
||||||
val inputStr = inputUrl.text
|
val inputStr = inputUrl.text
|
||||||
|
@ -170,7 +154,7 @@ class ViewSiteActivity : AppCompatActivity(),
|
||||||
|
|
||||||
responseValidationMode.onItemSelected { pos ->
|
responseValidationMode.onItemSelected { pos ->
|
||||||
responseValidationSearchTerm.showOrHide(pos == 1)
|
responseValidationSearchTerm.showOrHide(pos == 1)
|
||||||
responseValidationScript.showOrHide(pos == 2)
|
scriptInputLayout.showOrHide(pos == 2)
|
||||||
|
|
||||||
validationModeDescription.setText(
|
validationModeDescription.setText(
|
||||||
when (pos) {
|
when (pos) {
|
||||||
|
@ -213,45 +197,13 @@ class ViewSiteActivity : AppCompatActivity(),
|
||||||
|
|
||||||
if (this.checkInterval == 0L) {
|
if (this.checkInterval == 0L) {
|
||||||
textNextCheck.setText(R.string.none_turned_off)
|
textNextCheck.setText(R.string.none_turned_off)
|
||||||
checkIntervalInput.setText("")
|
checkIntervalLayout.clear()
|
||||||
checkIntervalSpinner.setSelection(0)
|
|
||||||
} else {
|
} else {
|
||||||
var lastCheck = this.lastCheck
|
var lastCheck = this.lastCheck
|
||||||
if (lastCheck == 0L) {
|
if (lastCheck == 0L) {
|
||||||
lastCheck = currentTimeMillis()
|
lastCheck = currentTimeMillis()
|
||||||
}
|
}
|
||||||
textNextCheck.text = (lastCheck + this.checkInterval).formatDate()
|
textNextCheck.text = (lastCheck + this.checkInterval).formatDate()
|
||||||
|
|
||||||
when {
|
|
||||||
this.checkInterval >= WEEK -> {
|
|
||||||
checkIntervalInput.setText(
|
|
||||||
ceil((this.checkInterval.toFloat() / WEEK).toDouble()).toInt().toString()
|
|
||||||
)
|
|
||||||
checkIntervalSpinner.setSelection(3)
|
|
||||||
}
|
|
||||||
this.checkInterval >= DAY -> {
|
|
||||||
checkIntervalInput.setText(
|
|
||||||
ceil((this.checkInterval.toFloat() / DAY.toFloat()).toDouble()).toInt().toString()
|
|
||||||
)
|
|
||||||
checkIntervalSpinner.setSelection(2)
|
|
||||||
}
|
|
||||||
this.checkInterval >= HOUR -> {
|
|
||||||
checkIntervalInput.setText(
|
|
||||||
ceil((this.checkInterval.toFloat() / HOUR.toFloat()).toDouble()).toInt().toString()
|
|
||||||
)
|
|
||||||
checkIntervalSpinner.setSelection(1)
|
|
||||||
}
|
|
||||||
this.checkInterval >= MINUTE -> {
|
|
||||||
checkIntervalInput.setText(
|
|
||||||
ceil((this.checkInterval.toFloat() / MINUTE.toFloat()).toDouble()).toInt().toString()
|
|
||||||
)
|
|
||||||
checkIntervalSpinner.setSelection(0)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
checkIntervalInput.setText("0")
|
|
||||||
checkIntervalSpinner.setSelection(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
responseValidationMode.setSelection(validationMode.value - 1)
|
responseValidationMode.setSelection(validationMode.value - 1)
|
||||||
|
@ -259,13 +211,11 @@ class ViewSiteActivity : AppCompatActivity(),
|
||||||
when (this.validationMode) {
|
when (this.validationMode) {
|
||||||
TERM_SEARCH -> responseValidationSearchTerm.setText(this.validationContent ?: "")
|
TERM_SEARCH -> responseValidationSearchTerm.setText(this.validationContent ?: "")
|
||||||
JAVASCRIPT -> {
|
JAVASCRIPT -> {
|
||||||
responseValidationScriptInput.setText(
|
scriptInputLayout.setCode(this.validationContent)
|
||||||
this.validationContent ?: getString(R.string.default_js)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
responseValidationSearchTerm.setText("")
|
responseValidationSearchTerm.setText("")
|
||||||
responseValidationScriptInput.setText("")
|
scriptInputLayout.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,13 +266,13 @@ class ViewSiteActivity : AppCompatActivity(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val parsedCheckInterval = getParsedCheckInterval()
|
val selectedCheckInterval = checkIntervalLayout.getSelectedCheckInterval()
|
||||||
val selectedValidationMode = getSelectedValidationMode()
|
val selectedValidationMode = getSelectedValidationMode()
|
||||||
val selectedValidationContent = getSelectedValidationContent()
|
val selectedValidationContent = getSelectedValidationContent()
|
||||||
|
|
||||||
currentModel = currentModel.copy(
|
currentModel = currentModel.copy(
|
||||||
checkInterval = parsedCheckInterval,
|
checkInterval = selectedCheckInterval,
|
||||||
lastCheck = currentTimeMillis() - parsedCheckInterval,
|
lastCheck = currentTimeMillis() - selectedCheckInterval,
|
||||||
validationMode = selectedValidationMode,
|
validationMode = selectedValidationMode,
|
||||||
validationContent = selectedValidationContent
|
validationContent = selectedValidationContent
|
||||||
)
|
)
|
||||||
|
@ -334,10 +284,10 @@ 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()
|
loadingProgress.setLoading()
|
||||||
if (!updateModelFromInput(true)) {
|
if (!updateModelFromInput(true)) {
|
||||||
// Validation didn't pass
|
// Validation didn't pass
|
||||||
content_loading_progress.hide()
|
loadingProgress.setDone()
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +295,7 @@ class ViewSiteActivity : AppCompatActivity(),
|
||||||
checkStatusManager.cancelCheck(currentModel)
|
checkStatusManager.cancelCheck(currentModel)
|
||||||
checkStatusManager.scheduleCheck(currentModel, rightNow = true)
|
checkStatusManager.scheduleCheck(currentModel, rightNow = true)
|
||||||
|
|
||||||
content_loading_progress.hide()
|
loadingProgress.setDone()
|
||||||
setResult(RESULT_OK)
|
setResult(RESULT_OK)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
@ -357,7 +307,7 @@ class ViewSiteActivity : AppCompatActivity(),
|
||||||
R.id.refresh -> {
|
R.id.refresh -> {
|
||||||
rootView.scopeWhileAttached(Main) {
|
rootView.scopeWhileAttached(Main) {
|
||||||
launch(coroutineContext) {
|
launch(coroutineContext) {
|
||||||
content_loading_progress.show()
|
loadingProgress.setLoading()
|
||||||
updateModelFromInput(false)
|
updateModelFromInput(false)
|
||||||
currentModel = currentModel.copy(status = WAITING)
|
currentModel = currentModel.copy(status = WAITING)
|
||||||
displayCurrentModel()
|
displayCurrentModel()
|
||||||
|
@ -366,7 +316,7 @@ class ViewSiteActivity : AppCompatActivity(),
|
||||||
|
|
||||||
checkStatusManager.cancelCheck(currentModel)
|
checkStatusManager.cancelCheck(currentModel)
|
||||||
checkStatusManager.scheduleCheck(currentModel, rightNow = true)
|
checkStatusManager.scheduleCheck(currentModel, rightNow = true)
|
||||||
content_loading_progress.hide()
|
loadingProgress.setDone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -400,9 +350,9 @@ class ViewSiteActivity : AppCompatActivity(),
|
||||||
private fun performRemoveSite(model: ServerModel) {
|
private fun performRemoveSite(model: ServerModel) {
|
||||||
rootView.scopeWhileAttached(Main) {
|
rootView.scopeWhileAttached(Main) {
|
||||||
launch(coroutineContext) {
|
launch(coroutineContext) {
|
||||||
content_loading_progress.show()
|
loadingProgress.setLoading()
|
||||||
async(IO) { serverModelStore.delete(model) }.await()
|
async(IO) { serverModelStore.delete(model) }.await()
|
||||||
content_loading_progress.hide()
|
loadingProgress.setDone()
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -413,16 +363,6 @@ class ViewSiteActivity : AppCompatActivity(),
|
||||||
item.isEnabled = currentModel.status != CHECKING && currentModel.status != WAITING
|
item.isEnabled = currentModel.status != CHECKING && currentModel.status != WAITING
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getParsedCheckInterval(): Long {
|
|
||||||
val intervalInput = checkIntervalInput.textAsLong()
|
|
||||||
return when (checkIntervalSpinner.selectedItemPosition) {
|
|
||||||
0 -> intervalInput * (60 * 1000)
|
|
||||||
1 -> intervalInput * (60 * 60 * 1000)
|
|
||||||
2 -> intervalInput * (60 * 60 * 24 * 1000)
|
|
||||||
else -> intervalInput * (60 * 60 * 24 * 7 * 1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getSelectedValidationMode() = when (responseValidationMode.selectedItemPosition) {
|
private fun getSelectedValidationMode() = when (responseValidationMode.selectedItemPosition) {
|
||||||
0 -> STATUS_CODE
|
0 -> STATUS_CODE
|
||||||
1 -> TERM_SEARCH
|
1 -> TERM_SEARCH
|
||||||
|
@ -437,7 +377,7 @@ class ViewSiteActivity : AppCompatActivity(),
|
||||||
private fun getSelectedValidationContent() = when (responseValidationMode.selectedItemPosition) {
|
private fun getSelectedValidationContent() = when (responseValidationMode.selectedItemPosition) {
|
||||||
0 -> null
|
0 -> null
|
||||||
1 -> responseValidationSearchTerm.trimmedText()
|
1 -> responseValidationSearchTerm.trimmedText()
|
||||||
2 -> responseValidationScriptInput.trimmedText()
|
2 -> scriptInputLayout.getCode()
|
||||||
else -> {
|
else -> {
|
||||||
throw IllegalStateException(
|
throw IllegalStateException(
|
||||||
"Unexpected validation mode index: ${responseValidationMode.selectedItemPosition}"
|
"Unexpected validation mode index: ${responseValidationMode.selectedItemPosition}"
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:shape="oval">
|
|
||||||
|
|
||||||
<solid android:color="@color/md_green"/>
|
|
||||||
|
|
||||||
<stroke android:color="#424242"/>
|
|
||||||
|
|
||||||
<size
|
|
||||||
android:width="@dimen/list_circle_size"
|
|
||||||
android:height="@dimen/list_circle_size"/>
|
|
||||||
</shape>
|
|
|
@ -1,12 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:shape="oval">
|
|
||||||
|
|
||||||
<solid android:color="@color/md_red"/>
|
|
||||||
|
|
||||||
<stroke android:color="#424242"/>
|
|
||||||
|
|
||||||
<size
|
|
||||||
android:width="@dimen/list_circle_size"
|
|
||||||
android:height="@dimen/list_circle_size"/>
|
|
||||||
</shape>
|
|
|
@ -1,12 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:shape="oval">
|
|
||||||
|
|
||||||
<solid android:color="@color/md_yellow"/>
|
|
||||||
|
|
||||||
<stroke android:color="#424242"/>
|
|
||||||
|
|
||||||
<size
|
|
||||||
android:width="@dimen/list_circle_size"
|
|
||||||
android:height="@dimen/list_circle_size"/>
|
|
||||||
</shape>
|
|
|
@ -96,62 +96,13 @@
|
||||||
tools:text="Warning: this app checks for server availability with HTTP requests. It's recommended that you use an HTTP URL."
|
tools:text="Warning: this app checks for server availability with HTTP requests. It's recommended that you use an HTTP URL."
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<View
|
<include layout="@layout/include_divider"/>
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dp"
|
|
||||||
android:layout_marginTop="@dimen/content_inset"
|
|
||||||
android:background="@color/dividerColorDark"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextView
|
<com.afollestad.nocknock.viewcomponents.CheckIntervalLayout
|
||||||
android:id="@+id/checkIntervalLabel"
|
android:id="@+id/checkIntervalLayout"
|
||||||
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_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
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>
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dp"
|
|
||||||
android:layout_marginTop="@dimen/content_inset"
|
android:layout_marginTop="@dimen/content_inset"
|
||||||
android:background="@color/dividerColorDark"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -186,7 +137,14 @@
|
||||||
tools:ignore="Autofill"
|
tools:ignore="Autofill"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<include layout="@layout/include_script_input"/>
|
<com.afollestad.nocknock.viewcomponents.JavaScriptInputLayout
|
||||||
|
android:id="@+id/scriptInputLayout"
|
||||||
|
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"
|
||||||
|
/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/validationModeDescription"
|
android:id="@+id/validationModeDescription"
|
||||||
|
@ -199,15 +157,13 @@
|
||||||
android:textSize="@dimen/body_font_size"
|
android:textSize="@dimen/body_font_size"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/doneBtn"
|
android:id="@+id/doneBtn"
|
||||||
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:layout_marginTop="@dimen/content_inset"
|
||||||
android:text="@string/done"
|
android:text="@string/done"
|
||||||
android:textColor="#fff"
|
style="@style/AccentButton"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -216,21 +172,10 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<FrameLayout
|
<com.afollestad.nocknock.viewcomponents.LoadingIndicatorFrame
|
||||||
android:id="@+id/content_loading_progress"
|
android:id="@+id/loadingProgress"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="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>
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
>
|
>
|
||||||
|
|
||||||
<com.afollestad.nocknock.views.StatusImageView
|
<com.afollestad.nocknock.viewcomponents.StatusImageView
|
||||||
android:id="@+id/iconStatus"
|
android:id="@+id/iconStatus"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -110,57 +110,20 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
<include
|
||||||
|
layout="@layout/include_divider"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:layout_marginTop="@dimen/content_inset_less"
|
android:layout_marginTop="@dimen/content_inset_less"
|
||||||
android:background="@color/dividerColorDark"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextView
|
<com.afollestad.nocknock.viewcomponents.CheckIntervalLayout
|
||||||
android:id="@+id/checkIntervalLabel"
|
android:id="@+id/checkIntervalLayout"
|
||||||
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_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:layout_marginTop="@dimen/content_inset"
|
||||||
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>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
|
@ -197,9 +160,17 @@
|
||||||
android:hint="@string/search_term"
|
android:hint="@string/search_term"
|
||||||
android:textSize="@dimen/body_font_size"
|
android:textSize="@dimen/body_font_size"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
tools:ignore="Autofill,TextFields"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<include layout="@layout/include_script_input"/>
|
<com.afollestad.nocknock.viewcomponents.JavaScriptInputLayout
|
||||||
|
android:id="@+id/scriptInputLayout"
|
||||||
|
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"
|
||||||
|
/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/validationModeDescription"
|
android:id="@+id/validationModeDescription"
|
||||||
|
@ -212,12 +183,7 @@
|
||||||
android:textSize="@dimen/body_font_size"
|
android:textSize="@dimen/body_font_size"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<View
|
<include layout="@layout/include_divider"/>
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dp"
|
|
||||||
android:layout_marginTop="@dimen/content_inset"
|
|
||||||
android:background="@color/dividerColorDark"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -259,15 +225,13 @@
|
||||||
tools:text="In 2 hours"
|
tools:text="In 2 hours"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/doneBtn"
|
android:id="@+id/doneBtn"
|
||||||
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_more"
|
android:layout_marginTop="@dimen/content_inset_more"
|
||||||
android:text="@string/save"
|
android:text="@string/save"
|
||||||
android:textColor="#fff"
|
style="@style/AccentButton"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -276,21 +240,10 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<FrameLayout
|
<com.afollestad.nocknock.viewcomponents.LoadingIndicatorFrame
|
||||||
android:id="@+id/content_loading_progress"
|
android:id="@+id/loadingProgress"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="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>
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
android:paddingTop="@dimen/content_inset_less"
|
android:paddingTop="@dimen/content_inset_less"
|
||||||
>
|
>
|
||||||
|
|
||||||
<com.afollestad.nocknock.views.StatusImageView
|
<com.afollestad.nocknock.viewcomponents.StatusImageView
|
||||||
android:id="@+id/iconStatus"
|
android:id="@+id/iconStatus"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<string-array name="interval_options">
|
|
||||||
<item>Minute(s)</item>
|
|
||||||
<item>Hour(s)</item>
|
|
||||||
<item>Day(s)</item>
|
|
||||||
<item>Week(s)</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<string-array name="site_long_options" translatable="false">
|
<string-array name="site_long_options" translatable="false">
|
||||||
<item>@string/refresh_status</item>
|
<item>@string/refresh_status</item>
|
||||||
<item>@string/remove_site</item>
|
<item>@string/remove_site</item>
|
||||||
|
|
|
@ -7,10 +7,4 @@
|
||||||
|
|
||||||
<color name="dividerColor">#EEEEEE</color>
|
<color name="dividerColor">#EEEEEE</color>
|
||||||
|
|
||||||
<color name="md_red">#E53935</color>
|
|
||||||
<color name="md_yellow">#FDD835</color>
|
|
||||||
<color name="md_green">#43A047</color>
|
|
||||||
|
|
||||||
<color name="dividerColorDark">#37474F</color>
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -2,20 +2,11 @@
|
||||||
|
|
||||||
<dimen name="title_font_size">20sp</dimen>
|
<dimen name="title_font_size">20sp</dimen>
|
||||||
<dimen name="medium_text_size">16sp</dimen>
|
<dimen name="medium_text_size">16sp</dimen>
|
||||||
<dimen name="body_font_size">14sp</dimen>
|
|
||||||
<dimen name="caption_font_size">12sp</dimen>
|
|
||||||
<dimen name="empty_text_size">26sp</dimen>
|
<dimen name="empty_text_size">26sp</dimen>
|
||||||
|
|
||||||
<dimen name="content_inset_half">8dp</dimen>
|
|
||||||
<dimen name="content_inset_less">12dp</dimen>
|
|
||||||
<dimen name="content_inset">16dp</dimen>
|
|
||||||
<dimen name="content_inset_more">24dp</dimen>
|
|
||||||
|
|
||||||
<dimen name="list_circle_size">42dp</dimen>
|
|
||||||
<dimen name="list_text_spacing">4dp</dimen>
|
<dimen name="list_text_spacing">4dp</dimen>
|
||||||
|
|
||||||
<dimen name="fab_elevation">4dp</dimen>
|
<dimen name="fab_elevation">4dp</dimen>
|
||||||
<dimen name="fab_elevation_pressed">8dp</dimen>
|
<dimen name="fab_elevation_pressed">8dp</dimen>
|
||||||
<dimen name="button_height">52dp</dimen>
|
|
||||||
<dimen name="code_font_size">14sp</dimen>
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
<string name="add_site">Add Site</string>
|
<string name="add_site">Add Site</string>
|
||||||
<string name="site_name">Site Name</string>
|
<string name="site_name">Site Name</string>
|
||||||
<string name="site_url">Site URL</string>
|
<string name="site_url">Site URL</string>
|
||||||
<string name="check_interval">Check Interval</string>
|
|
||||||
<string name="done">Done</string>
|
<string name="done">Done</string>
|
||||||
<string name="please_enter_name">Please enter a name!</string>
|
<string name="please_enter_name">Please enter a name!</string>
|
||||||
<string name="please_enter_url">Please enter a URL.</string>
|
<string name="please_enter_url">Please enter a URL.</string>
|
||||||
|
@ -42,9 +41,6 @@
|
||||||
<string name="warning_http_url">
|
<string name="warning_http_url">
|
||||||
Warning: this app checks for server availability with HTTP requests. It\'s recommended that you use an HTTP URL.
|
Warning: this app checks for server availability with HTTP requests. It\'s recommended that you use an HTTP URL.
|
||||||
</string>
|
</string>
|
||||||
<string name="default_js">var responseObj = JSON.parse(response);\nreturn responseObj.success === true;</string>
|
|
||||||
<string name="function_declaration">function validate(response) {</string>
|
|
||||||
<string name="function_end">}</string>
|
|
||||||
<string name="response_validation_mode">Response Validation Mode</string>
|
<string name="response_validation_mode">Response Validation Mode</string>
|
||||||
<string name="search_term">Search term…</string>
|
<string name="search_term">Search term…</string>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
<item name="colorAccent">@color/colorAccent</item>
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<item name="android:textColorSecondary">#727272</item>
|
<item name="android:textColorSecondary">#727272</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="AppTheme.Ink" parent="Theme.AppCompat.NoActionBar">
|
<style name="AppTheme.Ink" parent="Theme.MaterialComponents.NoActionBar">
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
<item name="colorAccent">@color/colorAccent</item>
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<item name="android:windowBackground">@android:color/transparent</item>
|
<item name="android:windowBackground">@android:color/transparent</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="AccentButton" parent="Widget.AppCompat.Button.Colored">
|
<style name="AccentButton" parent="Widget.MaterialComponents.Button">
|
||||||
<item name="android:textColor">#fff</item>
|
<item name="android:textColor">#fff</item>
|
||||||
<item name="android:colorButtonNormal">@color/colorAccent</item>
|
<item name="android:colorButtonNormal">@color/colorAccent</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
include ':app', ':engine', ':notifications', ':data', ':utilities'
|
include ':app', ':engine', ':notifications', ':data', ':utilities', ':viewcomponents'
|
||||||
|
|
1
viewcomponents/.gitignore
vendored
Normal file
1
viewcomponents/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/build
|
29
viewcomponents/build.gradle
Normal file
29
viewcomponents/build.gradle
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
apply from: '../dependencies.gradle'
|
||||||
|
apply plugin: 'com.android.library'
|
||||||
|
apply plugin: 'kotlin-android'
|
||||||
|
apply plugin: 'kotlin-android-extensions'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion versions.compileSdk
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion versions.minSdk
|
||||||
|
targetSdkVersion versions.compileSdk
|
||||||
|
versionCode versions.publishVersionCode
|
||||||
|
versionName versions.publishVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(':utilities')
|
||||||
|
implementation project(':data')
|
||||||
|
|
||||||
|
implementation 'androidx.appcompat:appcompat:' + versions.androidx
|
||||||
|
|
||||||
|
api 'com.squareup.okhttp3:okhttp:' + versions.okHttp
|
||||||
|
|
||||||
|
implementation 'com.google.dagger:dagger:' + versions.dagger
|
||||||
|
kapt 'com.google.dagger:dagger-compiler:' + versions.dagger
|
||||||
|
}
|
||||||
|
|
||||||
|
apply from: '../spotless.gradle'
|
2
viewcomponents/src/main/AndroidManifest.xml
Normal file
2
viewcomponents/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<manifest
|
||||||
|
package="com.afollestad.nocknock.viewcomponents"/>
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* Licensed under Apache-2.0
|
||||||
|
*
|
||||||
|
* Designed and developed by Aidan Follestad (@afollestad)
|
||||||
|
*/
|
||||||
|
package com.afollestad.nocknock.viewcomponents
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import androidx.annotation.CheckResult
|
||||||
|
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.viewcomponents.R.array
|
||||||
|
import com.afollestad.nocknock.viewcomponents.ext.textAsLong
|
||||||
|
import kotlinx.android.synthetic.main.check_interval_layout.view.input
|
||||||
|
import kotlinx.android.synthetic.main.check_interval_layout.view.spinner
|
||||||
|
import kotlin.math.ceil
|
||||||
|
|
||||||
|
/** @author Aidan Follestad (afollestad) */
|
||||||
|
class CheckIntervalLayout(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet? = null
|
||||||
|
) : LinearLayout(context, attrs) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val INDEX_MINUTE = 0
|
||||||
|
private const val INDEX_HOUR = 1
|
||||||
|
private const val INDEX_DAY = 2
|
||||||
|
private const val INDEX_WEEK = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
orientation = VERTICAL
|
||||||
|
inflate(context, R.layout.check_interval_layout, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFinishInflate() {
|
||||||
|
super.onFinishInflate()
|
||||||
|
val spinnerAdapter = ArrayAdapter(
|
||||||
|
context,
|
||||||
|
R.layout.list_item_spinner,
|
||||||
|
resources.getStringArray(array.interval_options)
|
||||||
|
)
|
||||||
|
spinnerAdapter.setDropDownViewResource(R.layout.list_item_spinner_dropdown)
|
||||||
|
spinner.adapter = spinnerAdapter
|
||||||
|
}
|
||||||
|
|
||||||
|
fun set(interval: Long) {
|
||||||
|
when {
|
||||||
|
interval >= WEEK -> {
|
||||||
|
input.setText(calculateDisplayValue(interval, WEEK))
|
||||||
|
spinner.setSelection(3)
|
||||||
|
}
|
||||||
|
interval >= DAY -> {
|
||||||
|
input.setText(calculateDisplayValue(interval, DAY))
|
||||||
|
spinner.setSelection(2)
|
||||||
|
}
|
||||||
|
interval >= HOUR -> {
|
||||||
|
input.setText(calculateDisplayValue(interval, HOUR))
|
||||||
|
spinner.setSelection(1)
|
||||||
|
}
|
||||||
|
interval >= MINUTE -> {
|
||||||
|
input.setText(calculateDisplayValue(interval, MINUTE))
|
||||||
|
spinner.setSelection(0)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
input.setText("0")
|
||||||
|
spinner.setSelection(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clear() {
|
||||||
|
input.setText("")
|
||||||
|
spinner.setSelection(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
@CheckResult fun getSelectedCheckInterval(): Long {
|
||||||
|
val intervalInput = input.textAsLong()
|
||||||
|
val spinnerPos = spinner.selectedItemPosition
|
||||||
|
return when (spinnerPos) {
|
||||||
|
INDEX_MINUTE -> intervalInput * MINUTE
|
||||||
|
INDEX_HOUR -> intervalInput * HOUR
|
||||||
|
INDEX_DAY -> intervalInput * DAY
|
||||||
|
INDEX_WEEK -> intervalInput * WEEK
|
||||||
|
else -> throw IllegalStateException("Unexpected index: $spinnerPos")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateDisplayValue(
|
||||||
|
interval: Long,
|
||||||
|
by: Long
|
||||||
|
): String {
|
||||||
|
val intervalFloat = interval.toFloat()
|
||||||
|
val byFloat = by.toFloat()
|
||||||
|
return ceil(intervalFloat / byFloat).toInt()
|
||||||
|
.toString()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Licensed under Apache-2.0
|
||||||
|
*
|
||||||
|
* Designed and developed by Aidan Follestad (@afollestad)
|
||||||
|
*/
|
||||||
|
package com.afollestad.nocknock.viewcomponents
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.widget.HorizontalScrollView
|
||||||
|
import androidx.annotation.CheckResult
|
||||||
|
import com.afollestad.nocknock.viewcomponents.ext.dimenFloat
|
||||||
|
import com.afollestad.nocknock.viewcomponents.ext.dimenInt
|
||||||
|
import com.afollestad.nocknock.viewcomponents.ext.trimmedText
|
||||||
|
import kotlinx.android.synthetic.main.javascript_input_layout.view.userInput
|
||||||
|
|
||||||
|
/** @author Aidan Follestad (afollestad) */
|
||||||
|
class JavaScriptInputLayout(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet? = null
|
||||||
|
) : HorizontalScrollView(context, attrs) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
val contentInset = dimenInt(R.dimen.content_inset)
|
||||||
|
val contentInsetHalf = dimenInt(R.dimen.content_inset_half)
|
||||||
|
setPadding(
|
||||||
|
contentInsetHalf, // left
|
||||||
|
contentInset, // top
|
||||||
|
contentInsetHalf, // right
|
||||||
|
contentInset // bottom
|
||||||
|
)
|
||||||
|
elevation = dimenFloat(R.dimen.default_elevation)
|
||||||
|
inflate(context, R.layout.javascript_input_layout, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setCode(code: String?) {
|
||||||
|
if (code.isNullOrEmpty()) {
|
||||||
|
setDefaultCode()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
userInput.setText(code.trim())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setDefaultCode() = userInput.setText(R.string.default_js)
|
||||||
|
|
||||||
|
@CheckResult fun getCode() = userInput.trimmedText()
|
||||||
|
|
||||||
|
fun clear() = userInput.setText("")
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Licensed under Apache-2.0
|
||||||
|
*
|
||||||
|
* Designed and developed by Aidan Follestad (@afollestad)
|
||||||
|
*/
|
||||||
|
package com.afollestad.nocknock.viewcomponents
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import com.afollestad.nocknock.viewcomponents.ext.hide
|
||||||
|
import com.afollestad.nocknock.viewcomponents.ext.show
|
||||||
|
|
||||||
|
/** @author Aidan Follestad (@afollestad) */
|
||||||
|
class LoadingIndicatorFrame(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet? = null
|
||||||
|
) : FrameLayout(context, attrs) {
|
||||||
|
companion object {
|
||||||
|
private const val SHOW_DELAY_MS = 200L
|
||||||
|
}
|
||||||
|
|
||||||
|
private val showRunnable = Runnable { show() }
|
||||||
|
|
||||||
|
init {
|
||||||
|
setBackgroundColor(ContextCompat.getColor(context, R.color.loading_indicator_frame_background))
|
||||||
|
hide() // hide self by default
|
||||||
|
inflate(context, R.layout.loading_indicator_frame, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setLoading() {
|
||||||
|
handler.postDelayed(showRunnable, SHOW_DELAY_MS)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setDone() {
|
||||||
|
handler.removeCallbacks(showRunnable)
|
||||||
|
hide()
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,12 +3,11 @@
|
||||||
*
|
*
|
||||||
* Designed and developed by Aidan Follestad (@afollestad)
|
* Designed and developed by Aidan Follestad (@afollestad)
|
||||||
*/
|
*/
|
||||||
package com.afollestad.nocknock.views
|
package com.afollestad.nocknock.viewcomponents
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import androidx.appcompat.widget.AppCompatImageView
|
import androidx.appcompat.widget.AppCompatImageView
|
||||||
import com.afollestad.nocknock.R
|
|
||||||
import com.afollestad.nocknock.data.ServerStatus
|
import com.afollestad.nocknock.data.ServerStatus
|
||||||
import com.afollestad.nocknock.data.ServerStatus.CHECKING
|
import com.afollestad.nocknock.data.ServerStatus.CHECKING
|
||||||
import com.afollestad.nocknock.data.ServerStatus.ERROR
|
import com.afollestad.nocknock.data.ServerStatus.ERROR
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Designed and developed by Aidan Follestad (@afollestad)
|
* Designed and developed by Aidan Follestad (@afollestad)
|
||||||
*/
|
*/
|
||||||
package com.afollestad.nocknock.utilities.ext
|
package com.afollestad.nocknock.viewcomponents.ext
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.View.GONE
|
import android.view.View.GONE
|
||||||
|
@ -13,6 +13,7 @@ import android.view.ViewTreeObserver
|
||||||
import android.widget.AdapterView
|
import android.widget.AdapterView
|
||||||
import android.widget.Spinner
|
import android.widget.Spinner
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.annotation.DimenRes
|
||||||
|
|
||||||
fun View.show() {
|
fun View.show() {
|
||||||
visibility = VISIBLE
|
visibility = VISIBLE
|
||||||
|
@ -59,3 +60,7 @@ fun View.onLayout(cb: () -> Unit) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun View.dimenFloat(@DimenRes res: Int) = resources.getDimension(res)
|
||||||
|
|
||||||
|
fun View.dimenInt(@DimenRes res: Int) = resources.getDimensionPixelSize(res)
|
10
viewcomponents/src/main/res/drawable/green_circle.xml
Normal file
10
viewcomponents/src/main/res/drawable/green_circle.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<solid android:color="@color/md_green"/>
|
||||||
|
<stroke android:color="#424242"/>
|
||||||
|
<size
|
||||||
|
android:height="@dimen/list_circle_size"
|
||||||
|
android:width="@dimen/list_circle_size"/>
|
||||||
|
</shape>
|
10
viewcomponents/src/main/res/drawable/red_circle.xml
Normal file
10
viewcomponents/src/main/res/drawable/red_circle.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<solid android:color="@color/md_red"/>
|
||||||
|
<stroke android:color="#424242"/>
|
||||||
|
<size
|
||||||
|
android:height="@dimen/list_circle_size"
|
||||||
|
android:width="@dimen/list_circle_size"/>
|
||||||
|
</shape>
|
|
@ -1,8 +1,9 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector
|
||||||
android:width="24dp"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:viewportHeight="24.0"
|
android:viewportHeight="24.0"
|
||||||
android:viewportWidth="24.0">
|
android:viewportWidth="24.0"
|
||||||
|
android:width="24dp">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#fff"
|
android:fillColor="#fff"
|
||||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
|
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
|
|
@ -1,8 +1,9 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector
|
||||||
android:width="24dp"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:viewportHeight="24.0"
|
android:viewportHeight="24.0"
|
||||||
android:viewportWidth="24.0">
|
android:viewportWidth="24.0"
|
||||||
|
android:width="24dp">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#fff"
|
android:fillColor="#fff"
|
||||||
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
|
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
|
|
@ -1,8 +1,9 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector
|
||||||
android:width="24dp"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:viewportHeight="24.0"
|
android:viewportHeight="24.0"
|
||||||
android:viewportWidth="24.0">
|
android:viewportWidth="24.0"
|
||||||
|
android:width="24dp">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#fff"
|
android:fillColor="#fff"
|
||||||
android:pathData="M6,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
|
android:pathData="M6,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
|
10
viewcomponents/src/main/res/drawable/yellow_circle.xml
Normal file
10
viewcomponents/src/main/res/drawable/yellow_circle.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<solid android:color="@color/md_yellow"/>
|
||||||
|
<stroke android:color="#424242"/>
|
||||||
|
<size
|
||||||
|
android:height="@dimen/list_circle_size"
|
||||||
|
android:width="@dimen/list_circle_size"/>
|
||||||
|
</shape>
|
53
viewcomponents/src/main/res/layout/check_interval_layout.xml
Normal file
53
viewcomponents/src/main/res/layout/check_interval_layout.xml
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<merge
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
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/input"
|
||||||
|
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="Autofill,HardcodedText,LabelFor"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/spinner"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end|center_vertical"
|
||||||
|
android:layout_marginEnd="-4dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</merge>
|
8
viewcomponents/src/main/res/layout/include_divider.xml
Normal file
8
viewcomponents/src/main/res/layout/include_divider.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<View
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginTop="@dimen/content_inset"
|
||||||
|
android:background="@color/dividerColorDark"
|
||||||
|
/>
|
|
@ -1,19 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<HorizontalScrollView
|
<merge
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/responseValidationScript"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
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:paddingBottom="@dimen/content_inset"
|
|
||||||
android:paddingLeft="@dimen/content_inset_half"
|
|
||||||
android:paddingRight="@dimen/content_inset_half"
|
|
||||||
android:paddingTop="@dimen/content_inset"
|
|
||||||
android:scrollbars="none"
|
|
||||||
tools:ignore="UnusedAttribute"
|
tools:ignore="UnusedAttribute"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
@ -34,7 +24,7 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/responseValidationScriptInput"
|
android:id="@+id/userInput"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
|
@ -62,4 +52,4 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</HorizontalScrollView>
|
</merge>
|
|
@ -6,4 +6,5 @@
|
||||||
android:fontFamily="sans-serif-light"
|
android:fontFamily="sans-serif-light"
|
||||||
android:gravity="center_vertical|start"
|
android:gravity="center_vertical|start"
|
||||||
android:textColor="?android:textColorPrimary"
|
android:textColor="?android:textColorPrimary"
|
||||||
android:textSize="@dimen/body_font_size" />
|
android:textSize="@dimen/body_font_size"
|
||||||
|
/>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<merge
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
style="?android:progressBarStyleLarge"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</merge>
|
11
viewcomponents/src/main/res/values/arrays.xml
Normal file
11
viewcomponents/src/main/res/values/arrays.xml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<string-array name="interval_options">
|
||||||
|
<item>Minute(s)</item>
|
||||||
|
<item>Hour(s)</item>
|
||||||
|
<item>Day(s)</item>
|
||||||
|
<item>Week(s)</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
</resources>
|
12
viewcomponents/src/main/res/values/colors.xml
Normal file
12
viewcomponents/src/main/res/values/colors.xml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<color name="dividerColorDark">#37474F</color>
|
||||||
|
|
||||||
|
<color name="loading_indicator_frame_background">#40000000</color>
|
||||||
|
|
||||||
|
<color name="md_red">#E53935</color>
|
||||||
|
<color name="md_yellow">#FDD835</color>
|
||||||
|
<color name="md_green">#43A047</color>
|
||||||
|
|
||||||
|
</resources>
|
19
viewcomponents/src/main/res/values/dimens.xml
Normal file
19
viewcomponents/src/main/res/values/dimens.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<dimen name="list_circle_size">42dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="default_elevation">4dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="content_inset_half">8dp</dimen>
|
||||||
|
<dimen name="content_inset_less">12dp</dimen>
|
||||||
|
<dimen name="content_inset">16dp</dimen>
|
||||||
|
<dimen name="content_inset_more">24dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="code_font_size">14sp</dimen>
|
||||||
|
<dimen name="body_font_size">14sp</dimen>
|
||||||
|
<dimen name="caption_font_size">12sp</dimen>
|
||||||
|
|
||||||
|
<dimen name="button_height">52dp</dimen>
|
||||||
|
|
||||||
|
</resources>
|
10
viewcomponents/src/main/res/values/strings.xml
Normal file
10
viewcomponents/src/main/res/values/strings.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<string name="default_js">var responseObj = JSON.parse(response);\nreturn responseObj.success === true;</string>
|
||||||
|
<string name="function_declaration">function validate(response) {</string>
|
||||||
|
<string name="function_end">}</string>
|
||||||
|
|
||||||
|
<string name="check_interval">Check Interval</string>
|
||||||
|
|
||||||
|
</resources>
|
Loading…
Add table
Add a link
Reference in a new issue