diff --git a/build.gradle b/build.gradle index 3b9d7658..81ddb8da 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ buildscript { } } dependencies { - classpath 'com.android.tools.build:gradle:3.5.3' + classpath 'com.android.tools.build:gradle:4.0.0-alpha08' classpath 'com.github.ben-manes:gradle-versions-plugin:0.27.0' classpath 'com.google.gms:google-services:4.3.3' classpath 'io.fabric.tools:gradle:1.31.2' diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 5c2d1cf0..cc4fdc29 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1ba7206f..31a0802f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 83f2acfd..2fe81a7d 100755 --- a/gradlew +++ b/gradlew @@ -154,19 +154,19 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $i + 1` done case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi @@ -175,14 +175,9 @@ save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -APP_ARGS=$(save "$@") +APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - exec "$JAVACMD" "$@" diff --git a/mobile/build.gradle b/mobile/build.gradle index 3b3b2b17..3787a455 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -11,7 +11,7 @@ if (!getGradle().getStartParameter().getTaskRequests().toString().contains("Fdro def javaVersion = JavaVersion.VERSION_1_8 def aux = [ 'com.crashlytics.sdk.android:crashlytics:2.10.1', - 'com.google.firebase:firebase-analytics:17.2.1', + 'com.google.firebase:firebase-analytics:17.2.2', ] def lifecycleVersion = '2.2.0-rc03' def roomVersion = '2.2.3' @@ -19,6 +19,7 @@ def roomVersion = '2.2.3' android { compileSdkVersion 29 compileOptions { + coreLibraryDesugaringEnabled true sourceCompatibility javaVersion targetCompatibility javaVersion } @@ -37,6 +38,10 @@ android { ] buildConfigField "boolean", "DONATIONS", "true" } + buildFeatures { + dataBinding = true + viewBinding = true + } buildTypes { debug { pseudoLocalesEnabled true @@ -47,7 +52,6 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } - dataBinding.enabled = true flavorDimensions("freedom") packagingOptions.exclude '**/*.kotlin_*' productFlavors { @@ -73,22 +77,23 @@ androidExtensions { } dependencies { + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.4' kapt "androidx.room:room-compiler:$roomVersion" implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.browser:browser:1.2.0' implementation 'androidx.core:core-ktx:1.1.0' implementation 'androidx.emoji:emoji:1.0.0' + implementation 'androidx.fragment:fragment-ktx:1.2.0-rc05' implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion" implementation "androidx.lifecycle:lifecycle-extensions:$lifecycleVersion" implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion" implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion" implementation 'androidx.preference:preference:1.1.0' implementation "androidx.room:room-ktx:$roomVersion" implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' implementation 'com.android.billingclient:billing-ktx:2.1.0' implementation 'com.github.topjohnwu.libsu:core:2.5.1' - implementation 'com.google.android.material:material:1.1.0-rc01' + implementation 'com.google.android.material:material:1.1.0-rc02' implementation 'com.google.zxing:core:3.4.0' implementation 'com.jakewharton.timber:timber:4.7.1' implementation 'com.linkedin.dexmaker:dexmaker:2.25.1' diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/EBegFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/EBegFragment.kt index 6cbab492..0767c197 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/EBegFragment.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/EBegFragment.kt @@ -6,14 +6,13 @@ import android.view.View import android.view.ViewGroup import android.widget.ArrayAdapter import android.widget.Button -import android.widget.Spinner import androidx.appcompat.app.AppCompatDialogFragment import androidx.lifecycle.lifecycleScope import be.mygod.vpnhotspot.App.Companion.app +import be.mygod.vpnhotspot.databinding.FragmentEbegBinding import be.mygod.vpnhotspot.util.launchUrl import be.mygod.vpnhotspot.widget.SmartSnackbar import com.android.billingclient.api.* -import kotlinx.android.synthetic.main.fragment_ebeg.view.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -65,11 +64,11 @@ class EBegFragment : AppCompatDialogFragment() { } } - private lateinit var googleSpinner: Spinner + private lateinit var binding: FragmentEbegBinding private var skus: List? = null set(value) { field = value - googleSpinner.apply { + binding.donationsGoogleAndroidMarketSpinner.apply { val adapter = ArrayAdapter(context ?: return, android.R.layout.simple_spinner_item, value?.map { it.price } ?: listOf("…")) adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) @@ -77,12 +76,13 @@ class EBegFragment : AppCompatDialogFragment() { } } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View = - inflater.inflate(R.layout.fragment_ebeg, container, false) + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + binding = FragmentEbegBinding.inflate(inflater, container, false) + return binding.root + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) dialog!!.setTitle(R.string.settings_misc_donate) - googleSpinner = view.donations__google_android_market_spinner lifecycleScope.launchWhenCreated { billingClient.querySkuDetails(SkuDetailsParams.newBuilder().apply { setSkusList(listOf("donate001", "donate002", "donate005", "donate010", "donate020", "donate050", @@ -95,14 +95,15 @@ class EBegFragment : AppCompatDialogFragment() { } } } - view.donations__google_android_market_donate_button.setOnClickListener { - val sku = skus?.getOrNull(googleSpinner.selectedItemPosition) + binding.donationsGoogleAndroidMarketDonateButton.setOnClickListener { + val sku = skus?.getOrNull(binding.donationsGoogleAndroidMarketSpinner.selectedItemPosition) if (sku != null) billingClient.launchBillingFlow(requireActivity(), BillingFlowParams.newBuilder().apply { setSkuDetails(sku) }.build()) else SmartSnackbar.make(R.string.donations__google_android_market_not_supported).show() } @Suppress("ConstantConditionIf") - if (BuildConfig.DONATIONS) (view.donations__more_stub.inflate() as Button) - .setOnClickListener { requireContext().launchUrl("https://mygod.be/donate/") } + if (BuildConfig.DONATIONS) (binding.donationsMoreStub.inflate() as Button).setOnClickListener { + requireContext().launchUrl("https://mygod.be/donate/") + } } } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/MainActivity.kt b/mobile/src/main/java/be/mygod/vpnhotspot/MainActivity.kt index 9c3b09c4..2763efdc 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/MainActivity.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/MainActivity.kt @@ -3,12 +3,10 @@ package be.mygod.vpnhotspot import android.content.Intent import android.os.Bundle import android.view.MenuItem +import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat -import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.get import androidx.lifecycle.observe import be.mygod.vpnhotspot.client.ClientViewModel import be.mygod.vpnhotspot.client.ClientsFragment @@ -22,16 +20,15 @@ import com.google.android.material.bottomnavigation.BottomNavigationView import java.net.Inet4Address class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener { - private lateinit var binding: ActivityMainBinding - val provider by lazy { ViewModelProvider(this) } + lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - binding = DataBindingUtil.setContentView(this, R.layout.activity_main) - binding.lifecycleOwner = this + binding = ActivityMainBinding.inflate(layoutInflater) + setContentView(binding.root) binding.navigation.setOnNavigationItemSelectedListener(this) if (savedInstanceState == null) displayFragment(TetheringFragment()) - val model = provider.get() + val model by viewModels() if (RepeaterService.supported) ServiceForegroundConnector(this, model, RepeaterService::class) model.clients.observe(this) { clients -> val count = clients.count { diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/RoutingManager.kt b/mobile/src/main/java/be/mygod/vpnhotspot/RoutingManager.kt index 60ca378b..fcd0e204 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/RoutingManager.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/RoutingManager.kt @@ -5,8 +5,6 @@ import android.os.Build import be.mygod.vpnhotspot.App.Companion.app import be.mygod.vpnhotspot.net.Routing import be.mygod.vpnhotspot.net.wifi.WifiDoubleLock -import be.mygod.vpnhotspot.util.putIfAbsentCompat -import be.mygod.vpnhotspot.util.removeCompat import be.mygod.vpnhotspot.widget.SmartSnackbar import timber.log.Timber @@ -56,7 +54,7 @@ abstract class RoutingManager(private val caller: Any, val downstream: String, p val started get() = active[downstream] === this private var routing: Routing? = null - fun start() = when (val other = active.putIfAbsentCompat(downstream, this)) { + fun start() = when (val other = active.putIfAbsent(downstream, this)) { null -> { if (isWifi) WifiDoubleLock.acquire(this) initRouting() @@ -85,7 +83,7 @@ abstract class RoutingManager(private val caller: Any, val downstream: String, p protected abstract fun Routing.configure() fun stop() { - if (active.removeCompat(downstream, this)) { + if (active.remove(downstream, this)) { if (isWifi) WifiDoubleLock.release(this) routing?.revert() } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/client/ClientsFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/client/ClientsFragment.kt index cc10300d..1ec06f90 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/client/ClientsFragment.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/client/ClientsFragment.kt @@ -12,12 +12,11 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import android.widget.EditText +import androidx.activity.viewModels import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.PopupMenu import androidx.databinding.BaseObservable -import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment -import androidx.lifecycle.get import androidx.lifecycle.lifecycleScope import androidx.lifecycle.observe import androidx.recyclerview.widget.DefaultItemAnimator @@ -38,7 +37,6 @@ import be.mygod.vpnhotspot.room.ClientStats import be.mygod.vpnhotspot.room.TrafficRecord import be.mygod.vpnhotspot.room.macToString import be.mygod.vpnhotspot.util.SpanFormatter -import be.mygod.vpnhotspot.util.computeIfAbsentCompat import be.mygod.vpnhotspot.util.toPluralInt import be.mygod.vpnhotspot.widget.SmartSnackbar import kotlinx.android.parcel.Parcelize @@ -182,7 +180,7 @@ class ClientsFragment : Fragment() { val client = getItem(position) holder.binding.client = client holder.binding.rate = - rates.computeIfAbsentCompat(Pair(client.iface, client.mac)) { TrafficRate() } + rates.computeIfAbsent(Pair(client.iface, client.mac)) { TrafficRate() } holder.binding.executePendingBindings() } @@ -197,7 +195,7 @@ class ClientsFragment : Fragment() { check(newRecord.receivedPackets == oldRecord.receivedPackets) check(newRecord.receivedBytes == oldRecord.receivedBytes) } else { - val rate = rates.computeIfAbsentCompat(Pair(newRecord.downstream, newRecord.mac)) { TrafficRate() } + val rate = rates.computeIfAbsent(Pair(newRecord.downstream, newRecord.mac)) { TrafficRate() } if (rate.send < 0 || rate.receive < 0) { rate.send = 0 rate.receive = 0 @@ -215,8 +213,7 @@ class ClientsFragment : Fragment() { private var rates = HashMap, TrafficRate>() override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - binding = DataBindingUtil.inflate(inflater, R.layout.fragment_clients, container, false) - binding.lifecycleOwner = this + binding = FragmentClientsBinding.inflate(inflater, container, false) binding.clients.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false) binding.clients.itemAnimator = DefaultItemAnimator() binding.clients.adapter = adapter @@ -224,7 +221,7 @@ class ClientsFragment : Fragment() { binding.swipeRefresher.setOnRefreshListener { IpNeighbourMonitor.instance?.flush() } - (activity as MainActivity).provider.get().clients.observe(this) { + (activity as MainActivity).viewModels().value.clients.observe(this) { adapter.submitList(it.toMutableList()) } return binding.root diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt index cf7381bc..17d1a1f1 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt @@ -20,9 +20,8 @@ import androidx.appcompat.app.AlertDialog import androidx.core.content.ContextCompat import androidx.databinding.BaseObservable import androidx.databinding.Bindable +import androidx.fragment.app.viewModels import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.get import androidx.recyclerview.widget.RecyclerView import be.mygod.vpnhotspot.* import be.mygod.vpnhotspot.databinding.ListitemRepeaterBinding @@ -136,7 +135,7 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic internal var binder: RepeaterService.Binder? = null private var p2pInterface: String? = null @Suppress("DEPRECATION") - private val holder = ViewModelProvider(parent).get() + private val holder by parent.viewModels() override fun bindTo(viewHolder: RecyclerView.ViewHolder) { (viewHolder as ViewHolder).binding.data = data diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt index 0e107c7e..6106e88f 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt @@ -12,7 +12,6 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat -import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.DefaultItemAnimator @@ -31,7 +30,6 @@ import be.mygod.vpnhotspot.util.ServiceForegroundConnector import be.mygod.vpnhotspot.util.broadcastReceiver import be.mygod.vpnhotspot.util.isNotGone import be.mygod.vpnhotspot.widget.SmartSnackbar -import kotlinx.android.synthetic.main.activity_main.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import timber.log.Timber @@ -107,8 +105,8 @@ class TetheringFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClick } private fun updateMonitorList(canMonitor: List = emptyList()) { - val activity = activity - val item = activity?.toolbar?.menu?.findItem(R.id.monitor) ?: return // assuming no longer foreground + val activity = activity as? MainActivity + val item = activity?.binding?.toolbar?.menu?.findItem(R.id.monitor) ?: return // assuming no longer foreground item.isNotGone = canMonitor.isNotEmpty() item.subMenu.apply { clear() @@ -157,14 +155,13 @@ class TetheringFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClick } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - binding = DataBindingUtil.inflate(inflater, R.layout.fragment_tethering, container, false) - binding.lifecycleOwner = this + binding = FragmentTetheringBinding.inflate(inflater, container, false) binding.interfaces.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false) binding.interfaces.itemAnimator = DefaultItemAnimator() binding.interfaces.adapter = adapter adapter.update(emptyList(), emptyList(), emptyList()) ServiceForegroundConnector(this, this, TetheringService::class) - requireActivity().toolbar.apply { + (activity as MainActivity).binding.toolbar.apply { inflateMenu(R.menu.toolbar_tethering) setOnMenuItemClickListener(this@TetheringFragment) } @@ -173,7 +170,7 @@ class TetheringFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClick override fun onDestroyView() { super.onDestroyView() - requireActivity().toolbar.apply { + (activity as MainActivity).binding.toolbar.apply { menu.clear() setOnMenuItemClickListener(null) } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/Routing.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/Routing.kt index c8aaae26..f18b93a6 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/Routing.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/Routing.kt @@ -11,7 +11,6 @@ import be.mygod.vpnhotspot.net.monitor.TrafficRecorder import be.mygod.vpnhotspot.net.monitor.UpstreamMonitor import be.mygod.vpnhotspot.room.AppDatabase import be.mygod.vpnhotspot.util.RootSession -import be.mygod.vpnhotspot.util.computeIfAbsentCompat import be.mygod.vpnhotspot.widget.SmartSnackbar import timber.log.Timber import java.io.IOException @@ -235,7 +234,7 @@ class Routing(private val caller: Any, private val downstream: String) : IpNeigh AppDatabase.instance.clientRecordDao.lookupOrDefaultBlocking(neighbour.lladdr).blocked) continue toRemove.remove(neighbour.ip) try { - clients.computeIfAbsentCompat(neighbour.ip) { Client(neighbour.ip, neighbour.lladdr) } + clients.computeIfAbsent(neighbour.ip) { Client(neighbour.ip, neighbour.lladdr) } } catch (e: Exception) { Timber.w(e) SmartSnackbar.make(e).show() diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/TrafficRecorder.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/TrafficRecorder.kt index 4cf954de..91c302bd 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/TrafficRecorder.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/TrafficRecorder.kt @@ -9,7 +9,6 @@ import be.mygod.vpnhotspot.room.TrafficRecord import be.mygod.vpnhotspot.util.Event2 import be.mygod.vpnhotspot.util.RootSession import be.mygod.vpnhotspot.util.parseNumericAddress -import be.mygod.vpnhotspot.util.putIfAbsentCompat import be.mygod.vpnhotspot.widget.SmartSnackbar import timber.log.Timber import java.net.InetAddress @@ -29,7 +28,7 @@ object TrafficRecorder { AppDatabase.instance.trafficRecordDao.insert(record) synchronized(this) { DebugHelper.log(TAG, "Registering $ip%$downstream") - check(records.putIfAbsentCompat(Pair(ip, downstream), record) == null) + check(records.putIfAbsent(Pair(ip, downstream), record) == null) scheduleUpdateLocked() } } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/configuration/WifiApDialogFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/configuration/WifiApDialogFragment.kt index dfd88e16..05928b04 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/configuration/WifiApDialogFragment.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/configuration/WifiApDialogFragment.kt @@ -21,12 +21,12 @@ import be.mygod.vpnhotspot.AlertDialogFragment import be.mygod.vpnhotspot.App.Companion.app import be.mygod.vpnhotspot.R import be.mygod.vpnhotspot.RepeaterService +import be.mygod.vpnhotspot.databinding.DialogWifiApBinding import be.mygod.vpnhotspot.util.QRCodeDialog import be.mygod.vpnhotspot.util.toByteArray import be.mygod.vpnhotspot.util.toParcelable import be.mygod.vpnhotspot.widget.SmartSnackbar import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.dialog_wifi_ap.view.* import java.nio.charset.Charset /** @@ -72,7 +72,7 @@ class WifiApDialogFragment : AlertDialogFragment private var started = false private val selectedSecurity get() = @@ -92,14 +92,14 @@ class WifiApDialogFragment : AlertDialogFragment?) = error("Must select something") override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { - dialogView.password_wrapper.isGone = position == WifiConfiguration.KeyMgmt.NONE + dialogView.passwordWrapper.isGone = position == WifiConfiguration.KeyMgmt.NONE } } } @@ -133,7 +133,7 @@ class WifiApDialogFragment : AlertDialogFragment dialogView.password.length() >= 8 else -> true // do not try to validate } - dialogView.password_wrapper.error = if (passwordValid) null else { + dialogView.passwordWrapper.error = if (passwordValid) null else { requireContext().getString(R.string.credentials_password_too_short) } (dialog as? AlertDialog)?.getButton(DialogInterface.BUTTON_POSITIVE)?.isEnabled = ssidValid && passwordValid diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt b/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt index c42c9155..47e2c4f2 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt @@ -123,15 +123,3 @@ var MenuItem.isNotGone: Boolean isVisible = value isEnabled = value } - -fun MutableMap.computeIfAbsentCompat(key: K, value: () -> V) = if (Build.VERSION.SDK_INT >= 24) - computeIfAbsent(key) { value() } else this[key] ?: value().also { put(key, it) } -fun MutableMap.putIfAbsentCompat(key: K, value: V) = if (Build.VERSION.SDK_INT >= 24) - putIfAbsent(key, value) else this[key] ?: put(key, value) -fun MutableMap.removeCompat(key: K, value: V) = if (Build.VERSION.SDK_INT >= 24) remove(key, value) else { - val curValue = get(key) - if (curValue === value && (curValue != null || containsKey(key))) { - remove(key) - true - } else false -} diff --git a/mobile/src/main/res/layout/activity_main.xml b/mobile/src/main/res/layout/activity_main.xml index e96761d8..56fbf6a7 100644 --- a/mobile/src/main/res/layout/activity_main.xml +++ b/mobile/src/main/res/layout/activity_main.xml @@ -1,50 +1,46 @@ - + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + tools:context="be.mygod.vpnhotspot.MainActivity"> - + android:layout_height="?attr/actionBarSize" + android:background="?attr/colorPrimary" + android:elevation="4dp" + app:title="@string/app_name"/> - + + + android:layout_height="match_parent"/> - + - + - + - - - - - - - + diff --git a/mobile/src/main/res/layout/dialog_nickname.xml b/mobile/src/main/res/layout/dialog_nickname.xml index 2d136aa2..4800be2d 100644 --- a/mobile/src/main/res/layout/dialog_nickname.xml +++ b/mobile/src/main/res/layout/dialog_nickname.xml @@ -3,7 +3,8 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="wrap_content"> + android:layout_height="wrap_content" + tools:viewBindingIgnore="true"> + android:layout_height="wrap_content" + tools:viewBindingIgnore="true"> - + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/swipeRefresher" + android:layout_width="match_parent" + android:layout_height="match_parent"> - - - - - + android:layout_height="match_parent" + android:clipToPadding="false" + android:scrollbars="vertical" + tools:listitem="@layout/listitem_client"/> + diff --git a/mobile/src/main/res/layout/fragment_ebeg_more.xml b/mobile/src/main/res/layout/fragment_ebeg_more.xml index a70d5cf6..c1ba416f 100644 --- a/mobile/src/main/res/layout/fragment_ebeg_more.xml +++ b/mobile/src/main/res/layout/fragment_ebeg_more.xml @@ -1,6 +1,9 @@ -