From d093f874238ff0bfea501fbc6d63a5670e35648d Mon Sep 17 00:00:00 2001 From: Arnau Mora Date: Thu, 24 Nov 2022 19:25:14 +0100 Subject: [PATCH 01/18] Migrated location permissions Signed-off-by: Arnau Mora --- .../fireflyiii/ui/tags/MapsFragment.kt | 201 +++++++++++------- 1 file changed, 122 insertions(+), 79 deletions(-) diff --git a/app/src/main/java/xyz/hisname/fireflyiii/ui/tags/MapsFragment.kt b/app/src/main/java/xyz/hisname/fireflyiii/ui/tags/MapsFragment.kt index 31346ca6..e5764b90 100644 --- a/app/src/main/java/xyz/hisname/fireflyiii/ui/tags/MapsFragment.kt +++ b/app/src/main/java/xyz/hisname/fireflyiii/ui/tags/MapsFragment.kt @@ -22,7 +22,6 @@ import android.Manifest import android.content.Context import android.content.Intent import android.content.pm.PackageManager -import android.location.Location import android.location.LocationListener import android.location.LocationManager import android.os.Bundle @@ -50,18 +49,22 @@ import org.osmdroid.events.MapEventsReceiver import org.osmdroid.tileprovider.tilesource.TileSourceFactory import org.osmdroid.util.GeoPoint import org.osmdroid.views.CustomZoomButtonsController -import org.osmdroid.views.overlay.* +import org.osmdroid.views.overlay.MapEventsOverlay +import org.osmdroid.views.overlay.Marker import xyz.hisname.fireflyiii.BuildConfig import xyz.hisname.fireflyiii.R import xyz.hisname.fireflyiii.databinding.FragmentMapBinding import xyz.hisname.fireflyiii.repository.models.nominatim.LocationSearchModel import xyz.hisname.fireflyiii.ui.base.BaseFragment -import xyz.hisname.fireflyiii.util.extension.* import xyz.hisname.fireflyiii.util.extension.getViewModel +import xyz.hisname.fireflyiii.util.extension.hideKeyboard +import xyz.hisname.fireflyiii.util.extension.toastInfo import xyz.hisname.fireflyiii.util.getUniqueHash +import xyz.hisname.fireflyiii.util.isPermissionGranted +import xyz.hisname.fireflyiii.util.launchLocationPermissionsRequest import java.io.File -class MapsFragment: BaseFragment() { +class MapsFragment : BaseFragment() { private val locationService by lazy { requireContext().getSystemService(Context.LOCATION_SERVICE) as LocationManager } private val mapsViewModel by lazy { getViewModel(MapsViewModel::class.java) } @@ -69,26 +72,40 @@ class MapsFragment: BaseFragment() { private val latitudeBundle by lazy { arguments?.getString("latitude") } private lateinit var startMarker: Marker private lateinit var cloneLocationList: List - private lateinit var gpsPermission: ActivityResultLauncher + private lateinit var gpsPermission: ActivityResultLauncher> private var fragmentMapBinding: FragmentMapBinding? = null private val binding get() = fragmentMapBinding!! private val mapController by lazy { binding.maps.controller } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { fragmentMapBinding = FragmentMapBinding.inflate(inflater, container, false) - val view = binding.root - return view + return binding.root } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - gpsPermission = registerForActivityResult(ActivityResultContracts.RequestPermission()) { success -> - if(success) { - if (ContextCompat.checkSelfPermission(requireContext(), - Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { + gpsPermission = registerForActivityResult( + ActivityResultContracts.RequestMultiplePermissions() + ) { success -> + if (success.any()) { + if (isPermissionGranted(Manifest.permission.ACCESS_COARSE_LOCATION)) { toastInfo("Waiting for location...") - locationService.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0L, 0f, locationListener) - locationService.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0L, 0f, locationListener) + locationService.requestLocationUpdates( + LocationManager.GPS_PROVIDER, + 0L, + 0f, + locationListener, + ) + locationService.requestLocationUpdates( + LocationManager.NETWORK_PROVIDER, + 0L, + 0f, + locationListener, + ) } } } @@ -96,15 +113,26 @@ class MapsFragment: BaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - Configuration.getInstance().load(requireContext(), requireContext().getSharedPreferences( - requireContext().getUniqueHash().toString() + "-user-preferences", Context.MODE_PRIVATE)) + Configuration.getInstance().load( + requireContext(), + requireContext() + .getSharedPreferences( + requireContext().getUniqueHash() + "-user-preferences", + Context.MODE_PRIVATE + ) + ) Configuration.getInstance().userAgentValue = BuildConfig.APPLICATION_ID Configuration.getInstance().osmdroidBasePath = requireContext().filesDir - Configuration.getInstance().osmdroidTileCache = File(requireContext().filesDir.toString() + "/tiles") + Configuration.getInstance().osmdroidTileCache = + File(requireContext().filesDir.toString() + "/tiles") startMarker = Marker(binding.maps) - if(!latitudeBundle.isNullOrEmpty() && !longitudeBundle.isNullOrEmpty()){ - setMap(GeoPoint(latitudeBundle?.toDouble() ?: 37.276675, - longitudeBundle?.toDouble() ?: -115.798936)) + if (!latitudeBundle.isNullOrEmpty() && !longitudeBundle.isNullOrEmpty()) { + setMap( + GeoPoint( + latitudeBundle?.toDouble() ?: 37.276675, + longitudeBundle?.toDouble() ?: -115.798936 + ) + ) } else { isGpsEnabled() } @@ -125,7 +153,7 @@ class MapsFragment: BaseFragment() { } } - private fun setMap(location: GeoPoint){ + private fun setMap(location: GeoPoint) { startMarker.position = location startMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM) binding.maps.setMultiTouchControls(true) @@ -141,17 +169,17 @@ class MapsFragment: BaseFragment() { mapController.setZoom(18.0) } - private fun searchLocation(){ - binding.mapSearch.setOnKeyListener { v, keyCode, event -> - if(event.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER){ + private fun searchLocation() { + binding.mapSearch.setOnKeyListener { _, keyCode, event -> + if (event.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER) { location(binding.mapSearch.text.toString()) hideKeyboard() } false } - binding.mapSearch.addTextChangedListener(object : TextWatcher{ + binding.mapSearch.addTextChangedListener(object : TextWatcher { override fun afterTextChanged(editable: Editable) { - if(editable.isNotBlank()) { + if (editable.isNotBlank()) { location(editable.toString()) } } @@ -162,22 +190,23 @@ class MapsFragment: BaseFragment() { override fun onTextChanged(charSequence: CharSequence, p1: Int, p2: Int, p3: Int) {} }) - binding.mapSearch.onItemClickListener = AdapterView.OnItemClickListener { adapterView, view, i, l -> + binding.mapSearch.onItemClickListener = AdapterView.OnItemClickListener { _, _, i, _ -> setMap(GeoPoint(cloneLocationList[i].lat, cloneLocationList[i].lon)) } } - private fun location(query: String){ - mapsViewModel.getLocationFromQuery(query).observe(viewLifecycleOwner){ data -> - if(data.isNotEmpty()){ - val adapter = ArrayAdapter(requireContext(), android.R.layout.select_dialog_item, data) + private fun location(query: String) { + mapsViewModel.getLocationFromQuery(query).observe(viewLifecycleOwner) { data -> + if (data.isNotEmpty()) { + val adapter = + ArrayAdapter(requireContext(), android.R.layout.select_dialog_item, data) binding.mapSearch.setAdapter(adapter) } } } - private fun setMapClick(){ - val mapReceiver = object : MapEventsReceiver{ + private fun setMapClick() { + val mapReceiver = object : MapEventsReceiver { override fun longPressHelper(geoPoint: GeoPoint): Boolean { setMap(geoPoint) return true @@ -191,65 +220,81 @@ class MapsFragment: BaseFragment() { binding.maps.overlays.add(MapEventsOverlay(mapReceiver)) } - private fun setFab(){ + private fun setFab() { binding.fabMap.setImageDrawable(IconicsDrawable(requireContext()).apply { icon = GoogleMaterial.Icon.gmd_my_location colorRes = R.color.md_black_1000 sizeDp = 16 }) binding.fabMap.setOnClickListener { - if(ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) - != PackageManager.PERMISSION_GRANTED){ - if (ActivityCompat.shouldShowRequestPermissionRationale(requireActivity(), - Manifest.permission.ACCESS_FINE_LOCATION)){ + if (!isPermissionGranted(Manifest.permission.ACCESS_COARSE_LOCATION)) { + if (ActivityCompat.shouldShowRequestPermissionRationale( + requireActivity(), + Manifest.permission.ACCESS_COARSE_LOCATION + ) + ) { AlertDialog.Builder(requireActivity()) - .setTitle("Grant access to location data?") - .setMessage("Choosing coordinates data is simple when location data permission is granted. " + - "Otherwise you may have to manually search for your location") - .setPositiveButton("OK"){_,_ -> - gpsPermission.launch(Manifest.permission.ACCESS_FINE_LOCATION) - } - .setNegativeButton("No"){ _,_ -> - toastInfo("Alright...") - } - .show() - } else { - gpsPermission.launch(Manifest.permission.ACCESS_FINE_LOCATION) - } + .setTitle("Grant access to location data?") + .setMessage( + "Choosing coordinates data is simple when location data permission is granted. " + + "Otherwise you may have to manually search for your location" + ) + .setPositiveButton("OK") { _, _ -> + gpsPermission.launchLocationPermissionsRequest() + } + .setNegativeButton("No") { _, _ -> + toastInfo("Alright...") + } + .show() + } else + gpsPermission.launchLocationPermissionsRequest() } else { - locationService.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0L, 0f, locationListener) - locationService.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0L, 0f, locationListener) + locationService.requestLocationUpdates( + LocationManager.GPS_PROVIDER, + 0L, + 0f, + locationListener + ) + locationService.requestLocationUpdates( + LocationManager.NETWORK_PROVIDER, + 0L, + 0f, + locationListener + ) } } } - private val locationListener: LocationListener = object : LocationListener { - override fun onLocationChanged(location: Location) { - setMap(GeoPoint(location.latitude, location.longitude)) - } - override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {} - override fun onProviderEnabled(provider: String) {} - override fun onProviderDisabled(provider: String) {} + private val locationListener: LocationListener = LocationListener { location -> + setMap(GeoPoint(location.latitude, location.longitude)) } - private fun isGpsEnabled(){ - if(!locationService.isProviderEnabled(LocationManager.GPS_PROVIDER)){ + private fun isGpsEnabled() { + if (!locationService.isProviderEnabled(LocationManager.GPS_PROVIDER)) { AlertDialog.Builder(requireActivity()) - .setMessage("For a better experience turn on device's location") - .setPositiveButton("Sure"){_, _ -> - requireActivity().startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)) - } - .setNegativeButton("No"){ _, _ -> - toastInfo("Alright...Using Network data instead.") - } - .show() + .setMessage("For a better experience turn on device's location") + .setPositiveButton("Sure") { _, _ -> + requireActivity().startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)) + } + .setNegativeButton("No") { _, _ -> + toastInfo("Alright...Using Network data instead.") + } + .show() } else { - if (ContextCompat.checkSelfPermission(requireContext(), - Manifest.permission.ACCESS_FINE_LOCATION) - == PackageManager.PERMISSION_GRANTED) { - toastInfo("Acquiring current location...") - locationService.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0L, 0f, locationListener) - locationService.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0L, 0f, locationListener) + if (isPermissionGranted(Manifest.permission.ACCESS_COARSE_LOCATION)) { + toastInfo("Acquiring current location...") + locationService.requestLocationUpdates( + LocationManager.GPS_PROVIDER, + 0L, + 0f, + locationListener + ) + locationService.requestLocationUpdates( + LocationManager.NETWORK_PROVIDER, + 0L, + 0f, + locationListener + ) } else { setMap(GeoPoint(37.276675, -115.798936)) } @@ -264,9 +309,7 @@ class MapsFragment: BaseFragment() { override fun onPause() { super.onPause() binding.maps.onPause() - if (ContextCompat.checkSelfPermission(requireContext(), - Manifest.permission.ACCESS_FINE_LOCATION) - == PackageManager.PERMISSION_GRANTED) { + if (isPermissionGranted(Manifest.permission.ACCESS_COARSE_LOCATION)) { locationService.removeUpdates(locationListener) } } From 2760f3a73943b4b61a2bae412efef8b409f76ea1 Mon Sep 17 00:00:00 2001 From: Arnau Mora Date: Thu, 24 Nov 2022 19:25:23 +0100 Subject: [PATCH 02/18] Added utility permissions functions Signed-off-by: Arnau Mora --- .../hisname/fireflyiii/util/Permissions.kt | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 app/src/main/java/xyz/hisname/fireflyiii/util/Permissions.kt diff --git a/app/src/main/java/xyz/hisname/fireflyiii/util/Permissions.kt b/app/src/main/java/xyz/hisname/fireflyiii/util/Permissions.kt new file mode 100644 index 00000000..97853254 --- /dev/null +++ b/app/src/main/java/xyz/hisname/fireflyiii/util/Permissions.kt @@ -0,0 +1,40 @@ +package xyz.hisname.fireflyiii.util + +import android.Manifest +import android.content.Context +import android.content.pm.PackageManager +import androidx.activity.result.ActivityResultLauncher +import androidx.core.content.ContextCompat +import androidx.fragment.app.Fragment + +/** + * Checks if the given permission has been granted. + * @author Arnau Mora + * @since 20221124 + */ +fun Context.isPermissionGranted(permission: String) = + ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED + +/** + * Alias for [Fragment.requireContext].[Context.isPermissionGranted]. + * Checks if the given permission has been granted. + * @author Arnau Mora + * @since 20221124 + * @throws IllegalStateException If not currently associated with a context. + */ +@Throws(IllegalStateException::class) +fun Fragment.isPermissionGranted(permission: String) = + requireContext().isPermissionGranted(permission) + +/** + * Runs [ActivityResultLauncher.launch] with the [Manifest.permission.ACCESS_COARSE_LOCATION] and + * [Manifest.permission.ACCESS_FINE_LOCATION] permissions. + * @author Arnau Mora + * @since 20221124 + */ +fun ActivityResultLauncher>.launchLocationPermissionsRequest() = launch( + arrayOf( + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + ) +) From ab25f263802ed04be34278cf3e0786014de29da5 Mon Sep 17 00:00:00 2001 From: Arnau Mora Date: Thu, 24 Nov 2022 19:27:28 +0100 Subject: [PATCH 03/18] Added coarse location permission Signed-off-by: Arnau Mora --- 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 c73d8109..96a39b32 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -23,6 +23,7 @@ + From f501f4c8b4989162e0dd550b36da8f0b8c417cdf Mon Sep 17 00:00:00 2001 From: Arnau Mora Date: Thu, 24 Nov 2022 19:27:45 +0100 Subject: [PATCH 04/18] Added `exported` Signed-off-by: Arnau Mora --- app/src/main/AndroidManifest.xml | 35 +++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 96a39b32..1895d009 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -50,10 +50,13 @@ android:label="@string/app_name" android:supportsRtl="true" android:networkSecurityConfig="@xml/network_security_config" - android:theme="@style/AppTheme.StartUpTheme"> + android:theme="@style/AppTheme.StartUpTheme" + tools:ignore="UnusedAttribute"> - + @@ -73,7 +76,9 @@ - + @@ -82,7 +87,9 @@ android:resource="@xml/balance_widget_info" /> - + @@ -92,7 +99,9 @@ - + @@ -103,7 +112,8 @@ + android:theme="@style/AppTheme" + android:exported="true"> @@ -150,13 +160,17 @@ - + - + @@ -195,7 +209,8 @@ android:name=".service.TransactionTilesService" android:icon="@drawable/ic_refresh" android:label="@string/transaction" - android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"> + android:permission="android.permission.BIND_QUICK_SETTINGS_TILE" + android:exported="true"> From 310beafbe248efdaa26384d17fe1e8a2fc26d1cd Mon Sep 17 00:00:00 2001 From: Arnau Mora Date: Thu, 24 Nov 2022 19:28:01 +0100 Subject: [PATCH 05/18] Updated AGP to `7.3.1` Signed-off-by: Arnau Mora --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3f7fa0a7..cbebbf2f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ buildscript { gradlePluginPortal() } dependencies { - classpath("com.android.tools.build:gradle:7.0.4") + classpath("com.android.tools.build:gradle:7.3.1") classpath(kotlin("gradle-plugin", Dependencies.kotlinVersion)) classpath("com.project.starter:easylauncher:3.2.1") classpath("com.github.ben-manes:gradle-versions-plugin:0.39.0") From 4ae26957afb99b1974f6285e6f9304def304811d Mon Sep 17 00:00:00 2001 From: Arnau Mora Date: Thu, 24 Nov 2022 19:28:37 +0100 Subject: [PATCH 06/18] Updated target and compile SDK to `33` Signed-off-by: Arnau Mora --- buildSrc/src/main/java/Dependencies.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index 6893f59e..91f876eb 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -1,8 +1,8 @@ object Dependencies{ const val minSdk = 23 - const val targetSdk = 30 - const val compileSdk = 31 + const val targetSdk = 33 + const val compileSdk = 33 const val kotlinVersion = "1.6.10" private const val retrofitVersion = "2.9.0" private const val lifecycleVersion = "2.4.0" From 0259e737d250928e7ba67aa32689ff4939231510 Mon Sep 17 00:00:00 2001 From: Arnau Mora Date: Thu, 24 Nov 2022 19:32:51 +0100 Subject: [PATCH 07/18] Null-safety for `Animator` in the listener Signed-off-by: Arnau Mora --- .../fireflyiii/ui/base/BaseAddObjectFragment.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/xyz/hisname/fireflyiii/ui/base/BaseAddObjectFragment.kt b/app/src/main/java/xyz/hisname/fireflyiii/ui/base/BaseAddObjectFragment.kt index 4e4c36f2..18b351ff 100644 --- a/app/src/main/java/xyz/hisname/fireflyiii/ui/base/BaseAddObjectFragment.kt +++ b/app/src/main/java/xyz/hisname/fireflyiii/ui/base/BaseAddObjectFragment.kt @@ -27,7 +27,7 @@ import androidx.core.view.isVisible import xyz.hisname.fireflyiii.util.animation.BakedBezierInterpolator import kotlin.math.max -abstract class BaseAddObjectFragment: BaseFragment() { +abstract class BaseAddObjectFragment : BaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -35,21 +35,21 @@ abstract class BaseAddObjectFragment: BaseFragment() { setWidgets() } - protected fun unReveal(rootView: View){ + protected fun unReveal(rootView: View) { val x = rootView.width / 2 val y = rootView.height / 2 val finalRadius = (max(rootView.width, rootView.height) * 1.1).toFloat() - val circularReveal= ViewAnimationUtils.createCircularReveal( - rootView, x, y,finalRadius, 0f) + val circularReveal = ViewAnimationUtils.createCircularReveal( + rootView, x, y, finalRadius, 0f + ) circularReveal.duration = 400 circularReveal.interpolator = BakedBezierInterpolator.FADE_OUT_CURVE - circularReveal.addListener(object : AnimatorListenerAdapter(){ - override fun onAnimationEnd(animation: Animator?) { + circularReveal.addListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator) { super.onAnimationEnd(animation) try { parentFragmentManager.popBackStack() - } catch(illegal: IllegalStateException){ - + } catch (_: IllegalStateException) { } rootView.isVisible = false fragmentContainer.isVisible = true From eddfe98b6ad823c6ce2307145a18a45614cf6196 Mon Sep 17 00:00:00 2001 From: Arnau Mora Date: Thu, 24 Nov 2022 19:33:30 +0100 Subject: [PATCH 08/18] Updated to Gradle `7.4` Signed-off-by: Arnau Mora --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 7f19a100..73cfdb1d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip From a69d26fdd79e12725ff8bf5bb496a048aaf7840e Mon Sep 17 00:00:00 2001 From: Arnau Mora Date: Thu, 24 Nov 2022 20:05:44 +0100 Subject: [PATCH 09/18] Removed old language backend Signed-off-by: Arnau Mora --- .../fireflyiii/data/local/pref/AppPref.kt | 4 - .../data/local/pref/PreferenceHelper.kt | 1 - .../fireflyiii/ui/base/BaseActivity.kt | 5 - app/src/main/res/values/array.xml | 26 ----- .../java/xyz/hisname/fireflyiii/LocaleTest.kt | 94 ------------------- .../hisname/languagepack/LanguageChanger.kt | 80 ---------------- 6 files changed, 210 deletions(-) delete mode 100644 languagepack/src/androidTest/java/xyz/hisname/fireflyiii/LocaleTest.kt delete mode 100644 languagepack/src/main/java/xyz/hisname/languagepack/LanguageChanger.kt diff --git a/app/src/main/java/xyz/hisname/fireflyiii/data/local/pref/AppPref.kt b/app/src/main/java/xyz/hisname/fireflyiii/data/local/pref/AppPref.kt index 068d5fb4..0970d685 100644 --- a/app/src/main/java/xyz/hisname/fireflyiii/data/local/pref/AppPref.kt +++ b/app/src/main/java/xyz/hisname/fireflyiii/data/local/pref/AppPref.kt @@ -52,10 +52,6 @@ class AppPref(private val sharedPref: SharedPreferences): PreferenceHelper { get() = sharedPref.getString("cert_value", "") ?: "" set(value) = sharedPref.edit { putString("cert_value", value) } - override var languagePref: String - get() = sharedPref.getString("language_pref", "") ?: "en" - set(value) = sharedPref.edit{ putString("language_pref", value)} - override var nightModeEnabled: Boolean get() = sharedPref.getBoolean("night_mode", false) set(value) = sharedPref.edit { putBoolean("night_mode", value) } diff --git a/app/src/main/java/xyz/hisname/fireflyiii/data/local/pref/PreferenceHelper.kt b/app/src/main/java/xyz/hisname/fireflyiii/data/local/pref/PreferenceHelper.kt index b9b5089f..cf5c621f 100644 --- a/app/src/main/java/xyz/hisname/fireflyiii/data/local/pref/PreferenceHelper.kt +++ b/app/src/main/java/xyz/hisname/fireflyiii/data/local/pref/PreferenceHelper.kt @@ -29,7 +29,6 @@ interface PreferenceHelper { var serverVersion: String var userOs: String var certValue: String - var languagePref: String var nightModeEnabled: Boolean var isKeyguardEnabled: Boolean var isCurrencyThumbnailEnabled: Boolean diff --git a/app/src/main/java/xyz/hisname/fireflyiii/ui/base/BaseActivity.kt b/app/src/main/java/xyz/hisname/fireflyiii/ui/base/BaseActivity.kt index 61b672c5..84bf0bc4 100644 --- a/app/src/main/java/xyz/hisname/fireflyiii/ui/base/BaseActivity.kt +++ b/app/src/main/java/xyz/hisname/fireflyiii/ui/base/BaseActivity.kt @@ -30,7 +30,6 @@ import xyz.hisname.fireflyiii.repository.GlobalViewModel import xyz.hisname.fireflyiii.util.extension.getCompatColor import xyz.hisname.fireflyiii.util.extension.getViewModel import xyz.hisname.fireflyiii.util.getUniqueHash -import xyz.hisname.languagepack.LanguageChanger @SuppressLint("Registered") open class BaseActivity: AppCompatActivity() { @@ -55,10 +54,6 @@ open class BaseActivity: AppCompatActivity() { } } - override fun attachBaseContext(newBase: Context) { - super.attachBaseContext(LanguageChanger.init(newBase, sharedPref(newBase).languagePref)) - } - override fun applyOverrideConfiguration(overrideConfiguration: Configuration) { val uiMode = overrideConfiguration.uiMode overrideConfiguration.setTo(baseContext.resources.configuration) diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml index c8f63f55..2018fcfc 100644 --- a/app/src/main/res/values/array.xml +++ b/app/src/main/res/values/array.xml @@ -40,32 +40,6 @@ 60 - - English - Deutsch - 正體中文 - 简体中文 - Français - Italiano - Nederlands - Español - Русский - Português do Brasil - - - - en - de - zh-rTW - zh-rCN - fr - it - nl - es - ru - pt-rBR - - Connected Un-Metered diff --git a/languagepack/src/androidTest/java/xyz/hisname/fireflyiii/LocaleTest.kt b/languagepack/src/androidTest/java/xyz/hisname/fireflyiii/LocaleTest.kt deleted file mode 100644 index 6446e969..00000000 --- a/languagepack/src/androidTest/java/xyz/hisname/fireflyiii/LocaleTest.kt +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2018 - 2021 Daniel Quah - * Copyright (c) 2021 ASDF Dev Pte. Ltd. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package xyz.hisname.fireflyiii - -import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner -import androidx.test.platform.app.InstrumentationRegistry -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith -import xyz.hisname.languagepack.LanguageChanger -import xyz.hisname.languagepack.R - -@RunWith(AndroidJUnit4ClassRunner ::class) -class LocaleTest { - - private val appContext by lazy { InstrumentationRegistry.getInstrumentation().context } - - - @Test - fun testUnsupportedLocale_Polish(){ - val contextWrapper = LanguageChanger.init(appContext, "pl") - assertEquals("Dashboard", contextWrapper.resources.getString(R.string.dashboard)) - } - - @Test - fun testSupportedLocale_German(){ - val contextWrapper = LanguageChanger.init(appContext, "de") - assertEquals("Übersicht", contextWrapper.resources.getString(R.string.dashboard)) - } - - @Test - fun testSupportedLocale_English(){ - val contextWrapper = LanguageChanger.init(appContext, "en") - assertEquals("Dashboard", contextWrapper.resources.getString(R.string.dashboard)) - } - - @Test - fun testSupportedLocale_SimplifiedChinese(){ - val contextWrapper = LanguageChanger.init(appContext, "zh-rCN") - assertEquals("监控面板", contextWrapper.resources.getString(R.string.dashboard)) - } - - @Test - fun testSupportedLocale_TraditionalChinese(){ - val contextWrapper = LanguageChanger.init(appContext, "zh-rTW") - assertEquals("監控面板", contextWrapper.resources.getString(R.string.dashboard)) - } - - @Test - fun testSupportedLocale_Dutch(){ - val contextWrapper = LanguageChanger.init(appContext, "nl") - assertEquals("Dashboard", contextWrapper.resources.getString(R.string.dashboard)) - } - - @Test - fun testSupportedLocale_French(){ - val contextWrapper = LanguageChanger.init(appContext, "fr") - assertEquals("Tableau de Bord", contextWrapper.resources.getString(R.string.dashboard)) - } - - @Test - fun testSupportedLocale_Italian(){ - val contextWrapper = LanguageChanger.init(appContext, "it") - assertEquals("Cruscotto", contextWrapper.resources.getString(R.string.dashboard)) - } - - @Test - fun testSupportedLocale_Russian(){ - val contextWrapper = LanguageChanger.init(appContext, "ru") - assertEquals("Сводка", contextWrapper.resources.getString(R.string.dashboard)) - } - - @Test - fun testSupportedLocale_Spanish(){ - val contextWrapper = LanguageChanger.init(appContext, "es") - assertEquals("Panel de control", contextWrapper.resources.getString(R.string.dashboard)) - } -} diff --git a/languagepack/src/main/java/xyz/hisname/languagepack/LanguageChanger.kt b/languagepack/src/main/java/xyz/hisname/languagepack/LanguageChanger.kt deleted file mode 100644 index a7994bb5..00000000 --- a/languagepack/src/main/java/xyz/hisname/languagepack/LanguageChanger.kt +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2018 - 2021 Daniel Quah - * Copyright (c) 2021 ASDF Dev Pte. Ltd. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package xyz.hisname.languagepack - -import android.annotation.TargetApi -import android.content.Context -import android.content.ContextWrapper -import android.content.res.Configuration -import android.os.Build -import androidx.core.content.ContextCompat -import androidx.core.os.ConfigurationCompat -import java.util.* - -class LanguageChanger(baseContext: Context): ContextWrapper(baseContext){ - - companion object { - - private lateinit var locale: Locale - private lateinit var config: Configuration - private val supportedLocale by lazy { arrayListOf("en", "de", "es", "fr", "it", "nl", "ru", "zh-rCN", "zh-rTW", "pt-rBR") } - - // Code adapted from: https://stackoverflow.com/questions/40221711/android-context-getresources-updateconfiguration-deprecated - - fun init(context: Context, language: String?): ContextWrapper{ - config = context.resources.configuration - if(supportedLocale.contains(language)) { - locale = when { - language.isNullOrEmpty() -> Locale("en") - language == "zh-rCN" -> Locale("zh", "CN") - language == "zh-rTW" -> Locale("zh", "TW") - language == "pt-rBR" -> Locale("pt", "BR") - else -> Locale(language) - } - } else { - locale = Locale("en") - } - Locale.setDefault(locale) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - setSystemLocale() - } else { - setSystemLocaleLegacy() - } - return LanguageChanger(context.createConfigurationContext(config)) - } - - @Suppress("DEPRECATION") - private fun setSystemLocaleLegacy() { - config.locale = locale - } - - @TargetApi(Build.VERSION_CODES.N) - private fun setSystemLocale() { - config.setLocale(locale) - } - - fun getLocale(context: Context): Locale{ - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - context.resources.configuration.locales.get(0) - } else { - context.resources.configuration.locale - } - } - } -} \ No newline at end of file From c6d1b2a5cd027a4ff821538e48b4cc8d22190a25 Mon Sep 17 00:00:00 2001 From: Arnau Mora Date: Thu, 24 Nov 2022 20:06:10 +0100 Subject: [PATCH 10/18] Using Android 13 per-app language Signed-off-by: Arnau Mora --- app/src/main/AndroidManifest.xml | 11 ++ .../ui/settings/SettingsFragment.kt | 104 +++++++++++------- 2 files changed, 74 insertions(+), 41 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1895d009..bcf18224 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -51,6 +51,7 @@ android:supportsRtl="true" android:networkSecurityConfig="@xml/network_security_config" android:theme="@style/AppTheme.StartUpTheme" + android:localeConfig="@xml/locales_config" tools:ignore="UnusedAttribute"> --> + + + + + diff --git a/app/src/main/java/xyz/hisname/fireflyiii/ui/settings/SettingsFragment.kt b/app/src/main/java/xyz/hisname/fireflyiii/ui/settings/SettingsFragment.kt index bf6ef505..709c99ef 100644 --- a/app/src/main/java/xyz/hisname/fireflyiii/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/xyz/hisname/fireflyiii/ui/settings/SettingsFragment.kt @@ -23,11 +23,13 @@ import android.os.Build import android.os.Bundle import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.widget.Toolbar import androidx.biometric.BiometricManager import androidx.biometric.BiometricManager.BIOMETRIC_SUCCESS import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.app.ActivityCompat +import androidx.core.os.LocaleListCompat import xyz.hisname.fireflyiii.R import androidx.fragment.app.commit import androidx.preference.CheckBoxPreference @@ -40,13 +42,14 @@ import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial import com.mikepenz.iconics.utils.* import xyz.hisname.fireflyiii.data.local.pref.AppPref import xyz.hisname.fireflyiii.util.biometric.KeyguardUtil -import xyz.hisname.languagepack.LanguageChanger +import xyz.hisname.languagepack.BuildConfig.TRANSLATION_ARRAY import java.io.File +import java.util.Locale -class SettingsFragment: BaseSettings() { +class SettingsFragment : BaseSettings() { - private lateinit var chooseFolder: ActivityResultLauncher + private lateinit var chooseFolder: ActivityResultLauncher private lateinit var userDownloadDirectoryPref: Preference override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { @@ -63,18 +66,27 @@ class SettingsFragment: BaseSettings() { userDefinedDirectory() } - private fun setLanguagePref(){ + private fun setLanguagePref() { val languagePref = findPreference("language_pref") as ListPreference - languagePref.value = AppPref(sharedPref).languagePref + val availableLocales = TRANSLATION_ARRAY.map { langCode -> + val hasCountry = langCode.contains("-") + if (hasCountry) + langCode.split("-").let { Locale(it[0], it[1]) } + else + Locale.forLanguageTag(langCode) + } + languagePref.entries = availableLocales.map { it.displayName }.toTypedArray() + languagePref.entryValues = TRANSLATION_ARRAY + + val localesList = AppCompatDelegate.getApplicationLocales() + val locales = (0 until localesList.size()).mapNotNull { localesList.get(it) } + val currentLanguage = locales.find { availableLocales.contains(it) } ?: Locale.ENGLISH + + languagePref.value = currentLanguage.language languagePref.setOnPreferenceChangeListener { _, newValue -> - AppPref(sharedPref).languagePref = newValue.toString() - LanguageChanger.init(requireContext(), AppPref(sharedPref).languagePref) - val coordinatorLayout = requireActivity().findViewById(R.id.coordinatorlayout) - Snackbar.make(coordinatorLayout, "Restart to apply changes", Snackbar.LENGTH_INDEFINITE) - .setAction(android.R.string.ok){ - ActivityCompat.recreate(requireActivity()) - } - .show() + val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags(newValue.toString()) + AppCompatDelegate.setApplicationLocales(appLocale) + true } languagePref.icon = IconicsDrawable(requireContext()).apply { @@ -84,7 +96,7 @@ class SettingsFragment: BaseSettings() { } } - private fun setAccountSection(){ + private fun setAccountSection() { val accountOptions = findPreference("account_options") as Preference accountOptions.setOnPreferenceClickListener { parentFragmentManager.commit { @@ -101,7 +113,7 @@ class SettingsFragment: BaseSettings() { } } - private fun setTransactionSection(){ + private fun setTransactionSection() { val transactionSettings = findPreference("transaction_settings") as Preference transactionSettings.setOnPreferenceClickListener { parentFragmentManager.commit { @@ -119,17 +131,18 @@ class SettingsFragment: BaseSettings() { } } - private fun setNightModeSection(){ + private fun setNightModeSection() { val nightModePref = findPreference("night_mode") as CheckBoxPreference nightModePref.setOnPreferenceChangeListener { preference, newValue -> val nightMode = newValue as Boolean AppPref(sharedPref).nightModeEnabled = nightMode - val coordinatorLayout = requireActivity().findViewById(R.id.coordinatorlayout) + val coordinatorLayout = + requireActivity().findViewById(R.id.coordinatorlayout) Snackbar.make(coordinatorLayout, "Restart to apply changes", Snackbar.LENGTH_INDEFINITE) - .setAction(android.R.string.ok){ - ActivityCompat.recreate(requireActivity()) - } - .show() + .setAction(android.R.string.ok) { + ActivityCompat.recreate(requireActivity()) + } + .show() true } nightModePref.icon = IconicsDrawable(requireContext()).apply { @@ -139,8 +152,9 @@ class SettingsFragment: BaseSettings() { } } - private fun setThumbnail(){ - val thumbnailPref = findPreference("currencyThumbnail") as CheckBoxPreference + private fun setThumbnail() { + val thumbnailPref = + findPreference("currencyThumbnail") as CheckBoxPreference thumbnailPref.icon = IconicsDrawable(requireContext()).apply { icon = GoogleMaterial.Icon.gmd_attach_money sizeDp = 24 @@ -153,7 +167,7 @@ class SettingsFragment: BaseSettings() { } } - private fun setTutorial(){ + private fun setTutorial() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { val tutorialSetting = findPreference("tutorial_setting") as Preference tutorialSetting.isVisible = true @@ -169,7 +183,7 @@ class SettingsFragment: BaseSettings() { } } - private fun setDeveloperOption(){ + private fun setDeveloperOption() { val developerSettings = findPreference("developer_options") as Preference developerSettings.setOnPreferenceClickListener { parentFragmentManager.commit { @@ -188,23 +202,29 @@ class SettingsFragment: BaseSettings() { override fun onResume() { super.onResume() - requireActivity().findViewById(R.id.activity_toolbar).title = resources.getString(R.string.settings) + requireActivity().findViewById(R.id.activity_toolbar).title = + resources.getString(R.string.settings) } - private fun setIconColor(): Int{ - return if(globalViewModel.isDark){ + private fun setIconColor(): Int { + return if (globalViewModel.isDark) { R.color.md_white_1000 } else { R.color.md_black_1000 } } - private fun setPinCode(){ + private fun setPinCode() { val keyguardPref = findPreference("keyguard") as Preference - if(!KeyguardUtil(requireActivity()).isDeviceKeyguardEnabled() || BiometricManager.from(requireContext()).canAuthenticate( - BiometricManager.Authenticators.BIOMETRIC_WEAK or BiometricManager.Authenticators.DEVICE_CREDENTIAL) != BIOMETRIC_SUCCESS){ + if (!KeyguardUtil(requireActivity()).isDeviceKeyguardEnabled() || BiometricManager.from( + requireContext() + ).canAuthenticate( + BiometricManager.Authenticators.BIOMETRIC_WEAK or BiometricManager.Authenticators.DEVICE_CREDENTIAL + ) != BIOMETRIC_SUCCESS + ) { keyguardPref.isSelectable = false - keyguardPref.summary = "Please enable pin / password / biometrics in your device settings" + keyguardPref.summary = + "Please enable pin / password / biometrics in your device settings" } keyguardPref.icon = IconicsDrawable(requireContext()).apply { icon = GoogleMaterial.Icon.gmd_lock @@ -218,7 +238,7 @@ class SettingsFragment: BaseSettings() { } } - private fun deleteItems(){ + private fun deleteItems() { val deleteData = findPreference("delete_data") as Preference deleteData.icon = IconicsDrawable(requireContext()).apply { icon = GoogleMaterial.Icon.gmd_delete_forever @@ -235,15 +255,16 @@ class SettingsFragment: BaseSettings() { } } - private fun userDefinedDirectory(){ - userDownloadDirectoryPref = findPreference("userDefinedDownloadDirectory") as Preference + private fun userDefinedDirectory() { + userDownloadDirectoryPref = + findPreference("userDefinedDownloadDirectory") as Preference val userPref = AppPref(sharedPref).userDefinedDownloadDirectory userDownloadDirectoryPref.icon = IconicsDrawable(requireContext()).apply { icon = GoogleMaterial.Icon.gmd_file_download sizeDp = 24 colorRes = setIconColor() } - val userDirectory = if(userPref.isEmpty()){ + val userDirectory = if (userPref.isEmpty()) { File(requireContext().getExternalFilesDir(null).toString()).toString() } else { userPref @@ -257,11 +278,12 @@ class SettingsFragment: BaseSettings() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - chooseFolder = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { folderChoosen -> - if(folderChoosen != null){ - AppPref(sharedPref).userDefinedDownloadDirectory = folderChoosen.toString() - userDownloadDirectoryPref.summary = folderChoosen.toString() + chooseFolder = + registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { folderChoosen -> + if (folderChoosen != null) { + AppPref(sharedPref).userDefinedDownloadDirectory = folderChoosen.toString() + userDownloadDirectoryPref.summary = folderChoosen.toString() + } } - } } } \ No newline at end of file From 063c098afc6d7e33467744d43ad7d6690ac3a0e9 Mon Sep 17 00:00:00 2001 From: Arnau Mora Date: Thu, 24 Nov 2022 20:06:27 +0100 Subject: [PATCH 11/18] Added automatic available languages generation Signed-off-by: Arnau Mora --- languagepack/build.gradle | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/languagepack/build.gradle b/languagepack/build.gradle index 60cb4252..577f6c0c 100644 --- a/languagepack/build.gradle +++ b/languagepack/build.gradle @@ -8,6 +8,10 @@ android { minSdkVersion 17 targetSdkVersion(Dependencies.targetSdk) testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + def locales = getLocales() + buildConfigField "String[]", "TRANSLATION_ARRAY", "new String[]{\"" + locales.join("\",\"") + "\"}" + resConfigs locales } buildTypes { @@ -24,6 +28,72 @@ android { } } + sourceSets { + main { + res.srcDirs += ['build/generated/res/locale'] + } + } +} + +import groovy.xml.MarkupBuilder + +import static groovy.io.FileType.DIRECTORIES + +/** + * Obtains a list of all the available locales + * @since 20220928 + * @return A list with the language codes of the locales available. + */ +def getLocales() { + // Initialize the list English, since it's available by default + def list = ["en"] + // Get all directories inside resources + def dir = new File(projectDir, "src/main/res") + dir.traverse(type: DIRECTORIES, maxDepth: 0) { file -> + // Get only values directories + def fileName = file.name + if (!fileName.startsWith("values-")) return + + // Take only the values directories that contain strings + def stringsFile = new File(file, "strings.xml") + if (!stringsFile.exists()) return + + // Add to the list the locale of the strings file + list.add(fileName.substring(fileName.indexOf('-') + 1)) + } + // Log the available locales + println "Supported locales: " + list.join(", ") + // Return the built list + return list +} + +task updateLocalesConfig() { + println 'Building locale config...' + ext.outputDir = new File(projectDir, 'build/generated/res/locale/xml') + + doFirst { + mkdir outputDir + + new File(outputDir, "locales_config.xml").withWriter { writer -> + def destXml = new MarkupBuilder(new IndentPrinter(writer, " ", true, true)) + destXml.setDoubleQuotes(true) + def destXmlMkp = destXml.getMkp() + destXmlMkp.xmlDeclaration(version: "1.0", encoding: "utf-8") + destXmlMkp.comment("Generated at ${new Date()}") + destXmlMkp.yield "\r\n" + + def locales = getLocales() + destXml."locale-config"(['xmlns:android': "http://schemas.android.com/apk/res/android"]) { + locales.forEach { locale -> + destXml."locale"("android:name": locale) + } + } + } + } +} + +gradle.projectsEvaluated { + preBuild.dependsOn('updateLocalesConfig') } dependencies { From 7a7a5ed42d2bc041d05e3dff8b4f469cf0b9045a Mon Sep 17 00:00:00 2001 From: Arnau Mora Date: Thu, 24 Nov 2022 20:06:48 +0100 Subject: [PATCH 12/18] Updated AppCompat to `1.6.0-rc01` Signed-off-by: Arnau Mora --- buildSrc/src/main/java/Dependencies.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index 91f876eb..82e7495e 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -8,7 +8,7 @@ object Dependencies{ private const val lifecycleVersion = "2.4.0" private const val roomVersion = "2.4.0" private const val coroutineVersion = "1.6.0" - private const val appCompatVersion = "1.4.0" + private const val appCompatVersion = "1.6.0-rc01" private const val androidxFragmentVersion = "1.4.0" private const val androidxAnnotationVersion = "1.3.0-beta01" private const val androidxRecyclerViewVersion = "1.3.0-alpha01" From c2ded3fb55629b07468ce2f49434df311056f91d Mon Sep 17 00:00:00 2001 From: Arnau Mora Date: Thu, 24 Nov 2022 20:10:56 +0100 Subject: [PATCH 13/18] Language shows in locale Signed-off-by: Arnau Mora --- .../xyz/hisname/fireflyiii/ui/settings/SettingsFragment.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/xyz/hisname/fireflyiii/ui/settings/SettingsFragment.kt b/app/src/main/java/xyz/hisname/fireflyiii/ui/settings/SettingsFragment.kt index 709c99ef..b0742896 100644 --- a/app/src/main/java/xyz/hisname/fireflyiii/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/xyz/hisname/fireflyiii/ui/settings/SettingsFragment.kt @@ -75,7 +75,10 @@ class SettingsFragment : BaseSettings() { else Locale.forLanguageTag(langCode) } - languagePref.entries = availableLocales.map { it.displayName }.toTypedArray() + languagePref.entries = availableLocales.map { locale -> + locale.getDisplayName(locale) + .replaceFirstChar { if (it.isLowerCase()) it.titlecase(locale) else it.toString() } + }.toTypedArray() languagePref.entryValues = TRANSLATION_ARRAY val localesList = AppCompatDelegate.getApplicationLocales() From ea85c9ab0793cffa350f27a69b2a1f726066db0d Mon Sep 17 00:00:00 2001 From: Arnau Mora Date: Thu, 24 Nov 2022 20:52:15 +0100 Subject: [PATCH 14/18] Updated all dependencies Signed-off-by: Arnau Mora --- app/build.gradle | 1 - buildSrc/src/main/java/Dependencies.kt | 172 ++++++++++++------------- buildSrc/src/main/java/Version.gradle | 4 +- 3 files changed, 88 insertions(+), 89 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index e11c4ebc..ee4913e2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,7 +5,6 @@ apply plugin: 'com.starter.easylauncher' apply plugin: "com.github.ben-manes.versions" android { - kotlinOptions.useIR = true compileSdkVersion(Dependencies.compileSdk) defaultConfig { applicationId "xyz.hisname.fireflyiii" diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index 82e7495e..b5c681d6 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -3,101 +3,101 @@ object Dependencies{ const val minSdk = 23 const val targetSdk = 33 const val compileSdk = 33 - const val kotlinVersion = "1.6.10" + const val kotlinVersion = "1.7.20" private const val retrofitVersion = "2.9.0" - private const val lifecycleVersion = "2.4.0" - private const val roomVersion = "2.4.0" - private const val coroutineVersion = "1.6.0" + private const val lifecycleVersion = "2.5.1" + private const val roomVersion = "2.4.3" + private const val coroutineVersion = "1.6.4" private const val appCompatVersion = "1.6.0-rc01" - private const val androidxFragmentVersion = "1.4.0" - private const val androidxAnnotationVersion = "1.3.0-beta01" - private const val androidxRecyclerViewVersion = "1.3.0-alpha01" - private const val materialDesignVersion = "1.6.0-alpha01" + private const val androidxFragmentVersion = "1.5.4" + private const val androidxAnnotationVersion = "1.5.0" + private const val androidxRecyclerViewVersion = "1.3.0-rc01" + private const val materialDesignVersion = "1.7.0" private const val swipeRefreshVersion = "1.1.0" - private const val androidxCoreVersion = "1.7.0" - private const val androidxConstraintLayoutVersion = "2.1.2" - private const val androidxPrefVersion = "1.2.0-rc01" + private const val androidxCoreVersion = "1.9.0" + private const val androidxConstraintLayoutVersion = "2.1.4" + private const val androidxPrefVersion = "1.2.0" private const val androidxWorkVersion = "2.7.1" - private const val materialDrawerVersion = "8.4.5" - private const val iconicsVersion = "5.3.2" - private const val toastyVersion = "7be5e09082" + private const val materialDrawerVersion = "9.0.1" + private const val iconicsVersion = "5.4.0" + private const val toastyVersion = "1.5.2" private const val chartVersion = "3.1.0" private const val aboutLibVersion = "3.2.0-rc01" - private const val glideVersion = "4.12.0" + private const val glideVersion = "4.14.2" private const val nachosVersion = "1.2.0" - private const val acraVersion = "5.8.4" - private const val osmdroidVersion = "6.1.11" - private const val jUnitVersion = "5.7.0" - private const val espressoVersion = "3.1.1" - private const val androidTestVersion = "1.1.1" - private const val androidTestCoreVersion = "1.0.0" + private const val acraVersion = "5.9.6" + private const val osmdroidVersion = "6.1.13" + private const val jUnitVersion = "5.9.1" + private const val espressoVersion = "3.5.0" + private const val androidTestVersion = "1.5.0" + private const val androidTestCoreVersion = "1.5.0" + private const val androidTestJunitVersion = "1.1.4" private const val accordionViewVersion = "1.2.4" - private const val fancyshowcaseviewVersion = "1.3.6" + private const val fancyshowcaseviewVersion = "1.3.9" private const val markdownVersion = "0.17.0" - private const val biometricVersion = "1.2.0-alpha04" - private const val testVersion = "1.3.0-alpha03" - private const val taskerPluginVersion = "0.4.2" - private const val moshiVersion = "1.13.0" - private const val calendarViewVersion = "1.0.4" - private const val pagingLibVersion = "3.1.0" + private const val biometricVersion = "1.2.0-alpha05" + private const val testOrchestratorVersion = "1.4.2" + private const val taskerPluginVersion = "0.4.6" + private const val moshiVersion = "1.14.0" + private const val calendarViewVersion = "2.0.4" + private const val pagingLibVersion = "3.1.1" private const val viewPager2Version = "1.1.0-beta01" - val lifecyclerLiveDataCore = "androidx.lifecycle:lifecycle-livedata-core-ktx:$lifecycleVersion" - val lifeCycleExtension = "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion" - val retrofitLibs = "com.squareup.retrofit2:retrofit:$retrofitVersion" - val retrofitMoshi = "com.squareup.retrofit2:converter-moshi:$retrofitVersion" - val retrofitScalar = "com.squareup.retrofit2:converter-scalars:$retrofitVersion" - val mockWebServer = "org.mock-server:mockserver-netty:5.11.2" - val roomLibs = "androidx.room:room-runtime:$roomVersion" - val roomExtension = "androidx.room:room-ktx:$roomVersion" - val roomCompiler = "androidx.room:room-compiler:$roomVersion" - val roomPaging = "androidx.room:room-paging:$roomVersion" - val coroutineCore = "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion" - val appCompat = "androidx.appcompat:appcompat:$appCompatVersion" - val swipeRefreshLayout = "androidx.swiperefreshlayout:swiperefreshlayout:$swipeRefreshVersion" - val androidxFragment = "androidx.fragment:fragment-ktx:$androidxFragmentVersion" - val androidxAnnotation = "androidx.annotation:annotation:$androidxAnnotationVersion" - val androidxRecyclerView = "androidx.recyclerview:recyclerview:$androidxRecyclerViewVersion" - val materialDesign = "com.google.android.material:material:$materialDesignVersion" - val androidxCore = "androidx.core:core-ktx:$androidxCoreVersion" - val androidxConstraintLayout = "androidx.constraintlayout:constraintlayout:$androidxConstraintLayoutVersion" - val androidxPref = "androidx.preference:preference:$androidxPrefVersion" - val androidxWork = "androidx.work:work-runtime-ktx:$androidxWorkVersion" - val materialDrawer = "com.mikepenz:materialdrawer:$materialDrawerVersion" - val iconics = "com.mikepenz:iconics-core:$iconicsVersion" - val materialDrawerIconics = "com.mikepenz:materialdrawer-iconics:$materialDrawerVersion" - val googleMaterialIcons = "com.mikepenz:google-material-typeface:4.0.0.2-kotlin@aar" - val fontAwesome = "com.mikepenz:fontawesome-typeface:5.9.0.2-kotlin@aar" - val toasty = "com.github.GrenderG:Toasty:$toastyVersion" - val chart = "com.github.PhilJay:MPAndroidChart:$chartVersion" - val aboutLib = "com.github.daniel-stoneuk:material-about-library:$aboutLibVersion" - val kotlinLib = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" - val glideLib = "com.github.bumptech.glide:glide:$glideVersion" - val glideCompiler = "com.github.bumptech.glide:compiler:$glideVersion" - val glideOkHttpExtension = "com.github.bumptech.glide:okhttp3-integration:$glideVersion" - val nachos = "com.github.hootsuite:nachos:$nachosVersion" - val acraMail = "ch.acra:acra-mail:$acraVersion" - val osmdroid = "org.osmdroid:osmdroid-android:$osmdroidVersion" - val junitEngine = "org.junit.jupiter:junit-jupiter-engine:$jUnitVersion" - val jUnitApi = "org.junit.jupiter:junit-jupiter-api:$jUnitVersion" - val jUnitParameter = "org.junit.jupiter:junit-jupiter-params:$jUnitVersion" - val espresso = "androidx.test.espresso:espresso-core:$espressoVersion" - val androidTest = "androidx.test:runner:$androidTestVersion" - val androidTestCore = "androidx.test:core:$androidTestCoreVersion" - val androidTestExt = "androidx.test.ext:junit:$androidTestCoreVersion" - val accordionView = "com.github.florent37:expansionpanel:$accordionViewVersion" - val fancyshowcaseview = "com.github.faruktoptas:fancyshowcaseview:$fancyshowcaseviewVersion" - val markdownLib = "com.atlassian.commonmark:commonmark:$markdownVersion" - val markdownStrikeThroughExtension = "com.atlassian.commonmark:commonmark-ext-gfm-strikethrough:$markdownVersion" - val markdownAutoLink = "com.atlassian.commonmark:commonmark-ext-autolink:$markdownVersion" - val biometricLib = "androidx.biometric:biometric:$biometricVersion" - val testRunner = "androidx.test:runner:$testVersion" - val testOrchestrator = "androidx.test:orchestrator:$testVersion" - val taskerPluginLib = "com.joaomgcd:taskerpluginlibrary:$taskerPluginVersion" - val notificationLib = "io.karn:notify:1.3.0" - val moshiLib = "com.squareup.moshi:moshi:$moshiVersion" - val moshiCodegen = "com.squareup.moshi:moshi-kotlin-codegen:$moshiVersion" - val calendarView = "com.github.kizitonwose:CalendarView:$calendarViewVersion" - val pagingLib = "androidx.paging:paging-runtime-ktx:$pagingLibVersion" - val viewPager2Lib = "androidx.viewpager2:viewpager2:$viewPager2Version" + const val lifecyclerLiveDataCore = "androidx.lifecycle:lifecycle-livedata-core-ktx:$lifecycleVersion" + const val lifeCycleExtension = "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion" + const val retrofitLibs = "com.squareup.retrofit2:retrofit:$retrofitVersion" + const val retrofitMoshi = "com.squareup.retrofit2:converter-moshi:$retrofitVersion" + const val retrofitScalar = "com.squareup.retrofit2:converter-scalars:$retrofitVersion" + const val mockWebServer = "org.mock-server:mockserver-netty:5.11.2" + const val roomLibs = "androidx.room:room-runtime:$roomVersion" + const val roomExtension = "androidx.room:room-ktx:$roomVersion" + const val roomCompiler = "androidx.room:room-compiler:$roomVersion" + const val roomPaging = "androidx.room:room-paging:$roomVersion" + const val coroutineCore = "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion" + const val appCompat = "androidx.appcompat:appcompat:$appCompatVersion" + const val swipeRefreshLayout = "androidx.swiperefreshlayout:swiperefreshlayout:$swipeRefreshVersion" + const val androidxFragment = "androidx.fragment:fragment-ktx:$androidxFragmentVersion" + const val androidxAnnotation = "androidx.annotation:annotation:$androidxAnnotationVersion" + const val androidxRecyclerView = "androidx.recyclerview:recyclerview:$androidxRecyclerViewVersion" + const val materialDesign = "com.google.android.material:material:$materialDesignVersion" + const val androidxCore = "androidx.core:core-ktx:$androidxCoreVersion" + const val androidxConstraintLayout = "androidx.constraintlayout:constraintlayout:$androidxConstraintLayoutVersion" + const val androidxPref = "androidx.preference:preference:$androidxPrefVersion" + const val androidxWork = "androidx.work:work-runtime-ktx:$androidxWorkVersion" + const val materialDrawer = "com.mikepenz:materialdrawer:$materialDrawerVersion" + const val iconics = "com.mikepenz:iconics-core:$iconicsVersion" + const val materialDrawerIconics = "com.mikepenz:materialdrawer-iconics:$materialDrawerVersion" + const val googleMaterialIcons = "com.mikepenz:google-material-typeface:4.0.0.2-kotlin@aar" + const val fontAwesome = "com.mikepenz:fontawesome-typeface:5.9.0.2-kotlin@aar" + const val toasty = "com.github.GrenderG:Toasty:$toastyVersion" + const val chart = "com.github.PhilJay:MPAndroidChart:$chartVersion" + const val aboutLib = "com.github.daniel-stoneuk:material-about-library:$aboutLibVersion" + const val kotlinLib = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" + const val glideLib = "com.github.bumptech.glide:glide:$glideVersion" + const val glideCompiler = "com.github.bumptech.glide:compiler:$glideVersion" + const val glideOkHttpExtension = "com.github.bumptech.glide:okhttp3-integration:$glideVersion" + const val nachos = "com.github.hootsuite:nachos:$nachosVersion" + const val acraMail = "ch.acra:acra-mail:$acraVersion" + const val osmdroid = "org.osmdroid:osmdroid-android:$osmdroidVersion" + const val junitEngine = "org.junit.jupiter:junit-jupiter-engine:$jUnitVersion" + const val jUnitApi = "org.junit.jupiter:junit-jupiter-api:$jUnitVersion" + const val jUnitParameter = "org.junit.jupiter:junit-jupiter-params:$jUnitVersion" + const val espresso = "androidx.test.espresso:espresso-core:$espressoVersion" + const val androidTest = "androidx.test:runner:$androidTestVersion" + const val androidTestCore = "androidx.test:core:$androidTestCoreVersion" + const val androidTestExt = "androidx.test.ext:junit:$androidTestJunitVersion" + const val accordionView = "com.github.florent37:expansionpanel:$accordionViewVersion" + const val fancyshowcaseview = "com.github.faruktoptas:fancyshowcaseview:$fancyshowcaseviewVersion" + const val markdownLib = "com.atlassian.commonmark:commonmark:$markdownVersion" + const val markdownStrikeThroughExtension = "com.atlassian.commonmark:commonmark-ext-gfm-strikethrough:$markdownVersion" + const val markdownAutoLink = "com.atlassian.commonmark:commonmark-ext-autolink:$markdownVersion" + const val biometricLib = "androidx.biometric:biometric:$biometricVersion" + const val testOrchestrator = "androidx.test:orchestrator:$testOrchestratorVersion" + const val taskerPluginLib = "com.joaomgcd:taskerpluginlibrary:$taskerPluginVersion" + const val notificationLib = "io.karn:notify:1.3.0" + const val moshiLib = "com.squareup.moshi:moshi:$moshiVersion" + const val moshiCodegen = "com.squareup.moshi:moshi-kotlin-codegen:$moshiVersion" + const val calendarView = "com.kizitonwose.calendar:view:$calendarViewVersion" + const val pagingLib = "androidx.paging:paging-runtime-ktx:$pagingLibVersion" + const val viewPager2Lib = "androidx.viewpager2:viewpager2:$viewPager2Version" } \ No newline at end of file diff --git a/buildSrc/src/main/java/Version.gradle b/buildSrc/src/main/java/Version.gradle index e94c6204..8c1ae060 100644 --- a/buildSrc/src/main/java/Version.gradle +++ b/buildSrc/src/main/java/Version.gradle @@ -8,7 +8,7 @@ ext { androidx = Group { implementation Dependencies.appCompat implementation Dependencies.androidxFragment - compileOnly Dependencies.androidxAnnotation + implementation Dependencies.androidxAnnotation implementation Dependencies.androidxRecyclerView implementation Dependencies.androidxCore implementation Dependencies.androidxConstraintLayout @@ -66,7 +66,7 @@ ext { testImplementation Dependencies.jUnitParameter testImplementation Dependencies.mockWebServer - androidTestImplementation Dependencies.testRunner + androidTestImplementation Dependencies.androidTest androidTestUtil Dependencies.testOrchestrator } } \ No newline at end of file From 6f3cb7b5440fe3e476fdf63998a0dc82963e7202 Mon Sep 17 00:00:00 2001 From: Arnau Mora Date: Fri, 25 Nov 2022 11:06:26 +0100 Subject: [PATCH 15/18] Code migrations Signed-off-by: Arnau Mora --- .../java/xyz/hisname/fireflyiii/CustomApp.kt | 2 +- .../ui/bills/details/BillDetailsFragment.kt | 42 +++++++++---------- .../TransactionSeparatorAdapter.kt | 1 + .../transaction/list/TransactionFragment.kt | 33 +++++++-------- .../main/res/layout/fragment_bill_details.xml | 8 ++-- .../main/res/layout/fragment_transaction.xml | 5 +-- app/src/main/res/values/styles.xml | 2 +- 7 files changed, 46 insertions(+), 47 deletions(-) diff --git a/app/src/main/java/xyz/hisname/fireflyiii/CustomApp.kt b/app/src/main/java/xyz/hisname/fireflyiii/CustomApp.kt index 15cf6cde..ff7a9627 100644 --- a/app/src/main/java/xyz/hisname/fireflyiii/CustomApp.kt +++ b/app/src/main/java/xyz/hisname/fireflyiii/CustomApp.kt @@ -40,7 +40,7 @@ class CustomApp: Application() { initAcra { reportFormat = StringFormat.KEY_VALUE_LIST buildConfigClass = BuildConfig::class.java - reportContent = arrayOf(ReportField.REPORT_ID, ReportField.APP_VERSION_NAME, + reportContent = listOf(ReportField.REPORT_ID, ReportField.APP_VERSION_NAME, ReportField.PHONE_MODEL, ReportField.BRAND, ReportField.PRODUCT, ReportField.ANDROID_VERSION, ReportField.BUILD_CONFIG, ReportField.STACK_TRACE, ReportField.LOGCAT) mailSender { diff --git a/app/src/main/java/xyz/hisname/fireflyiii/ui/bills/details/BillDetailsFragment.kt b/app/src/main/java/xyz/hisname/fireflyiii/ui/bills/details/BillDetailsFragment.kt index a4fc33f6..58def8fa 100644 --- a/app/src/main/java/xyz/hisname/fireflyiii/ui/bills/details/BillDetailsFragment.kt +++ b/app/src/main/java/xyz/hisname/fireflyiii/ui/bills/details/BillDetailsFragment.kt @@ -34,11 +34,11 @@ import androidx.lifecycle.asLiveData import androidx.paging.LoadState import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager -import com.kizitonwose.calendarview.CalendarView -import com.kizitonwose.calendarview.model.CalendarDay -import com.kizitonwose.calendarview.model.DayOwner -import com.kizitonwose.calendarview.ui.DayBinder -import com.kizitonwose.calendarview.ui.ViewContainer +import com.kizitonwose.calendar.core.CalendarDay +import com.kizitonwose.calendar.core.DayPosition +import com.kizitonwose.calendar.view.CalendarView +import com.kizitonwose.calendar.view.MonthDayBinder +import com.kizitonwose.calendar.view.ViewContainer import xyz.hisname.fireflyiii.R import xyz.hisname.fireflyiii.databinding.CalendarDayBinding import xyz.hisname.fireflyiii.databinding.DetailsCardBinding @@ -149,15 +149,15 @@ class BillDetailsFragment: BaseDetailFragment() { val onDayText = CalendarDayBinding.bind(view).dayText } - binding.payDatesCalendarView.dayBinder = object: DayBinder{ - override fun bind(container: DayViewContainer, day: CalendarDay) { - container.day = day + binding.payDatesCalendarView.dayBinder = object: MonthDayBinder{ + override fun bind(container: DayViewContainer, data: CalendarDay) { + container.day = data val textView = container.onDayText - textView.text = day.date.dayOfMonth.toString() - if (day.owner == DayOwner.THIS_MONTH) { + textView.text = data.date.dayOfMonth.toString() + if (data.position == DayPosition.MonthDate) { if (selectedPayDays.isNotEmpty()){ - selectedPayDays.forEach { data -> - if(data == day.date){ + selectedPayDays.forEach { day -> + if(day == data.date){ textView.setBackgroundColor(getCompatColor(R.color.md_red_400)) } else { textView.setTextColor(setDayNightTheme()) @@ -208,21 +208,21 @@ class BillDetailsFragment: BaseDetailFragment() { } } - binding.paidDatesCalendarView.dayBinder = object: DayBinder{ - override fun bind(container: DayViewContainer, day: CalendarDay) { - container.day = day + binding.paidDatesCalendarView.dayBinder = object: MonthDayBinder{ + override fun bind(container: DayViewContainer, data: CalendarDay) { + container.day = data val textView = container.onDayText val divider = container.legendDivider - textView.text = day.date.dayOfMonth.toString() - if (day.owner == DayOwner.THIS_MONTH) { + textView.text = data.date.dayOfMonth.toString() + if (data.position == DayPosition.MonthDate) { if (selectedPaidDays.isNotEmpty()){ - selectedPaidDays.forEach { data -> - if(data == day.date){ + selectedPaidDays.forEach { day -> + if(day == data.date){ divider.setBackgroundColor(getCompatColor(R.color.md_green_500)) } } } - if(selectedDate == day.date){ + if(selectedDate == data.date){ textView.setBackgroundColor(getCompatColor(R.color.md_green_500)) } textView.setTextColor(setDayNightTheme()) @@ -251,7 +251,7 @@ class BillDetailsFragment: BaseDetailFragment() { calendarView.setup(startMonth, endMonth, WeekFields.of(Locale.getDefault()).firstDayOfWeek) calendarView.scrollToMonth(currentMonth) - calendarView.updateMonthConfiguration() + calendarView.updateMonthData() } private fun progressCircle(){ diff --git a/app/src/main/java/xyz/hisname/fireflyiii/ui/transaction/TransactionSeparatorAdapter.kt b/app/src/main/java/xyz/hisname/fireflyiii/ui/transaction/TransactionSeparatorAdapter.kt index b3246f97..bad96761 100644 --- a/app/src/main/java/xyz/hisname/fireflyiii/ui/transaction/TransactionSeparatorAdapter.kt +++ b/app/src/main/java/xyz/hisname/fireflyiii/ui/transaction/TransactionSeparatorAdapter.kt @@ -102,6 +102,7 @@ class TransactionSeparatorAdapter(private val clickListener:(Transactions) -> Un } binding.listItem.setOnClickListener {clickListener(separator.transaction)} } + else -> null } } } diff --git a/app/src/main/java/xyz/hisname/fireflyiii/ui/transaction/list/TransactionFragment.kt b/app/src/main/java/xyz/hisname/fireflyiii/ui/transaction/list/TransactionFragment.kt index 5992b1c9..c3789377 100644 --- a/app/src/main/java/xyz/hisname/fireflyiii/ui/transaction/list/TransactionFragment.kt +++ b/app/src/main/java/xyz/hisname/fireflyiii/ui/transaction/list/TransactionFragment.kt @@ -44,10 +44,10 @@ import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.datepicker.MaterialDatePicker -import com.kizitonwose.calendarview.model.CalendarDay -import com.kizitonwose.calendarview.model.DayOwner -import com.kizitonwose.calendarview.ui.DayBinder -import com.kizitonwose.calendarview.ui.ViewContainer +import com.kizitonwose.calendar.core.CalendarDay +import com.kizitonwose.calendar.core.DayPosition +import com.kizitonwose.calendar.view.MonthDayBinder +import com.kizitonwose.calendar.view.ViewContainer import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesome import com.mikepenz.iconics.utils.sizeDp @@ -168,7 +168,7 @@ class TransactionFragment: BaseFragment(){ view.setOnClickListener { selectedDates.clear() dateRange.clear() - if (day.owner == DayOwner.THIS_MONTH) { + if (day.position == DayPosition.MonthDate) { selectedDate = day.date selectedDates.clear() binding.transactionCalendar.notifyCalendarChanged() @@ -221,25 +221,25 @@ class TransactionFragment: BaseFragment(){ } } } - binding.transactionCalendar.dayBinder = object: DayBinder{ - override fun bind(container: DayViewContainer, day: CalendarDay) { - container.day = day + binding.transactionCalendar.dayBinder = object: MonthDayBinder{ + override fun bind(container: DayViewContainer, data: CalendarDay) { + container.day = data val textView = container.onDayText - textView.text = day.date.dayOfMonth.toString() + textView.text = data.date.dayOfMonth.toString() setShowCase(textView) - if (day.owner == DayOwner.THIS_MONTH) { + if (data.position == DayPosition.MonthDate) { when { - selectedDates.contains(day.date) -> { + selectedDates.contains(data.date) -> { if (selectedDates.size != 2){ dateRange.clear() } textView.setTextColor(setDayNightTheme()) textView.setBackgroundResource(R.drawable.today_bg) } - dateRange.contains(day.date) -> { + dateRange.contains(data.date) -> { textView.setBackgroundResource(R.drawable.today_bg) } - selectedDate == day.date -> { + selectedDate == data.date -> { if(selectedDate == today){ textView.setTextColor(getCompatColor(R.color.md_red_800)) } else { @@ -269,10 +269,9 @@ class TransactionFragment: BaseFragment(){ val currentMonth = YearMonth.now() val startMonth = currentMonth.minusYears(80) val endMonth = currentMonth.plusYears(20) - binding.transactionCalendar.setupAsync(startMonth, endMonth, DayOfWeek.SUNDAY){ - binding.transactionCalendar.scrollToMonth(currentMonth) - binding.transactionCalendar.updateMonthConfiguration() - } + binding.transactionCalendar.setup(startMonth, endMonth, DayOfWeek.SUNDAY) + binding.transactionCalendar.scrollToMonth(currentMonth) + binding.transactionCalendar.updateMonthData() } private fun dragAndDrop(){ diff --git a/app/src/main/res/layout/fragment_bill_details.xml b/app/src/main/res/layout/fragment_bill_details.xml index b40e9866..29a3a8fe 100644 --- a/app/src/main/res/layout/fragment_bill_details.xml +++ b/app/src/main/res/layout/fragment_bill_details.xml @@ -134,14 +134,14 @@ android:layout_marginTop="10dp" android:layout_marginBottom="10dp" /> - + app:cv_scrollPaged="true" /> @@ -208,14 +208,14 @@ android:layout_marginTop="10dp" android:layout_marginBottom="10dp" /> - + app:cv_scrollPaged="true" /> - diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index b8dc1f12..156c6107 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -57,7 +57,7 @@ false true - @style/MaterialDrawer.DrawerArrowStyle +