diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 18df800..85cf0b4 100644 Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ diff --git a/.idea/navEditor.xml b/.idea/navEditor.xml new file mode 100644 index 0000000..0054711 --- /dev/null +++ b/.idea/navEditor.xml @@ -0,0 +1,52 @@ + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 77af67f..848e336 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,7 +18,7 @@ android { applicationId "com.tommasoberlose.anotherwidget" minSdkVersion 23 targetSdkVersion 29 - versionCode 76 + versionCode 77 versionName "2.0.5" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/release/app-release.aab b/app/release/app-release.aab index 5e872c6..e6f178b 100644 Binary files a/app/release/app-release.aab and b/app/release/app-release.aab differ diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/CalendarHelper.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/CalendarHelper.kt index ff0d1e1..4224989 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/CalendarHelper.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/CalendarHelper.kt @@ -11,6 +11,7 @@ import com.tommasoberlose.anotherwidget.models.Event import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver import com.tommasoberlose.anotherwidget.ui.activities.MainActivity +import com.tommasoberlose.anotherwidget.ui.fragments.AppMainFragment import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission import me.everything.providers.android.calendar.CalendarProvider @@ -127,7 +128,7 @@ object CalendarHelper { UpdatesReceiver.setUpdates(context) MainWidget.updateWidget(context) - EventBus.getDefault().post(MainActivity.UpdateUiMessageEvent()) + EventBus.getDefault().post(AppMainFragment.UpdateUiMessageEvent()) } fun getCalendarList(context: Context): List { diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/WeatherHelper.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/WeatherHelper.kt index 0971aab..b9e4936 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/WeatherHelper.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/WeatherHelper.kt @@ -14,6 +14,7 @@ import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi import com.tommasoberlose.anotherwidget.ui.activities.MainActivity +import com.tommasoberlose.anotherwidget.ui.fragments.AppMainFragment import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission import org.greenrobot.eventbus.EventBus @@ -38,7 +39,7 @@ object WeatherHelper { Preferences.customLocationLon = location.longitude.toString() networkApi.updateWeather() - EventBus.getDefault().post(MainActivity.UpdateUiMessageEvent()) + EventBus.getDefault().post(AppMainFragment.UpdateUiMessageEvent()) } } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/network/WeatherNetworkApi.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/network/WeatherNetworkApi.kt index d94e4b7..02f25d4 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/network/WeatherNetworkApi.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/network/WeatherNetworkApi.kt @@ -9,6 +9,7 @@ import com.kwabenaberko.openweathermaplib.models.currentweather.CurrentWeather import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.helpers.WeatherHelper import com.tommasoberlose.anotherwidget.ui.activities.MainActivity +import com.tommasoberlose.anotherwidget.ui.fragments.AppMainFragment import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import org.greenrobot.eventbus.EventBus @@ -26,7 +27,7 @@ class WeatherNetworkApi(val context: Context) { Preferences.weatherRealTempUnit = Preferences.weatherTempUnit MainWidget.updateWidget(context) - EventBus.getDefault().post(MainActivity.UpdateUiMessageEvent()) + EventBus.getDefault().post(AppMainFragment.UpdateUiMessageEvent()) } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/MainActivity.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/MainActivity.kt index 6a61c00..33e0875 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/MainActivity.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/MainActivity.kt @@ -24,8 +24,15 @@ import androidx.core.view.isVisible import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope +import androidx.navigation.NavController +import androidx.navigation.Navigation import com.google.android.material.badge.BadgeDrawable import com.google.android.material.tabs.TabLayoutMediator +import com.karumi.dexter.Dexter +import com.karumi.dexter.MultiplePermissionsReport +import com.karumi.dexter.PermissionToken +import com.karumi.dexter.listener.PermissionRequest +import com.karumi.dexter.listener.multi.MultiplePermissionsListener import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog import com.tommasoberlose.anotherwidget.global.Actions @@ -50,10 +57,16 @@ import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode -class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceChangeListener { +class MainActivity : AppCompatActivity() { private var mAppWidgetId: Int = -1 private lateinit var viewModel: MainViewModel + private val mainNavController: NavController? by lazy { + Navigation.findNavController( + this, + R.id.content_fragment + ) + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -62,235 +75,19 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh viewModel = ViewModelProvider(this).get(MainViewModel::class.java) controlExtras(intent) - - // Viewpager - pager.adapter = ViewPagerAdapter(this) - pager.offscreenPageLimit = 4 - TabLayoutMediator(tabs, pager) { tab, position -> - tab.text = when (position) { - 0 -> getString(R.string.settings_general_title) - 1 -> getString(R.string.settings_calendar_title) - 2 -> getString(R.string.settings_weather_title) - 3 -> getString(R.string.settings_clock_title) - 4 -> getString(R.string.advanced_settings_title) - else -> "" - } - }.attach() - - // Init clock - time.setTextColor(ColorHelper.getFontColor()) - time.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(this@MainActivity)) - time_am_pm.setTextColor(ColorHelper.getFontColor()) - time_am_pm.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(this@MainActivity) / 5 * 2) - time_container.isVisible = Preferences.showClock - - preview.layoutParams = preview.layoutParams.apply { - height = 160.toPixel(this@MainActivity) + if (Preferences.showClock) 100.toPixel(this@MainActivity) else 0 - } - - Preferences.preferences.registerOnSharedPreferenceChangeListener(this) - subscribeUi(viewModel) - updateUI() - - // Warnings - if (getString(R.string.xiaomi_manufacturer).equals(Build.MANUFACTURER, ignoreCase = true) && Preferences.showXiaomiWarning) { - MaterialBottomSheetDialog(this, getString(R.string.xiaomi_warning_title), getString(R.string.xiaomi_warning_message)) - .setNegativeButton(getString(R.string.action_ignore)) { - Preferences.showXiaomiWarning = false - } - .setPositiveButton(getString(R.string.action_grant_permission)) { - Preferences.showXiaomiWarning = false - val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { - data = Uri.parse("package:$packageName") - } - startActivity(intent) - } - .show() - } - } - - private var uiJob: Job? = null - - private fun updateUI() { - uiJob?.cancel() - - if (Preferences.showPreview) { - preview.setCardBackgroundColor( - getColor( - if (ColorHelper.getFontColor() - .isColorDark() - ) android.R.color.white else R.color.colorAccent - ) - ) - widget_shape_background.setImageDrawable(BitmapHelper.getTintedDrawable(this, R.drawable.card_background, ColorHelper.getBackgroundColor())) - uiJob = lifecycleScope.launch(Dispatchers.IO) { - delay(200) - val generatedView = MainWidget.generateWidgetView(this@MainActivity) - - withContext(Dispatchers.Main) { - generatedView.measure(0, 0) - preview.measure(0, 0) - } - - val bitmap = BitmapHelper.getBitmapFromView( - generatedView, - if (preview.width > 0) preview.width else generatedView.measuredWidth, - generatedView.measuredHeight - ) - withContext(Dispatchers.Main) { - // Clock - time.setTextColor(ColorHelper.getFontColor()) - time_am_pm.setTextColor(ColorHelper.getFontColor()) - time.setTextSize( - TypedValue.COMPLEX_UNIT_SP, - Preferences.clockTextSize.toPixel(this@MainActivity) - ) - time_am_pm.setTextSize( - TypedValue.COMPLEX_UNIT_SP, - Preferences.clockTextSize.toPixel(this@MainActivity) / 5 * 2 - ) - - // Clock bottom margin - clock_bottom_margin_none.isVisible = - Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.value - clock_bottom_margin_small.isVisible = - Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.value - clock_bottom_margin_medium.isVisible = - Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.value - clock_bottom_margin_large.isVisible = - Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.value - - if ((Preferences.showClock && !time_container.isVisible) || (!Preferences.showClock && time_container.isVisible)) { - if (Preferences.showClock) { - time_container.layoutParams = time_container.layoutParams.apply { - height = RelativeLayout.LayoutParams.WRAP_CONTENT - } - time_container.measure(0, 0) - } - val initialHeight = time_container.measuredHeight - ValueAnimator.ofFloat( - if (Preferences.showClock) 0f else 1f, - if (Preferences.showClock) 1f else 0f - ).apply { - duration = 500L - addUpdateListener { - val animatedValue = animatedValue as Float - time_container.layoutParams = time_container.layoutParams.apply { - height = (initialHeight * animatedValue).toInt() - } - } - addListener( - onStart = { - if (Preferences.showClock) { - time_container.isVisible = true - } - }, - onEnd = { - if (!Preferences.showClock) { - time_container.isVisible = false - } - } - ) - }.start() - - ValueAnimator.ofInt( - preview.height, - 160.toPixel(this@MainActivity) + if (Preferences.showClock) 100.toPixel( - this@MainActivity - ) else 0 - ).apply { - duration = 500L - addUpdateListener { - val animatedValue = animatedValue as Int - val layoutParams = preview.layoutParams - layoutParams.height = animatedValue - preview.layoutParams = layoutParams - } - }.start() - } else { - time_container.layoutParams = time_container.layoutParams.apply { - height = RelativeLayout.LayoutParams.WRAP_CONTENT - } - time_container.measure(0, 0) - } - - if (preview.height == 0) { - ValueAnimator.ofInt( - preview.height, - 160.toPixel(this@MainActivity) + if (Preferences.showClock) 100.toPixel( - this@MainActivity - ) else 0 - ).apply { - duration = 300L - addUpdateListener { - val animatedValue = animatedValue as Int - val layoutParams = preview.layoutParams - layoutParams.height = animatedValue - preview.layoutParams = layoutParams - } - }.start() - } - - bitmap_container.setImageBitmap(bitmap) - widget_loader.animate().scaleX(0f).scaleY(0f).start() - widget.animate().alpha(1f).start() - } - } - } else { - ValueAnimator.ofInt( - preview.height, - 0 - ).apply { - duration = 300L - addUpdateListener { - val animatedValue = animatedValue as Int - val layoutParams = preview.layoutParams - layoutParams.height = animatedValue - preview.layoutParams = layoutParams - } - }.start() - } - - - // Calendar error indicator - tabs.getTabAt(1)?.orCreateBadge?.apply { - backgroundColor = ContextCompat.getColor(this@MainActivity, R.color.errorColorText) - badgeGravity = BadgeDrawable.TOP_END - }?.isVisible = Preferences.showEvents && !checkGrantedPermission(Manifest.permission.READ_CALENDAR) - - // Weather error indicator - tabs.getTabAt(2)?.orCreateBadge?.apply { - backgroundColor = ContextCompat.getColor(this@MainActivity, R.color.errorColorText) - badgeGravity = BadgeDrawable.TOP_END - }?.isVisible = Preferences.showWeather && (Preferences.weatherProviderApi == "" || (Preferences.customLocationAdd == "" && !checkGrantedPermission(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION))) - - } - - private fun subscribeUi(viewModel: MainViewModel) { - viewModel.showWallpaper.observe(this, Observer { - val wallpaper = getCurrentWallpaper() - widget_bg.setImageDrawable(if (it) wallpaper else null) - widget_bg.layoutParams = widget_bg.layoutParams.apply { - - val metrics = DisplayMetrics() - windowManager.defaultDisplay.getMetrics(metrics) - - height = metrics.heightPixels - width = (wallpaper?.intrinsicWidth ?: 1) * metrics.heightPixels / (wallpaper?.intrinsicWidth ?: 1) - } - }) - - logo.setOnClickListener { -// startActivity(Intent(this, SupportDevActivity::class.java)) - } + requirePermission() } override fun onBackPressed() { - if (mAppWidgetId > 0) { - addNewWidget() + if (mainNavController?.currentDestination?.id == R.id.appMainFragment) { + if (mAppWidgetId > 0) { + addNewWidget() + } else { + setResult(Activity.RESULT_OK) + finish() + } } else { - setResult(Activity.RESULT_OK) - finish() + super.onBackPressed() } } @@ -330,30 +127,27 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh finish() } - override fun onDestroy() { - super.onDestroy() - Preferences.preferences.unregisterOnSharedPreferenceChangeListener(this) - } + private fun requirePermission() { + Dexter.withContext(this) + .withPermissions( + Manifest.permission.READ_EXTERNAL_STORAGE + ).withListener(object : MultiplePermissionsListener { + override fun onPermissionsChecked(report: MultiplePermissionsReport?) { + report?.let { + Preferences.showWallpaper = false + Preferences.showWallpaper = report.areAllPermissionsGranted() + } + } - override fun onSharedPreferenceChanged(preferences: SharedPreferences, p1: String) { - updateUI() - MainWidget.updateWidget(this) - } - - override fun onStart() { - super.onStart() - EventBus.getDefault().register(this) - } - - override fun onStop() { - super.onStop() - EventBus.getDefault().unregister(this) - } - - class UpdateUiMessageEvent - - @Subscribe(threadMode = ThreadMode.MAIN) - fun onMessageEvent(ignore: UpdateUiMessageEvent?) { - updateUI() + override fun onPermissionRationaleShouldBeShown( + permissions: MutableList?, + token: PermissionToken? + ) { + // Remember to invoke this method when the custom rationale is closed + // or just by default if you don't want to use any custom rationale. + token?.cancelPermissionRequest() + } + }) + .check() } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/adapters/ViewPagerAdapter.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/adapters/ViewPagerAdapter.kt index 790dc52..8ff3153 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/adapters/ViewPagerAdapter.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/adapters/ViewPagerAdapter.kt @@ -8,14 +8,13 @@ import com.tommasoberlose.anotherwidget.ui.fragments.* class ViewPagerAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) { - override fun getItemCount(): Int = 5 + override fun getItemCount(): Int = 4 override fun createFragment(position: Int): Fragment { return when (position) { 1 -> CalendarSettingsFragment.newInstance() 2 -> WeatherSettingsFragment.newInstance() 3 -> ClockSettingsFragment.newInstance() - 4 -> AdvancedSettingsFragment.newInstance() else -> GeneralSettingsFragment.newInstance() } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/AppMainFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/AppMainFragment.kt new file mode 100644 index 0000000..9ce0677 --- /dev/null +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/AppMainFragment.kt @@ -0,0 +1,333 @@ +package com.tommasoberlose.anotherwidget.ui.fragments + +import android.Manifest +import android.animation.ValueAnimator +import android.content.Intent +import android.content.SharedPreferences +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.provider.Settings +import android.util.DisplayMetrics +import android.util.TypedValue +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.RelativeLayout +import androidx.core.animation.addListener +import androidx.core.content.ContextCompat +import androidx.core.view.isVisible +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope +import androidx.navigation.Navigation +import androidx.navigation.fragment.FragmentNavigator +import com.google.android.material.badge.BadgeDrawable +import com.google.android.material.tabs.TabLayoutMediator +import com.google.android.material.transition.MaterialSharedAxis +import com.tommasoberlose.anotherwidget.R +import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog +import com.tommasoberlose.anotherwidget.databinding.FragmentAdvancedSettingsBinding +import com.tommasoberlose.anotherwidget.databinding.FragmentAppMainBinding +import com.tommasoberlose.anotherwidget.global.Constants +import com.tommasoberlose.anotherwidget.global.Preferences +import com.tommasoberlose.anotherwidget.helpers.BitmapHelper +import com.tommasoberlose.anotherwidget.helpers.ColorHelper +import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark +import com.tommasoberlose.anotherwidget.ui.activities.MainActivity +import com.tommasoberlose.anotherwidget.ui.adapters.ViewPagerAdapter +import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel +import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget +import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission +import com.tommasoberlose.anotherwidget.utils.getCurrentWallpaper +import com.tommasoberlose.anotherwidget.utils.toPixel +import kotlinx.android.synthetic.main.fragment_app_main.* +import kotlinx.android.synthetic.main.the_widget_sans.* +import kotlinx.coroutines.* +import org.greenrobot.eventbus.EventBus +import org.greenrobot.eventbus.Subscribe +import org.greenrobot.eventbus.ThreadMode + +class AppMainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeListener { + + companion object { + fun newInstance() = AppMainFragment() + } + + private lateinit var viewModel: MainViewModel + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + enterTransition = MaterialSharedAxis.create(MaterialSharedAxis.X, true) + reenterTransition = MaterialSharedAxis.create(MaterialSharedAxis.X, false) + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java) + return inflater.inflate(R.layout.fragment_app_main, container, false) + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + subscribeUi(viewModel) + + // Viewpager + pager.adapter = ViewPagerAdapter(requireActivity()) + pager.offscreenPageLimit = 4 + TabLayoutMediator(tabs, pager) { tab, position -> + tab.text = when (position) { + 0 -> getString(R.string.settings_general_title) + 1 -> getString(R.string.settings_calendar_title) + 2 -> getString(R.string.settings_weather_title) + 3 -> getString(R.string.settings_clock_title) + else -> "" + } + }.attach() + + // Init clock + time.setTextColor(ColorHelper.getFontColor()) + time.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(requireContext())) + time_am_pm.setTextColor(ColorHelper.getFontColor()) + time_am_pm.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(requireContext()) / 5 * 2) + time_container.isVisible = Preferences.showClock + + preview.layoutParams = preview.layoutParams.apply { + height = 160.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(requireContext()) else 0 + } + subscribeUi(viewModel) + updateUI() + + // Warnings + if (getString(R.string.xiaomi_manufacturer).equals(Build.MANUFACTURER, ignoreCase = true) && Preferences.showXiaomiWarning) { + MaterialBottomSheetDialog(requireContext(), getString(R.string.xiaomi_warning_title), getString(R.string.xiaomi_warning_message)) + .setNegativeButton(getString(R.string.action_ignore)) { + Preferences.showXiaomiWarning = false + } + .setPositiveButton(getString(R.string.action_grant_permission)) { + Preferences.showXiaomiWarning = false + val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.parse("package:${activity?.packageName}") + } + startActivity(intent) + } + .show() + } + } + + private var uiJob: Job? = null + + private fun updateUI() { + uiJob?.cancel() + + if (Preferences.showPreview) { + preview.setCardBackgroundColor( + ContextCompat.getColor( + requireContext(), + if (ColorHelper.getFontColor() + .isColorDark() + ) android.R.color.white else R.color.colorAccent + ) + ) + widget_shape_background.setImageDrawable(BitmapHelper.getTintedDrawable(requireContext(), R.drawable.card_background, ColorHelper.getBackgroundColor())) + uiJob = viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) { + delay(200) + val generatedView = MainWidget.generateWidgetView(requireContext()) + + withContext(Dispatchers.Main) { + generatedView.measure(0, 0) + preview.measure(0, 0) + } + + val bitmap = BitmapHelper.getBitmapFromView( + generatedView, + if (preview.width > 0) preview.width else generatedView.measuredWidth, + generatedView.measuredHeight + ) + withContext(Dispatchers.Main) { + // Clock + time.setTextColor(ColorHelper.getFontColor()) + time_am_pm.setTextColor(ColorHelper.getFontColor()) + time.setTextSize( + TypedValue.COMPLEX_UNIT_SP, + Preferences.clockTextSize.toPixel(requireContext()) + ) + time_am_pm.setTextSize( + TypedValue.COMPLEX_UNIT_SP, + Preferences.clockTextSize.toPixel(requireContext()) / 5 * 2 + ) + + // Clock bottom margin + clock_bottom_margin_none.isVisible = + Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.value + clock_bottom_margin_small.isVisible = + Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.value + clock_bottom_margin_medium.isVisible = + Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.value + clock_bottom_margin_large.isVisible = + Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.value + + if ((Preferences.showClock && !time_container.isVisible) || (!Preferences.showClock && time_container.isVisible)) { + if (Preferences.showClock) { + time_container.layoutParams = time_container.layoutParams.apply { + height = RelativeLayout.LayoutParams.WRAP_CONTENT + } + time_container.measure(0, 0) + } + val initialHeight = time_container.measuredHeight + ValueAnimator.ofFloat( + if (Preferences.showClock) 0f else 1f, + if (Preferences.showClock) 1f else 0f + ).apply { + duration = 500L + addUpdateListener { + val animatedValue = animatedValue as Float + time_container.layoutParams = time_container.layoutParams.apply { + height = (initialHeight * animatedValue).toInt() + } + } + addListener( + onStart = { + if (Preferences.showClock) { + time_container.isVisible = true + } + }, + onEnd = { + if (!Preferences.showClock) { + time_container.isVisible = false + } + } + ) + }.start() + + ValueAnimator.ofInt( + preview.height, + 160.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel( + requireContext() + ) else 0 + ).apply { + duration = 500L + addUpdateListener { + val animatedValue = animatedValue as Int + val layoutParams = preview.layoutParams + layoutParams.height = animatedValue + preview.layoutParams = layoutParams + } + }.start() + } else { + time_container.layoutParams = time_container.layoutParams.apply { + height = RelativeLayout.LayoutParams.WRAP_CONTENT + } + time_container.measure(0, 0) + } + + if (preview.height == 0) { + ValueAnimator.ofInt( + preview.height, + 160.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel( + requireContext() + ) else 0 + ).apply { + duration = 300L + addUpdateListener { + val animatedValue = animatedValue as Int + val layoutParams = preview.layoutParams + layoutParams.height = animatedValue + preview.layoutParams = layoutParams + } + }.start() + } + + bitmap_container.setImageBitmap(bitmap) + widget_loader.animate().scaleX(0f).scaleY(0f).start() + widget.animate().alpha(1f).start() + } + } + } else { + ValueAnimator.ofInt( + preview.height, + 0 + ).apply { + duration = 300L + addUpdateListener { + val animatedValue = animatedValue as Int + val layoutParams = preview.layoutParams + layoutParams.height = animatedValue + preview.layoutParams = layoutParams + } + }.start() + } + + + // Calendar error indicator + tabs?.getTabAt(1)?.orCreateBadge?.apply { + backgroundColor = ContextCompat.getColor(requireContext(), R.color.errorColorText) + badgeGravity = BadgeDrawable.TOP_END + }?.isVisible = Preferences.showEvents && activity?.checkGrantedPermission(Manifest.permission.READ_CALENDAR) != true + + // Weather error indicator + tabs?.getTabAt(2)?.orCreateBadge?.apply { + backgroundColor = ContextCompat.getColor(requireContext(), R.color.errorColorText) + badgeGravity = BadgeDrawable.TOP_END + }?.isVisible = Preferences.showWeather && (Preferences.weatherProviderApi == "" || (Preferences.customLocationAdd == "" && activity?.checkGrantedPermission(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION) != true)) + + } + + private fun subscribeUi(viewModel: MainViewModel) { + viewModel.showWallpaper.observe(viewLifecycleOwner, Observer { + activity?.let { act -> + val wallpaper = act.getCurrentWallpaper() + widget_bg.setImageDrawable(if (it) wallpaper else null) + widget_bg.layoutParams = widget_bg.layoutParams.apply { + + val metrics = DisplayMetrics() + act.windowManager.defaultDisplay.getMetrics(metrics) + + height = metrics.heightPixels + width = (wallpaper?.intrinsicWidth ?: 1) * metrics.heightPixels / (wallpaper?.intrinsicWidth ?: 1) + } + } + }) + + logo.setOnClickListener { +// startActivity(Intent(this, SupportDevActivity::class.java)) + } + + action_settings.setOnClickListener { + Navigation.findNavController(it).navigate(R.id.action_appMainFragment_to_appSettingsFragment) + } + } + + override fun onDestroy() { + super.onDestroy() + } + + override fun onSharedPreferenceChanged(preferences: SharedPreferences, p1: String) { + updateUI() + MainWidget.updateWidget(requireContext()) + } + + override fun onResume() { + super.onResume() + Preferences.preferences.registerOnSharedPreferenceChangeListener(this) + EventBus.getDefault().register(this) + } + + override fun onPause() { + Preferences.preferences.unregisterOnSharedPreferenceChangeListener(this) + EventBus.getDefault().unregister(this) + super.onPause() + } + + class UpdateUiMessageEvent + + @Subscribe(threadMode = ThreadMode.MAIN) + fun onMessageEvent(ignore: UpdateUiMessageEvent?) { + updateUI() + } +} diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/AdvancedSettingsFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/SettingsFragment.kt similarity index 94% rename from app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/AdvancedSettingsFragment.kt rename to app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/SettingsFragment.kt index d81378a..3909452 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/AdvancedSettingsFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/SettingsFragment.kt @@ -2,10 +2,8 @@ package com.tommasoberlose.anotherwidget.ui.fragments import android.Manifest import android.content.Intent -import android.content.pm.PackageManager import android.os.Build import android.os.Bundle -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -15,6 +13,9 @@ import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope +import androidx.navigation.Navigation +import com.google.android.material.transition.MaterialContainerTransform +import com.google.android.material.transition.MaterialSharedAxis import com.karumi.dexter.Dexter import com.karumi.dexter.MultiplePermissionsReport import com.karumi.dexter.PermissionToken @@ -30,7 +31,6 @@ import com.tommasoberlose.anotherwidget.ui.activities.SupportDevActivity import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel import com.tommasoberlose.anotherwidget.helpers.CalendarHelper import com.tommasoberlose.anotherwidget.helpers.WeatherHelper -import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission import com.tommasoberlose.anotherwidget.utils.openURI import kotlinx.android.synthetic.main.fragment_advanced_settings.* @@ -38,16 +38,18 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch -class AdvancedSettingsFragment : Fragment() { +class SettingsFragment : Fragment() { companion object { - fun newInstance() = AdvancedSettingsFragment() + fun newInstance() = SettingsFragment() } private lateinit var viewModel: MainViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + enterTransition = MaterialSharedAxis.create(MaterialSharedAxis.X, true) + returnTransition = MaterialSharedAxis.create(MaterialSharedAxis.X, false) } override fun onCreateView( @@ -58,8 +60,6 @@ class AdvancedSettingsFragment : Fragment() { viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java) val binding = DataBindingUtil.inflate(inflater, R.layout.fragment_advanced_settings, container, false) - subscribeUi(viewModel) - binding.lifecycleOwner = this binding.viewModel = viewModel @@ -69,10 +69,15 @@ class AdvancedSettingsFragment : Fragment() { override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) + action_back.setOnClickListener { + Navigation.findNavController(it).popBackStack() + } + + subscribeUi(viewModel) + setupListener() app_version.text = "v%s (%s)".format(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE) - requirePermission() } private fun subscribeUi( diff --git a/app/src/main/res/drawable-hdpi/round_arrow_back.png b/app/src/main/res/drawable-hdpi/round_arrow_back.png new file mode 100644 index 0000000..c3de8c1 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/round_arrow_back.png differ diff --git a/app/src/main/res/drawable-hdpi/round_short_text.png b/app/src/main/res/drawable-hdpi/round_short_text.png new file mode 100644 index 0000000..404d941 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/round_short_text.png differ diff --git a/app/src/main/res/drawable-hdpi/round_short_text_black_18.png b/app/src/main/res/drawable-hdpi/round_short_text_black_18.png new file mode 100644 index 0000000..cad2176 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/round_short_text_black_18.png differ diff --git a/app/src/main/res/drawable-hdpi/round_short_text_black_24.png b/app/src/main/res/drawable-hdpi/round_short_text_black_24.png new file mode 100644 index 0000000..8aa7ead Binary files /dev/null and b/app/src/main/res/drawable-hdpi/round_short_text_black_24.png differ diff --git a/app/src/main/res/drawable-hdpi/round_short_text_black_36.png b/app/src/main/res/drawable-hdpi/round_short_text_black_36.png new file mode 100644 index 0000000..e318dbe Binary files /dev/null and b/app/src/main/res/drawable-hdpi/round_short_text_black_36.png differ diff --git a/app/src/main/res/drawable-mdpi/round_arrow_back.png b/app/src/main/res/drawable-mdpi/round_arrow_back.png new file mode 100644 index 0000000..26e0280 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/round_arrow_back.png differ diff --git a/app/src/main/res/drawable-mdpi/round_short_text.png b/app/src/main/res/drawable-mdpi/round_short_text.png new file mode 100644 index 0000000..08b68a9 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/round_short_text.png differ diff --git a/app/src/main/res/drawable-mdpi/round_short_text_black_18.png b/app/src/main/res/drawable-mdpi/round_short_text_black_18.png new file mode 100644 index 0000000..3441e79 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/round_short_text_black_18.png differ diff --git a/app/src/main/res/drawable-mdpi/round_short_text_black_24.png b/app/src/main/res/drawable-mdpi/round_short_text_black_24.png new file mode 100644 index 0000000..24a9d4b Binary files /dev/null and b/app/src/main/res/drawable-mdpi/round_short_text_black_24.png differ diff --git a/app/src/main/res/drawable-mdpi/round_short_text_black_36.png b/app/src/main/res/drawable-mdpi/round_short_text_black_36.png new file mode 100644 index 0000000..8aa7ead Binary files /dev/null and b/app/src/main/res/drawable-mdpi/round_short_text_black_36.png differ diff --git a/app/src/main/res/drawable-xhdpi/round_arrow_back.png b/app/src/main/res/drawable-xhdpi/round_arrow_back.png new file mode 100644 index 0000000..91774ea Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/round_arrow_back.png differ diff --git a/app/src/main/res/drawable-xhdpi/round_short_text.png b/app/src/main/res/drawable-xhdpi/round_short_text.png new file mode 100644 index 0000000..bcd30cb Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/round_short_text.png differ diff --git a/app/src/main/res/drawable-xhdpi/round_short_text_black_18.png b/app/src/main/res/drawable-xhdpi/round_short_text_black_18.png new file mode 100644 index 0000000..8aa7ead Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/round_short_text_black_18.png differ diff --git a/app/src/main/res/drawable-xhdpi/round_short_text_black_24.png b/app/src/main/res/drawable-xhdpi/round_short_text_black_24.png new file mode 100644 index 0000000..08b68a9 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/round_short_text_black_24.png differ diff --git a/app/src/main/res/drawable-xhdpi/round_short_text_black_36.png b/app/src/main/res/drawable-xhdpi/round_short_text_black_36.png new file mode 100644 index 0000000..404d941 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/round_short_text_black_36.png differ diff --git a/app/src/main/res/drawable-xxhdpi/round_arrow_back.png b/app/src/main/res/drawable-xxhdpi/round_arrow_back.png new file mode 100644 index 0000000..7553ab2 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/round_arrow_back.png differ diff --git a/app/src/main/res/drawable-xxhdpi/round_short_text.png b/app/src/main/res/drawable-xxhdpi/round_short_text.png new file mode 100644 index 0000000..561e36c Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/round_short_text.png differ diff --git a/app/src/main/res/drawable-xxhdpi/round_short_text_black_18.png b/app/src/main/res/drawable-xxhdpi/round_short_text_black_18.png new file mode 100644 index 0000000..e318dbe Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/round_short_text_black_18.png differ diff --git a/app/src/main/res/drawable-xxhdpi/round_short_text_black_24.png b/app/src/main/res/drawable-xxhdpi/round_short_text_black_24.png new file mode 100644 index 0000000..404d941 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/round_short_text_black_24.png differ diff --git a/app/src/main/res/drawable-xxhdpi/round_short_text_black_36.png b/app/src/main/res/drawable-xxhdpi/round_short_text_black_36.png new file mode 100644 index 0000000..f9c26ed Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/round_short_text_black_36.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/round_arrow_back.png b/app/src/main/res/drawable-xxxhdpi/round_arrow_back.png new file mode 100644 index 0000000..ad6b82b Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/round_arrow_back.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/round_short_text.png b/app/src/main/res/drawable-xxxhdpi/round_short_text.png new file mode 100644 index 0000000..28ba1b1 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/round_short_text.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/round_short_text_black_18.png b/app/src/main/res/drawable-xxxhdpi/round_short_text_black_18.png new file mode 100644 index 0000000..404d941 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/round_short_text_black_18.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/round_short_text_black_24.png b/app/src/main/res/drawable-xxxhdpi/round_short_text_black_24.png new file mode 100644 index 0000000..bcd30cb Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/round_short_text_black_24.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/round_short_text_black_36.png b/app/src/main/res/drawable-xxxhdpi/round_short_text_black_36.png new file mode 100644 index 0000000..561e36c Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/round_short_text_black_36.png differ diff --git a/app/src/main/res/drawable/round_arrow_back_24.xml b/app/src/main/res/drawable/round_arrow_back_24.xml new file mode 100644 index 0000000..26d33e0 --- /dev/null +++ b/app/src/main/res/drawable/round_arrow_back_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/round_short_text_24.xml b/app/src/main/res/drawable/round_short_text_24.xml new file mode 100644 index 0000000..29905ab --- /dev/null +++ b/app/src/main/res/drawable/round_short_text_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index f23d51d..d9d0479 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,156 +1,42 @@ - + + + - + - - - - - - - - - - - - - - - - - - - + android:layout_height="72dp" + android:text="@string/add_widget" + android:layout_marginTop="-8dp" + android:clickable="false" + android:focusable="false" + android:gravity="center" + android:textColor="@android:color/white" + app:cornerRadius="0dp" + style="@style/Widget.MaterialComponents.Button.TextButton"/> - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_advanced_settings.xml b/app/src/main/res/layout/fragment_advanced_settings.xml index 641310e..9fe5d1f 100644 --- a/app/src/main/res/layout/fragment_advanced_settings.xml +++ b/app/src/main/res/layout/fragment_advanced_settings.xml @@ -7,350 +7,393 @@ name="viewModel" type="com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel" /> - - + - + + android:layout_height="56dp"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:padding="10dp" + android:src="@drawable/round_arrow_back" + android:tint="@color/colorPrimaryText" + android:layout_centerVertical="true" + android:clickable="true" + android:focusable="true" + android:layout_marginEnd="8dp" + android:layout_alignParentLeft="true" + android:layout_marginStart="8dp" + android:background="?attr/selectableItemBackgroundBorderless" + android:id="@+id/action_back" /> + + + + + - + + + + + + + + android:paddingTop="16dp" + android:paddingBottom="16dp" + android:paddingLeft="8dp" + android:paddingRight="8dp" + android:clickable="true" + android:focusable="true" + android:background="?android:attr/selectableItemBackground" + android:gravity="center_vertical" + android:id="@+id/action_show_widget_preview" + android:orientation="horizontal"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_app_main.xml b/app/src/main/res/layout/fragment_app_main.xml new file mode 100644 index 0000000..043669c --- /dev/null +++ b/app/src/main/res/layout/fragment_app_main.xml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml new file mode 100644 index 0000000..e6acf00 --- /dev/null +++ b/app/src/main/res/navigation/nav_graph.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 6b6440e..6c77629 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -206,4 +206,5 @@ Background color Transparent The next alarm clock seems to be wrong.\nIt has been set by %s. + Settings \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 3784a7c..05ae11b 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -186,4 +186,5 @@ Background color Transparent The next alarm clock seems to be wrong.\nIt has been set by %s. + Settings \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 20ede23..1774a93 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -185,4 +185,5 @@ Colore background Trasparente La sveglia sembra impostata male.\nĂˆ stata impostata dall\'app %s. + Impostazioni \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2d97ad6..26b69e8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -197,4 +197,5 @@ Alpha Transparent The next alarm clock seems to be wrong.\nIt has been set by %s. + Settings diff --git a/tasksintegration/build/intermediates/bundle_manifest/debug/bundle-manifest/AndroidManifest.xml b/tasksintegration/build/intermediates/bundle_manifest/debug/bundle-manifest/AndroidManifest.xml index f168d87..418eb2a 100644 --- a/tasksintegration/build/intermediates/bundle_manifest/debug/bundle-manifest/AndroidManifest.xml +++ b/tasksintegration/build/intermediates/bundle_manifest/debug/bundle-manifest/AndroidManifest.xml @@ -3,7 +3,7 @@ xmlns:dist="http://schemas.android.com/apk/distribution" featureSplit="tasksintegration" package="com.tommasoberlose.anotherwidget" - android:versionCode="75" + android:versionCode="76" android:versionName="2.0.5" > 8 9