diff --git a/app/src/main/kotlin/io/treehouses/remote/bases/FragmentViewModel.kt b/app/src/main/kotlin/io/treehouses/remote/bases/FragmentViewModel.kt index 7b1c2830b..62fda3ece 100644 --- a/app/src/main/kotlin/io/treehouses/remote/bases/FragmentViewModel.kt +++ b/app/src/main/kotlin/io/treehouses/remote/bases/FragmentViewModel.kt @@ -96,12 +96,14 @@ open class FragmentViewModel(application: Application) : AndroidViewModel(applic /** * @param toSend : String = A string to send to the Raspberry Pi */ - fun sendMessage(toSend: String) { - lastCommand = toSend + fun sendMessage(toSend: String?) { + if (toSend != null) { + lastCommand = toSend + } if (_connectionStatus.value != Constants.STATE_CONNECTED) { Toast.makeText(getApplication(), "Not Connected to Bluetooth", Toast.LENGTH_LONG).show() } - else mChatService.write(toSend.toByteArray()) + else mChatService.write(toSend?.toByteArray()) } /** diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/home/BaseHomeFragment.kt b/app/src/main/kotlin/io/treehouses/remote/ui/home/BaseHomeFragment.kt index 3e7e8b0ec..689d19291 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/home/BaseHomeFragment.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/home/BaseHomeFragment.kt @@ -74,29 +74,33 @@ open class BaseHomeFragment : BaseFragment() { * - last time dialog was shows (only show after a week) * @param preferences : SharedPreferences = Preferences to save the user preferences to */ - protected fun showLogDialog(preferences: SharedPreferences) { - val connectionCount = preferences.getInt("connection_count", 0) - val lastDialogShown = preferences.getLong("last_dialog_shown", 0) + protected fun showLogDialog(preferences: SharedPreferences?) { + val connectionCount = preferences?.getInt("connection_count", 0) + val lastDialogShown = preferences?.getLong("last_dialog_shown", 0) val date = Calendar.getInstance() date.add(Calendar.DAY_OF_YEAR, -7) val v = layoutInflater.inflate(R.layout.alert_log, null) val emoji = String(Character.toChars(0x1F60A)) - if (lastDialogShown < date.timeInMillis && !preferences.getBoolean("send_log", false)) { - if (connectionCount >= 3) { - preferences.edit().putLong("last_dialog_shown", Calendar.getInstance().timeInMillis).apply() - val builder = DialogUtils.createAlertDialog(activity, - "Sharing is Caring $emoji", - "Treehouses wants to collect your activities. Do you like to share it? It will help us to improve.", v) - .setCancelable(false) - DialogUtils.createAdvancedDialog(builder, Pair("Continue", "Cancel"), { - if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { - ActivityCompat.requestPermissions(requireActivity(), arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION), - REQUEST_LOCATION_PERMISSION_FOR_ACTIVITY_COLLECTION - ) - } else { - preferences.edit()?.putBoolean("send_log", true)?.apply() + if (lastDialogShown != null) { + if (lastDialogShown < date.timeInMillis && !preferences.getBoolean("send_log", false)) { + if (connectionCount != null) { + if (connectionCount >= 3) { + preferences.edit().putLong("last_dialog_shown", Calendar.getInstance().timeInMillis).apply() + val builder = DialogUtils.createAlertDialog(activity, + "Sharing is Caring $emoji", + "Treehouses wants to collect your activities. Do you like to share it? It will help us to improve.", v) + .setCancelable(false) + DialogUtils.createAdvancedDialog(builder, Pair("Continue", "Cancel"), { + if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(requireActivity(), arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION), + REQUEST_LOCATION_PERMISSION_FOR_ACTIVITY_COLLECTION + ) + } else { + preferences.edit()?.putBoolean("send_log", true)?.apply() + } + }, { MainApplication.showLogDialog = false }) } - }, { MainApplication.showLogDialog = false }) + } } } } @@ -119,37 +123,41 @@ open class BaseHomeFragment : BaseFragment() { * - Should show at the same time as the sharing data dialog * @param preferences : SharedPreferences = preferences to save user preferences to */ - protected fun rate(preferences: SharedPreferences) { - val connectionCount = preferences.getInt("connection_count", 0) - val ratingDialog = preferences.getBoolean("ratingDialog", true) - val lastDialogShown = preferences.getLong("last_dialog_shown", 0) + protected fun rate(preferences: SharedPreferences?) { + val connectionCount = preferences?.getInt("connection_count", 0) + val ratingDialog = preferences?.getBoolean("ratingDialog", true) + val lastDialogShown = preferences?.getLong("last_dialog_shown", 0) val date = Calendar.getInstance() - if (lastDialogShown < date.timeInMillis) { - if (connectionCount >= 3 && ratingDialog) { - val a = DialogUtils.createAlertDialog(activity,"Thank You").setCancelable(false).setMessage("We're so happy to hear that you love the Treehouses app! " + - "It'd be really helpful if you rated us. Thanks so much for spending some time with us.") - .setPositiveButton("RATE IT NOW") { _: DialogInterface?, _: Int -> - val intent = Intent(Intent.ACTION_VIEW) - intent.data = Uri.parse("https://play.google.com/store/apps/details?id=io.treehouses.remote") - startActivity(intent) - preferences.edit().putBoolean("ratingDialog", false).apply() - }.setNeutralButton("REMIND ME LATER") { _: DialogInterface?, _: Int -> MainApplication.ratingDialog = false } - .setNegativeButton("NO THANKS") { _: DialogInterface?, _: Int -> preferences.edit().putBoolean("ratingDialog", false).apply() }.create() - a.window!!.setBackgroundDrawableResource(android.R.color.transparent) - a.show() + if (lastDialogShown != null) { + if (lastDialogShown < date.timeInMillis) { + if (connectionCount != null) { + if (connectionCount >= 3 && ratingDialog == true) { + val a = DialogUtils.createAlertDialog(activity,"Thank You").setCancelable(false).setMessage("We're so happy to hear that you love the Treehouses app! " + + "It'd be really helpful if you rated us. Thanks so much for spending some time with us.") + .setPositiveButton("RATE IT NOW") { _: DialogInterface?, _: Int -> + val intent = Intent(Intent.ACTION_VIEW) + intent.data = Uri.parse("https://play.google.com/store/apps/details?id=io.treehouses.remote") + startActivity(intent) + preferences.edit().putBoolean("ratingDialog", false).apply() + }.setNeutralButton("REMIND ME LATER") { _: DialogInterface?, _: Int -> MainApplication.ratingDialog = false } + .setNegativeButton("NO THANKS") { _: DialogInterface?, _: Int -> preferences.edit().putBoolean("ratingDialog", false).apply() }.create() + a.window?.setBackgroundDrawableResource(android.R.color.transparent) + a.show() + } + } } } } - protected fun showDialogOnce(preferences: SharedPreferences) { - val firstTime = preferences.getBoolean(Screens.FIRST_TIME.name, true) - if (firstTime) { + protected fun showDialogOnce(preferences: SharedPreferences?) { + val firstTime = preferences?.getBoolean(Screens.FIRST_TIME.name, true) + if (firstTime == true) { // showWelcomeDialog() val i = Intent(activity, IntroActivity::class.java) startActivity(i) val editor = preferences.edit() - editor.putBoolean(Screens.FIRST_TIME.name, false) - editor.apply() + editor?.putBoolean(Screens.FIRST_TIME.name, false) + editor?.apply() } } @@ -173,7 +181,7 @@ open class BaseHomeFragment : BaseFragment() { animationDrawableGreen.start() animationDrawableRed.start() val a = createTestConnectionDialog(mView, dismissable, title, messageID) - a.window!!.setBackgroundDrawableResource(android.R.color.transparent) + a.window?.setBackgroundDrawableResource(android.R.color.transparent) a.show() return a } @@ -199,7 +207,7 @@ open class BaseHomeFragment : BaseFragment() { } .setNegativeButton("Upgrade Later") { dialog: DialogInterface, _: Int -> dialog.dismiss() } .create() - alertDialog.window!!.setBackgroundDrawableResource(android.R.color.transparent) + alertDialog.window?.setBackgroundDrawableResource(android.R.color.transparent) alertDialog.show() } @@ -212,7 +220,7 @@ open class BaseHomeFragment : BaseFragment() { val inputStream = context?.assets?.open("bluetooth-server.txt") val localString = inputStream?.bufferedReader().use { it?.readText() } inputStream?.close() - val hashed = Utils.hashString(localString!!) + val hashed = localString?.let { Utils.hashString(it) } //Bluetooth file is outdated, but RPI is connected to the internet if (Matcher.isError(serverHash) && viewModel.internetStatus.value == true) { askForBluetoothUpgradeOverInternet() @@ -222,8 +230,10 @@ open class BaseHomeFragment : BaseFragment() { noInternetForBluetoothUpgrade() } //If there is no error, compare the server hashes to determine whether an upgrade is needed - else if (hashed.trim() != serverHash.trim() && PreferenceManager.getDefaultSharedPreferences(requireContext()).getBoolean("bluetooth_file_local_upgrade", false)) { - askForBluetoothUpgradeStable(localString) + else if (hashed?.trim() != serverHash.trim() && PreferenceManager.getDefaultSharedPreferences(requireContext()).getBoolean("bluetooth_file_local_upgrade", false)) { + if (localString != null) { + askForBluetoothUpgradeStable(localString) + } } } @@ -238,7 +248,7 @@ open class BaseHomeFragment : BaseFragment() { .setPositiveButton("Ok") { d, _ -> d.dismiss() }.create() - dialog.window!!.setBackgroundDrawableResource(android.R.color.transparent) + dialog.window?.setBackgroundDrawableResource(android.R.color.transparent) dialog.show() } @@ -252,7 +262,7 @@ open class BaseHomeFragment : BaseFragment() { viewModel.sendMessage(getString(R.string.TREEHOUSES_UPGRADE_BLUETOOTH_MASTER)) } .setNegativeButton("Cancel") {dialog, _ -> dialog.dismiss()}.create() - dialog.window!!.setBackgroundDrawableResource(android.R.color.transparent) + dialog.window?.setBackgroundDrawableResource(android.R.color.transparent) dialog.show() } @@ -270,7 +280,7 @@ open class BaseHomeFragment : BaseFragment() { }.setNegativeButton("Cancel") { dialog: DialogInterface, _: Int -> dialog.dismiss() }.create() - dialog.window!!.setBackgroundDrawableResource(android.R.color.transparent) + dialog.window?.setBackgroundDrawableResource(android.R.color.transparent) dialog.show() } @@ -289,7 +299,7 @@ open class BaseHomeFragment : BaseFragment() { startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=$appPackageName"))) } }.create() - alertDialog.window!!.setBackgroundDrawableResource(android.R.color.transparent) + alertDialog.window?.setBackgroundDrawableResource(android.R.color.transparent) alertDialog.show() } diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/home/HomeFragment.kt b/app/src/main/kotlin/io/treehouses/remote/ui/home/HomeFragment.kt index 2b70492cd..f825c01a8 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/home/HomeFragment.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/home/HomeFragment.kt @@ -59,7 +59,7 @@ class HomeFragment : BaseHomeFragment() { bind = ActivityHomeFragmentBinding.inflate(inflater, container, false) preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) setupProfiles() - showDialogOnce(preferences!!) + showDialogOnce(preferences) connectRpiListener() testConnectionListener() return bind.root @@ -68,8 +68,8 @@ class HomeFragment : BaseHomeFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { observeConnectionState() bind.btnGetStarted.setOnClickListener { - instance!!.checkStatusNow() - if (instance!!.hasValidConnection()) { + instance?.checkStatusNow() + if (instance?.hasValidConnection() == true) { switchFragment(TerminalFragment(), "Terminal") } else { switchFragment(AboutFragment(), "About") @@ -135,7 +135,7 @@ class HomeFragment : BaseHomeFragment() { viewModel.networkProfileResult.observe(viewLifecycleOwner, Observer { when(it.status) { Status.SUCCESS, Status.ERROR, Status.NOTHING -> { - if (progressDialog != null) progressDialog!!.dismiss() + if (progressDialog != null) progressDialog?.dismiss() if (it.message.isNotEmpty()) context.toast(it.message) } Status.LOADING -> { @@ -154,7 +154,7 @@ class HomeFragment : BaseHomeFragment() { * Switches fragment (To go to Terminal, or about for example) */ private fun switchFragment(fragment: Fragment, title: String) { - instance!!.openCallFragment(fragment) + instance?.openCallFragment(fragment) activity?.let { it.title = title} } @@ -168,9 +168,9 @@ class HomeFragment : BaseHomeFragment() { if (groupPosition == 3) { viewModel.sendMessage(getString(R.string.TREEHOUSES_DEFAULT_NETWORK)) context.toast("Switched to Default Network", Toast.LENGTH_LONG) - } else if (SaveUtils.getProfiles(requireContext()).size > 0 && SaveUtils.getProfiles(requireContext())[listOf(*group_labels)[groupPosition]]!!.isNotEmpty()) { - if (SaveUtils.getProfiles(requireContext())[listOf(*group_labels)[groupPosition]]!!.size <= childPosition) return@setOnChildClickListener false - viewModel.networkProfile = SaveUtils.getProfiles(requireContext())[listOf(*group_labels)[groupPosition]]!![childPosition] + } else if (SaveUtils.getProfiles(requireContext()).size > 0 && SaveUtils.getProfiles(requireContext())[listOf(*group_labels)[groupPosition]]?.isNotEmpty() == true) { + if ((SaveUtils.getProfiles(requireContext())[listOf(*group_labels)[groupPosition]]?.size ?: 0) <= childPosition) return@setOnChildClickListener false + viewModel.networkProfile = SaveUtils.getProfiles(requireContext())[listOf(*group_labels)[groupPosition]]?.get(childPosition) viewModel.sendMessage(getString(R.string.TREEHOUSES_DEFAULT_NETWORK)) requireContext().toast("Configuring...", Toast.LENGTH_LONG) } @@ -186,8 +186,8 @@ class HomeFragment : BaseHomeFragment() { override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) if (MainApplication.showLogDialog) { - rate(preferences!!) - showLogDialog(preferences!!) + rate(preferences) + showLogDialog(preferences) } activity?.invalidateOptionsMenu() } @@ -203,7 +203,7 @@ class HomeFragment : BaseHomeFragment() { else vibe.vibrate(10) } if (viewModel.connectionStatus.value == Constants.STATE_CONNECTED) { - RPIDialogFragment.instance!!.bluetoothCheck("unregister") + RPIDialogFragment.instance?.bluetoothCheck("unregister") viewModel.disconnectBT() return@setOnClickListener } @@ -228,7 +228,7 @@ class HomeFragment : BaseHomeFragment() { viewModel.selectedLed = options.indexOf(preference) viewModel.sendMessage(optionsCode[viewModel.selectedLed]) testConnectionDialog = showTestConnectionDialog(false, "Testing Connection...", R.string.test_connection_message, viewModel.selectedLed) - testConnectionDialog?.window!!.setBackgroundDrawableResource(android.R.color.transparent) + testConnectionDialog?.window?.setBackgroundDrawableResource(android.R.color.transparent) testConnectionDialog?.show() viewModel.testConnectionResult.value = Resource.loading() } @@ -246,7 +246,7 @@ class HomeFragment : BaseHomeFragment() { connectionDialog?.dismiss() when (connected) { Constants.STATE_CONNECTED -> { - showLogDialog(preferences!!) + showLogDialog(preferences) viewModel.internetSent = true viewModel.sendMessage(getString(R.string.TREEHOUSES_INTERNET)) Tutorials.homeTutorials(bind, requireActivity()) @@ -297,7 +297,7 @@ class HomeFragment : BaseHomeFragment() { */ private fun dismissTestConnection() { if (testConnectionDialog != null) { - testConnectionDialog!!.cancel() + testConnectionDialog?.cancel() showTestConnectionDialog(true, "Process Finished", R.string.test_finished, viewModel.selectedLed) } } diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/home/HomeViewModel.kt b/app/src/main/kotlin/io/treehouses/remote/ui/home/HomeViewModel.kt index 1d73a4ab1..06d5a3e5d 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/home/HomeViewModel.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/home/HomeViewModel.kt @@ -197,7 +197,7 @@ class HomeViewModel(application: Application) : FragmentViewModel(application) { */ private fun sendLog(deviceName: String, readMessage: List) { val preferences = PreferenceManager.getDefaultSharedPreferences(getApplication()) - val connectionCount = preferences!!.getInt("connection_count", 0) + val connectionCount = preferences.getInt("connection_count", 0) val sendLog = preferences.getBoolean("send_log", true) preferences.edit().putInt("connection_count", connectionCount + 1).apply() if (connectionCount >= 3 && sendLog) { diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/network/BaseNetworkViewModel.kt b/app/src/main/kotlin/io/treehouses/remote/ui/network/BaseNetworkViewModel.kt index 59f263c1e..7625c8823 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/network/BaseNetworkViewModel.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/network/BaseNetworkViewModel.kt @@ -23,8 +23,7 @@ open class BaseNetworkViewModel(application: Application) : FragmentViewModel(ap } fun bridgeSetAddProfileListener(stringMap: Map) { - val networkProfile = NetworkProfile(stringMap.getValue("etEssid"), stringMap.getValue("etHotspotEssid"), - stringMap.getValue("etPassword"), stringMap.getValue("etHotspotPassword")) + val networkProfile = NetworkProfile(stringMap.getValue("etEssid"), stringMap.getValue("etHotspotEssid"), stringMap.getValue("etPassword"), stringMap.getValue("etHotspotPassword")) SaveUtils.addProfile(context, networkProfile) Toast.makeText(context, "Bridge Profile Added", Toast.LENGTH_LONG).show() } @@ -33,26 +32,22 @@ open class BaseNetworkViewModel(application: Application) : FragmentViewModel(ap sendMessage(getString(R.string.TREEHOUSES_ETHERNET, ip, mask, gateway, dns)) } - fun hotspotStartConfigListener(etHotspotSsid: String, etHotspotPassword: String, - checkBoxHiddenHotspot: Boolean, spnHotspotType: String) { - if (checkBoxHiddenHotspot) sendHotspotMessage(R.string.TREEHOUSES_AP_HIDDEN, spnHotspotType, - etHotspotSsid, etHotspotPassword) - else sendHotspotMessage(R.string.TREEHOUSES_AP, spnHotspotType, etHotspotSsid, etHotspotPassword) + fun hotspotStartConfigListener(etHotspotSsid: String, etHotspotPassword: String, checkBoxHiddenHotspot: Boolean, spnHotspotType: String) { + if (checkBoxHiddenHotspot) { + sendHotspotMessage(R.string.TREEHOUSES_AP_HIDDEN, spnHotspotType, etHotspotSsid, etHotspotPassword) + } else { + sendHotspotMessage(R.string.TREEHOUSES_AP, spnHotspotType, etHotspotSsid, etHotspotPassword) + } Toast.makeText(context, "Connecting...", Toast.LENGTH_LONG).show() } private fun sendHotspotMessage(command : Int, spnHotspotType: String, etHotspotSsid: String, etHotspotPassword: String) { showNetworkProgress.value = true - sendMessage(getString(command, spnHotspotType, - etHotspotSsid, etHotspotPassword)) - + sendMessage(getString(command, spnHotspotType, etHotspotSsid, etHotspotPassword)) } - fun hotspotSetAddProfileListener(checkBoxHiddenHotspot: Boolean, spnHotspotType: String, - etHotspotSsid: String, etHotspotPassword: String) { - SaveUtils.addProfile(context, - NetworkProfile(etHotspotSsid, etHotspotPassword, - spnHotspotType, checkBoxHiddenHotspot)) + fun hotspotSetAddProfileListener(checkBoxHiddenHotspot: Boolean, spnHotspotType: String, etHotspotSsid: String, etHotspotPassword: String) { + SaveUtils.addProfile(context, NetworkProfile(etHotspotSsid, etHotspotPassword, spnHotspotType, checkBoxHiddenHotspot)) Toast.makeText(context, "Hotspot Profile Saved", Toast.LENGTH_LONG).show() } @@ -73,8 +68,7 @@ open class BaseNetworkViewModel(application: Application) : FragmentViewModel(ap } fun wifiSetAddProfileListener(editTextSSID: String, wifipassword: String, checkBoxHiddenWifi: Boolean) { - SaveUtils.addProfile(context, NetworkProfile(editTextSSID, - wifipassword, checkBoxHiddenWifi)) + SaveUtils.addProfile(context, NetworkProfile(editTextSSID, wifipassword, checkBoxHiddenWifi)) Toast.makeText(context, "WiFi Profile Saved", Toast.LENGTH_LONG).show() } diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/network/NetworkFragment.kt b/app/src/main/kotlin/io/treehouses/remote/ui/network/NetworkFragment.kt index ec1cceffc..4c209dfe2 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/network/NetworkFragment.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/network/NetworkFragment.kt @@ -37,7 +37,7 @@ open class NetworkFragment : BaseFragment(), View.OnClickListener, FragmentDialo private lateinit var speedDialogTest: Button private var speedDialogCheck: Boolean = false protected val viewModel: NetworkViewModel by viewModels(ownerProducer = { this }) - lateinit var dialogSpeedtestBinding: DialogSpeedtestBinding + private lateinit var dialogSpeedtestBinding: DialogSpeedtestBinding override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { binding = ActivityNetworkFragmentBinding.inflate(inflater, container, false) loadObservers() @@ -108,7 +108,7 @@ open class NetworkFragment : BaseFragment(), View.OnClickListener, FragmentDialo viewModel.rebootHelper() dialog.dismiss() }.setNegativeButton("No") { dialog: DialogInterface, _: Int -> dialog.dismiss() }.create() - a.window!!.setBackgroundDrawableResource(android.R.color.transparent) + a.window?.setBackgroundDrawableResource(android.R.color.transparent) a.show() } @@ -118,12 +118,12 @@ open class NetworkFragment : BaseFragment(), View.OnClickListener, FragmentDialo .setPositiveButton("Yes") { _: DialogInterface?, _: Int -> viewModel.resetNetwork() }.setNegativeButton("No") { dialog: DialogInterface, _: Int -> dialog.dismiss() }.create() - a.window!!.setBackgroundDrawableResource(android.R.color.transparent) + a.window?.setBackgroundDrawableResource(android.R.color.transparent) a.show() } private fun speedTest(){ - speedDialog.window!!.setBackgroundDrawableResource(android.R.color.transparent) + speedDialog.window?.setBackgroundDrawableResource(android.R.color.transparent) speedDialog.show() if(!speedDialogCheck){ viewModel.treehousesInternet() diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/network/NetworkViewModel.kt b/app/src/main/kotlin/io/treehouses/remote/ui/network/NetworkViewModel.kt index c51d4cba6..15b691a8b 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/network/NetworkViewModel.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/network/NetworkViewModel.kt @@ -32,7 +32,7 @@ class NetworkViewModel(application: Application) : BaseNetworkViewModel(applicat private fun showIpAddress(output: String) { var ip = output.substringAfter("ip: ").substringBefore(", has") if (ip == "") ip = "N/A" - ipAddress.value = "IP Address: " + ip + ipAddress.value = "IP Address: $ip" } fun rebootHelper() { @@ -90,19 +90,6 @@ class NetworkViewModel(application: Application) : BaseNetworkViewModel(applicat sendMessage(msg) } -// fun showRemoteReverse(output: String){ -// val reverseData = Gson().fromJson(output, ReverseData::class.java) -// val ip = "ip: " + reverseData.ip -// val postal = "postal: " + reverseData.postal -// val city = "city: " + reverseData.city -// val country = "country: " + reverseData.country -// val org = "org: " + reverseData.org -// val timezone = "timezone: " + reverseData.timezone -// reverseText.value = ip + "\n" + org + "\n" + country + "\n" + city + "\n" + postal + "\n" + timezone -// -//// reverseText.value = output -// } - override fun onError(output: String) { super.onError(output) downloadUpload.value = "Speed Test Failed" @@ -114,7 +101,7 @@ class NetworkViewModel(application: Application) : BaseNetworkViewModel(applicat sendMessage("treehouses internet") } - fun updateInternet(output: String){ + private fun updateInternet(output: String){ if (output.contains("true")) { downloadUpload.value = "Internet check passed. Performing speed test......" sendMessage("treehouses speedtest") @@ -123,21 +110,20 @@ class NetworkViewModel(application: Application) : BaseNetworkViewModel(applicat } } - fun updateSpeed(output: String){ + private fun updateSpeed(output: String){ if (output.contains("Download:") && output.contains("Upload:")){ downloadUpload.value = getSubString("Download:", output) - downloadUpload.value += "\n" + getSubString("Upload", output) + downloadUpload.value += "\n ${getSubString("Upload", output)}" } else if (output.contains("Download:")){ downloadUpload.value = getSubString("Download:", output) } else { - downloadUpload.value += "\n" + getSubString("Upload", output) + downloadUpload.value += "\n ${getSubString("Upload", output)}" } } - fun getSubString(stringStart: String, output: String) : String { + private fun getSubString(stringStart: String, output: String) : String { val startIndex = output.indexOf(stringStart) val endIndex = output.indexOf("/s", startIndex) return output.substring(startIndex, endIndex + 2) } - } \ No newline at end of file diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/BridgeBottomSheet.kt b/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/BridgeBottomSheet.kt index 2dc9915d4..6fb1a74f0 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/BridgeBottomSheet.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/BridgeBottomSheet.kt @@ -16,7 +16,7 @@ import io.treehouses.remote.fragments.dialogfragments.WifiDialogFragment import io.treehouses.remote.ui.network.NetworkFragment.Companion.openWifiDialog import io.treehouses.remote.ui.network.NetworkViewModel -class BridgeBottomSheet : BaseBottomSheetDialog() { +open class BridgeBottomSheet : BaseBottomSheetDialog() { protected val viewModel: NetworkViewModel by viewModels(ownerProducer = { requireParentFragment() }) private lateinit var bind: DialogBridgeBinding override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { @@ -46,8 +46,9 @@ class BridgeBottomSheet : BaseBottomSheetDialog() { } private fun getValuesMap(): Map { - return mapOf("etEssid" to bind.etEssid.text.toString(), "etHotspotEssid" to bind.etHotspotEssid.text.toString(), - "etPassword" to bind.etPassword.text.toString(), "etHotspotPassword" to bind.etHotspotPassword.text.toString()) + return mapOf("etEssid" to "${bind.etEssid.text}", "etHotspotEssid" to "${bind.etHotspotEssid.text}", + "etPassword" to "${bind.etPassword.text}", "etHotspotPassword" to "${bind.etHotspotPassword.text}" + ) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { @@ -55,7 +56,7 @@ class BridgeBottomSheet : BaseBottomSheetDialog() { return } if (requestCode == Constants.REQUEST_DIALOG_WIFI) { - val ssid = data!!.getStringExtra(WifiDialogFragment.WIFI_SSID_KEY) + val ssid = data?.getStringExtra(WifiDialogFragment.WIFI_SSID_KEY) bind.etEssid.setText(ssid) } } diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/EthernetBottomSheet.kt b/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/EthernetBottomSheet.kt index a0a67329b..bd1c0cb14 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/EthernetBottomSheet.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/EthernetBottomSheet.kt @@ -9,14 +9,13 @@ import io.treehouses.remote.bases.BaseBottomSheetDialog import io.treehouses.remote.databinding.DialogEthernetBinding import io.treehouses.remote.ui.network.NetworkViewModel -class EthernetBottomSheet : BaseBottomSheetDialog() { +open class EthernetBottomSheet : BaseBottomSheetDialog() { protected val viewModel: NetworkViewModel by viewModels(ownerProducer = { requireParentFragment() }) private lateinit var bind: DialogEthernetBinding override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { bind = DialogEthernetBinding.inflate(inflater, container, false) bind.btnStartConfig.setOnClickListener { - viewModel.ethernetStartConfigListener(bind.ip.text.toString(), bind.mask.text.toString(), - bind.gateway.text.toString(), bind.dns.text.toString()) + viewModel.ethernetStartConfigListener("${bind.ip.text}", "${bind.mask.text}", "${bind.gateway.text}", "${bind.dns.text}") dismiss() } return bind.root diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/HotspotBottomSheet.kt b/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/HotspotBottomSheet.kt index 70ade3663..40ee520ce 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/HotspotBottomSheet.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/HotspotBottomSheet.kt @@ -9,19 +9,19 @@ import io.treehouses.remote.bases.BaseBottomSheetDialog import io.treehouses.remote.databinding.DialogHotspotBinding import io.treehouses.remote.ui.network.NetworkViewModel -class HotspotBottomSheet : BaseBottomSheetDialog() { +open class HotspotBottomSheet : BaseBottomSheetDialog() { protected val viewModel: NetworkViewModel by viewModels(ownerProducer = { requireParentFragment() }) private lateinit var bind: DialogHotspotBinding override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { bind = DialogHotspotBinding.inflate(inflater, container, false) bind.btnStartConfig.setOnClickListener { - viewModel.hotspotStartConfigListener(bind.etHotspotSsid.text.toString(), bind.etHotspotPassword.text.toString(), - bind.checkBoxHiddenHotspot.isChecked, bind.spnHotspotType.selectedItem.toString()) + viewModel.hotspotStartConfigListener("${bind.etHotspotSsid.text}", "${bind.etHotspotPassword.text}", + bind.checkBoxHiddenHotspot.isChecked, "${bind.spnHotspotType.selectedItem}" + ) dismiss() } bind.setHotspotProfile.setOnClickListener { - viewModel.hotspotSetAddProfileListener(bind.checkBoxHiddenHotspot.isChecked, bind.spnHotspotType.selectedItem.toString(), - bind.etHotspotSsid.text.toString(), bind.etHotspotPassword.text.toString()) + viewModel.hotspotSetAddProfileListener(bind.checkBoxHiddenHotspot.isChecked, "${bind.spnHotspotType.selectedItem}", "${bind.etHotspotSsid.text}", "${bind.etHotspotPassword.text}") } return bind.root } diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/WifiBottomSheet.kt b/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/WifiBottomSheet.kt index 5dcf11309..9b8657c51 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/WifiBottomSheet.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/network/bottomsheetdialogs/WifiBottomSheet.kt @@ -15,7 +15,7 @@ import io.treehouses.remote.fragments.dialogfragments.WifiDialogFragment import io.treehouses.remote.ui.network.NetworkFragment.Companion.openWifiDialog import io.treehouses.remote.ui.network.NetworkViewModel -class WifiBottomSheet : BaseBottomSheetDialog() { +open class WifiBottomSheet : BaseBottomSheetDialog() { protected val viewModel: NetworkViewModel by viewModels(ownerProducer = { requireParentFragment() }) private lateinit var bind: DialogWifiBinding override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { @@ -46,15 +46,12 @@ class WifiBottomSheet : BaseBottomSheetDialog() { private fun setClickListeners() { bind.btnStartConfig.setOnClickListener { - val booleanMap = mapOf("checkBoxHiddenWifi" to bind.checkBoxHiddenWifi.isChecked, - "checkBoxEnterprise" to bind.checkBoxEnterprise.isChecked) - viewModel.sendWifiMessage(booleanMap, bind.editTextSSID.text.toString(), - bind.wifipassword.text.toString(), bind.wifiUsername.text.toString()) + val booleanMap = mapOf("checkBoxHiddenWifi" to bind.checkBoxHiddenWifi.isChecked, "checkBoxEnterprise" to bind.checkBoxEnterprise.isChecked) + viewModel.sendWifiMessage(booleanMap, "${bind.editTextSSID.text}", "${bind.wifipassword.text}", "${bind.wifiUsername.text}") dismiss() } bind.setWifiProfile.setOnClickListener { - viewModel.wifiSetAddProfileListener(bind.editTextSSID.text.toString(), bind.wifipassword.text.toString(), - bind.checkBoxHiddenWifi.isChecked) + viewModel.wifiSetAddProfileListener("${bind.editTextSSID.text}", "${bind.wifipassword.text}", bind.checkBoxHiddenWifi.isChecked) } bind.checkBoxEnterprise.setOnCheckedChangeListener { _, isChecked -> viewModel.hiddenOrEnterprise(isChecked) diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/services/BaseServicesDetailsFragment.kt b/app/src/main/kotlin/io/treehouses/remote/ui/services/BaseServicesDetailsFragment.kt index c372c0288..1de4e825e 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/services/BaseServicesDetailsFragment.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/services/BaseServicesDetailsFragment.kt @@ -93,7 +93,7 @@ open class BaseServicesDetailsFragment: BaseFragment(), OnItemSelectedListener, .setPositiveButton("Delete") { _: DialogInterface?, _: Int -> viewModel.onInstallClicked(s) }.setNegativeButton("Cancel") { dialog: DialogInterface, _: Int -> dialog.dismiss() }.create() - dialog.window!!.setBackgroundDrawableResource(android.R.color.transparent) + dialog.window?.setBackgroundDrawableResource(android.R.color.transparent) dialog.show() } } @@ -108,10 +108,10 @@ open class BaseServicesDetailsFragment: BaseFragment(), OnItemSelectedListener, override fun onClickLink(s: ServiceInfo?) { val chooseBind = DialogChooseUrlBinding.inflate(layoutInflater) val alertDialog = AlertDialog.Builder(ContextThemeWrapper(activity, R.style.CustomAlertDialogStyle)).setView(chooseBind.root).create() - alertDialog.window!!.setBackgroundDrawableResource(android.R.color.transparent) + alertDialog.window?.setBackgroundDrawableResource(android.R.color.transparent) chooseBind.closeButton.setOnClickListener { alertDialog.dismiss() } - chooseBind.localButton.setOnClickListener { viewModel.getLocalLink(s!!); alertDialog.dismiss() } - chooseBind.torButton.setOnClickListener { viewModel.getTorLink(s!!); alertDialog.dismiss() } + chooseBind.localButton.setOnClickListener { viewModel.getLocalLink(s); alertDialog.dismiss() } + chooseBind.torButton.setOnClickListener { viewModel.getTorLink(s); alertDialog.dismiss() } alertDialog.show() } diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesDetailsFragment.kt b/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesDetailsFragment.kt index b72fc167a..55dc41b5d 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesDetailsFragment.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesDetailsFragment.kt @@ -108,7 +108,7 @@ class ServicesDetailsFragment : BaseServicesDetailsFragment() { viewModel.getLinkAction.observe(viewLifecycleOwner) { when (it.status) { Status.SUCCESS -> { - openURL(it.data.toString()) + openURL("${it.data}") binding.progressBar.visibility = View.GONE viewModel.getLinkAction.value = Resource.nothing() } @@ -120,10 +120,10 @@ class ServicesDetailsFragment : BaseServicesDetailsFragment() { viewModel.editEnvAction.observe(viewLifecycleOwner) { if (it.status == Status.SUCCESS) { - var tokens = it.data!! - val name = tokens[2] - tokens = tokens.subList(6, tokens.size - 1) - showEditDialog(name, tokens.size, tokens) + var tokens = it.data + val name = tokens?.get(2) + tokens = tokens?.subList(6, tokens.size - 1) + tokens?.size?.let { it1 -> showEditDialog(name, it1, tokens) } viewModel.editEnvAction.value = Resource.nothing() } } @@ -193,19 +193,21 @@ class ServicesDetailsFragment : BaseServicesDetailsFragment() { * @param name : String = Name of Service * @param vars : List = The variables that can be configured */ - private fun showEditDialog(name: String, size: Int, vars: List) { + private fun showEditDialog(name: String?, size: Int, vars: List?) { val inflater = requireActivity().layoutInflater; val dialogBinding = EnvVarBinding.inflate(inflater) for (i in 0 until size) { val rowBinding = EnvVarItemBinding.inflate(inflater) val envName = rowBinding.envName val newVal = rowBinding.newVal - envName.text = vars[i].trim { it <= '\"'} + ":" + envName.text = "${(vars?.get(i)?.trim { it <= '\"'})}:" newVal.id = i envName.setTextColor(ContextCompat.getColor(requireContext(), R.color.daynight_textColor)); newVal.setTextColor(ContextCompat.getColor(requireContext(), R.color.daynight_textColor)) dialogBinding.varList.addView(rowBinding.root) } - createEditDialog(dialogBinding.root, name, size) + if (name != null) { + createEditDialog(dialogBinding.root, name, size) + } } /** diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesFragment.kt b/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesFragment.kt index 81e6b8824..a22a293fb 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesFragment.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesFragment.kt @@ -19,7 +19,7 @@ class ServicesFragment : BaseFragment() { private var servicesTabFragment: ServicesOverviewFragment? = null private var servicesDetailsFragment: ServicesDetailsFragment? = null lateinit var bind: ActivityServicesFragmentBinding - var worked = false + private var worked = false private var currentTab:Int = 0 private val viewModel by viewModels(ownerProducer = {this}) @@ -94,9 +94,4 @@ class ServicesFragment : BaseFragment() { transaction.commitAllowingStateLoss() } } - - - companion object { - private const val TAG = "ServicesFragment" - } } \ No newline at end of file diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesOverviewFragment.kt b/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesOverviewFragment.kt index 408c07dc4..a2a1a2f2d 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesOverviewFragment.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesOverviewFragment.kt @@ -20,7 +20,6 @@ import io.treehouses.remote.pojo.enum.Status class ServicesOverviewFragment : BaseFragment(), OnItemClickListener { private var adapter: ServicesListAdapter? = null private lateinit var bind: ActivityServicesTabFragmentBinding - private val viewModel by viewModels(ownerProducer = {requireParentFragment()}) override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { @@ -28,7 +27,7 @@ class ServicesOverviewFragment : BaseFragment(), OnItemClickListener { adapter = ServicesListAdapter(requireContext(), viewModel.formattedServices, ContextCompat.getColor(requireContext(), R.color.bg_white)) bind.searchBar.doOnTextChanged { text, _, _, _ -> - adapter?.filter?.filter(text.toString()) + adapter?.filter?.filter("$text") } return bind.root } @@ -50,9 +49,4 @@ class ServicesOverviewFragment : BaseFragment(), OnItemClickListener { val selected = viewModel.formattedServices[position] viewModel.clickedService.value = selected } - - companion object { - private const val TAG = "ServicesTabFragment" - } - } \ No newline at end of file diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesViewModel.kt b/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesViewModel.kt index 7da424566..de524708f 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesViewModel.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/services/ServicesViewModel.kt @@ -230,7 +230,7 @@ class ServicesViewModel(application: Application) : FragmentViewModel(applicatio * @param service : ServiceInfo = Clicked */ fun editEnvVariableRequest(service: ServiceInfo) { - sendMessage("treehouses services " + service.name + " config edit request") + sendMessage("treehouses services ${service.name} config edit request") editEnvAction.value = Resource.loading() } @@ -240,7 +240,7 @@ class ServicesViewModel(application: Application) : FragmentViewModel(applicatio * @param newValue : Boolean = the new value of the desired autorun config */ fun switchAutoRun(service: ServiceInfo, newValue: Boolean) { - sendMessage(getString(R.string.TREEHOUSES_SERVICES_AUTORUN, service.name, newValue.toString())) + sendMessage(getString(R.string.TREEHOUSES_SERVICES_AUTORUN, service.name, "$newValue")) autoRunAction.value = Resource.loading() } @@ -249,7 +249,7 @@ class ServicesViewModel(application: Application) : FragmentViewModel(applicatio * @param service : ServiceInfo = Service clicked */ - fun getLocalLink(service: ServiceInfo) { + fun getLocalLink(service: ServiceInfo?) { getLink(service, R.string.TREEHOUSES_SERVICES_URL_LOCAL) } @@ -259,7 +259,7 @@ class ServicesViewModel(application: Application) : FragmentViewModel(applicatio * @param service : ServiceInfo = Service clicked */ - fun getTorLink(service: ServiceInfo) { + fun getTorLink(service: ServiceInfo?) { getLink(service, R.string.TREEHOUSES_SERVICES_URL_TOR) } @@ -268,8 +268,8 @@ class ServicesViewModel(application: Application) : FragmentViewModel(applicatio * @param service : ServiceInfo = Service clicked * @param id : Int = Identifier for command string */ - private fun getLink(service: ServiceInfo, id: Int) { - sendMessage(getString(id, service.name)) + private fun getLink(service: ServiceInfo?, id: Int) { + sendMessage(service?.name?.let { getString(id, it) }) getLinkAction.value = Resource.loading() } @@ -279,7 +279,7 @@ class ServicesViewModel(application: Application) : FragmentViewModel(applicatio override fun onCleared() { super.onCleared() if (error.value.isNullOrEmpty() && rawServicesData.value != null) { - updateServicesCache(Gson().toJson(rawServicesData.value!!.data)) + updateServicesCache(Gson().toJson(rawServicesData.value?.data)) } } diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/socks/SocksFragment.kt b/app/src/main/kotlin/io/treehouses/remote/ui/socks/SocksFragment.kt index 23b668887..f8c55f97a 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/socks/SocksFragment.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/socks/SocksFragment.kt @@ -9,9 +9,6 @@ import android.view.ViewGroup import android.view.WindowManager import android.widget.AdapterView import android.widget.ArrayAdapter -import android.widget.Button -import android.widget.EditText -import android.widget.ListView import android.widget.TextView import android.widget.Toast import androidx.fragment.app.Fragment @@ -21,36 +18,21 @@ import io.treehouses.remote.databinding.ActivitySocksFragmentBinding import io.treehouses.remote.databinding.DialogAddProfileBinding import io.treehouses.remote.utils.DialogUtils -class SocksFragment : Fragment() { - +open class SocksFragment : Fragment() { protected val viewModel: SocksViewModel by viewModels(ownerProducer = { this }) - private var addProfileButton: Button? = null - private var addingProfileButton: Button? = null - private var cancelProfileButton: Button? = null private var textStatus: TextView? = null private var adapter: ArrayAdapter? = null private lateinit var dialog: Dialog - private lateinit var password: EditText - private lateinit var serverPort: EditText - private lateinit var localPort: EditText - private lateinit var localAddress: EditText - private lateinit var serverHost: EditText - private var portList: ListView? = null - var bind: ActivitySocksFragmentBinding? = null - var bindProfile: DialogAddProfileBinding? = null + lateinit var bind: ActivitySocksFragmentBinding + private lateinit var bindProfile: DialogAddProfileBinding override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { bind = ActivitySocksFragmentBinding.inflate(inflater, container, false) bindProfile = DialogAddProfileBinding.inflate(inflater, container, false) -// viewModel.onLoad() - addProfileButton = bind!!.btnAddProfile - portList = bind!!.profiles initializeDialog() messageObservers() addProfileButtonListeners(dialog) - portList = bind!!.profiles - - return bind!!.root + return bind.root } override fun setUserVisibleHint(visible: Boolean) { @@ -64,27 +46,18 @@ class SocksFragment : Fragment() { private fun initializeDialog() { dialog = Dialog(requireContext()) addPortListListener() - - dialog.setContentView(bindProfile!!.root) - - serverHost = bindProfile!!.ServerHost - serverPort = bindProfile!!.serverPort - localAddress = bindProfile!!.LocalAddress - localPort = bindProfile!!.localPort - password = bindProfile!!.password - addingProfileButton = bindProfile!!.addingProfileButton - cancelProfileButton = bindProfile!!.cancel + dialog.setContentView(bindProfile.root) val window = dialog.window - window!!.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) - window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) - window.setBackgroundDrawableResource(android.R.color.transparent) + window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) + window?.setBackgroundDrawableResource(android.R.color.transparent) initializeObservers() } private fun addPortListListener() { - portList!!.onItemClickListener = AdapterView.OnItemClickListener { av: AdapterView<*>?, _: View?, position: Int, _: Long -> + bind.profiles.onItemClickListener = AdapterView.OnItemClickListener { av: AdapterView<*>?, _: View?, position: Int, _: Long -> val builder = AlertDialog.Builder(activity, R.style.CustomAlertDialogStyle) val selectedString = av?.getItemAtPosition(position) builder.setTitle("Delete Profile $selectedString ?") @@ -98,7 +71,7 @@ class SocksFragment : Fragment() { private fun initializeObservers() { viewModel.addProfileButtonText.observe(viewLifecycleOwner) { - addingProfileButton?.text = it + bindProfile.addingProfileButton.text = it } } @@ -107,35 +80,34 @@ class SocksFragment : Fragment() { textStatus?.text = it } - - viewModel.addProfileButtonText.observe(viewLifecycleOwner) { - addProfileButton?.text = it + bind.btnAddProfile.text = it } viewModel.addProfileButtonEnabled.observe(viewLifecycleOwner) { - addProfileButton?.isEnabled = it + bind.btnAddProfile.isEnabled = it } viewModel.refreshList.observe(viewLifecycleOwner) { adapter = ArrayAdapter(requireContext(), R.layout.select_dialog_item, it) - bind!!.profiles.adapter = adapter + bind.profiles.adapter = adapter } } private fun addProfileButtonListeners(dialog: Dialog) { - - addProfileButton!!.setOnClickListener { + bind.btnAddProfile.setOnClickListener { dialog.show() } - cancelProfileButton!!.setOnClickListener { + bindProfile.cancel.setOnClickListener { dialog.dismiss() } - addingProfileButton!!.setOnClickListener { - val stringMap = mapOf("serverHost" to serverHost.text.toString(), - "localAddress" to localAddress.text.toString(), "localPort" to localPort.text.toString(), - "serverPort" to serverPort.text.toString(), "password" to password.text.toString()) + + bindProfile.addingProfileButton.setOnClickListener { + val stringMap = mapOf("serverHost" to "${bindProfile.ServerHost.text}", + "localAddress" to "${bindProfile.LocalAddress.text}", "localPort" to "${bindProfile.localPort.text}", + "serverPort" to "${bindProfile.serverPort.text}", "password" to "${bindProfile.password.text}" + ) viewModel.addProfile(stringMap) viewModel.profileDialogDismiss.observe(viewLifecycleOwner) { if (it) { @@ -144,7 +116,6 @@ class SocksFragment : Fragment() { } } } - } diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/socks/SocksViewModel.kt b/app/src/main/kotlin/io/treehouses/remote/ui/socks/SocksViewModel.kt index 6a90db7d7..b1263f00c 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/socks/SocksViewModel.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/socks/SocksViewModel.kt @@ -12,7 +12,7 @@ class SocksViewModel(application: Application) : FragmentViewModel(application) val addProfileButtonEnabled: MutableLiveData = MutableLiveData() val textStatusText: MutableLiveData = MutableLiveData() val refreshList: MutableLiveData> = MutableLiveData() - var profileNameText = mutableListOf() + private var profileNameText = mutableListOf() val profileDialogDismiss: MutableLiveData = MutableLiveData() fun onLoad() { diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/BaseSSHTunnelFragment.kt b/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/BaseSSHTunnelFragment.kt index f251e345f..c75729d91 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/BaseSSHTunnelFragment.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/BaseSSHTunnelFragment.kt @@ -26,8 +26,8 @@ open class BaseSSHTunnelFragment : Fragment() { val builder = AlertDialog.Builder(context) builder.setTitle("Save Key To Pi") builder.setMessage( - "Phone Public Key for ${profile}: \n$storedPublicKey\n\n" + - "Phone Private Key for ${profile}: \n$storedPrivateKey") + "Phone Public Key for ${profile}: \n$storedPublicKey\n\n" + + "Phone Private Key for ${profile}: \n$storedPrivateKey") builder.setPositiveButton("Save to Pi") { _: DialogInterface?, _: Int -> viewModel.sendMessage("treehouses remote key receive \"${storedPublicKey}\" \"${storedPrivateKey}\" $profile") Toast.makeText(context, "Key saved to Pi successfully", Toast.LENGTH_LONG).show() diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/BaseSSHTunnelViewModel.kt b/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/BaseSSHTunnelViewModel.kt index 01b7665ed..a82c6b4d7 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/BaseSSHTunnelViewModel.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/BaseSSHTunnelViewModel.kt @@ -17,13 +17,11 @@ import org.json.JSONObject open class BaseSSHTunnelViewModel(application: Application) : FragmentViewModel(application) { private val context = getApplication().applicationContext - - // hostsPosition var tunnelSSHData: MutableLiveData> = MutableLiveData() var tunnelSSHKeyDialogData: MutableLiveData> = MutableLiveData() var show: MutableLiveData> = MutableLiveData() var tunnelSSHObject: TunnelSSHData = TunnelSSHData() // hostsPosition - var tunnelSSHKeyDialogObj: TunnelSSHKeyDialogData = TunnelSSHKeyDialogData() // hostsPosition + private var tunnelSSHKeyDialogObj: TunnelSSHKeyDialogData = TunnelSSHKeyDialogData() // hostsPosition protected var jsonReceiving = false protected var jsonSent = false protected var jsonString = "" @@ -37,7 +35,6 @@ open class BaseSSHTunnelViewModel(application: Application) : FragmentViewModel( } } - protected fun buildJSON() { try { val jsonObject = JSONObject(jsonString) @@ -49,8 +46,11 @@ open class BaseSSHTunnelViewModel(application: Application) : FragmentViewModel( val inPhoneOnly = piPublicKey == "No public key found" && piPrivateKey == "No private key found " && !storedPublicKey.isNullOrBlank() && !storedPrivateKey.isNullOrBlank() val inNeither = piPublicKey == "No public key found" && piPrivateKey == "No private key found " && storedPublicKey.isNullOrBlank() && storedPrivateKey.isNullOrBlank() tunnelSSHKeyDialogObj = TunnelSSHKeyDialogData() - tunnelSSHKeyDialogObj.profile = profile;tunnelSSHKeyDialogObj.storedPrivateKey = storedPrivateKey!!;tunnelSSHKeyDialogObj.storedPublicKey = storedPublicKey!!;tunnelSSHKeyDialogObj.piPrivateKey = - piPrivateKey;tunnelSSHKeyDialogObj.piPublicKey = piPublicKey + tunnelSSHKeyDialogObj.profile = profile;if (storedPrivateKey != null) { + tunnelSSHKeyDialogObj.storedPrivateKey = storedPrivateKey + };if (storedPublicKey != null) { + tunnelSSHKeyDialogObj.storedPublicKey = storedPublicKey + };tunnelSSHKeyDialogObj.piPrivateKey = piPrivateKey;tunnelSSHKeyDialogObj.piPublicKey = piPublicKey // Pi and phone keys are the same if (inPiAndPhone) Toast.makeText(context, "The same keys for $profile are already saved in both Pi and phone", Toast.LENGTH_SHORT).show() // Key exists in Pi but not phone @@ -61,7 +61,9 @@ open class BaseSSHTunnelViewModel(application: Application) : FragmentViewModel( else if (inNeither) Toast.makeText(context, "No keys for $profile exist on either Pi or phone!", Toast.LENGTH_SHORT).show() // Keys are different, overwrite one or cancel else { tunnelSSHKeyDialogObj.showHandleDifferentKeysDialog = true;tunnelSSHKeyDialogData.value = Resource.success(tunnelSSHKeyDialogObj) } - } catch (e: JSONException) { } + } catch (e: JSONException) { + e.printStackTrace() + } } @@ -97,8 +99,8 @@ open class BaseSSHTunnelViewModel(application: Application) : FragmentViewModel( } fun searchArray(array: java.util.ArrayList?, portnum: String): Boolean { - for (name in array!!) { - var check = name.substringAfter(":") + for (name in array ?: emptyList()) { + val check = name.substringAfter(":") if (check == portnum) return true } return false diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/SSHTunnelFragment.kt b/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/SSHTunnelFragment.kt index a44888681..d3ad71849 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/SSHTunnelFragment.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/SSHTunnelFragment.kt @@ -23,7 +23,7 @@ import io.treehouses.remote.utils.* class SSHTunnelFragment : BaseSSHTunnelFragment() { lateinit var dialogSshTunnelPortsBinding: DialogSshtunnelPortsBinding - lateinit var dialogSshTunnelKeyBinding: DialogSshtunnelKeyBinding + private lateinit var dialogSshTunnelKeyBinding: DialogSshtunnelKeyBinding lateinit var dialogSshTunnelHostsBinding: DialogSshtunnelHostsBinding @RequiresApi(Build.VERSION_CODES.N) @@ -42,18 +42,15 @@ class SSHTunnelFragment : BaseSSHTunnelFragment() { viewModel.tunnelSSHKeyDialogData.observe(viewLifecycleOwner) { when (it.status) { Status.SUCCESS -> { - if (it.data!!.showHandleDifferentKeysDialog) handleDifferentKeys(it.data) - if (it.data.showHandlePhoneKeySaveDialog) + if (it.data?.showHandleDifferentKeysDialog == true) { + handleDifferentKeys(it.data) + } + if (it.data?.showHandlePhoneKeySaveDialog == true) { handlePhoneKeySave(it.data) - if (it.data!!.showHandlePiKeySaveDialog) - handlePiKeySave( - it.data.profile, - it.data.storedPublicKey, - it.data.storedPrivateKey - ) - } - - else -> {} + } + if (it.data?.showHandlePiKeySaveDialog == true) + handlePiKeySave(it.data.profile, it.data.storedPublicKey, it.data.storedPrivateKey) + } else -> {} } } } @@ -65,8 +62,8 @@ class SSHTunnelFragment : BaseSSHTunnelFragment() { viewModel.setUserVisibleHint() } - fun showDialog(dialog: Dialog) { - dialog.window!!.setBackgroundDrawableResource(android.R.color.transparent) + private fun showDialog(dialog: Dialog) { + dialog.window?.setBackgroundDrawableResource(android.R.color.transparent) dialog.show() } @@ -81,27 +78,27 @@ class SSHTunnelFragment : BaseSSHTunnelFragment() { val builder = AlertDialog.Builder(ContextThemeWrapper(context, R.style.CustomAlertDialogStyle)); builder.setTitle("SSH Help") builder.setMessage(R.string.ssh_info) val dialog = builder.create() - dialog.window!!.setBackgroundDrawableResource(android.R.color.transparent); dialog.show() + dialog.window?.setBackgroundDrawableResource(android.R.color.transparent); dialog.show() } dialogSshTunnelPortsBinding.btnAddingPort.setOnClickListener { handleAddPort() } dialogSshTunnelHostsBinding.btnAddingHost.setOnClickListener { - val m1 = dialogSshTunnelHostsBinding.PortNumberInput.text.toString() - val m2 = dialogSshTunnelHostsBinding.UserNameInput.text.toString() + "@" + dialogSshTunnelHostsBinding.DomainIPInput.text.toString() + val m1 = "${dialogSshTunnelHostsBinding.PortNumberInput.text}" + val m2 = "${dialogSshTunnelHostsBinding.UserNameInput.text}@${dialogSshTunnelHostsBinding.DomainIPInput.text}" viewModel.addingHostButton(m1, m2) dialogHosts.dismiss() } } private fun handleAddPort() { - if (dialogSshTunnelPortsBinding.ExternalTextInput.text!!.isNotEmpty() && dialogSshTunnelPortsBinding.InternalTextInput.text!!.isNotEmpty()) { - val parts = dialogSshTunnelPortsBinding.hosts.selectedItem.toString().split(":")[0] - viewModel.addingPortButton(dialogSshTunnelPortsBinding.InternalTextInput.text.toString(), dialogSshTunnelPortsBinding.ExternalTextInput.text.toString(), parts) + if (dialogSshTunnelPortsBinding.ExternalTextInput.text?.isNotEmpty() == true && dialogSshTunnelPortsBinding.InternalTextInput.text?.isNotEmpty() == true) { + val parts = "${dialogSshTunnelPortsBinding.hosts.selectedItem}".split(":")[0] + viewModel.addingPortButton("${dialogSshTunnelPortsBinding.InternalTextInput.text}", "${dialogSshTunnelPortsBinding.ExternalTextInput.text}", parts) dialogPort.dismiss() } } private fun addListeners2() { - val profile = dialogKeys.findViewById(R.id.sshtunnel_profile).text.toString() + val profile = "${dialogKeys.findViewById(R.id.sshtunnel_profile).text}" dialogSshTunnelKeyBinding.btnSaveKeys.setOnClickListener { viewModel.keyClickListener(profile); } dialogSshTunnelKeyBinding.btnShowKeys.setOnClickListener { viewModel.keyClickListener(profile); viewModel.handleShowKeys(profile) @@ -115,18 +112,18 @@ class SSHTunnelFragment : BaseSSHTunnelFragment() { } private fun handleDeletePort(position: Int) { - if (portsName!!.size > 1 && position == portsName!!.size - 1) { + if ((portsName?.size ?: 0) > 1 && position == (portsName?.size ?: (0 - 1))) { DialogUtils.createAlertDialog(context, "Delete All Hosts and Ports?") { viewModel.deleteHostPorts() } } else { val builder = AlertDialog.Builder(ContextThemeWrapper(context, R.style.CustomAlertDialogStyle)) - if (portsName!![position].contains("@")) { + if (portsName?.get(position)?.contains("@") == true) { setPortDialog(builder, position, "Delete Host ") } else { setPortDialog(builder, position, "Delete Port ") } builder.setNegativeButton("Cancel", null) val dialog = builder.create() - dialog.window!!.setBackgroundDrawableResource(android.R.color.transparent); dialog.show() + dialog.window?.setBackgroundDrawableResource(android.R.color.transparent); dialog.show() } } @@ -135,13 +132,13 @@ class SSHTunnelFragment : BaseSSHTunnelFragment() { viewModel.tunnelSSHData.observe(viewLifecycleOwner, androidx.lifecycle.Observer { when (it.status) { Status.SUCCESS -> { - bind.notifyNow.isEnabled = it.data!!.enabledNotifyNow - bind.switchNotification.isEnabled = it.data.enableSwitchNotification; bind.btnAddHosts.text = it.data.addHostText - bind.btnAddPort.text = it.data.addPortText; bind.btnAddPort.isEnabled = it.data.enableAddPort - bind.btnAddHosts.isEnabled = it.data.enableAddHost; bind.sshPorts.isEnabled = it.data.enableSSHPort - dialogSshTunnelKeyBinding.publicKey.text = it.data.publicKey; dialogSshTunnelKeyBinding.privateKey.text = it.data.privateKey + bind.notifyNow.isEnabled = it.data?.enabledNotifyNow ?: false + bind.switchNotification.isEnabled = it.data?.enableSwitchNotification == true; bind.btnAddHosts.text = it.data?.addHostText + bind.btnAddPort.text = it.data?.addPortText; bind.btnAddPort.isEnabled = it.data?.enableAddPort == true + bind.btnAddHosts.isEnabled = it.data?.enableAddHost == true; bind.sshPorts.isEnabled = it.data?.enableSSHPort == true + dialogSshTunnelKeyBinding.publicKey.text = it.data?.publicKey; dialogSshTunnelKeyBinding.privateKey.text = it.data?.privateKey dialogSshTunnelKeyBinding.progressBar.visibility = View.GONE - portsName = it.data.portNames; hostsName = it.data.hostNames + portsName = it.data?.portNames; hostsName = it.data?.hostNames adapter = TunnelUtils.getPortAdapter(requireContext(), portsName) bind.sshPorts.adapter = adapter adapter2 = ArrayAdapter(requireContext(), R.layout.support_simple_spinner_dropdown_item, hostsName!!) @@ -170,32 +167,27 @@ class SSHTunnelFragment : BaseSSHTunnelFragment() { dialogKeys.setContentView(dialogSshTunnelKeyBinding.root) addHostSyntaxCheck(dialogSshTunnelHostsBinding.UserNameInput, dialogSshTunnelHostsBinding.TLusername, Constants.userRegex, Constants.hostError) - addHostSyntaxCheck(dialogSshTunnelHostsBinding.DomainIPInput, dialogSshTunnelHostsBinding.TLdomain, Constants.domainRegex + "|" + Constants.ipRegex, Constants.domainIPError) + addHostSyntaxCheck(dialogSshTunnelHostsBinding.DomainIPInput, dialogSshTunnelHostsBinding.TLdomain, "${Constants.domainRegex}|${Constants.ipRegex}", Constants.domainIPError) addHostSyntaxCheck(dialogSshTunnelHostsBinding.PortNumberInput, dialogSshTunnelHostsBinding.TLportname, Constants.portRegex, Constants.portError) addPortSyntaxCheck(dialogSshTunnelPortsBinding.ExternalTextInput, dialogSshTunnelPortsBinding.TLexternal) addPortSyntaxCheck(dialogSshTunnelPortsBinding.InternalTextInput, dialogSshTunnelPortsBinding.TLinternal) viewModel.initializeArrays() val window = dialogPort.window val windowHost = dialogHosts.window - window!!.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) - windowHost!!.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) - window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) - windowHost.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) + window?.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) + windowHost?.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) + window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) + windowHost?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) } -// -// override fun setUserVisibleHint(visible: Boolean) { -// if (visible) { -// -// } -// } - fun checkAddingHostButtonEnable() { - if (dialogSshTunnelHostsBinding.UserNameInput.editableText.isNotEmpty() && dialogSshTunnelHostsBinding.DomainIPInput.editableText.isNotEmpty() - && dialogSshTunnelHostsBinding.PortNumberInput.editableText.isNotEmpty()) - if (!dialogSshTunnelHostsBinding.TLusername.isErrorEnabled && !dialogSshTunnelHostsBinding.TLdomain.isErrorEnabled && !dialogSshTunnelHostsBinding.TLportname.isErrorEnabled) + if (dialogSshTunnelHostsBinding.UserNameInput.editableText.isNotEmpty() && + dialogSshTunnelHostsBinding.DomainIPInput.editableText.isNotEmpty() + && dialogSshTunnelHostsBinding.PortNumberInput.editableText.isNotEmpty()) { + if (!dialogSshTunnelHostsBinding.TLusername.isErrorEnabled && !dialogSshTunnelHostsBinding.TLdomain.isErrorEnabled && !dialogSshTunnelHostsBinding.TLportname.isErrorEnabled) { dialogSshTunnelHostsBinding.btnAddingHost.isEnabled = true - + } + } } fun checkAddingPortButtonEnable() { @@ -204,18 +196,14 @@ class SSHTunnelFragment : BaseSSHTunnelFragment() { dialogSshTunnelPortsBinding.btnAddingPort.isEnabled = true } - /* - adds a syntax check to textInputEditText. If input in textInputEditText does not match regex, outputs error message in textInputLayout - and disables addingHostButton - */ - fun addHostSyntaxCheck(textInputEditText: TextInputEditText, textInputLayout: TextInputLayout, regex: String, error: String) { + private fun addHostSyntaxCheck(textInputEditText: TextInputEditText, textInputLayout: TextInputLayout, regex: String, error: String) { textInputEditText.addTextChangedListener(object : TextWatcher { override fun afterTextChanged(s: Editable?) { textInputLayout.isErrorEnabled = true - if (s!!.isEmpty()) { + if (s?.isEmpty() == true) { dialogSshTunnelHostsBinding.btnAddingHost.isEnabled = false } else { - if (!s.toString().matches(regex.toRegex())) { + if (!"$s".matches(regex.toRegex())) { dialogSshTunnelHostsBinding.btnAddingHost.isEnabled = false textInputLayout.error = error } else { @@ -230,17 +218,17 @@ class SSHTunnelFragment : BaseSSHTunnelFragment() { }) } - fun addPortSyntaxCheck(textInputEditText: TextInputEditText, textInputLayout: TextInputLayout) { + private fun addPortSyntaxCheck(textInputEditText: TextInputEditText, textInputLayout: TextInputLayout) { textInputEditText.addTextChangedListener(object : TextWatcher { override fun afterTextChanged(s: Editable?) { textInputLayout.isErrorEnabled = true - if (s!!.isEmpty()) { + if (s?.isEmpty() == true) { dialogSshTunnelPortsBinding.btnAddingPort.isEnabled = false } else { - if (!s.toString().matches(Constants.portRegex.toRegex())) { + if (!"$s".matches(Constants.portRegex.toRegex())) { dialogSshTunnelPortsBinding.btnAddingPort.isEnabled = false textInputLayout.error = Constants.portError - } else if (textInputEditText == dialogSshTunnelPortsBinding.ExternalTextInput && viewModel.searchArray(portsName, s.toString())) { + } else if (textInputEditText == dialogSshTunnelPortsBinding.ExternalTextInput && viewModel.searchArray(portsName, "$s")) { dialogSshTunnelPortsBinding.btnAddingPort.isEnabled = false dialogSshTunnelPortsBinding.TLexternal.error = "Port number already exists" } else { diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/SSHTunnelViewModel.kt b/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/SSHTunnelViewModel.kt index 796ad27bc..ffe0119ed 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/SSHTunnelViewModel.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/sshtunnel/SSHTunnelViewModel.kt @@ -83,7 +83,6 @@ open class SSHTunnelViewModel(application: Application) : BaseSSHTunnelViewModel } } - fun onCreateView() { tunnelSSHData.value = Resource.loading(tunnelSSHObject) tunnelSSHObject.enableSwitchNotification = true @@ -92,8 +91,6 @@ open class SSHTunnelViewModel(application: Application) : BaseSSHTunnelViewModel tunnelSSHData.value = Resource.success(tunnelSSHObject) } - - fun deleteHostPorts() { tunnelSSHObject.addHostText = "Deleting all hosts..." tunnelSSHObject.enableAddHost = false @@ -121,7 +118,7 @@ open class SSHTunnelViewModel(application: Application) : BaseSSHTunnelViewModel sendMessage(getString(R.string.TREEHOUSES_SSHTUNNEL_ADD_PORT_ACTUAL, s2, s1, parts)) } - fun handleNewList(readMessage: String) { + private fun handleNewList(readMessage: String) { var position = 0 tunnelSSHObject.addPortText = "Add Port" tunnelSSHObject.addHostText = "Add Host" @@ -180,7 +177,7 @@ open class SSHTunnelViewModel(application: Application) : BaseSSHTunnelViewModel tunnelSSHObject.privateKey = strPhonePrivateKey } - protected fun handleOnStatus() { + private fun handleOnStatus() { tunnelSSHObject.checkSwitchNotification = true tunnelSSHObject.enableSwitchNotification = true tunnelSSHObject.enabledNotifyNow = true @@ -188,14 +185,14 @@ open class SSHTunnelViewModel(application: Application) : BaseSSHTunnelViewModel sendMessage(getString(R.string.TREEHOUSES_SSHTUNNEL_PORTS)) } - protected fun handleOffStatus() { + private fun handleOffStatus() { tunnelSSHObject.checkSwitchNotification = false tunnelSSHObject.enableSwitchNotification = true tunnelSSHObject.enabledNotifyNow = true sendMessage(getString(R.string.TREEHOUSES_SSHTUNNEL_PORTS)) } - protected fun handleNoPorts() { + private fun handleNoPorts() { tunnelSSHObject.enableSSHPort = true tunnelSSHObject.addPortText = "Add Port" tunnelSSHObject.addHostText = "Add Host" @@ -214,10 +211,9 @@ open class SSHTunnelViewModel(application: Application) : BaseSSHTunnelViewModel tunnelSSHData.value = Resource.success(tunnelSSHObject) Toast.makeText(context, "Host not found. Failure to delete port.", Toast.LENGTH_SHORT).show() - } - protected fun handleModifiedList() { + private fun handleModifiedList() { Toast.makeText(context, "Added/Removed. Retrieving port list.", Toast.LENGTH_SHORT).show() tunnelSSHObject.addPortText = "Retrieving..." tunnelSSHObject.addHostText = "Retrieving..." @@ -246,7 +242,7 @@ open class SSHTunnelViewModel(application: Application) : BaseSSHTunnelViewModel if (tunnelSSHObject.hostPosition.last() < position) myPos = tunnelSSHObject.hostPosition.lastIndex val portName = TunnelUtils.getPortName(tunnelSSHObject.portNames, position) - val formatArgs = portName + " " + tunnelSSHObject.hostNames[myPos].split(":")[0] + val formatArgs = "$portName ${tunnelSSHObject.hostNames[myPos].split(":")[0]}" sendMessage(getString(R.string.TREEHOUSES_SSHTUNNEL_REMOVE_PORT, formatArgs)); tunnelSSHObject.addPortText = "deleting port ....." tunnelSSHObject.enableSSHPort = false; tunnelSSHObject.enableAddPort = false diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/status/StatusFragment.kt b/app/src/main/kotlin/io/treehouses/remote/ui/status/StatusFragment.kt index 628819d2c..b1874d3ad 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/status/StatusFragment.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/status/StatusFragment.kt @@ -11,7 +11,6 @@ import android.view.ViewGroup import android.widget.AdapterView import android.widget.ArrayAdapter import android.widget.EditText -import android.widget.ListView import android.widget.ProgressBar import android.widget.SearchView import android.widget.Toast @@ -29,10 +28,8 @@ import io.treehouses.remote.interfaces.FragmentDialogInterface import io.treehouses.remote.utils.DialogUtils import io.treehouses.remote.utils.Utils -class StatusFragment : BaseFragment(), FragmentDialogInterface { - +open class StatusFragment : BaseFragment(), FragmentDialogInterface { protected val viewModel: StatusViewModel by viewModels(ownerProducer = { this }) - var countryList: ListView? = null private lateinit var bind: ActivityStatusFragmentBinding private var notificationListener: NotificationCallback? = null @@ -53,12 +50,11 @@ class StatusFragment : BaseFragment(), FragmentDialogInterface { val dialogWifiCountryBinding = DialogWificountryBinding.inflate(layoutInflater) dialog.setContentView(dialogWifiCountryBinding.root) dialogWifiCountryBinding.countries - countryList = dialogWifiCountryBinding.countries adapter.filter.filter("") - countryList?.adapter = adapter - countryList?.isTextFilterEnabled = true - countryList?.onItemClickListener = AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, p: Int, _: Long -> - viewModel.onSelectCountry(countryList!!.getItemAtPosition(p).toString()) + dialogWifiCountryBinding.countries.adapter = adapter + dialogWifiCountryBinding.countries.isTextFilterEnabled = true + dialogWifiCountryBinding.countries.onItemClickListener = AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, p: Int, _: Long -> + viewModel.onSelectCountry("${dialogWifiCountryBinding.countries.getItemAtPosition(p)}") dialog.dismiss() } @@ -150,7 +146,7 @@ class StatusFragment : BaseFragment(), FragmentDialogInterface { upgradeBoxObservers() networkBoxObservers() viewModel.showNotification.observe(viewLifecycleOwner) { - notificationListener!!.setNotification(false) + notificationListener?.setNotification(false) } viewModel.isLoading.observe(viewLifecycleOwner) { bind.progressBar.visibility = if (it) View.VISIBLE else View.GONE @@ -175,9 +171,9 @@ class StatusFragment : BaseFragment(), FragmentDialogInterface { override fun onQueryTextChange(newText: String): Boolean { if (TextUtils.isEmpty(newText)) { - countryList!!.clearTextFilter() + dialogWifiCountryBinding.countries.clearTextFilter() } else { - countryList!!.setFilterText(newText) + dialogWifiCountryBinding.countries.setFilterText(newText) } return true } @@ -204,10 +200,10 @@ class StatusFragment : BaseFragment(), FragmentDialogInterface { viewModel.refresh() } bind.swiperefresh.setColorSchemeColors( - ContextCompat.getColor(requireContext(), android.R.color.holo_red_light), - ContextCompat.getColor(requireContext(), android.R.color.holo_orange_light), - ContextCompat.getColor(requireContext(), android.R.color.holo_blue_light), - ContextCompat.getColor(requireContext(), android.R.color.holo_green_light)) + ContextCompat.getColor(requireContext(), android.R.color.holo_red_light), + ContextCompat.getColor(requireContext(), android.R.color.holo_orange_light), + ContextCompat.getColor(requireContext(), android.R.color.holo_blue_light), + ContextCompat.getColor(requireContext(), android.R.color.holo_green_light)) viewModel.showRefresh.observe(viewLifecycleOwner) { bind.refreshBtn.isEnabled = it } @@ -222,10 +218,10 @@ class StatusFragment : BaseFragment(), FragmentDialogInterface { } private fun createRenameDialog(view: View, mEditText: EditText) { - val builder = DialogUtils.createAlertDialog(context, "Rename " + viewModel.hostName.value, view, R.drawable.dialog_icon) + val builder = DialogUtils.createAlertDialog(context, "Rename ${viewModel.hostName.value}", view, R.drawable.dialog_icon) DialogUtils.createAdvancedDialog(builder, Pair("Rename", "Cancel"), { - if (mEditText.text.toString() != "") { - viewModel.sendMessage(requireActivity().getString(R.string.TREEHOUSES_RENAME, mEditText.text.toString())) + if ("${mEditText.text}" != "") { + viewModel.sendMessage(requireActivity().getString(R.string.TREEHOUSES_RENAME, "${mEditText.text}")) Toast.makeText(context, "Raspberry Pi Renamed", Toast.LENGTH_LONG).show() viewModel.refresh() } else { @@ -238,14 +234,13 @@ class StatusFragment : BaseFragment(), FragmentDialogInterface { val a = createRemoteReverseDialog(context) viewModel.treehousesRemoteReverse() viewModel.reverseTextStatus.observe(viewLifecycleOwner) { - a!!.setMessage(it) + a?.setMessage(it) } - a!!.show() + a?.show() } override fun onAttach(context: Context) { super.onAttach(context) notificationListener = Utils.attach(context) } - } diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/status/StatusViewModel.kt b/app/src/main/kotlin/io/treehouses/remote/ui/status/StatusViewModel.kt index 32c3a08c3..a08ab64dd 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/status/StatusViewModel.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/status/StatusViewModel.kt @@ -13,7 +13,6 @@ import io.treehouses.remote.utils.Utils import java.util.Locale class StatusViewModel(application: Application) : FragmentViewModel(application) { - var updateRightNow = false val deviceName: MutableLiveData = MutableLiveData() val error: MutableLiveData = MutableLiveData() @@ -87,27 +86,33 @@ class StatusViewModel(application: Application) : FragmentViewModel(application) } private fun updateViews(output: String) { - try { if (lastCommand == getString(R.string.TREEHOUSES_REMOTE_STATUSPAGE)) { + try { + if (lastCommand == getString(R.string.TREEHOUSES_REMOTE_STATUSPAGE)) { val statusData = Gson().fromJson(output, StatusData::class.java) temperature.value = statusData.temperature val usedMemory = statusData.memory_used.trim { it <= ' ' }.toDouble() val totalMemory = statusData.memory_total.trim { it <= ' ' }.toDouble() storageBarValue.value = statusData.storage.split(" ")[3].dropLast(1).toInt() storage.value = statusData.storage.split(" ")[2].dropLast(1).replace("G", "GB") - cpuModelText.value = "CPU: ARM " + statusData.arm + cpuModelText.value = "CPU: ARM ${statusData.arm}" writeNetworkInfo(statusData.networkmode, statusData.info) - hostName.value = "Hostname: " + statusData.hostname + hostName.value = "Hostname: ${statusData.hostname}" memoryBarValue.value = (usedMemory / totalMemory * 100).toInt() - memory.value = usedMemory.toString() + "GB" + "/" + totalMemory.toString() + "GB" + memory.value = "${usedMemory}GB/${totalMemory}GB" val res = statusData.status.trim().split(" ") imageText.value = String.format("Image Version: %s", res[2].substring(8)) deviceAddress.value = res[1] - rpiType.value = "Model: " + res[4] + rpiType.value = "Model: ${res[4]}" rpiVersion = res[3] - remoteVersion.value = "Remote Version: " + BuildConfig.VERSION_NAME + remoteVersion.value = "Remote Version: ${BuildConfig.VERSION_NAME}" checkWifiStatus(statusData.internet) isLoading.value = false - } else checkUpgradeStatus(output) } catch (e: Exception) { } + } else { + checkUpgradeStatus(output) + } + } catch (e: Exception) { + e.printStackTrace() + } } private fun checkUpgradeStatus(readMessage: String) { @@ -144,17 +149,6 @@ class StatusViewModel(application: Application) : FragmentViewModel(application) sendMessage("treehouses remote reverse") } -// fun showRemoteReverse(output: String){ -// val reverseData = Gson().fromJson(output, ReverseData::class.java) -// val ip = "ip: " + reverseData.ip -// val postal = "postal: " + reverseData.postal -// val city = "city: " + reverseData.city -// val country = "country: " + reverseData.country -// val org = "org: " + reverseData.org -// val timezone = "timezone: " + reverseData.timezone -// reverseText.value = ip + "\n" + org + "\n" + country + "\n" + city + "\n" + postal + "\n" + timezone -// } - private fun writeNetworkInfo(networkMode: String, readMessage: String) { val ssid = readMessage.substringAfter("essid: ").substringBefore(", ip:") var ip = readMessage.substringAfter("ip: ").substringBefore(", has") @@ -171,8 +165,8 @@ class StatusViewModel(application: Application) : FragmentViewModel(application) if (ip == "") { ip = "N/A" } - ipAddressText.value = "IP Address: " + ip - ssidText.value = "SSID: " + ssid + ipAddressText.value = "IP Address: $ip" + ssidText.value = "SSID: $ssid" } fun setChecking() { diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/system/SystemFragment.kt b/app/src/main/kotlin/io/treehouses/remote/ui/system/SystemFragment.kt index d83d1ee91..4dd27865b 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/system/SystemFragment.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/system/SystemFragment.kt @@ -15,8 +15,7 @@ import io.treehouses.remote.bases.BaseFragment import io.treehouses.remote.databinding.ActivitySystemFragmentBinding import io.treehouses.remote.pojo.NetworkListItem -class SystemFragment : BaseFragment() { - +open class SystemFragment : BaseFragment() { protected val viewModel: SystemViewModel by viewModels(ownerProducer = { this }) private lateinit var bind: ActivitySystemFragmentBinding lateinit var adapter: SystemListAdapter @@ -29,7 +28,6 @@ class SystemFragment : BaseFragment() { viewModel.onClickListItem(groupPosition) } bind.listView.setAdapter(adapter) - //Tutorials.systemTutorials(bind, requireActivity()) return bind.root } diff --git a/app/src/main/kotlin/io/treehouses/remote/ui/tor/TorFragment.kt b/app/src/main/kotlin/io/treehouses/remote/ui/tor/TorFragment.kt index 5ffd26980..e476cfe60 100644 --- a/app/src/main/kotlin/io/treehouses/remote/ui/tor/TorFragment.kt +++ b/app/src/main/kotlin/io/treehouses/remote/ui/tor/TorFragment.kt @@ -24,12 +24,12 @@ import io.treehouses.remote.databinding.ActivityTorFragmentBinding import io.treehouses.remote.utils.DialogUtils import io.treehouses.remote.utils.TunnelUtils -class TorFragment : BaseFragment() { +open class TorFragment : BaseFragment() { private lateinit var bind: ActivityTorFragmentBinding protected val viewModel: TorViewModel by viewModels(ownerProducer = { this }) - var portsName: ArrayList? = null + private var portsName: ArrayList? = null var adapter: TunnelPortAdapter? = null - var hostName: String = "" + private var hostName: String = "" override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { bind = ActivityTorFragmentBinding.inflate(inflater, container, false) @@ -56,10 +56,11 @@ class TorFragment : BaseFragment() { private fun setListeners() { bind.btnHostName.setOnClickListener { val builder = AlertDialog.Builder(ContextThemeWrapper(context, R.style.CustomAlertDialogStyle)).setTitle("Tor Hostname") - .setMessage(hostName).setPositiveButton("Copy") { _, _ -> viewModel.addHostName(hostName) } - .setNegativeButton("Exit", null) + .setMessage(hostName).setPositiveButton("Copy") { _, _ -> + viewModel.addHostName(hostName) + }.setNegativeButton("Exit", null) val dialog = builder.create() - dialog.window!!.setBackgroundDrawableResource(android.R.color.transparent) + dialog.window?.setBackgroundDrawableResource(android.R.color.transparent) dialog.show() } bind.notifyNow.setOnClickListener { @@ -69,9 +70,9 @@ class TorFragment : BaseFragment() { viewModel.addNotification(isChecked) } bind.portList.onItemClickListener = OnItemClickListener { _: AdapterView<*>?, _: View?, position: Int, _: Long -> - val deleteAllPortsButtonSelected = portsName!!.size > 1 && position == portsName!!.size - 1 + val deleteAllPortsButtonSelected = (portsName?.size ?: 0) > 1 && position == (portsName?.size ?: 0) - 1 if (deleteAllPortsButtonSelected) DialogUtils.createAlertDialog(context, "Delete All Ports?") { viewModel.addPortList() } - else DialogUtils.createAlertDialog(context, "Delete Port " + portsName!![position] + " ?") { viewModel.promptDeletePort(portsName, position) } + else DialogUtils.createAlertDialog(context, "Delete Port " + (portsName?.get(position)) + " ?") { viewModel.promptDeletePort(portsName, position) } } bind.btnTorStart.setOnClickListener { viewModel.addStart(bind.btnTorStart.text.toString()) @@ -113,12 +114,6 @@ class TorFragment : BaseFragment() { viewModel.portsNameList.observe(viewLifecycleOwner) { portsName = it adapter = TunnelUtils.getPortAdapter(requireContext(), portsName) -// try { -// adapter = TunnelPortAdapter(requireContext(), portsName!!) -// logE("adapter successful") -// } catch (e: Exception) { -// logE(e.toString()) -// } val portList = requireView().findViewById(R.id.portList) portList.adapter = adapter } @@ -134,27 +129,27 @@ class TorFragment : BaseFragment() { bind.btnAddPort.setOnClickListener { inputExternal.clearFocus() inputInternal.clearFocus() - dialog.window!!.setBackgroundDrawableResource(android.R.color.transparent) + dialog.window?.setBackgroundDrawableResource(android.R.color.transparent) dialog.show() } val addingPortButton = dialog.findViewById