Update dependencies

This commit is contained in:
Mygod
2020-01-19 14:14:21 +08:00
parent 0e527de3b9
commit 006e4e47c0
21 changed files with 131 additions and 160 deletions

View File

@@ -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'

Binary file not shown.

View File

@@ -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

29
gradlew vendored
View File

@@ -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" "$@"

View File

@@ -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'

View File

@@ -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<SkuDetails>? = 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/")
}
}
}

View File

@@ -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<ClientViewModel>()
val model by viewModels<ClientViewModel>()
if (RepeaterService.supported) ServiceForegroundConnector(this, model, RepeaterService::class)
model.clients.observe(this) { clients ->
val count = clients.count {

View File

@@ -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()
}

View File

@@ -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<Pair<String, Long>, 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<ClientViewModel>().clients.observe(this) {
(activity as MainActivity).viewModels<ClientViewModel>().value.clients.observe(this) {
adapter.submitList(it.toMutableList())
}
return binding.root

View File

@@ -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<ConfigHolder>()
private val holder by parent.viewModels<ConfigHolder>()
override fun bindTo(viewHolder: RecyclerView.ViewHolder) {
(viewHolder as ViewHolder).binding.data = data

View File

@@ -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<String> = 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)
}

View File

@@ -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()

View File

@@ -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()
}
}

View File

@@ -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<WifiApDialogFragment.Arg, WifiA
}
}
private lateinit var dialogView: View
private lateinit var dialogView: DialogWifiApBinding
private lateinit var bandOptions: MutableList<BandOption>
private var started = false
private val selectedSecurity get() =
@@ -92,14 +92,14 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
override fun AlertDialog.Builder.prepare(listener: DialogInterface.OnClickListener) {
val activity = requireActivity()
@SuppressLint("InflateParams")
dialogView = activity.layoutInflater.inflate(R.layout.dialog_wifi_ap, null)
setView(dialogView)
dialogView = DialogWifiApBinding.inflate(activity.layoutInflater)
setView(dialogView.root)
if (!arg.readOnly) setPositiveButton(R.string.wifi_save, listener)
setNegativeButton(R.string.donations__button_close, null)
dialogView.toolbar.inflateMenu(R.menu.toolbar_configuration)
dialogView.toolbar.setOnMenuItemClickListener(this@WifiApDialogFragment)
if (!arg.readOnly) dialogView.ssid.addTextChangedListener(this@WifiApDialogFragment)
if (arg.p2pMode) dialogView.security_wrapper.isGone = true else dialogView.security.apply {
if (arg.p2pMode) dialogView.securityWrapper.isGone = true else dialogView.security.apply {
adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_item, 0,
WifiConfiguration.KeyMgmt.strings).apply {
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
@@ -107,7 +107,7 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) = 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<WifiApDialogFragment.Arg, WifiA
if (Build.VERSION.SDK_INT < 23) {
setSelection(bandOptions.indexOfFirst { it.apChannel == RepeaterService.operatingChannel })
}
} else dialogView.band_wrapper.isGone = true
} else dialogView.bandWrapper.isGone = true
populateFromConfiguration(arg.configuration)
}
@@ -165,7 +165,7 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
WifiConfiguration.KeyMgmt.WPA_PSK, WPA2_PSK -> 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

View File

@@ -123,15 +123,3 @@ var MenuItem.isNotGone: Boolean
isVisible = value
isEnabled = value
}
fun <K, V> MutableMap<K, V>.computeIfAbsentCompat(key: K, value: () -> V) = if (Build.VERSION.SDK_INT >= 24)
computeIfAbsent(key) { value() } else this[key] ?: value().also { put(key, it) }
fun <K, V> MutableMap<K, V>.putIfAbsentCompat(key: K, value: V) = if (Build.VERSION.SDK_INT >= 24)
putIfAbsent(key, value) else this[key] ?: put(key, value)
fun <K, V> MutableMap<K, V>.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
}

View File

@@ -1,10 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<layout
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
@@ -46,5 +44,3 @@
tools:ignore="PxUsage"/>
</LinearLayout>
</layout>

View File

@@ -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">
<androidx.emoji.widget.EmojiEditText
android:id="@android:id/edit"
android:layout_width="match_parent"

View File

@@ -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">
<EditText
android:id="@android:id/edit"
android:layout_width="match_parent"

View File

@@ -1,9 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/swipeRefresher"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -16,4 +14,3 @@
android:scrollbars="vertical"
tools:listitem="@layout/listitem_client"/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</layout>

View File

@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
<Button
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/donations__more_donate_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/settings_misc_donate_more"/>
android:text="@string/settings_misc_donate_more"
tools:viewBindingIgnore="true"/>

View File

@@ -1,12 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/interfaces"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:scrollbars="vertical"
tools:listitem="@layout/listitem_interface"/>
</layout>