Add the ability to duplicate sites in the long-press menu. Resolves #40.

This commit is contained in:
Aidan Follestad 2019-01-08 16:21:26 -08:00
parent 646bc25232
commit 74f7aa8aa2
6 changed files with 125 additions and 2 deletions

View file

@ -19,8 +19,10 @@ import android.annotation.SuppressLint
import android.os.Bundle
import android.widget.ArrayAdapter
import com.afollestad.nocknock.R
import com.afollestad.nocknock.data.model.Site
import com.afollestad.nocknock.data.model.ValidationMode
import com.afollestad.nocknock.ui.DarkModeSwitchActivity
import com.afollestad.nocknock.ui.viewsite.KEY_SITE
import com.afollestad.nocknock.viewcomponents.ext.dimenFloat
import com.afollestad.nocknock.viewcomponents.ext.onScroll
import com.afollestad.nocknock.viewcomponents.livedata.attachLiveData
@ -59,6 +61,10 @@ class AddSiteActivity : DarkModeSwitchActivity() {
lifecycle.addObserver(viewModel)
// Populate view model with initial data
val model = intent.getSerializableExtra(KEY_SITE) as? Site
model?.let { viewModel.prePopulateFromModel(model) }
// Loading
loadingProgress.observe(this, viewModel.onIsLoading())

View file

@ -0,0 +1,99 @@
/**
* Designed and developed by Aidan Follestad (@afollestad)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.afollestad.nocknock.ui.addsite
import com.afollestad.nocknock.data.model.RetryPolicy
import com.afollestad.nocknock.data.model.Site
import com.afollestad.nocknock.data.model.ValidationMode.JAVASCRIPT
import com.afollestad.nocknock.data.model.ValidationMode.TERM_SEARCH
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 kotlin.math.ceil
fun AddSiteViewModel.prePopulateFromModel(site: Site) {
val settings = site.settings ?: throw IllegalArgumentException("Settings must be populated!")
name.value = site.name
tags.value = site.tags
url.value = site.url
timeout.value = settings.networkTimeout
validationMode.value = settings.validationMode
when (settings.validationMode) {
TERM_SEARCH -> {
validationSearchTerm.value = settings.validationArgs
validationScript.value = null
}
JAVASCRIPT -> {
validationSearchTerm.value = null
validationScript.value = settings.validationArgs
}
else -> {
validationSearchTerm.value = null
validationScript.value = null
}
}
setCheckInterval(settings.validationIntervalMs)
setRetryPolicy(site.retryPolicy)
headers.value = site.headers
}
private fun AddSiteViewModel.setCheckInterval(interval: Long) {
when {
interval >= WEEK -> {
checkIntervalValue.value =
getIntervalFromUnit(interval, WEEK)
checkIntervalUnit.value = WEEK
}
interval >= DAY -> {
checkIntervalValue.value =
getIntervalFromUnit(interval, DAY)
checkIntervalUnit.value = DAY
}
interval >= HOUR -> {
checkIntervalValue.value =
getIntervalFromUnit(interval, HOUR)
checkIntervalUnit.value = HOUR
}
interval >= MINUTE -> {
checkIntervalValue.value =
getIntervalFromUnit(interval, MINUTE)
checkIntervalUnit.value = MINUTE
}
else -> {
checkIntervalValue.value = 0
checkIntervalUnit.value = MINUTE
}
}
}
private fun AddSiteViewModel.setRetryPolicy(policy: RetryPolicy?) {
if (policy == null) return
retryPolicyTimes.value = policy.count
retryPolicyMinutes.value = policy.minutes
}
private fun getIntervalFromUnit(
millis: Long,
unit: Long
): Int {
val intervalFloat = millis.toFloat()
val byFloat = unit.toFloat()
return ceil(intervalFloat / byFloat).toInt()
}

View file

@ -135,7 +135,8 @@ class MainActivity : DarkModeSwitchActivity() {
listItems(R.array.site_long_options) { _, i, _ ->
when (i) {
0 -> viewModel.refreshSite(model)
1 -> maybeRemoveSite(model)
1 -> addSiteForDuplication(model)
2 -> maybeRemoveSite(model)
}
}
}

View file

@ -28,10 +28,23 @@ import com.afollestad.nocknock.utilities.providers.RealIntentProvider.Companion.
internal const val VIEW_SITE_RQ = 6923
internal const val ADD_SITE_RQ = 6969
// ADD
internal fun MainActivity.addSite() {
startActivityForResult(Intent(this, AddSiteActivity::class.java), ADD_SITE_RQ)
startActivityForResult(intentToAdd(), ADD_SITE_RQ)
}
internal fun MainActivity.addSiteForDuplication(site: Site) {
startActivityForResult(intentToAdd(site), ADD_SITE_RQ)
}
private fun MainActivity.intentToAdd(model: Site? = null) =
Intent(this, AddSiteActivity::class.java).apply {
model?.let { putExtra(KEY_SITE, it) }
}
// VIEW
internal fun MainActivity.viewSite(model: Site) {
startActivityForResult(intentToView(model), VIEW_SITE_RQ)
}
@ -41,6 +54,8 @@ private fun MainActivity.intentToView(model: Site) =
putExtra(KEY_SITE, model)
}
// MISC
internal fun MainActivity.maybeRemoveSite(model: Site) {
MaterialDialog(this).show {
title(R.string.remove_site)

View file

@ -3,6 +3,7 @@
<string-array name="site_long_options" translatable="false">
<item>@string/refresh_status</item>
<item>@string/duplicate_and_modify</item>
<item>@string/remove_site</item>
</string-array>

View file

@ -35,6 +35,7 @@
<string name="options">Options</string>
<string name="remove_site">Remove Site</string>
<string name="duplicate_and_modify">Duplicate and Modify</string>
<string name="remove_site_prompt"><![CDATA[Remove <b>%1$s</b> from your sites?]]></string>
<string name="remove">Remove</string>
<string name="save_changes">Save Changes</string>