From 2191502c7ffa5d336ca51444a2f9458a2454d48f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrej=20Martin=C3=A1k?= Date: Sun, 6 Dec 2020 10:34:29 +0100 Subject: [PATCH 1/7] Update dependencies --- app/build.gradle | 12 ++++++------ build.gradle | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 7328541..a6ec4e6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -31,13 +31,13 @@ android { dependencies { // Android - implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.appcompat:appcompat:1.2.0' implementation "androidx.activity:activity-ktx:1.1.0" // Kotlin implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.5' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1' // Room def room_version = "2.2.5" @@ -49,11 +49,11 @@ dependencies { implementation "io.ktor:ktor-client-logging-jvm:1.3.2" // UI - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - implementation 'com.google.android.material:material:1.1.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation 'com.google.android.material:material:1.2.1' implementation 'com.afollestad.material-dialogs:core:3.3.0' implementation 'com.afollestad.material-dialogs:files:3.3.0' // Others - implementation "com.squareup.moshi:moshi-kotlin:1.9.2" + implementation "com.squareup.moshi:moshi-kotlin:1.10.0" } diff --git a/build.gradle b/build.gradle index 969c8e1..eaf3f50 100644 --- a/build.gradle +++ b/build.gradle @@ -1,13 +1,13 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.3.61' + ext.kotlin_version = '1.4.20' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:4.0.0' + classpath 'com.android.tools.build:gradle:4.1.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4688429..39ae025 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip From d9c21ddf5386f792ee55e3c597ae00c88a86158e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrej=20Martin=C3=A1k?= Date: Sun, 6 Dec 2020 10:35:22 +0100 Subject: [PATCH 2/7] Disable automatic backup --- app/src/main/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4016ca4..dc22e97 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,7 +6,7 @@ Date: Sun, 6 Dec 2020 10:41:13 +0100 Subject: [PATCH 3/7] Create DAO method for fetching request by ID --- .../java/sk/amk/homeberry/model/database/RequestDao.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/sk/amk/homeberry/model/database/RequestDao.kt b/app/src/main/java/sk/amk/homeberry/model/database/RequestDao.kt index 7344fc8..4580e7d 100644 --- a/app/src/main/java/sk/amk/homeberry/model/database/RequestDao.kt +++ b/app/src/main/java/sk/amk/homeberry/model/database/RequestDao.kt @@ -1,7 +1,11 @@ package sk.amk.homeberry.model.database import androidx.lifecycle.LiveData -import androidx.room.* +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query import sk.amk.homeberry.model.HomeberryRequest /** @@ -9,6 +13,9 @@ import sk.amk.homeberry.model.HomeberryRequest */ @Dao interface RequestDao { + @Query("SELECT * FROM homeberryrequest WHERE id = :id") + fun getById(id: Long): HomeberryRequest + @Query("SELECT * FROM homeberryrequest") fun getAll(): List From d2903e9e4505af99434eb451d0aa2d37c50edf92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrej=20Martin=C3=A1k?= Date: Sun, 6 Dec 2020 10:43:16 +0100 Subject: [PATCH 4/7] Implement Andoroid Dynamic Shortucts --- .../sk/amk/homeberry/main/MainActivity.kt | 64 +++++++++++++++++-- .../sk/amk/homeberry/main/MainViewModel.kt | 44 +++++++++---- 2 files changed, 93 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/sk/amk/homeberry/main/MainActivity.kt b/app/src/main/java/sk/amk/homeberry/main/MainActivity.kt index 9eb556c..e4c4e96 100644 --- a/app/src/main/java/sk/amk/homeberry/main/MainActivity.kt +++ b/app/src/main/java/sk/amk/homeberry/main/MainActivity.kt @@ -3,7 +3,11 @@ package sk.amk.homeberry.main import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent -import android.graphics.Typeface +import android.content.pm.ShortcutInfo +import android.content.pm.ShortcutManager +import android.graphics.drawable.Icon +import android.net.Uri +import android.os.Build import android.os.Bundle import android.util.TypedValue import android.view.Menu @@ -14,9 +18,9 @@ import android.widget.LinearLayout import android.widget.TextView import android.widget.Toast import androidx.activity.viewModels +import androidx.annotation.RequiresApi import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isVisible -import androidx.lifecycle.Observer import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.callbacks.onCancel import com.afollestad.materialdialogs.customview.customView @@ -39,16 +43,20 @@ class MainActivity : AppCompatActivity() { setSupportActionBar(toolbar) title = "" - viewModel.requests.observe(this, Observer { requests -> + viewModel.requests.observe(this, { requests -> txtEmptyState.isVisible = requests.isEmpty() buttonOpenSettings.isVisible = requests.isEmpty() if (requests.isNotEmpty()) { generateButtons(requests) } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { + createShortcuts(requests) + } }) - viewModel.state.observe(this, Observer { state -> + viewModel.state.observe(this, { state -> if (state !is MainState.RequestInProgress) { progressDialog?.dismiss() } @@ -64,6 +72,14 @@ class MainActivity : AppCompatActivity() { buttonOpenSettings.setOnClickListener { openSettings() } } + override fun onResume() { + super.onResume() + + intent.dataString?.toLong()?.let { + viewModel.callRequest(it) + } + } + override fun onPause() { progressDialog?.dismiss() viewModel.cancelRequest() @@ -157,6 +173,11 @@ class MainActivity : AppCompatActivity() { ).show() } } + + // close when app launched from shortcut + if (intent.dataString != null) { + finish() + } } private fun handleError(errorMessage: String, request: HomeberryRequest) { @@ -180,6 +201,40 @@ class MainActivity : AppCompatActivity() { startActivity(Intent(this, SettingsActivity::class.java)) } + @RequiresApi(Build.VERSION_CODES.N_MR1) + private fun createShortcuts(requests: List) { + val shortcutManager = getSystemService(ShortcutManager::class.java) + shortcutManager.removeAllDynamicShortcuts() + + val shortcuts: MutableList = mutableListOf() + + val shortcutsCount = if (requests.size >= MAX_DYNAMIC_SHORTCUTS_COUNT) { + MAX_DYNAMIC_SHORTCUTS_COUNT + } else { + requests.size + } + + for (i in 0 until shortcutsCount) { + val request = requests[i] + + val shortcut = ShortcutInfo.Builder(this, request.id.toString()) + .setShortLabel(request.name) + .setLongLabel(request.name) + .setIcon(Icon.createWithResource(this, R.drawable.ic_icons8_raspberry_pi)) + .setIntent( + Intent(this, MainActivity::class.java).apply { + flags = Intent.FLAG_ACTIVITY_CLEAR_TASK + action = Intent.ACTION_VIEW + data = Uri.parse(request.id.toString()) + }) + .build() + + shortcuts.add(shortcut) + } + + shortcutManager!!.dynamicShortcuts = shortcuts + } + /** Open another app. * @param context current Context, like Activity, App, or Service * @param packageName the full package name of the app to open @@ -199,5 +254,6 @@ class MainActivity : AppCompatActivity() { companion object { const val BUTTON_MARGIN_DP = 16f + const val MAX_DYNAMIC_SHORTCUTS_COUNT = 4 } } diff --git a/app/src/main/java/sk/amk/homeberry/main/MainViewModel.kt b/app/src/main/java/sk/amk/homeberry/main/MainViewModel.kt index bc1b4b0..f375e06 100644 --- a/app/src/main/java/sk/amk/homeberry/main/MainViewModel.kt +++ b/app/src/main/java/sk/amk/homeberry/main/MainViewModel.kt @@ -15,6 +15,7 @@ import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import sk.amk.homeberry.HomeberryApp import sk.amk.homeberry.model.HomeberryRequest @@ -46,20 +47,41 @@ class MainViewModel(val app: Application) : AndroidViewModel(app) { lastRunningJob = viewModelScope.launch { withContext(Dispatchers.IO) { - try { - var url = "" + sendRequest(request) + } + } + } - if (!baseUrl.contains("http") && !baseUrl.contains("https")) { - url += "http://" - } + fun callRequest(requestId: Long) { + val request = runBlocking { + withContext(Dispatchers.IO) { + (app as HomeberryApp).db.requestDao().getById(requestId) + } + } + + state.postValue(MainState.RequestInProgress(request)) + lastRunningJob?.cancel() - url += "$baseUrl/${request.endpoint}" - val response = httpClient.get(urlString = url) - state.postValue(MainState.RequestSuccess(response, request)) - } catch (exception: Exception) { - handleEndpointError(exception, request) - } + lastRunningJob = viewModelScope.launch { + withContext(Dispatchers.IO) { + sendRequest(request) + } + } + } + + private suspend fun sendRequest(request: HomeberryRequest) { + try { + var url = "" + + if (!baseUrl.contains("http") && !baseUrl.contains("https")) { + url += "http://" } + + url += "$baseUrl/${request.endpoint}" + val response = httpClient.get(urlString = url) + state.postValue(MainState.RequestSuccess(response, request)) + } catch (exception: Exception) { + handleEndpointError(exception, request) } } From bf383ca9bfaaa8dadd1300b60b7a13df299595d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrej=20Martin=C3=A1k?= Date: Sun, 6 Dec 2020 10:34:49 +0100 Subject: [PATCH 5/7] Increase app version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index a6ec4e6..a195975 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "sk.amk.homeberry" minSdkVersion 21 targetSdkVersion 29 - versionCode 1 - versionName "1.0" + versionCode 2 + versionName "1.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { From e91713d0470104a1666a4b00136e5b21886439da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrej=20Martin=C3=A1k?= Date: Sun, 6 Dec 2020 11:13:36 +0100 Subject: [PATCH 6/7] Use Room with coroutines --- app/build.gradle | 1 + .../homeberry/model/database/RequestDao.kt | 12 ++++----- .../homeberry/settings/SettingsViewModel.kt | 27 ++++++------------- 3 files changed, 15 insertions(+), 25 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index a195975..ef0ee00 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -42,6 +42,7 @@ dependencies { // Room def room_version = "2.2.5" implementation "androidx.room:room-runtime:$room_version" + implementation "androidx.room:room-ktx:$room_version" kapt "androidx.room:room-compiler:$room_version" // Network diff --git a/app/src/main/java/sk/amk/homeberry/model/database/RequestDao.kt b/app/src/main/java/sk/amk/homeberry/model/database/RequestDao.kt index 4580e7d..4fe289b 100644 --- a/app/src/main/java/sk/amk/homeberry/model/database/RequestDao.kt +++ b/app/src/main/java/sk/amk/homeberry/model/database/RequestDao.kt @@ -14,23 +14,23 @@ import sk.amk.homeberry.model.HomeberryRequest @Dao interface RequestDao { @Query("SELECT * FROM homeberryrequest WHERE id = :id") - fun getById(id: Long): HomeberryRequest + suspend fun getById(id: Long): HomeberryRequest @Query("SELECT * FROM homeberryrequest") - fun getAll(): List + suspend fun getAll(): List @Query("SELECT * FROM homeberryrequest") fun getAllLiveData(): LiveData> @Insert(onConflict = OnConflictStrategy.REPLACE) - fun insert(request: HomeberryRequest) + suspend fun insert(request: HomeberryRequest) @Insert(onConflict = OnConflictStrategy.REPLACE) - fun insertAll(requests: List) + suspend fun insertAll(requests: List) @Delete - fun delete(request: HomeberryRequest) + suspend fun delete(request: HomeberryRequest) @Query("DELETE FROM homeberryrequest") - fun deleteAll() + suspend fun deleteAll() } diff --git a/app/src/main/java/sk/amk/homeberry/settings/SettingsViewModel.kt b/app/src/main/java/sk/amk/homeberry/settings/SettingsViewModel.kt index 15760ce..7cb1528 100644 --- a/app/src/main/java/sk/amk/homeberry/settings/SettingsViewModel.kt +++ b/app/src/main/java/sk/amk/homeberry/settings/SettingsViewModel.kt @@ -9,13 +9,10 @@ import com.squareup.moshi.JsonDataException import com.squareup.moshi.JsonEncodingException import com.squareup.moshi.Moshi import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import sk.amk.homeberry.HomeberryApp import sk.amk.homeberry.HomeberryApp.Companion.BASE_URL_KEY import sk.amk.homeberry.HomeberryApp.Companion.DEFAULT_BASE_URL - import sk.amk.homeberry.model.Config import sk.amk.homeberry.model.HomeberryRequest @@ -43,10 +40,8 @@ class SettingsViewModel(val app: Application) : AndroidViewModel(app) { )!! viewModelScope.launch { - withContext(Dispatchers.IO) { - requests = db.requestDao().getAll().toMutableList() - updateUi.postValue(true) - } + requests = db.requestDao().getAll().toMutableList() + updateUi.value = true } } @@ -69,19 +64,15 @@ class SettingsViewModel(val app: Application) : AndroidViewModel(app) { this.requests[index] = request viewModelScope.launch { - withContext(Dispatchers.IO) { - db.requestDao().insert(request) - } + db.requestDao().insert(request) } } fun deleteRequest(request: HomeberryRequest) { viewModelScope.launch { - withContext(Dispatchers.IO) { - db.requestDao().delete(request) - requests.remove(request) - updateUi.postValue(true) - } + db.requestDao().delete(request) + requests.remove(request) + updateUi.value = true } } @@ -98,10 +89,8 @@ class SettingsViewModel(val app: Application) : AndroidViewModel(app) { jsonAdapter.fromJson(configJson)?.run { this@SettingsViewModel.requests = requests.toMutableList() viewModelScope.launch { - withContext(Dispatchers.IO) { - db.requestDao().deleteAll() - db.requestDao().insertAll(requests) - } + db.requestDao().deleteAll() + db.requestDao().insertAll(requests) } updateBaseUrl(this.baseUrl) updateUi.postValue(true) From 34c77a338fce5ca932f2494083e4858638b89020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrej=20Martin=C3=A1k?= Date: Sun, 6 Dec 2020 11:22:48 +0100 Subject: [PATCH 7/7] Clean up the code --- .../sk/amk/homeberry/main/MainActivity.kt | 83 ++++++++++--------- .../sk/amk/homeberry/main/MainViewModel.kt | 15 ++-- .../homeberry/settings/SettingsActivity.kt | 67 ++++++++------- .../homeberry/settings/SettingsViewModel.kt | 2 +- app/src/main/res/layout/activity_main.xml | 1 - 5 files changed, 89 insertions(+), 79 deletions(-) diff --git a/app/src/main/java/sk/amk/homeberry/main/MainActivity.kt b/app/src/main/java/sk/amk/homeberry/main/MainActivity.kt index e4c4e96..b5603a2 100644 --- a/app/src/main/java/sk/amk/homeberry/main/MainActivity.kt +++ b/app/src/main/java/sk/amk/homeberry/main/MainActivity.kt @@ -43,31 +43,8 @@ class MainActivity : AppCompatActivity() { setSupportActionBar(toolbar) title = "" - viewModel.requests.observe(this, { requests -> - txtEmptyState.isVisible = requests.isEmpty() - buttonOpenSettings.isVisible = requests.isEmpty() - - if (requests.isNotEmpty()) { - generateButtons(requests) - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { - createShortcuts(requests) - } - }) - - viewModel.state.observe(this, { state -> - if (state !is MainState.RequestInProgress) { - progressDialog?.dismiss() - } - - when (state) { - is MainState.RequestInProgress -> showProgressDialog(state.request!!) - is MainState.RequestSuccess -> handleSuccess(state.message, state.request!!) - is MainState.RequestFailure -> handleError(state.message, state.request!!) - is MainState.RequestFailureConnection -> showConnectionErrorDialog() - } - }) + viewModel.requests.observe(this, this::observeRequests) + viewModel.state.observe(this, this::observeVmState) buttonOpenSettings.setOnClickListener { openSettings() } } @@ -86,6 +63,47 @@ class MainActivity : AppCompatActivity() { super.onPause() } + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.main, menu) + return true + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + R.id.menu_main_power -> showShutDownDialog() + R.id.menu_main_restart -> showRebootDialog() + R.id.menu_main_settings -> openSettings() + } + + return super.onOptionsItemSelected(item) + } + + private fun observeVmState(state: MainState){ + if (state !is MainState.RequestInProgress) { + progressDialog?.dismiss() + } + + when (state) { + is MainState.RequestInProgress -> showProgressDialog(state.request!!) + is MainState.RequestSuccess -> handleSuccess(state.message, state.request!!) + is MainState.RequestFailure -> handleError(state.message, state.request!!) + is MainState.RequestFailureConnection -> showConnectionErrorDialog() + } + } + + private fun observeRequests(requests: List) { + txtEmptyState.isVisible = requests.isEmpty() + buttonOpenSettings.isVisible = requests.isEmpty() + + if (requests.isNotEmpty()) { + generateButtons(requests) + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { + createShortcuts(requests) + } + } + private fun generateButtons(requests: List) { for (request in requests) { val button = Button(this) @@ -110,21 +128,6 @@ class MainActivity : AppCompatActivity() { ).toInt() } - override fun onCreateOptionsMenu(menu: Menu?): Boolean { - menuInflater.inflate(R.menu.main, menu) - return true - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - when (item.itemId) { - R.id.menu_main_power -> showShutDownDialog() - R.id.menu_main_restart -> showRebootDialog() - R.id.menu_main_settings -> openSettings() - } - - return super.onOptionsItemSelected(item) - } - private fun showRebootDialog() { MaterialDialog(this).show { title(res = R.string.are_you_sure) diff --git a/app/src/main/java/sk/amk/homeberry/main/MainViewModel.kt b/app/src/main/java/sk/amk/homeberry/main/MainViewModel.kt index f375e06..5c43b4d 100644 --- a/app/src/main/java/sk/amk/homeberry/main/MainViewModel.kt +++ b/app/src/main/java/sk/amk/homeberry/main/MainViewModel.kt @@ -26,14 +26,17 @@ import java.net.ConnectException */ class MainViewModel(val app: Application) : AndroidViewModel(app) { - val state: MutableLiveData = MutableLiveData() - - val requests = (app as HomeberryApp).db.requestDao().getAllLiveData() - val baseUrl = (app as HomeberryApp).sharedPreferences.getString( + val baseUrl : String = (app as HomeberryApp).sharedPreferences.getString( HomeberryApp.BASE_URL_KEY, HomeberryApp.DEFAULT_BASE_URL )!! + val state: MutableLiveData = MutableLiveData() + private val db = (app as HomeberryApp).db + + val requests = db.requestDao().getAllLiveData() + private var lastRunningJob: Job? = null + private val httpClient = HttpClient { install(Logging) { logger = Logger.ANDROID @@ -54,9 +57,7 @@ class MainViewModel(val app: Application) : AndroidViewModel(app) { fun callRequest(requestId: Long) { val request = runBlocking { - withContext(Dispatchers.IO) { - (app as HomeberryApp).db.requestDao().getById(requestId) - } + db.requestDao().getById(requestId) } state.postValue(MainState.RequestInProgress(request)) diff --git a/app/src/main/java/sk/amk/homeberry/settings/SettingsActivity.kt b/app/src/main/java/sk/amk/homeberry/settings/SettingsActivity.kt index fd7921c..262b7da 100644 --- a/app/src/main/java/sk/amk/homeberry/settings/SettingsActivity.kt +++ b/app/src/main/java/sk/amk/homeberry/settings/SettingsActivity.kt @@ -9,10 +9,12 @@ import android.view.View import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.core.widget.addTextChangedListener -import androidx.lifecycle.Observer import com.afollestad.materialdialogs.MaterialDialog -import kotlinx.android.synthetic.main.activity_settings.* -import kotlinx.android.synthetic.main.content_settings.* +import kotlinx.android.synthetic.main.activity_settings.fab +import kotlinx.android.synthetic.main.activity_settings.toolbar +import kotlinx.android.synthetic.main.content_settings.editTextBaseUrl +import kotlinx.android.synthetic.main.content_settings.layoutEndpointsContainer +import kotlinx.android.synthetic.main.content_settings.scrollViewSettings import sk.amk.homeberry.R import sk.amk.homeberry.model.HomeberryRequest @@ -27,38 +29,15 @@ class SettingsActivity : AppCompatActivity() { setTitle(R.string.settings_title) supportActionBar?.setDisplayHomeAsUpEnabled(true) - viewModel.updateUi.observe(this, Observer { - layoutEndpointsContainer.removeAllViews() - viewModel.requests.forEach { - layoutEndpointsContainer.addView( - SettingsRequestView.create(this, viewModel, it) - ) - } - editTextBaseUrl.setText(viewModel.baseUrl.value) - }) - - viewModel.errorState.observe(this, Observer { state -> - when (state) { - SettingsErrorSate.ERROR_IMPORT_INVALID_JSON -> showInvalidJsonFileErrorDialog() - SettingsErrorSate.ERROR_IMPORT_INVALID_CONFIG -> showInvalidConfigErrorDialog() - } - }) + viewModel.updateUi.observe(this, this::observeUiUpdate) + viewModel.errorState.observe(this, this::observeErrorState) editTextBaseUrl.setText(viewModel.baseUrl.value) editTextBaseUrl.addTextChangedListener { viewModel.updateBaseUrl(it.toString()) } - fab.setOnClickListener { - val request = HomeberryRequest() - viewModel.createNewRequest(request) - layoutEndpointsContainer.addView( - SettingsRequestView.create(this, viewModel, request) - ) - scrollViewSettings.post { - scrollViewSettings.fullScroll(View.FOCUS_DOWN) - } - } + fab.setOnClickListener { createNewRequest() } } override fun onCreateOptionsMenu(menu: Menu?): Boolean { @@ -79,7 +58,7 @@ class SettingsActivity : AppCompatActivity() { if (requestCode == REQUEST_FILE_PICKER && resultCode == Activity.RESULT_OK) { data?.data?.also { uri -> val content = contentResolver.openInputStream(uri) - ?.bufferedReader().use { it?.readText() } + ?.bufferedReader().use { it?.readText() } if (content == null) { showInvalidJsonFileErrorDialog() } else { @@ -91,6 +70,34 @@ class SettingsActivity : AppCompatActivity() { } } + private fun observeUiUpdate(update: Boolean){ + layoutEndpointsContainer.removeAllViews() + viewModel.requests.forEach { + layoutEndpointsContainer.addView( + SettingsRequestView.create(this, viewModel, it) + ) + } + editTextBaseUrl.setText(viewModel.baseUrl.value) + } + + private fun observeErrorState(state: SettingsErrorSate) { + when (state) { + SettingsErrorSate.ERROR_IMPORT_INVALID_JSON -> showInvalidJsonFileErrorDialog() + SettingsErrorSate.ERROR_IMPORT_INVALID_CONFIG -> showInvalidConfigErrorDialog() + } + } + + private fun createNewRequest() { + val request = HomeberryRequest() + viewModel.createNewRequest(request) + layoutEndpointsContainer.addView( + SettingsRequestView.create(this, viewModel, request) + ) + scrollViewSettings.post { + scrollViewSettings.fullScroll(View.FOCUS_DOWN) + } + } + private fun exportSettings() { val uri = ConfigFileProvider.createFileUri(this, viewModel.createConfigJson()) diff --git a/app/src/main/java/sk/amk/homeberry/settings/SettingsViewModel.kt b/app/src/main/java/sk/amk/homeberry/settings/SettingsViewModel.kt index 7cb1528..5433d1d 100644 --- a/app/src/main/java/sk/amk/homeberry/settings/SettingsViewModel.kt +++ b/app/src/main/java/sk/amk/homeberry/settings/SettingsViewModel.kt @@ -93,7 +93,7 @@ class SettingsViewModel(val app: Application) : AndroidViewModel(app) { db.requestDao().insertAll(requests) } updateBaseUrl(this.baseUrl) - updateUi.postValue(true) + updateUi.value = true } } catch (invalidConfigException: JsonDataException) { errorState.value = SettingsErrorSate.ERROR_IMPORT_INVALID_CONFIG diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 2140b16..d2257cc 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -62,7 +62,6 @@ android:layout_marginLeft="32dp" android:layout_marginTop="16dp" android:layout_marginRight="32dp" - android:fontFamily="@font/font_awesome_5_brands" android:text="@string/main_empty_state_button" />