From eda0208fcb3de7cd9d9a867f4d569a2821ccee3f Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Wed, 17 Jul 2024 12:04:37 +0700 Subject: [PATCH 1/7] Switch to MaterialAlertDialog everywhere Works much better with Material themes Signed-off-by: Aayush Gupta --- app/src/main/java/app/opass/ccip/ui/MainActivity.kt | 4 ++-- .../main/java/app/opass/ccip/ui/auth/TokenCheckFragment.kt | 4 ++-- .../java/app/opass/ccip/ui/fastpass/FastPassFragment.kt | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/app/opass/ccip/ui/MainActivity.kt b/app/src/main/java/app/opass/ccip/ui/MainActivity.kt index d965d68a..9715f669 100644 --- a/app/src/main/java/app/opass/ccip/ui/MainActivity.kt +++ b/app/src/main/java/app/opass/ccip/ui/MainActivity.kt @@ -12,7 +12,6 @@ import android.widget.ImageView import android.widget.RelativeLayout import android.widget.TextView import androidx.appcompat.app.ActionBarDrawerToggle -import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.coordinatorlayout.widget.CoordinatorLayout @@ -41,6 +40,7 @@ import app.opass.ccip.util.CryptoUtil import app.opass.ccip.util.PreferenceUtil import app.opass.ccip.util.WifiUtil import coil.load +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.navigation.NavigationView import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.CoroutineScope @@ -337,7 +337,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope { } private fun showWifiDialog(networks: List) { - val dialog = AlertDialog.Builder(this).setTitle(R.string.choose_network_to_connect).create() + val dialog = MaterialAlertDialogBuilder(this).setTitle(R.string.choose_network_to_connect).create() val rv = RecyclerView(this).apply { layoutParams = RecyclerView.LayoutParams( RecyclerView.LayoutParams.MATCH_PARENT, diff --git a/app/src/main/java/app/opass/ccip/ui/auth/TokenCheckFragment.kt b/app/src/main/java/app/opass/ccip/ui/auth/TokenCheckFragment.kt index 70db759e..a7b81d5c 100644 --- a/app/src/main/java/app/opass/ccip/ui/auth/TokenCheckFragment.kt +++ b/app/src/main/java/app/opass/ccip/ui/auth/TokenCheckFragment.kt @@ -1,6 +1,5 @@ package app.opass.ccip.ui.auth -import android.app.AlertDialog import android.app.NotificationManager import android.content.Context import android.os.Bundle @@ -19,6 +18,7 @@ import app.opass.ccip.extension.isInverted import app.opass.ccip.network.CCIPClient import app.opass.ccip.util.PreferenceUtil import coil.load +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.onesignal.OneSignal import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -77,7 +77,7 @@ class TokenCheckFragment : AuthActivity.PageFragment() { val manager = mActivity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager if (!manager.areNotificationsEnabled()) { - AlertDialog.Builder(mActivity) + MaterialAlertDialogBuilder(mActivity) .setMessage(R.string.on_login_request_notification_permission) .setPositiveButton(android.R.string.ok) { _, _ -> GlobalScope.launch { OneSignal.Notifications.requestPermission(true) } diff --git a/app/src/main/java/app/opass/ccip/ui/fastpass/FastPassFragment.kt b/app/src/main/java/app/opass/ccip/ui/fastpass/FastPassFragment.kt index d1cfed48..ed864e63 100644 --- a/app/src/main/java/app/opass/ccip/ui/fastpass/FastPassFragment.kt +++ b/app/src/main/java/app/opass/ccip/ui/fastpass/FastPassFragment.kt @@ -6,7 +6,6 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast -import androidx.appcompat.app.AlertDialog import androidx.core.view.updatePadding import androidx.fragment.app.Fragment import androidx.recyclerview.widget.DefaultItemAnimator @@ -25,6 +24,7 @@ import app.opass.ccip.ui.MainActivity import app.opass.ccip.ui.auth.AuthActivity import app.opass.ccip.util.JsonUtil import app.opass.ccip.util.PreferenceUtil +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -195,7 +195,7 @@ class FastPassFragment : Fragment(), CoroutineScope { Toast.makeText(mActivity, message, Toast.LENGTH_LONG).show() } response.code() == 403 -> { - AlertDialog.Builder(mActivity) + MaterialAlertDialogBuilder(mActivity) .setTitle(R.string.connect_to_conference_wifi) .setPositiveButton(android.R.string.ok, null) .show() @@ -209,7 +209,7 @@ class FastPassFragment : Fragment(), CoroutineScope { } private fun showConfirmDialog(scenario: Scenario) { - AlertDialog.Builder(mActivity) + MaterialAlertDialogBuilder(mActivity) .setTitle(R.string.confirm_dialog_title) .setPositiveButton(R.string.positive_button) { dialogInterface, i -> useScenario(scenario) } .setNegativeButton(R.string.negative_button, null) From ff40a2b119b915b1aca8503d5995ebeb6ca7ef33 Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Wed, 17 Jul 2024 12:13:00 +0700 Subject: [PATCH 2/7] AndroidManifest: Enable predictive back animations Signed-off-by: Aayush Gupta --- app/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 78b835fb..50c70cb4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ Date: Wed, 17 Jul 2024 12:17:14 +0700 Subject: [PATCH 3/7] treewide: Optimize imports using AS Get rid of wildcard imports otherwise ktlint complains about it Signed-off-by: Aayush Gupta --- .../main/java/app/opass/ccip/model/Room.kt | 2 +- .../main/java/app/opass/ccip/model/Session.kt | 2 +- .../java/app/opass/ccip/model/SessionLang.kt | 2 +- .../java/app/opass/ccip/model/SessionTag.kt | 2 +- .../java/app/opass/ccip/model/SessionType.kt | 2 +- .../main/java/app/opass/ccip/model/Speaker.kt | 2 +- .../app/opass/ccip/ui/DrawerMenuAdapter.kt | 4 +++- .../java/app/opass/ccip/ui/PuzzleFragment.kt | 7 +++++- .../ui/announcement/AnnouncementAdapter.kt | 3 ++- .../app/opass/ccip/ui/auth/AuthActivity.kt | 7 +++++- .../ccip/ui/fastpass/CountdownActivity.kt | 2 +- .../opass/ccip/ui/fastpass/ScenarioAdapter.kt | 3 ++- .../ccip/ui/schedule/ScheduleTabFragment.kt | 24 +++++++++++++++---- .../ccip/ui/schedule/ScheduleViewModel.kt | 2 +- .../java/app/opass/ccip/util/AlarmUtil.kt | 2 +- .../java/app/opass/ccip/util/LocaleUtil.kt | 2 +- .../ccip/util/NotificationClickListener.kt | 2 +- 17 files changed, 50 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/app/opass/ccip/model/Room.kt b/app/src/main/java/app/opass/ccip/model/Room.kt index a642361b..f55ab6da 100644 --- a/app/src/main/java/app/opass/ccip/model/Room.kt +++ b/app/src/main/java/app/opass/ccip/model/Room.kt @@ -2,7 +2,7 @@ package app.opass.ccip.model import android.content.Context import app.opass.ccip.util.LocaleUtil -import java.util.* +import java.util.Locale data class Room( val id: String, diff --git a/app/src/main/java/app/opass/ccip/model/Session.kt b/app/src/main/java/app/opass/ccip/model/Session.kt index 8d254aae..0af7b6f5 100644 --- a/app/src/main/java/app/opass/ccip/model/Session.kt +++ b/app/src/main/java/app/opass/ccip/model/Session.kt @@ -3,7 +3,7 @@ package app.opass.ccip.model import android.content.Context import app.opass.ccip.util.LocaleUtil import com.google.gson.annotations.SerializedName -import java.util.* +import java.util.Locale data class Session( val id: String, diff --git a/app/src/main/java/app/opass/ccip/model/SessionLang.kt b/app/src/main/java/app/opass/ccip/model/SessionLang.kt index 69ae3ed3..62717ef2 100644 --- a/app/src/main/java/app/opass/ccip/model/SessionLang.kt +++ b/app/src/main/java/app/opass/ccip/model/SessionLang.kt @@ -2,7 +2,7 @@ package app.opass.ccip.model import android.content.Context import app.opass.ccip.util.LocaleUtil -import java.util.* +import java.util.Locale data class SessionLang( val id: String, diff --git a/app/src/main/java/app/opass/ccip/model/SessionTag.kt b/app/src/main/java/app/opass/ccip/model/SessionTag.kt index 9996efbc..43d8620f 100644 --- a/app/src/main/java/app/opass/ccip/model/SessionTag.kt +++ b/app/src/main/java/app/opass/ccip/model/SessionTag.kt @@ -2,7 +2,7 @@ package app.opass.ccip.model import android.content.Context import app.opass.ccip.util.LocaleUtil -import java.util.* +import java.util.Locale data class SessionTag( val id: String, diff --git a/app/src/main/java/app/opass/ccip/model/SessionType.kt b/app/src/main/java/app/opass/ccip/model/SessionType.kt index c02b833c..2313ead4 100644 --- a/app/src/main/java/app/opass/ccip/model/SessionType.kt +++ b/app/src/main/java/app/opass/ccip/model/SessionType.kt @@ -2,7 +2,7 @@ package app.opass.ccip.model import android.content.Context import app.opass.ccip.util.LocaleUtil -import java.util.* +import java.util.Locale data class SessionType( val id: String, diff --git a/app/src/main/java/app/opass/ccip/model/Speaker.kt b/app/src/main/java/app/opass/ccip/model/Speaker.kt index c889eedd..23e1c34b 100644 --- a/app/src/main/java/app/opass/ccip/model/Speaker.kt +++ b/app/src/main/java/app/opass/ccip/model/Speaker.kt @@ -2,7 +2,7 @@ package app.opass.ccip.model import android.content.Context import app.opass.ccip.util.LocaleUtil -import java.util.* +import java.util.Locale data class Speaker( val id: String, diff --git a/app/src/main/java/app/opass/ccip/ui/DrawerMenuAdapter.kt b/app/src/main/java/app/opass/ccip/ui/DrawerMenuAdapter.kt index 1c0bbe61..c8072884 100644 --- a/app/src/main/java/app/opass/ccip/ui/DrawerMenuAdapter.kt +++ b/app/src/main/java/app/opass/ccip/ui/DrawerMenuAdapter.kt @@ -16,7 +16,9 @@ import androidx.recyclerview.widget.RecyclerView.NO_POSITION import app.opass.ccip.R import app.opass.ccip.model.Feature import app.opass.ccip.model.FeatureType -import app.opass.ccip.ui.DrawerMenuViewHolder.* +import app.opass.ccip.ui.DrawerMenuViewHolder.DividerViewHolder +import app.opass.ccip.ui.DrawerMenuViewHolder.MenuItemViewHolder +import app.opass.ccip.ui.DrawerMenuViewHolder.PlaceholderItemViewHolder import coil.load class DrawerMenuAdapter( diff --git a/app/src/main/java/app/opass/ccip/ui/PuzzleFragment.kt b/app/src/main/java/app/opass/ccip/ui/PuzzleFragment.kt index eae7836c..543ae882 100644 --- a/app/src/main/java/app/opass/ccip/ui/PuzzleFragment.kt +++ b/app/src/main/java/app/opass/ccip/ui/PuzzleFragment.kt @@ -6,7 +6,12 @@ import android.content.Intent import android.content.pm.PackageManager import android.os.Build import android.os.Bundle -import android.view.* +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup import android.webkit.PermissionRequest import android.webkit.WebSettings import androidx.core.view.updatePadding diff --git a/app/src/main/java/app/opass/ccip/ui/announcement/AnnouncementAdapter.kt b/app/src/main/java/app/opass/ccip/ui/announcement/AnnouncementAdapter.kt index 2274dd54..7111ce94 100644 --- a/app/src/main/java/app/opass/ccip/ui/announcement/AnnouncementAdapter.kt +++ b/app/src/main/java/app/opass/ccip/ui/announcement/AnnouncementAdapter.kt @@ -13,7 +13,8 @@ import app.opass.ccip.R import app.opass.ccip.model.Announcement import app.opass.ccip.util.LocaleUtil import java.text.SimpleDateFormat -import java.util.* +import java.util.Date +import java.util.Locale class AnnouncementAdapter(private val mContext: Context, private val announcementList: List) : RecyclerView.Adapter() { diff --git a/app/src/main/java/app/opass/ccip/ui/auth/AuthActivity.kt b/app/src/main/java/app/opass/ccip/ui/auth/AuthActivity.kt index 617f8752..19d8be3f 100644 --- a/app/src/main/java/app/opass/ccip/ui/auth/AuthActivity.kt +++ b/app/src/main/java/app/opass/ccip/ui/auth/AuthActivity.kt @@ -17,7 +17,12 @@ import app.opass.ccip.databinding.ActivityAuthBinding import app.opass.ccip.ui.MainActivity import app.opass.ccip.ui.event.EventActivity import com.google.android.material.snackbar.Snackbar -import com.google.zxing.* +import com.google.zxing.BinaryBitmap +import com.google.zxing.ChecksumException +import com.google.zxing.FormatException +import com.google.zxing.MultiFormatReader +import com.google.zxing.NotFoundException +import com.google.zxing.RGBLuminanceSource import com.google.zxing.common.HybridBinarizer import com.google.zxing.integration.android.IntentIntegrator import java.io.IOException diff --git a/app/src/main/java/app/opass/ccip/ui/fastpass/CountdownActivity.kt b/app/src/main/java/app/opass/ccip/ui/fastpass/CountdownActivity.kt index 8bf6b9de..6f53072c 100644 --- a/app/src/main/java/app/opass/ccip/ui/fastpass/CountdownActivity.kt +++ b/app/src/main/java/app/opass/ccip/ui/fastpass/CountdownActivity.kt @@ -11,7 +11,7 @@ import app.opass.ccip.databinding.ActivityCountdownBinding import app.opass.ccip.model.Scenario import app.opass.ccip.util.JsonUtil import java.text.SimpleDateFormat -import java.util.* +import java.util.Date class CountdownActivity : AppCompatActivity() { companion object { diff --git a/app/src/main/java/app/opass/ccip/ui/fastpass/ScenarioAdapter.kt b/app/src/main/java/app/opass/ccip/ui/fastpass/ScenarioAdapter.kt index a706462c..2fa85ee9 100644 --- a/app/src/main/java/app/opass/ccip/ui/fastpass/ScenarioAdapter.kt +++ b/app/src/main/java/app/opass/ccip/ui/fastpass/ScenarioAdapter.kt @@ -15,7 +15,8 @@ import app.opass.ccip.R import app.opass.ccip.model.Scenario import app.opass.ccip.util.LocaleUtil import java.text.SimpleDateFormat -import java.util.* +import java.util.Date +import java.util.Locale class ScenarioAdapter( private val mContext: Context, diff --git a/app/src/main/java/app/opass/ccip/ui/schedule/ScheduleTabFragment.kt b/app/src/main/java/app/opass/ccip/ui/schedule/ScheduleTabFragment.kt index 3958a8db..2d3c90b5 100644 --- a/app/src/main/java/app/opass/ccip/ui/schedule/ScheduleTabFragment.kt +++ b/app/src/main/java/app/opass/ccip/ui/schedule/ScheduleTabFragment.kt @@ -5,7 +5,13 @@ import android.content.Intent import android.os.Bundle import android.text.Editable import android.text.TextWatcher -import android.view.* +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import android.view.ViewTreeObserver import android.view.animation.DecelerateInterpolator import android.view.inputmethod.EditorInfo import androidx.core.view.isGone @@ -15,7 +21,11 @@ import androidx.fragment.app.viewModels import androidx.lifecycle.distinctUntilChanged import app.opass.ccip.R import app.opass.ccip.databinding.FragmentScheduleTabBinding -import app.opass.ccip.extension.* +import app.opass.ccip.extension.asyncExecute +import app.opass.ccip.extension.doOnApplyWindowInsets +import app.opass.ccip.extension.focusAndShowKeyboard +import app.opass.ccip.extension.hideIme +import app.opass.ccip.extension.updateMargin import app.opass.ccip.model.ConfSchedule import app.opass.ccip.ui.MainActivity import app.opass.ccip.util.JsonUtil @@ -23,11 +33,17 @@ import app.opass.ccip.util.PreferenceUtil import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.snackbar.Snackbar import com.google.android.material.tabs.TabLayout -import kotlinx.coroutines.* +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import okhttp3.OkHttpClient import okhttp3.Request import java.text.SimpleDateFormat -import java.util.* +import java.util.Date +import java.util.Locale import kotlin.coroutines.CoroutineContext class ScheduleTabFragment : Fragment(), CoroutineScope, MainActivity.BackPressAwareFragment { diff --git a/app/src/main/java/app/opass/ccip/ui/schedule/ScheduleViewModel.kt b/app/src/main/java/app/opass/ccip/ui/schedule/ScheduleViewModel.kt index f56fb6e2..83dfa261 100644 --- a/app/src/main/java/app/opass/ccip/ui/schedule/ScheduleViewModel.kt +++ b/app/src/main/java/app/opass/ccip/ui/schedule/ScheduleViewModel.kt @@ -26,7 +26,7 @@ import kotlinx.coroutines.withContext import java.text.ParseException import java.text.ParsePosition import java.text.SimpleDateFormat -import java.util.* +import java.util.Locale private val SDF_DATE = SimpleDateFormat("MM/dd", Locale.US) private val SDF_TIME = SimpleDateFormat("HH:mm", Locale.TAIWAN) diff --git a/app/src/main/java/app/opass/ccip/util/AlarmUtil.kt b/app/src/main/java/app/opass/ccip/util/AlarmUtil.kt index 4d00691a..86092667 100644 --- a/app/src/main/java/app/opass/ccip/util/AlarmUtil.kt +++ b/app/src/main/java/app/opass/ccip/util/AlarmUtil.kt @@ -14,7 +14,7 @@ import app.opass.ccip.model.Session import app.opass.ccip.ui.sessiondetail.SessionDetailActivity import com.google.gson.internal.bind.util.ISO8601Utils import java.text.ParsePosition -import java.util.* +import java.util.Calendar object AlarmUtil { diff --git a/app/src/main/java/app/opass/ccip/util/LocaleUtil.kt b/app/src/main/java/app/opass/ccip/util/LocaleUtil.kt index 426215de..8bc3c527 100644 --- a/app/src/main/java/app/opass/ccip/util/LocaleUtil.kt +++ b/app/src/main/java/app/opass/ccip/util/LocaleUtil.kt @@ -3,7 +3,7 @@ package app.opass.ccip.util import android.annotation.TargetApi import android.content.Context import android.os.Build -import java.util.* +import java.util.Locale object LocaleUtil { @Suppress("DEPRECATION") diff --git a/app/src/main/java/app/opass/ccip/util/NotificationClickListener.kt b/app/src/main/java/app/opass/ccip/util/NotificationClickListener.kt index 7a65bdaf..2de2d3fe 100644 --- a/app/src/main/java/app/opass/ccip/util/NotificationClickListener.kt +++ b/app/src/main/java/app/opass/ccip/util/NotificationClickListener.kt @@ -4,8 +4,8 @@ import android.app.Application import android.content.Intent import android.net.Uri import app.opass.ccip.ui.MainActivity -import com.onesignal.notifications.INotificationClickListener import com.onesignal.notifications.INotificationClickEvent +import com.onesignal.notifications.INotificationClickListener class NotificationClickListener(private val context: Application) : INotificationClickListener { override fun onClick(event: INotificationClickEvent) { From 505cc3939d7c16793f8fa1896ca4936a179a9e8f Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Wed, 14 Feb 2024 20:04:51 +0530 Subject: [PATCH 4/7] WiFiNetwork: Extract WiFi dialog logic to separate fragment Also move it to a new package Signed-off-by: Aayush Gupta --- .../java/app/opass/ccip/ui/MainActivity.kt | 57 ++------------- .../WiFiNetworkAdapter.kt} | 2 +- .../opass/ccip/ui/wifi/WiFiNetworkFragment.kt | 69 +++++++++++++++++++ 3 files changed, 74 insertions(+), 54 deletions(-) rename app/src/main/java/app/opass/ccip/ui/{WifiNetworkAdapter.kt => wifi/WiFiNetworkAdapter.kt} (98%) create mode 100644 app/src/main/java/app/opass/ccip/ui/wifi/WiFiNetworkFragment.kt diff --git a/app/src/main/java/app/opass/ccip/ui/MainActivity.kt b/app/src/main/java/app/opass/ccip/ui/MainActivity.kt index 9715f669..8df18b4c 100644 --- a/app/src/main/java/app/opass/ccip/ui/MainActivity.kt +++ b/app/src/main/java/app/opass/ccip/ui/MainActivity.kt @@ -1,8 +1,6 @@ package app.opass.ccip.ui import android.app.Activity -import android.content.ClipData -import android.content.ClipboardManager import android.content.Intent import android.content.res.Configuration import android.os.Bundle @@ -15,7 +13,6 @@ import androidx.appcompat.app.ActionBarDrawerToggle import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.coordinatorlayout.widget.CoordinatorLayout -import androidx.core.content.getSystemService import androidx.core.net.toUri import androidx.core.view.GravityCompat import androidx.core.view.updatePadding @@ -29,20 +26,17 @@ import app.opass.ccip.extension.setOnApplyWindowInsetsListenerCompat import app.opass.ccip.extension.updateMargin import app.opass.ccip.model.Feature import app.opass.ccip.model.FeatureType -import app.opass.ccip.model.WifiNetworkInfo import app.opass.ccip.network.PortalClient import app.opass.ccip.ui.announcement.AnnouncementFragment import app.opass.ccip.ui.event.EventActivity import app.opass.ccip.ui.fastpass.FastPassFragment import app.opass.ccip.ui.fastpass.MyTicketFragment import app.opass.ccip.ui.schedule.ScheduleTabFragment +import app.opass.ccip.ui.wifi.WiFiNetworkFragment import app.opass.ccip.util.CryptoUtil import app.opass.ccip.util.PreferenceUtil -import app.opass.ccip.util.WifiUtil import coil.load -import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.navigation.NavigationView -import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -275,7 +269,9 @@ class MainActivity : AppCompatActivity(), CoroutineScope { val feature = item.origFeature if (item.shouldShowLaunchIcon) return this.startActivity(Intent(Intent.ACTION_VIEW, feature.url!!.toUri())) if (feature.feature == FeatureType.WIFI) { - feature.wifiNetworks?.let(::showWifiDialog) + feature.wifiNetworks?.let { + WiFiNetworkFragment.show(it, supportFragmentManager) + } mDrawerLayout.closeDrawers() return } @@ -309,51 +305,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope { mDrawerLayout.closeDrawers() } - private fun onWifiSelected(info: WifiNetworkInfo) { - val success = WifiUtil.installNetwork(this, info) - if (success) { - Snackbar - .make(mDrawerLayout, R.string.wifi_saved, Snackbar.LENGTH_SHORT) - .setAnchorView(navbarAnchor) - .show() - } else { - val hasPassword = !info.password.isNullOrEmpty() - if (!hasPassword) { - Snackbar - .make(mDrawerLayout, R.string.failed_to_save_wifi, Snackbar.LENGTH_LONG) - .setAnchorView(navbarAnchor) - .show() - return - } - - getSystemService()?.run { - setPrimaryClip(ClipData.newPlainText("", info.password)) - } ?: return - Snackbar - .make(mDrawerLayout, R.string.failed_to_save_wifi_copied_to_clipboard, Snackbar.LENGTH_LONG) - .setAnchorView(navbarAnchor) - .show() - } - } - - private fun showWifiDialog(networks: List) { - val dialog = MaterialAlertDialogBuilder(this).setTitle(R.string.choose_network_to_connect).create() - val rv = RecyclerView(this).apply { - layoutParams = RecyclerView.LayoutParams( - RecyclerView.LayoutParams.MATCH_PARENT, - RecyclerView.LayoutParams.MATCH_PARENT - ) - layoutManager = LinearLayoutManager(this@MainActivity) - adapter = WifiNetworkAdapter(networks) { info -> - dialog.dismiss() - onWifiSelected(info) - } - } - - dialog.setView(rv) - dialog.show() - } - private fun isFeatureValid(f: Feature) : Boolean { return when (f.feature) { FeatureType.FAST_PASS, diff --git a/app/src/main/java/app/opass/ccip/ui/WifiNetworkAdapter.kt b/app/src/main/java/app/opass/ccip/ui/wifi/WiFiNetworkAdapter.kt similarity index 98% rename from app/src/main/java/app/opass/ccip/ui/WifiNetworkAdapter.kt rename to app/src/main/java/app/opass/ccip/ui/wifi/WiFiNetworkAdapter.kt index 71fc2dde..5e2bcf96 100644 --- a/app/src/main/java/app/opass/ccip/ui/WifiNetworkAdapter.kt +++ b/app/src/main/java/app/opass/ccip/ui/wifi/WiFiNetworkAdapter.kt @@ -1,4 +1,4 @@ -package app.opass.ccip.ui +package app.opass.ccip.ui.wifi import android.view.LayoutInflater import android.view.View diff --git a/app/src/main/java/app/opass/ccip/ui/wifi/WiFiNetworkFragment.kt b/app/src/main/java/app/opass/ccip/ui/wifi/WiFiNetworkFragment.kt new file mode 100644 index 00000000..3a0d7f9b --- /dev/null +++ b/app/src/main/java/app/opass/ccip/ui/wifi/WiFiNetworkFragment.kt @@ -0,0 +1,69 @@ +package app.opass.ccip.ui.wifi + +import android.app.Dialog +import android.content.ClipData +import android.content.ClipboardManager +import android.os.Bundle +import androidx.core.content.getSystemService +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.FragmentManager +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import app.opass.ccip.R +import app.opass.ccip.model.WifiNetworkInfo +import app.opass.ccip.util.WifiUtil +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.snackbar.Snackbar + +class WiFiNetworkFragment(private val wifiNetworkInfoList: List) : + DialogFragment() { + + companion object { + private const val TAG = "WiFiNetworkFragment" + + fun show(wifiNetworkInfoList: List, fragmentManager: FragmentManager) { + WiFiNetworkFragment(wifiNetworkInfoList).show(fragmentManager, TAG) + } + } + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val recyclerView = RecyclerView(requireContext()).apply { + layoutParams = RecyclerView.LayoutParams( + RecyclerView.LayoutParams.MATCH_PARENT, + RecyclerView.LayoutParams.MATCH_PARENT + ) + layoutManager = LinearLayoutManager(requireContext()) + adapter = WifiNetworkAdapter(wifiNetworkInfoList) { info -> + onWifiSelected(info) + dialog?.dismiss() + } + } + return MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.choose_network_to_connect) + .setView(recyclerView) + .create() + } + + private fun onWifiSelected(info: WifiNetworkInfo) { + val rootView = requireActivity().window.decorView.rootView + + // Return early if password is null or empty + if (info.password.isNullOrEmpty()) { + Snackbar.make(rootView, R.string.failed_to_save_wifi, Snackbar.LENGTH_LONG).show() + return + } + + if (WifiUtil.installNetwork(requireContext(), info)) { + Snackbar.make(rootView, R.string.wifi_saved, Snackbar.LENGTH_SHORT).show() + } else { + requireContext().getSystemService()?.run { + setPrimaryClip(ClipData.newPlainText("", info.password)) + } ?: return + Snackbar.make( + rootView, + R.string.failed_to_save_wifi_copied_to_clipboard, + Snackbar.LENGTH_LONG + ).show() + } + } +} From ce6f16263211fd3608d4c6cefad8c19df4093283 Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Wed, 17 Jul 2024 12:51:13 +0700 Subject: [PATCH 5/7] gradle: Format kotlin scripts using ktlint Signed-off-by: Aayush Gupta --- app/build.gradle.kts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 661bf040..79f878f1 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -28,7 +28,7 @@ android { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android.txt"), - "proguard-rules.pro" + "proguard-rules.pro", ) } } @@ -38,7 +38,6 @@ android { } } - compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 From 670b605d895a6008bb51f6e72eed36f9fe4450a7 Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Sun, 21 Jul 2024 20:52:45 +0700 Subject: [PATCH 6/7] Drop ObsoleteSdkInt checks Signed-off-by: Aayush Gupta --- .../app/opass/ccip/model/LocalizedString.kt | 18 ++---------------- .../network/webclient/OfficialWebViewClient.kt | 8 -------- .../java/app/opass/ccip/ui/PuzzleFragment.kt | 17 +++++------------ .../java/app/opass/ccip/ui/WebViewFragment.kt | 15 +++++---------- .../java/app/opass/ccip/util/LocaleUtil.kt | 9 +-------- 5 files changed, 13 insertions(+), 54 deletions(-) diff --git a/app/src/main/java/app/opass/ccip/model/LocalizedString.kt b/app/src/main/java/app/opass/ccip/model/LocalizedString.kt index 39501e1a..90d66437 100644 --- a/app/src/main/java/app/opass/ccip/model/LocalizedString.kt +++ b/app/src/main/java/app/opass/ccip/model/LocalizedString.kt @@ -1,9 +1,7 @@ package app.opass.ccip.model import android.content.Context -import android.os.Build import android.os.LocaleList -import androidx.annotation.RequiresApi class LocalizedString { companion object { @@ -34,26 +32,14 @@ class LocalizedString { if (translations.size == 0) return null val keys = translations.keys.toList() - if (Build.VERSION.SDK_INT >= 24) { - localeListToStringList(context.resources.configuration.locales).firstOrNull(keys::contains)?.let { - return translations[it] - } - } else { - val locale = if (Build.VERSION.SDK_INT >= 24) { - context.resources.configuration.locales.get(0) - } else { - @Suppress("DEPRECATION") - context.resources.configuration.locale - } - val language = locale.language - if (translations.containsKey(language)) return translations[language] + localeListToStringList(context.resources.configuration.locales).firstOrNull(keys::contains)?.let { + return translations[it] } // No matches. Fallback to the first translation. return translations[keys[0]] } - @RequiresApi(24) private fun localeListToStringList(localeList: LocaleList): Array { val list = mutableSetOf() for (i in 0 until localeList.size()) { diff --git a/app/src/main/java/app/opass/ccip/network/webclient/OfficialWebViewClient.kt b/app/src/main/java/app/opass/ccip/network/webclient/OfficialWebViewClient.kt index da4a5306..c408453c 100644 --- a/app/src/main/java/app/opass/ccip/network/webclient/OfficialWebViewClient.kt +++ b/app/src/main/java/app/opass/ccip/network/webclient/OfficialWebViewClient.kt @@ -1,22 +1,14 @@ package app.opass.ccip.network.webclient -import android.annotation.TargetApi import android.content.Intent import android.net.Uri -import android.os.Build import android.webkit.WebResourceError import android.webkit.WebResourceRequest import android.webkit.WebView import android.webkit.WebViewClient class OfficialWebViewClient : WebViewClient() { - @Deprecated("Deprecated in Java") - override fun onReceivedError(view: WebView, errorCode: Int, description: String?, failingUrl: String?) { - super.onReceivedError(view, errorCode, description, failingUrl) - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) view.loadUrl("file:///android_asset/no_network.html") - } - @TargetApi(Build.VERSION_CODES.M) override fun onReceivedError(view: WebView, request: WebResourceRequest, error: WebResourceError) { super.onReceivedError(view, request, error) if (request.isForMainFrame) view.loadUrl("file:///android_asset/no_network.html") diff --git a/app/src/main/java/app/opass/ccip/ui/PuzzleFragment.kt b/app/src/main/java/app/opass/ccip/ui/PuzzleFragment.kt index 543ae882..c9f498b6 100644 --- a/app/src/main/java/app/opass/ccip/ui/PuzzleFragment.kt +++ b/app/src/main/java/app/opass/ccip/ui/PuzzleFragment.kt @@ -4,7 +4,6 @@ import android.Manifest import android.annotation.SuppressLint import android.content.Intent import android.content.pm.PackageManager -import android.os.Build import android.os.Bundle import android.view.LayoutInflater import android.view.Menu @@ -57,14 +56,10 @@ class PuzzleFragment : Fragment() { webView.webViewClient = OfficialWebViewClient() webView.webChromeClient = WebChromeViewClient(binding.progressBar, fun (request) { if (!request!!.resources.contains(PermissionRequest.RESOURCE_VIDEO_CAPTURE)) request.deny() - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - // Android M Permission check - if (mActivity.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { - requestPermissions(arrayOf(Manifest.permission.CAMERA), 2) - request.deny() - } else { - request.grant(request.resources) - } + // Android M Permission check + if (mActivity.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { + requestPermissions(arrayOf(Manifest.permission.CAMERA), 2) + request.deny() } else { request.grant(request.resources) } @@ -85,9 +80,7 @@ class PuzzleFragment : Fragment() { val settings = webView.settings settings.javaScriptEnabled = true settings.domStorageEnabled = true - if (Build.VERSION.SDK_INT >= 21) { - settings.mixedContentMode = WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE - } + settings.mixedContentMode = WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE } override fun onDestroyView() { diff --git a/app/src/main/java/app/opass/ccip/ui/WebViewFragment.kt b/app/src/main/java/app/opass/ccip/ui/WebViewFragment.kt index b09d2ae3..67009be4 100644 --- a/app/src/main/java/app/opass/ccip/ui/WebViewFragment.kt +++ b/app/src/main/java/app/opass/ccip/ui/WebViewFragment.kt @@ -3,7 +3,6 @@ package app.opass.ccip.ui import android.Manifest import android.annotation.SuppressLint import android.content.pm.PackageManager -import android.os.Build import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -42,14 +41,10 @@ class WebViewFragment : Fragment() { val webView = binding.webView webView.webChromeClient = WebChromeViewClient(binding.progressBar, fun (request) { if (!request!!.resources.contains(RESOURCE_VIDEO_CAPTURE)) request.deny() - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - // Android M Permission check - if (mActivity.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { - requestPermissions(arrayOf(Manifest.permission.CAMERA), 2) - request.deny() - } else { - request.grant(request.resources) - } + // Android M Permission check + if (mActivity.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { + requestPermissions(arrayOf(Manifest.permission.CAMERA), 2) + request.deny() } else { request.grant(request.resources) } @@ -62,7 +57,7 @@ class WebViewFragment : Fragment() { builtInZoomControls = true displayZoomControls = false } - if (Build.VERSION.SDK_INT >= 21) mixedContentMode = MIXED_CONTENT_COMPATIBILITY_MODE + mixedContentMode = MIXED_CONTENT_COMPATIBILITY_MODE } webView.loadUrl(args.getString(EXTRA_URL).toString()) } diff --git a/app/src/main/java/app/opass/ccip/util/LocaleUtil.kt b/app/src/main/java/app/opass/ccip/util/LocaleUtil.kt index 8bc3c527..7c14fca8 100644 --- a/app/src/main/java/app/opass/ccip/util/LocaleUtil.kt +++ b/app/src/main/java/app/opass/ccip/util/LocaleUtil.kt @@ -1,16 +1,9 @@ package app.opass.ccip.util -import android.annotation.TargetApi import android.content.Context -import android.os.Build import java.util.Locale object LocaleUtil { - @Suppress("DEPRECATION") - @TargetApi(Build.VERSION_CODES.N) - fun getCurrentLocale(context: Context): Locale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + fun getCurrentLocale(context: Context): Locale = context.resources.configuration.locales.get(0) - } else { - context.resources.configuration.locale - } } From b8a53a496432bf9fefb35b50a9c8fbf422f7830b Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Mon, 22 Jul 2024 18:32:32 +0700 Subject: [PATCH 7/7] Migrate to gradle build version catalogs Signed-off-by: Aayush Gupta --- app/build.gradle.kts | 66 ++++++++++++++++++++------------------- build.gradle.kts | 6 ++-- gradle/libs.versions.toml | 54 ++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 35 deletions(-) create mode 100644 gradle/libs.versions.toml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 79f878f1..e08b8183 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -58,40 +58,42 @@ android { dependencies { - implementation("com.google.firebase:firebase-analytics-ktx:22.0.2") - implementation("com.onesignal:OneSignal:5.1.17") - - implementation("androidx.appcompat:appcompat:1.7.0") - implementation("com.google.android.material:material:1.12.0") - implementation("androidx.recyclerview:recyclerview:1.3.2") - implementation("androidx.cardview:cardview:1.0.0") - implementation("androidx.core:core-ktx:1.13.1") - implementation("androidx.fragment:fragment-ktx:1.8.1") - implementation("androidx.viewpager2:viewpager2:1.1.0") - implementation("androidx.constraintlayout:constraintlayout:2.1.4") - implementation("com.google.android.flexbox:flexbox:3.0.0") - implementation("com.google.code.gson:gson:2.10.1") - implementation("com.squareup.okhttp3:okhttp:4.12.0") - implementation("com.squareup.retrofit2:retrofit:2.11.0") - implementation("com.squareup.retrofit2:converter-gson:2.9.0") - - implementation("com.journeyapps:zxing-android-embedded:4.3.0") + // AndroidX + implementation(libs.androidx.appcompat) + implementation(libs.androidx.cardview) + implementation(libs.androidx.core) + implementation(libs.androidx.constraintlayout) + implementation(libs.androidx.fragment) + implementation(libs.androidx.viewmodel) + implementation(libs.androidx.livedata) + implementation(libs.androidx.recyclerview) + implementation(libs.androidx.viewpager2) + + // Google + implementation(libs.google.material) + implementation(libs.google.flexbox) + implementation(libs.google.gson) + implementation(libs.google.firebase.analytics) // Coil - implementation("io.coil-kt:coil:2.6.0") + implementation(libs.coil) // Coroutines - val coroutinesVersion = "1.8.1" - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion") - - // Lifecycle - val lifecycleVersion = "2.8.3" - implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion") - implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion") - - // Markwon - val markwonVersion = "4.6.2" - implementation("io.noties.markwon:core:$markwonVersion") - implementation("io.noties.markwon:linkify:$markwonVersion") + implementation(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.coroutines.android) + + // MarkWon + implementation(libs.markwon.core) + implementation(libs.markwon.linkify) + + // Okhttp + implementation(libs.squareup.okhttp) + implementation(libs.squareup.retrofit) + implementation(libs.squareup.converter.gson) + + // OneSignal + implementation(libs.onesignal) + + // Zxing + implementation(libs.zxing.android.embedded) } diff --git a/build.gradle.kts b/build.gradle.kts index 19ab5e54..f53e9baa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,6 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id("com.android.application") version "8.5.1" apply false - id("org.jetbrains.kotlin.android") version "2.0.0" apply false - id("com.google.gms.google-services") version "4.4.2" apply false + alias(libs.plugins.android.application) apply false + alias(libs.plugins.jetbrains.kotlin.android) apply false + alias(libs.plugins.google.play.services) apply false } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..78744c75 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,54 @@ +[versions] +androidGradlePlugin = "8.5.1" +appcompat = "1.7.0" +cardview = "1.0.0" +coil = "2.6.0" +constraintlayout = "2.1.4" +converterGson = "2.9.0" +core = "1.13.1" +coroutinesVersion = "1.8.1" +firebaseAnalytics = "22.0.2" +flexbox = "3.0.0" +fragment = "1.8.1" +gson = "2.10.1" +kotlin = "2.0.0" +lifecycleVersion = "2.8.3" +markwonVersion = "4.6.2" +material = "1.12.0" +okhttp = "4.12.0" +onesignal = "5.1.17" +playServices = "4.4.2" +recyclerview = "1.3.2" +retrofit = "2.11.0" +viewpager2 = "1.1.0" +zxingAndroidEmbedded = "4.3.0" + +[libraries] +androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" } +androidx-cardview = { module = "androidx.cardview:cardview", version.ref = "cardview" } +androidx-core = { module = "androidx.core:core-ktx", version.ref = "core" } +androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayout" } +androidx-fragment = { module = "androidx.fragment:fragment-ktx", version.ref = "fragment" } +androidx-livedata = { module = "androidx.lifecycle:lifecycle-livedata-ktx", version.ref = "lifecycleVersion" } +androidx-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycleVersion" } +androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "recyclerview" } +androidx-viewpager2 = { module = "androidx.viewpager2:viewpager2", version.ref = "viewpager2" } +coil = { module = "io.coil-kt:coil", version.ref = "coil" } +google-flexbox = { module = "com.google.android.flexbox:flexbox", version.ref = "flexbox" } +google-firebase-analytics = { module = "com.google.firebase:firebase-analytics-ktx", version.ref = "firebaseAnalytics" } +google-gson = { module = "com.google.code.gson:gson", version.ref = "gson" } +google-material = { module = "com.google.android.material:material", version.ref = "material" } +kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutinesVersion" } +kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutinesVersion" } +markwon-core = { module = "io.noties.markwon:core", version.ref = "markwonVersion" } +markwon-linkify = { module = "io.noties.markwon:linkify", version.ref = "markwonVersion" } +onesignal = { module = "com.onesignal:OneSignal", version.ref = "onesignal" } +squareup-converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "converterGson" } +squareup-okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } +squareup-retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" } +zxing-android-embedded = { module = "com.journeyapps:zxing-android-embedded", version.ref = "zxingAndroidEmbedded" } + +[plugins] +android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" } +google-play-services = { id = "com.google.gms.google-services", version.ref = "playServices" } +jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }