diff --git a/app/src/main/java/com/aurora/store/view/ui/preferences/NetworkPreference.kt b/app/src/main/java/com/aurora/store/view/ui/preferences/NetworkPreference.kt index bd851b0f3..fa06c70d9 100644 --- a/app/src/main/java/com/aurora/store/view/ui/preferences/NetworkPreference.kt +++ b/app/src/main/java/com/aurora/store/view/ui/preferences/NetworkPreference.kt @@ -20,38 +20,29 @@ package com.aurora.store.view.ui.preferences import android.os.Bundle -import android.util.Log import android.view.View import androidx.appcompat.widget.Toolbar +import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import androidx.preference.EditTextPreference import androidx.preference.Preference import androidx.preference.SwitchPreferenceCompat -import com.aurora.Constants import com.aurora.extensions.runOnUiThread import com.aurora.extensions.toast import com.aurora.store.R -import com.aurora.store.data.network.HttpClient import com.aurora.store.util.CommonUtil import com.aurora.store.util.Preferences import com.aurora.store.util.save -import com.google.gson.Gson import dagger.hilt.android.AndroidEntryPoint -import javax.inject.Inject -import kotlinx.coroutines.DelicateCoroutinesApi -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.flow.filter import kotlinx.coroutines.launch @AndroidEntryPoint class NetworkPreference : BasePreferenceFragment() { - @Inject - lateinit var gson: Gson + private val viewModel: SettingsViewModel by viewModels() - private val TAG = NetworkPreference::class.java.simpleName - - @OptIn(DelicateCoroutinesApi::class) override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.preferences_network, rootKey) @@ -64,39 +55,11 @@ class NetworkPreference : BasePreferenceFragment() { val newProxyInfo = CommonUtil.parseProxyUrl(newProxyUrl) if (newProxyInfo == null) { - runOnUiThread { - requireContext().toast(getString(R.string.toast_proxy_invalid)) - } - false + requireContext().toast(getString(R.string.toast_proxy_invalid)) } else { - GlobalScope.launch(Dispatchers.IO) { - try { - val result = HttpClient - .getPreferredClient(requireContext()) - .setProxy(newProxyInfo) - .get(Constants.ANDROID_CONNECTIVITY_URL, mapOf()) - - if (result.code == 204) { - save(Preferences.PREFERENCE_PROXY_URL, newProxyUrl) - save(Preferences.PREFERENCE_PROXY_INFO, gson.toJson(newProxyInfo)) - - runOnUiThread { - requireContext().toast(getString(R.string.toast_proxy_success)) - } - - it.summary = newProxyUrl - } else { - throw Exception("Failed to set proxy") - } - } catch (exception: Exception) { - Log.e(TAG, "Failed to set proxy", exception) - runOnUiThread { - requireContext().toast(getText(R.string.toast_proxy_failed)) - } - } - } - true + viewModel.saveProxyDetails(newProxyUrl, newProxyInfo) } + false } } @@ -126,5 +89,23 @@ class NetworkPreference : BasePreferenceFragment() { title = getString(R.string.pref_network_title) setNavigationOnClickListener { findNavController().navigateUp() } } + + viewLifecycleOwner.lifecycleScope.launch { + viewModel.proxyURL.filter { it.isNotBlank() }.collect { pURL -> + findPreference(Preferences.PREFERENCE_PROXY_URL)?.let { + it.summary = pURL + } + } + } + + viewLifecycleOwner.lifecycleScope.launch { + viewModel.proxyInfo.collect { + if (it == null) { + requireContext().toast(getText(R.string.toast_proxy_failed)) + } else { + requireContext().toast(getString(R.string.toast_proxy_success)) + } + } + } } } diff --git a/app/src/main/java/com/aurora/store/view/ui/preferences/SettingsViewModel.kt b/app/src/main/java/com/aurora/store/view/ui/preferences/SettingsViewModel.kt new file mode 100644 index 000000000..bb85119a3 --- /dev/null +++ b/app/src/main/java/com/aurora/store/view/ui/preferences/SettingsViewModel.kt @@ -0,0 +1,63 @@ +package com.aurora.store.view.ui.preferences + +import android.annotation.SuppressLint +import android.content.Context +import android.util.Log +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.aurora.Constants +import com.aurora.store.data.model.ProxyInfo +import com.aurora.store.data.network.HttpClient +import com.aurora.store.util.Preferences.PREFERENCE_PROXY_INFO +import com.aurora.store.util.Preferences.PREFERENCE_PROXY_URL +import com.aurora.store.util.save +import com.google.gson.Gson +import dagger.hilt.android.lifecycle.HiltViewModel +import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch + +@HiltViewModel +@SuppressLint("StaticFieldLeak") // false positive, see https://github.com/google/dagger/issues/3253 +class SettingsViewModel @Inject constructor( + private val gson: Gson, + @ApplicationContext private val context: Context +): ViewModel() { + + private val TAG = SettingsViewModel::class.java.simpleName + + private val _proxyURL = MutableStateFlow(String()) + val proxyURL = _proxyURL.asStateFlow() + + private val _proxyInfo = MutableSharedFlow() + val proxyInfo = _proxyInfo.asSharedFlow() + + fun saveProxyDetails(url: String, info: ProxyInfo) { + viewModelScope.launch(Dispatchers.IO) { + try { + val result = HttpClient + .getPreferredClient(context) + .setProxy(info) + .get(Constants.ANDROID_CONNECTIVITY_URL, mapOf()) + + if (result.code == 204) { + context.save(PREFERENCE_PROXY_URL, url) + _proxyURL.value = url + + context.save(PREFERENCE_PROXY_INFO, gson.toJson(info)) + _proxyInfo.emit(info) + } else { + throw Exception("Failed to set proxy") + } + } catch (exception: Exception) { + Log.e(TAG, "Failed to set proxy", exception) + _proxyInfo.emit(null) + } + } + } +}