Release v2.0.1

This commit is contained in:
Tommaso Berlose
2020-05-03 17:54:35 +02:00
parent 3aecf9851a
commit 9a978ac8d3
135 changed files with 2368 additions and 1221 deletions

View File

@ -3,33 +3,22 @@ package com.tommasoberlose.anotherwidget.ui.activities
import android.app.Activity
import android.os.Bundle
import com.tommasoberlose.anotherwidget.R
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import android.content.Intent
import android.content.pm.ApplicationInfo
import com.tommasoberlose.anotherwidget.components.events.ApplicationListEvent
import android.text.Editable
import android.text.TextWatcher
import android.content.pm.ResolveInfo
import android.view.View
import android.view.Window
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.databinding.Observable
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.transition.MaterialFadeThrough
import com.tommasoberlose.anotherwidget.components.events.AppInfoSavedEvent
import com.bumptech.glide.Glide
import com.tommasoberlose.anotherwidget.databinding.ActivityChooseApplicationBinding
import com.tommasoberlose.anotherwidget.databinding.FragmentClockSettingsBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.ui.viewmodels.ChooseApplicationViewModel
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.utils.toast
import kotlinx.android.synthetic.main.activity_choose_application.*
import kotlinx.android.synthetic.main.activity_choose_application.list_view
import kotlinx.coroutines.*
@ -71,14 +60,16 @@ class ChooseApplicationActivity : AppCompatActivity() {
finish()
}
}
.register<ApplicationInfo>(R.layout.application_info_layout) { item, injector ->
.register<ResolveInfo>(R.layout.application_info_layout) { item, injector ->
injector
.text(R.id.text, pm.getApplicationLabel(item).toString())
try {
injector.image(R.id.icon, item.loadIcon(pm))
} catch (ignore: Exception) {
}
.text(R.id.text, item.loadLabel(pm))
.with<ImageView>(R.id.icon) {
Glide
.with(this)
.load(item.loadIcon(pm))
.centerCrop()
.into(it)
}
injector.clicked(R.id.item) {
saveApp(item)
@ -110,9 +101,7 @@ class ChooseApplicationActivity : AppCompatActivity() {
viewModel.appList.value!!
} else {
viewModel.appList.value!!.filter {
pm.getApplicationLabel(
it
).toString().contains(search, true)
it.loadLabel(pm).contains(search, true)
}
}
withContext(Dispatchers.Main) {
@ -130,10 +119,10 @@ class ChooseApplicationActivity : AppCompatActivity() {
}
}
private fun saveApp(app: ApplicationInfo) {
private fun saveApp(app: ResolveInfo) {
val resultIntent = Intent()
resultIntent.putExtra(Constants.RESULT_APP_NAME, pm.getApplicationLabel(app).toString())
resultIntent.putExtra(Constants.RESULT_APP_PACKAGE, app.packageName)
resultIntent.putExtra(Constants.RESULT_APP_NAME, app.loadLabel(pm))
resultIntent.putExtra(Constants.RESULT_APP_PACKAGE, app.resolvePackageName)
setResult(Activity.RESULT_OK, resultIntent)
finish()
}

View File

@ -0,0 +1,124 @@
package com.tommasoberlose.anotherwidget.ui.activities
import android.app.Activity
import android.location.Address
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.chibatching.kotpref.bulk
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.databinding.ActivityCustomDateBinding
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.DateHelper
import com.tommasoberlose.anotherwidget.ui.viewmodels.CustomDateViewModel
import com.tommasoberlose.anotherwidget.utils.openURI
import kotlinx.android.synthetic.main.activity_custom_date.*
import kotlinx.android.synthetic.main.activity_custom_location.action_back
import kotlinx.android.synthetic.main.activity_custom_location.list_view
import kotlinx.coroutines.*
import net.idik.lib.slimadapter.SlimAdapter
import java.lang.Exception
import java.text.SimpleDateFormat
import java.util.*
class CustomDateActivity : AppCompatActivity() {
private lateinit var adapter: SlimAdapter
private lateinit var viewModel: CustomDateViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(CustomDateViewModel::class.java)
val binding = DataBindingUtil.setContentView<ActivityCustomDateBinding>(this, R.layout.activity_custom_date)
list_view.setHasFixedSize(true)
val mLayoutManager = LinearLayoutManager(this)
list_view.layoutManager = mLayoutManager
adapter = SlimAdapter.create()
adapter
.register<String>(R.layout.custom_date_example_item) { item, injector ->
injector
.text(R.id.custom_date_example_format, item)
.text(R.id.custom_date_example_value, SimpleDateFormat(item, Locale.getDefault()).format(DATE.time))
}
.attachTo(list_view)
adapter.updateData(
listOf(
"d", "dd", "EE", "EEEE", "MM", "MMM", "MMMM", "yy", "yyyy"
)
)
setupListener()
subscribeUi(binding, viewModel)
date_format.requestFocus()
}
private var formatJob: Job? = null
private fun subscribeUi(binding: ActivityCustomDateBinding, viewModel: CustomDateViewModel) {
binding.viewModel = viewModel
viewModel.dateInput.observe(this, Observer { dateFormat ->
formatJob?.cancel()
formatJob = lifecycleScope.launch(Dispatchers.IO) {
withContext(Dispatchers.Main) {
loader.visibility = View.VISIBLE
}
delay(200)
val text = if (dateFormat != "") {
try {
SimpleDateFormat(dateFormat, Locale.getDefault()).format(DATE.time)
} catch (e: Exception) {
ERROR_STRING
}
} else {
"__"
}
withContext(Dispatchers.Main) {
action_save.isVisible = text != ERROR_STRING
loader.visibility = View.INVISIBLE
date_format_value.text = text
}
}
})
}
private fun setupListener() {
action_back.setOnClickListener {
onBackPressed()
}
action_save.setOnClickListener {
Preferences.dateFormat = viewModel.dateInput.value ?: ""
finish()
}
action_date_format_info.setOnClickListener {
openURI("https://developer.android.com/reference/java/text/SimpleDateFormat")
}
}
companion object {
const val ERROR_STRING = "--"
val DATE: Calendar = Calendar.getInstance().apply {
set(Calendar.MONTH, 10)
set(Calendar.DAY_OF_MONTH, 1)
set(Calendar.YEAR, 1993)
}
}
}

View File

@ -27,7 +27,6 @@ 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.components.events.CustomLocationEvent
import com.tommasoberlose.anotherwidget.databinding.ActivityChooseApplicationBinding
import com.tommasoberlose.anotherwidget.databinding.ActivityCustomLocationBinding
import com.tommasoberlose.anotherwidget.global.Preferences

View File

@ -2,37 +2,43 @@ package com.tommasoberlose.anotherwidget.ui.activities
import android.animation.ValueAnimator
import android.app.Activity
import android.os.Bundle
import android.appwidget.AppWidgetManager
import android.view.View
import com.tommasoberlose.anotherwidget.R
import android.content.Intent
import android.content.SharedPreferences
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.util.Log
import android.util.TypedValue
import android.widget.LinearLayout
import android.view.View
import android.widget.RelativeLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.core.animation.addListener
import androidx.core.animation.doOnEnd
import androidx.core.view.isVisible
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.google.android.material.tabs.TabLayoutMediator
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.global.Actions
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.global.RequestCode
import com.tommasoberlose.anotherwidget.helpers.BitmapHelper
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
import com.tommasoberlose.anotherwidget.helpers.ColorHelper
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
import com.tommasoberlose.anotherwidget.ui.adapters.ViewPagerAdapter
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.utils.*
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import com.tommasoberlose.anotherwidget.utils.getCurrentWallpaper
import com.tommasoberlose.anotherwidget.utils.toPixel
import kotlinx.android.synthetic.main.activity_main.*
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
import com.tommasoberlose.anotherwidget.receivers.WeatherReceiver
import com.tommasoberlose.anotherwidget.ui.widgets.TheWidget
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceChangeListener {
@ -62,19 +68,38 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
}
}.attach()
// Init clock
clock.setTextColor(ColorHelper.getFontColor())
clock.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(this@MainActivity))
clock.format12Hour = "hh:mm"
clock.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()
CalendarHelper.updateEventList(this)
WeatherHelper.updateWeather(this)
}
private var uiJob: Job? = null
private fun updateUI() {
lifecycleScope.launch(Dispatchers.IO) {
val generatedView = TheWidget.generateWidgetView(this@MainActivity, preview.measuredWidth)
generatedView.measure(0, 0)
val bitmap = Util.getBitmapFromView(generatedView, generatedView.measuredWidth, generatedView.measuredHeight)
preview.setCardBackgroundColor(getColor(if (ColorHelper.getFontColor().isColorDark()) android.R.color.white else R.color.colorAccent))
val generatedView = MainWidget.generateWidgetView(this@MainActivity)
generatedView.measure(0, 0)
preview.measure(0, 0)
uiJob?.cancel()
uiJob = lifecycleScope.launch(Dispatchers.IO) {
val bitmap = BitmapHelper.getBitmapFromView(generatedView, if (preview.width > 0) preview.width else generatedView.measuredWidth, generatedView.measuredHeight)
withContext(Dispatchers.Main) {
// Clock
clock.setTextColor(Util.getFontColor())
clock.setTextColor(ColorHelper.getFontColor())
clock.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(this@MainActivity))
clock.format12Hour = "hh:mm"
@ -112,7 +137,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
}.start()
ValueAnimator.ofInt(
preview.measuredHeight,
preview.height,
160.toPixel(this@MainActivity) + if (Preferences.showClock) 100.toPixel(this@MainActivity) else 0
).apply {
duration = 500L
@ -126,14 +151,20 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
}
widget_bitmap.setImageBitmap(bitmap)
widget_loader.animate().scaleX(0f).scaleY(0f).start()
widget.animate().alpha(1f).start()
}
}
}
private fun subscribeUi(viewModel: MainViewModel) {
viewModel.showWallpaper.observe(this, Observer {
widget_bg.setImageDrawable(if (it) Util.getCurrentWallpaper(this) else null)
widget_bg.setImageDrawable(if (it) getCurrentWallpaper() else null)
})
logo.setOnClickListener {
// startActivity(Intent(this, SupportDevActivity::class.java))
}
}
override fun onBackPressed() {
@ -171,11 +202,6 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
if (extras.containsKey(Actions.ACTION_EXTRA_OPEN_WEATHER_PROVIDER)) {
startActivityForResult(Intent(this, WeatherProviderActivity::class.java), RequestCode.WEATHER_PROVIDER_REQUEST_CODE.code)
}
if (extras.containsKey(Actions.ACTION_EXTRA_DISABLE_GPS_NOTIFICATION)) {
Preferences.showGpsInformation = false
sendBroadcast(Intent(Actions.ACTION_WEATHER_UPDATE))
finish()
}
}
}
@ -193,6 +219,23 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
override fun onSharedPreferenceChanged(preferences: SharedPreferences, p1: String) {
updateUI()
Util.updateWidget(this)
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()
}
}

View File

@ -5,6 +5,7 @@ import android.content.Intent
import android.location.Address
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
@ -26,7 +27,6 @@ import net.idik.lib.slimadapter.SlimAdapter
class SupportDevActivity : AppCompatActivity(), PurchasesUpdatedListener {
private val BILLING_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAox5CcxuoLJ6CmNS7s6lVQzJ253njKKGF8MoQ/gQ5gEw2Fr03fBvtHpiVMpnjhNLw5NMeIpzRvkVqeQ7BfkC7c0BLCJUqf/fFA11ArQe8na6QKt5O4d+v4sbHtP7mm3GQNPOBaqRzcpFZaiAbfk6mnalo+tzM47GXrQFt5bNSrMctCs7bbChqJfH2cyMW0F8DHWEEeO5xElBmH3lh4FVpwIUTPYJIV3n0yhE3qqRA0WXkDej66g/uAt/rebmMZLmwNwIive5cObU4o41YyKRv2wSAicrv3W40LftzXAOOordIbmzDFN8ksh3VrnESqwCDGG97nZVbPG/+3LD0xHWiRwIDAQAB"
private lateinit var viewModel: SupportDevViewModel
private lateinit var adapter: SlimAdapter
@ -35,7 +35,7 @@ class SupportDevActivity : AppCompatActivity(), PurchasesUpdatedListener {
viewModel = ViewModelProvider(this).get(SupportDevViewModel::class.java)
viewModel.billingClient = BillingClient.newBuilder(this).enablePendingPurchases().setListener(this).build()
val binding = DataBindingUtil.setContentView<ActivitySupportDevBinding>(this, R.layout.activity_support_dev)
DataBindingUtil.setContentView<ActivitySupportDevBinding>(this, R.layout.activity_support_dev)
list_view.setHasFixedSize(true)

View File

@ -1,21 +1,14 @@
package com.tommasoberlose.anotherwidget.ui.activities
import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.content.DialogInterface
import android.content.SharedPreferences
import android.os.Build
import android.os.Bundle
import android.text.Editable
import android.text.Html
import android.text.TextWatcher
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.utils.Util
import com.tommasoberlose.anotherwidget.utils.WeatherUtil
import com.tommasoberlose.anotherwidget.utils.openURI
import kotlinx.android.synthetic.main.activity_weather_provider.*
@ -46,18 +39,4 @@ class WeatherProviderActivity : AppCompatActivity() {
}
api_key.editText?.setText(Preferences.weatherProviderApi)
}
override fun onBackPressed() {
if (api_key.editText?.text.toString() == "") {
AlertDialog.Builder(this)
.setMessage(getString(R.string.error_weather_api_key))
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.yes) { _, _ ->
super.onBackPressed()
}
.show()
} else {
super.onBackPressed()
}
}
}

View File

@ -14,23 +14,21 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.google.android.material.bottomsheet.BottomSheetDialog
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.BuildConfig
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
import com.tommasoberlose.anotherwidget.databinding.FragmentAdvancedSettingsBinding
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
import com.tommasoberlose.anotherwidget.receivers.WeatherReceiver
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.activities.SupportDevActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.utils.CalendarUtil
import com.tommasoberlose.anotherwidget.utils.Util
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import com.tommasoberlose.anotherwidget.utils.openURI
import kotlinx.android.synthetic.main.fragment_advanced_settings.*
import kotlinx.coroutines.delay
@ -57,7 +55,7 @@ class AdvancedSettingsFragment : Fragment() {
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
val binding = DataBindingUtil.inflate<FragmentAdvancedSettingsBinding>(inflater, R.layout.fragment_advanced_settings, container, false)
subscribeUi(binding, viewModel)
subscribeUi(viewModel)
binding.lifecycleOwner = this
binding.viewModel = viewModel
@ -69,10 +67,11 @@ class AdvancedSettingsFragment : Fragment() {
super.onActivityCreated(savedInstanceState)
setupListener()
app_version.text = "v%s".format(BuildConfig.VERSION_NAME)
}
private fun subscribeUi(
binding: FragmentAdvancedSettingsBinding,
viewModel: MainViewModel
) {
viewModel.darkThemePreference.observe(viewLifecycleOwner, Observer {
@ -94,8 +93,8 @@ class AdvancedSettingsFragment : Fragment() {
private fun setupListener() {
action_change_theme.setOnClickListener {
maintainScrollPosition {
BottomSheetMenu<Int>(requireContext())
.selectResource(Preferences.darkThemePreference)
BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_theme_title))
.setSelectedValue(Preferences.darkThemePreference)
.addItem(
getString(R.string.settings_subtitle_dark_theme_light),
AppCompatDelegate.MODE_NIGHT_NO
@ -116,11 +115,23 @@ class AdvancedSettingsFragment : Fragment() {
action_show_wallpaper.setOnClickListener {
maintainScrollPosition {
if (Preferences.showWallpaper) {
Preferences.showWallpaper = false
} else {
requirePermission()
}
BottomSheetMenu<Boolean>(requireContext(), header = getString(R.string.settings_title_show_wallpaper))
.setSelectedValue(Preferences.showWallpaper)
.addItem(
getString(R.string.settings_visible),
true
)
.addItem(
getString(R.string.settings_not_visible),
false
)
.addOnSelectItemListener { value ->
if (value) {
requirePermission()
} else {
Preferences.showWallpaper = value
}
}.show()
}
}
@ -137,8 +148,8 @@ class AdvancedSettingsFragment : Fragment() {
}
action_refresh_widget.setOnClickListener {
Util.updateWidget(requireContext())
CalendarUtil.updateEventList(requireContext())
MainWidget.updateWidget(requireContext())
CalendarHelper.updateEventList(requireContext())
}
}

View File

@ -4,12 +4,11 @@ import android.Manifest
import android.app.Activity
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.SimpleAdapter
import androidx.appcompat.app.AlertDialog
import androidx.core.view.isVisible
import androidx.databinding.DataBindingUtil
@ -25,7 +24,7 @@ import com.karumi.dexter.listener.PermissionRequest
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
import com.tommasoberlose.anotherwidget.components.CalendarSelector
import com.tommasoberlose.anotherwidget.models.CalendarSelector
import com.tommasoberlose.anotherwidget.databinding.FragmentCalendarSettingsBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
@ -33,16 +32,19 @@ import com.tommasoberlose.anotherwidget.global.RequestCode
import com.tommasoberlose.anotherwidget.ui.activities.ChooseApplicationActivity
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.utils.CalendarUtil
import com.tommasoberlose.anotherwidget.utils.Util
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
import com.tommasoberlose.anotherwidget.helpers.DateHelper
import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper
import com.tommasoberlose.anotherwidget.ui.activities.CustomDateActivity
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import com.tommasoberlose.anotherwidget.utils.toast
import kotlinx.android.synthetic.main.fragment_calendar_settings.*
import kotlinx.android.synthetic.main.fragment_calendar_settings.scrollView
import kotlinx.android.synthetic.main.fragment_weather_settings.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.*
import kotlin.Comparator
class CalendarSettingsFragment : Fragment() {
@ -85,6 +87,12 @@ class CalendarSettingsFragment : Fragment() {
viewModel.showEvents.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
binding.isCalendarEnabled = it
if (it) {
CalendarHelper.setEventUpdatesAndroidN(requireContext())
} else {
CalendarHelper.removeEventUpdatesAndroidN(requireContext())
}
}
checkReadEventsPermission()
})
@ -106,7 +114,7 @@ class CalendarSettingsFragment : Fragment() {
viewModel.secondRowInformation.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
second_row_info_label.text = getString(Util.getSecondRowInfoString(it))
second_row_info_label.text = getString(SettingsStringHelper.getSecondRowInfoString(it))
}
})
@ -118,23 +126,18 @@ class CalendarSettingsFragment : Fragment() {
viewModel.showUntil.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
show_until_label.text = getString(Util.getShowUntilString(it))
show_until_label.text = getString(SettingsStringHelper.getShowUntilString(it))
}
checkReadEventsPermission()
})
viewModel.showNextEvent.observe(viewLifecycleOwner, Observer {
show_multiple_events_label.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
show_multiple_events_label.setTextKeepState(if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible))
})
viewModel.dateFormat.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
val now = Calendar.getInstance()
var dateStringValue: String = String.format("%s%s", SimpleDateFormat(Constants.engDateFormat, Locale.getDefault()).format(now.time)[0].toUpperCase(), SimpleDateFormat(Constants.engDateFormat, Locale.getDefault()).format(now.time).substring(1))
if (it) {
dateStringValue = String.format("%s%s", SimpleDateFormat(Constants.itDateFormat, Locale.getDefault()).format(now.time)[0].toUpperCase(), SimpleDateFormat(Constants.itDateFormat, Locale.getDefault()).format(now.time).substring(1))
}
date_format_label.text = dateStringValue
date_format_label.text = DateHelper.getDateText(requireContext(), Calendar.getInstance())
}
})
@ -159,26 +162,51 @@ class CalendarSettingsFragment : Fragment() {
}
action_filter_calendar.setOnClickListener {
val calendarSelectorList: List<CalendarSelector> = CalendarUtil.getCalendarList(requireContext()).map { CalendarSelector(it.id.toInt(), it.displayName, it.accountName) }
var calFiltered = Preferences.calendarFilter
val calendarSelectorList: List<CalendarSelector> = CalendarHelper.getCalendarList(requireContext()).map {
CalendarSelector(
it.id,
it.displayName,
it.accountName
)
}.sortedWith(Comparator { cal1, cal2 ->
when {
cal1.accountName != cal2.accountName -> {
cal1.accountName.compareTo(cal2.accountName)
}
cal1.accountName == cal1.name -> {
-1
}
cal2.accountName == cal2.accountName -> {
1
}
else -> {
cal1.name.compareTo(cal2.name)
}
}
})
if (calendarSelectorList.isNotEmpty()) {
val calNames = calendarSelectorList.map { if (it.name == it.account_name) String.format("%s: %s", getString(R.string.main_calendar), it.name) else it.name }.toTypedArray()
val calSelected = calendarSelectorList.map { !calFiltered.contains(" " + it.id.toString() + ",") }.toBooleanArray()
val filteredCalendarIds = CalendarHelper.getFilteredCalendarIdList()
val visibleCalendarIds = calendarSelectorList.map { it.id }.filter { id: Long -> !filteredCalendarIds.contains(id) }
AlertDialog.Builder(requireContext()).setTitle(getString(R.string.settings_filter_calendar_subtitle))
.setMultiChoiceItems(calNames, calSelected) { _, item, isChecked ->
val dialogItem: String = String.format(" %s%s", calendarSelectorList.get(item).id, ",")
calFiltered = calFiltered.replace(dialogItem, "");
if (!isChecked) {
calFiltered += dialogItem
}
val dialog = BottomSheetMenu<Long>(requireContext(), header = getString(R.string.settings_filter_calendar_subtitle), isMultiSelection = true)
.setSelectedValues(visibleCalendarIds)
calendarSelectorList.indices.forEach { index ->
if (index == 0 || calendarSelectorList[index].accountName != calendarSelectorList[index - 1].accountName) {
dialog.addItem(calendarSelectorList[index].accountName)
}
.setPositiveButton(android.R.string.ok) { _: DialogInterface, _: Int ->
Preferences.calendarFilter = calFiltered
}
.setNegativeButton(android.R.string.cancel, null)
.show()
dialog.addItem(
if (calendarSelectorList[index].name == calendarSelectorList[index].accountName) getString(R.string.account_events) else calendarSelectorList[index].name,
calendarSelectorList[index].id
)
}
dialog.addOnMultipleSelectItemListener { values ->
CalendarHelper.filterCalendar(calendarSelectorList.map { it.id }.filter { !values.contains(it) })
checkReadEventsPermission()
}.show()
} else {
requireActivity().toast(getString(R.string.calendar_settings_list_error))
}
@ -186,7 +214,7 @@ class CalendarSettingsFragment : Fragment() {
action_show_all_day.setOnClickListener {
if (Preferences.showEvents) {
BottomSheetMenu<Boolean>(requireContext()).selectResource(Preferences.calendarAllDay)
BottomSheetMenu<Boolean>(requireContext(), header = getString(R.string.settings_all_day_title)).setSelectedValue(Preferences.calendarAllDay)
.addItem(getString(R.string.settings_all_day_subtitle_visible), true)
.addItem(getString(R.string.settings_all_day_subtitle_gone), false)
.addOnSelectItemListener { value ->
@ -197,7 +225,7 @@ class CalendarSettingsFragment : Fragment() {
action_show_declined_events.setOnClickListener {
if (Preferences.showEvents) {
BottomSheetMenu<Boolean>(requireContext()).selectResource(Preferences.showDeclinedEvents)
BottomSheetMenu<Boolean>(requireContext(), header = getString(R.string.settings_show_declined_events_title)).setSelectedValue(Preferences.showDeclinedEvents)
.addItem(getString(R.string.settings_visible), true)
.addItem(getString(R.string.settings_not_visible), false)
.addOnSelectItemListener { value ->
@ -208,7 +236,7 @@ class CalendarSettingsFragment : Fragment() {
action_show_multiple_events.setOnClickListener {
if (Preferences.showEvents) {
BottomSheetMenu<Boolean>(requireContext()).selectResource(Preferences.showNextEvent)
BottomSheetMenu<Boolean>(requireContext(), header = getString(R.string.settings_show_multiple_events_title)).setSelectedValue(Preferences.showNextEvent)
.addItem(getString(R.string.settings_visible), true)
.addItem(getString(R.string.settings_not_visible), false)
.addOnSelectItemListener { value ->
@ -219,7 +247,7 @@ class CalendarSettingsFragment : Fragment() {
action_show_diff_time.setOnClickListener {
if (Preferences.showEvents) {
BottomSheetMenu<Boolean>(requireContext()).selectResource(Preferences.showDiffTime)
BottomSheetMenu<Boolean>(requireContext(), header = getString(R.string.settings_show_diff_time_title)).setSelectedValue(Preferences.showDiffTime)
.addItem(getString(R.string.settings_visible), true)
.addItem(getString(R.string.settings_not_visible), false)
.addOnSelectItemListener { value ->
@ -230,9 +258,9 @@ class CalendarSettingsFragment : Fragment() {
action_second_row_info.setOnClickListener {
if (Preferences.showEvents) {
val dialog = BottomSheetMenu<Int>(requireContext()).selectResource(Preferences.secondRowInformation)
val dialog = BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_second_row_info_title)).setSelectedValue(Preferences.secondRowInformation)
(0 .. 1).forEach {
dialog.addItem(getString(Util.getSecondRowInfoString(it)), it)
dialog.addItem(getString(SettingsStringHelper.getSecondRowInfoString(it)), it)
}
dialog.addOnSelectItemListener { value ->
Preferences.secondRowInformation = value
@ -242,9 +270,9 @@ class CalendarSettingsFragment : Fragment() {
action_show_until.setOnClickListener {
if (Preferences.showEvents) {
val dialog = BottomSheetMenu<Int>(requireContext()).selectResource(Preferences.showUntil)
val dialog = BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_show_until_title)).setSelectedValue(Preferences.showUntil)
intArrayOf(6,7,0,1,2,3,4,5).forEach {
dialog.addItem(getString(Util.getShowUntilString(it)), it)
dialog.addItem(getString(SettingsStringHelper.getShowUntilString(it)), it)
}
dialog.addOnSelectItemListener { value ->
Preferences.showUntil = value
@ -252,6 +280,27 @@ class CalendarSettingsFragment : Fragment() {
}
}
action_date_format.setOnClickListener {
if (Preferences.showEvents) {
val now = Calendar.getInstance()
val dialog = BottomSheetMenu<String>(requireContext(), header = getString(R.string.settings_date_format_title)).setSelectedValue(Preferences.dateFormat)
dialog.addItem(DateHelper.getDefaultDateText(requireContext(), now), "")
if (Preferences.dateFormat != "") {
dialog.addItem(DateHelper.getDateText(requireContext(), now), Preferences.dateFormat)
}
dialog.addItem(getString(R.string.custom_date_format), "-")
dialog.addOnSelectItemListener { value ->
if (value == "-") {
startActivity(Intent(requireActivity(), CustomDateActivity::class.java))
} else {
Preferences.dateFormat = value
}
}.show()
}
}
action_event_app.setOnClickListener {
startActivityForResult(Intent(requireContext(), ChooseApplicationActivity::class.java), RequestCode.EVENT_APP_REQUEST_CODE.code)
}
@ -262,10 +311,10 @@ class CalendarSettingsFragment : Fragment() {
}
private fun checkReadEventsPermission(showEvents: Boolean = Preferences.showEvents) {
if (requireActivity().checkCallingOrSelfPermission(Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED) {
if (requireActivity().checkGrantedPermission(Manifest.permission.READ_CALENDAR)) {
show_events_label.text = if (showEvents) getString(R.string.show_events_visible) else getString(R.string.show_events_not_visible)
read_calendar_permission_alert_icon.isVisible = false
CalendarUtil.updateEventList(requireContext())
CalendarHelper.updateEventList(requireContext())
} else {
show_events_label.text = if (showEvents) getString(R.string.description_permission_calendar) else getString(R.string.show_events_not_visible)
read_calendar_permission_alert_icon.isVisible = showEvents

View File

@ -3,10 +3,10 @@ package com.tommasoberlose.anotherwidget.ui.fragments
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
@ -15,7 +15,6 @@ import androidx.lifecycle.lifecycleScope
import com.chibatching.kotpref.bulk
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
import com.tommasoberlose.anotherwidget.databinding.FragmentCalendarSettingsBinding
import com.tommasoberlose.anotherwidget.databinding.FragmentClockSettingsBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
@ -23,8 +22,6 @@ import com.tommasoberlose.anotherwidget.global.RequestCode
import com.tommasoberlose.anotherwidget.ui.activities.ChooseApplicationActivity
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.utils.Util
import com.tommasoberlose.anotherwidget.utils.toast
import kotlinx.android.synthetic.main.fragment_clock_settings.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -67,6 +64,11 @@ class ClockSettingsFragment : Fragment() {
binding: FragmentClockSettingsBinding,
viewModel: MainViewModel
) {
viewModel.showBigClockWarning.observe(viewLifecycleOwner, Observer {
large_clock_warning.isVisible = it
small_clock_warning.isVisible = !it
})
viewModel.showClock.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
show_clock_label.text =
@ -96,12 +98,16 @@ class ClockSettingsFragment : Fragment() {
}
private fun setupListener() {
action_hide_large_clock_warning.setOnClickListener {
Preferences.showBigClockWarning = false
}
action_show_clock.setOnClickListener {
Preferences.showClock = !Preferences.showClock
}
action_clock_text_size.setOnClickListener {
val dialog = BottomSheetMenu<Float>(requireContext()).selectResource(Preferences.clockTextSize)
val dialog = BottomSheetMenu<Float>(requireContext(), header = getString(R.string.settings_clock_text_size_title)).setSelectedValue(Preferences.clockTextSize)
(46 downTo 28).filter { it % 2 == 0 }.forEach {
dialog.addItem("${it}sp", it.toFloat())
}
@ -111,7 +117,7 @@ class ClockSettingsFragment : Fragment() {
}
action_show_next_alarm.setOnClickListener {
BottomSheetMenu<Boolean>(requireContext()).selectResource(Preferences.showNextAlarm)
BottomSheetMenu<Boolean>(requireContext(), header = getString(R.string.settings_show_next_alarm_title)).setSelectedValue(Preferences.showNextAlarm)
.addItem(getString(R.string.settings_visible), true)
.addItem(getString(R.string.settings_not_visible), false)
.addOnSelectItemListener { value ->

View File

@ -13,20 +13,17 @@ import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetColorPicker
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
import com.tommasoberlose.anotherwidget.databinding.FragmentGeneralSettingsBinding
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.global.RequestCode
import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.utils.Util
import com.tommasoberlose.anotherwidget.utils.toPixel
import com.tommasoberlose.anotherwidget.utils.toast
import dev.sasikanth.colorsheet.ColorSheet
import kotlinx.android.synthetic.main.fragment_general_settings.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.*
class GeneralSettingsFragment : Fragment() {
@ -50,7 +47,7 @@ class GeneralSettingsFragment : Fragment() {
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
val binding = DataBindingUtil.inflate<FragmentGeneralSettingsBinding>(inflater, R.layout.fragment_general_settings, container, false)
subscribeUi(binding, viewModel)
subscribeUi(viewModel)
binding.lifecycleOwner = this
binding.viewModel = viewModel
@ -66,7 +63,6 @@ class GeneralSettingsFragment : Fragment() {
private fun subscribeUi(
binding: FragmentGeneralSettingsBinding,
viewModel: MainViewModel
) {
@ -95,13 +91,13 @@ class GeneralSettingsFragment : Fragment() {
viewModel.textShadow.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
text_shadow_label.text = getString(Util.getTextShadowString(it))
text_shadow_label.text = getString(SettingsStringHelper.getTextShadowString(it))
}
})
viewModel.customFont.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
custom_font_label.text = getString(Util.getCustomFontLabel(it))
custom_font_label.text = getString(SettingsStringHelper.getCustomFontLabel(it))
}
})
}
@ -117,7 +113,7 @@ class GeneralSettingsFragment : Fragment() {
private fun setupListener() {
action_main_text_size.setOnClickListener {
val dialog = BottomSheetMenu<Float>(requireContext()).selectResource(Preferences.textMainSize)
val dialog = BottomSheetMenu<Float>(requireContext(), header = getString(R.string.title_main_text_size)).setSelectedValue(Preferences.textMainSize)
(32 downTo 20).filter { it % 2 == 0 }.forEach {
dialog.addItem("${it}sp", it.toFloat())
}
@ -127,7 +123,7 @@ class GeneralSettingsFragment : Fragment() {
}
action_second_text_size.setOnClickListener {
val dialog = BottomSheetMenu<Float>(requireContext()).selectResource(Preferences.textSecondSize)
val dialog = BottomSheetMenu<Float>(requireContext(), header = getString(R.string.title_second_text_size)).setSelectedValue(Preferences.textSecondSize)
(24 downTo 12).filter { it % 2 == 0 }.forEach {
dialog.addItem("${it}sp", it.toFloat())
}
@ -143,21 +139,21 @@ class GeneralSettingsFragment : Fragment() {
Preferences.textGlobalColor = "#FFFFFF"
Color.parseColor(Preferences.textGlobalColor)
}
ColorSheet()
.cornerRadius(16.toPixel(requireContext()))
.colorPicker(
BottomSheetColorPicker(requireContext(),
colors = requireActivity().resources.getIntArray(R.array.grey),
selectedColor = textColor,
listener = { color ->
Preferences.textGlobalColor = "#" + Integer.toHexString(color)
})
.show(requireActivity().supportFragmentManager)
header = getString(R.string.settings_font_color_title),
selected = textColor,
onColorSelected = { color: Int ->
val colorString = Integer.toHexString(color)
Preferences.textGlobalColor = "#" + if (colorString.length > 6) colorString.substring(2) else colorString
}
).show()
}
action_text_shadow.setOnClickListener {
val dialog = BottomSheetMenu<Int>(requireContext()).selectResource(Preferences.textShadow)
val dialog = BottomSheetMenu<Int>(requireContext(), header = getString(R.string.title_text_shadow)).setSelectedValue(Preferences.textShadow)
(2 downTo 0).forEach {
dialog.addItem(getString(Util.getTextShadowString(it)), it)
dialog.addItem(getString(SettingsStringHelper.getTextShadowString(it)), it)
}
dialog.addOnSelectItemListener { value ->
Preferences.textShadow = value
@ -165,9 +161,9 @@ class GeneralSettingsFragment : Fragment() {
}
action_custom_font.setOnClickListener {
val dialog = BottomSheetMenu<Int>(requireContext()).selectResource(Preferences.customFont)
val dialog = BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_custom_font_title)).setSelectedValue(Preferences.customFont)
(0..1).forEach {
dialog.addItem(getString(Util.getCustomFontLabel(it)), it)
dialog.addItem(getString(SettingsStringHelper.getCustomFontLabel(it)), it)
}
dialog.addOnSelectItemListener { value ->
Preferences.customFont = value

View File

@ -3,7 +3,6 @@ package com.tommasoberlose.anotherwidget.ui.fragments
import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -26,13 +25,15 @@ import com.tommasoberlose.anotherwidget.databinding.FragmentWeatherSettingsBindi
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.global.RequestCode
import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper
import com.tommasoberlose.anotherwidget.receivers.WeatherReceiver
import com.tommasoberlose.anotherwidget.ui.activities.ChooseApplicationActivity
import com.tommasoberlose.anotherwidget.ui.activities.CustomLocationActivity
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.activities.WeatherProviderActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.utils.Util
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import kotlinx.android.synthetic.main.fragment_weather_settings.*
import kotlinx.android.synthetic.main.fragment_weather_settings.scrollView
import kotlinx.coroutines.delay
@ -76,6 +77,10 @@ class WeatherSettingsFragment : Fragment() {
binding: FragmentWeatherSettingsBinding,
viewModel: MainViewModel
) {
viewModel.showWeatherWarning.observe(viewLifecycleOwner, Observer {
weather_warning.isVisible = it
})
viewModel.showWeather.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
show_weather_label.text =
@ -113,7 +118,7 @@ class WeatherSettingsFragment : Fragment() {
viewModel.weatherRefreshPeriod.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
label_weather_refresh_period.text = getString(Util.getRefreshPeriodString(it))
label_weather_refresh_period.text = getString(SettingsStringHelper.getRefreshPeriodString(it))
}
checkLocationPermission()
})
@ -127,7 +132,7 @@ class WeatherSettingsFragment : Fragment() {
}
private fun checkLocationPermission() {
if (requireActivity().checkCallingOrSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if (requireActivity().checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
location_permission_alert_icon.isVisible = false
WeatherReceiver.setUpdates(requireContext())
} else if (Preferences.showWeather && Preferences.customLocationAdd == "") {
@ -139,6 +144,9 @@ class WeatherSettingsFragment : Fragment() {
}
private fun setupListener() {
action_hide_weather_warning.setOnClickListener {
Preferences.showWeatherWarning = false
}
action_show_weather.setOnClickListener {
Preferences.showWeather = !Preferences.showWeather
@ -164,7 +172,7 @@ class WeatherSettingsFragment : Fragment() {
action_change_unit.setOnClickListener {
if (Preferences.showWeather) {
BottomSheetMenu<String>(requireContext()).selectResource(Preferences.weatherTempUnit)
BottomSheetMenu<String>(requireContext(), header = getString(R.string.settings_unit_title)).setSelectedValue(Preferences.weatherTempUnit)
.addItem(getString(R.string.fahrenheit), "F")
.addItem(getString(R.string.celsius), "C")
.addOnSelectItemListener { value ->
@ -176,9 +184,9 @@ class WeatherSettingsFragment : Fragment() {
action_weather_refresh_period.setOnClickListener {
if (Preferences.showWeather) {
val dialog =
BottomSheetMenu<Int>(requireContext()).selectResource(Preferences.weatherRefreshPeriod)
BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_weather_refresh_period_title)).setSelectedValue(Preferences.weatherRefreshPeriod)
(5 downTo 0).forEach {
dialog.addItem(getString(Util.getRefreshPeriodString(it)), it)
dialog.addItem(getString(SettingsStringHelper.getRefreshPeriodString(it)), it)
}
dialog
.addOnSelectItemListener { value ->
@ -202,13 +210,14 @@ class WeatherSettingsFragment : Fragment() {
when (requestCode) {
Constants.RESULT_CODE_CUSTOM_LOCATION -> {
WeatherReceiver.setUpdates(requireContext())
checkLocationPermission()
}
RequestCode.WEATHER_APP_REQUEST_CODE.code -> {
Preferences.bulk {
weatherAppName = data?.getStringExtra(Constants.RESULT_APP_NAME) ?: getString(R.string.default_weather_app)
weatherAppPackage = data?.getStringExtra(Constants.RESULT_APP_PACKAGE) ?: ""
}
Util.updateWidget(requireContext())
MainWidget.updateWidget(requireContext())
}
RequestCode.WEATHER_PROVIDER_REQUEST_CODE.code -> {
WeatherReceiver.setOneTimeUpdate(requireContext())

View File

@ -1,17 +1,21 @@
package com.tommasoberlose.anotherwidget.ui.viewmodels
import android.app.Application
import android.content.Intent
import android.content.pm.ApplicationInfo
import androidx.databinding.ObservableField
import androidx.lifecycle.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import android.content.pm.ResolveInfo
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.liveData
class ChooseApplicationViewModel(application: Application) : AndroidViewModel(application) {
val appList: LiveData<List<ApplicationInfo>> = liveData {
val app = application.packageManager.getInstalledApplications(0)
val appList: LiveData<List<ResolveInfo>> = liveData {
val mainIntent = Intent(Intent.ACTION_MAIN, null).apply {
addCategory(Intent.CATEGORY_LAUNCHER)
}
val app = application.packageManager.queryIntentActivities( mainIntent, 0)
emit(app)
}
val searchInput: MutableLiveData<String> = MutableLiveData("")

View File

@ -0,0 +1,10 @@
package com.tommasoberlose.anotherwidget.ui.viewmodels
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import com.tommasoberlose.anotherwidget.global.Preferences
class CustomDateViewModel(application: Application) : AndroidViewModel(application) {
val dateInput: MutableLiveData<String> = MutableLiveData(if (Preferences.dateFormat == "") "EEEE, MMM dd" else Preferences.dateFormat)
}

View File

@ -26,7 +26,6 @@ class MainViewModel : ViewModel() {
val eventAppName = Preferences.asLiveData(Preferences::eventAppName)
// Clock Settings
val showClock = Preferences.asLiveData(Preferences::showClock)
val clockTextSize = Preferences.asLiveData(Preferences::clockTextSize)
@ -35,6 +34,8 @@ class MainViewModel : ViewModel() {
val showNextAlarm = Preferences.asLiveData(Preferences::showNextAlarm)
val dateFormat = Preferences.asLiveData(Preferences::dateFormat)
val showBigClockWarning = Preferences.asLiveData(Preferences::showBigClockWarning)
// Weather Settings
val showWeather = Preferences.asLiveData(Preferences::showWeather)
val weatherTempUnit = Preferences.asLiveData(Preferences::weatherTempUnit)
@ -45,6 +46,8 @@ class MainViewModel : ViewModel() {
val customLocationAdd = Preferences.asLiveData(Preferences::customLocationAdd)
val showWeatherWarning = Preferences.asLiveData(Preferences::showWeatherWarning)
// Advanced Settings
val darkThemePreference = Preferences.asLiveData(Preferences::darkThemePreference)
val showWallpaper = Preferences.asLiveData(Preferences::showWallpaper)

View File

@ -4,10 +4,10 @@ import android.Manifest
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.res.Resources
import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.Typeface
import android.os.Bundle
@ -22,25 +22,27 @@ import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.db.EventRepository
import com.tommasoberlose.anotherwidget.global.Actions
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.*
import com.tommasoberlose.anotherwidget.receivers.NewCalendarEventReceiver
import com.tommasoberlose.anotherwidget.receivers.WidgetClickListenerReceiver
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
import com.tommasoberlose.anotherwidget.receivers.WeatherReceiver
import com.tommasoberlose.anotherwidget.utils.CalendarUtil
import com.tommasoberlose.anotherwidget.utils.Util
import com.tommasoberlose.anotherwidget.utils.WeatherUtil
import com.tommasoberlose.anotherwidget.receivers.WidgetClickListenerReceiver
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import com.tommasoberlose.anotherwidget.utils.convertSpToPixels
import com.tommasoberlose.anotherwidget.utils.getCapWordString
import com.tommasoberlose.anotherwidget.utils.toPixel
import kotlinx.android.synthetic.main.the_widget.view.*
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.math.min
class TheWidget : AppWidgetProvider() {
class MainWidget : AppWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
for (appWidgetId in appWidgetIds) {
@ -54,8 +56,14 @@ class TheWidget : AppWidgetProvider() {
}
override fun onEnabled(context: Context) {
CalendarUtil.updateEventList(context)
CalendarHelper.updateEventList(context)
WeatherReceiver.setUpdates(context)
if (Preferences.showEvents) {
CalendarHelper.setEventUpdatesAndroidN(context)
} else {
CalendarHelper.removeEventUpdatesAndroidN(context)
}
}
override fun onDisabled(context: Context) {
@ -65,27 +73,37 @@ class TheWidget : AppWidgetProvider() {
companion object {
fun updateWidget(context: Context) {
val widgetManager = AppWidgetManager.getInstance(context)
val widgetComponent = ComponentName(context, MainWidget::class.java)
val widgetIds = widgetManager.getAppWidgetIds(widgetComponent)
val update = Intent(context, MainWidget::class.java)
update.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIds)
update.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
context.sendBroadcast(update)
}
internal fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManager,
appWidgetId: Int) {
val displayMetrics = Resources.getSystem().displayMetrics
var height = 110.toPixel(context)
val width = displayMetrics.widthPixels
if (Preferences.showClock) {
height += Util.convertSpToPixels(Preferences.clockTextSize, context).toInt() + 16.toPixel(context)
height += Preferences.clockTextSize.convertSpToPixels(context).toInt() + 16.toPixel(context)
}
if (Preferences.textMainSize > 30 && Preferences.textSecondSize > 22) {
height += 24.toPixel(context)
}
generateWidgetView(context, appWidgetId, appWidgetManager, width - 16.toPixel(context), height)
generateWidgetView(context, appWidgetId, appWidgetManager, width - 16.toPixel(context))
}
private fun generateWidgetView(context: Context, appWidgetId: Int, appWidgetManager: AppWidgetManager, w: Int, h: Int) {
private fun generateWidgetView(context: Context, appWidgetId: Int, appWidgetManager: AppWidgetManager, w: Int) {
var views = RemoteViews(context.packageName, R.layout.the_widget_sans)
val generatedView = generateWidgetView(context, w)
val generatedView = generateWidgetView(context)
generatedView.measure(0, 0)
views.setImageViewBitmap(R.id.bitmap_container, Util.getBitmapFromView(generatedView, w, generatedView.measuredHeight))
views.setImageViewBitmap(R.id.bitmap_container, BitmapHelper.getBitmapFromView(generatedView, w - 32.toPixel(context), generatedView.measuredHeight))
// Clock
views = updateClockView(context, views, appWidgetId)
@ -98,29 +116,30 @@ class TheWidget : AppWidgetProvider() {
}
private fun updateCalendarView(context: Context, v: View, views: RemoteViews, widgetID: Int): RemoteViews {
val eventRepository = EventRepository(context)
v.empty_date.measure(0, 0)
views.setImageViewBitmap(R.id.empty_date_rect, Util.getBitmapFromView(v.empty_date))
views.setImageViewBitmap(R.id.empty_date_rect, BitmapHelper.getBitmapFromView(v.empty_date))
views.setViewVisibility(R.id.empty_layout_rect, View.VISIBLE)
views.setViewVisibility(R.id.calendar_layout_rect, View.GONE)
views.setViewVisibility(R.id.second_row_rect, View.GONE)
val calPIntent = PendingIntent.getActivity(context, widgetID, Util.getCalendarIntent(context), 0)
val calPIntent = PendingIntent.getActivity(context, widgetID, IntentHelper.getCalendarIntent(context), 0)
views.setOnClickPendingIntent(R.id.empty_date_rect, calPIntent)
val nextEvent = CalendarUtil.getNextEvent()
val nextAlarm = Util.getNextAlarm(context)
val nextEvent = eventRepository.getNextEvent()
val nextAlarm = AlarmHelper.getNextAlarm(context)
if (Preferences.showEvents && Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR) && nextEvent != null) {
if (Preferences.showNextEvent && CalendarUtil.getEventsCount() > 1) {
if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null) {
if (Preferences.showNextEvent && eventRepository.getEventsCount() > 1) {
v.action_next.measure(0, 0)
views.setImageViewBitmap(R.id.action_next_rect, Util.getBitmapFromView(v.action_next))
views.setImageViewBitmap(R.id.action_next_rect, BitmapHelper.getBitmapFromView(v.action_next))
views.setViewVisibility(R.id.action_next_rect, View.VISIBLE)
views.setOnClickPendingIntent(R.id.action_next_rect, PendingIntent.getBroadcast(context, widgetID, Intent(context, NewCalendarEventReceiver::class.java).apply { action = Actions.ACTION_GO_TO_NEXT_EVENT }, 0))
v.action_previous.measure(0, 0)
views.setImageViewBitmap(R.id.action_previous_rect, Util.getBitmapFromView(v.action_previous))
views.setImageViewBitmap(R.id.action_previous_rect, BitmapHelper.getBitmapFromView(v.action_previous))
views.setViewVisibility(R.id.action_previous_rect, View.VISIBLE)
views.setOnClickPendingIntent(R.id.action_previous_rect, PendingIntent.getBroadcast(context, widgetID, Intent(context, NewCalendarEventReceiver::class.java).apply { action = Actions.ACTION_GO_TO_PREVIOUS_EVENT }, 0))
} else {
@ -128,44 +147,44 @@ class TheWidget : AppWidgetProvider() {
views.setViewVisibility(R.id.action_previous_rect, View.GONE)
}
val pIntent = PendingIntent.getActivity(context, widgetID, Util.getEventIntent(context, nextEvent), 0)
val pIntent = PendingIntent.getActivity(context, widgetID, IntentHelper.getEventIntent(context, nextEvent), 0)
views.setOnClickPendingIntent(R.id.next_event_rect, pIntent)
views.setOnClickPendingIntent(R.id.next_event_difference_time_rect, pIntent)
if (Preferences.showDiffTime && Calendar.getInstance().timeInMillis < nextEvent.startDate) {
if (Preferences.showDiffTime && Calendar.getInstance().timeInMillis < (nextEvent.startDate - 1000 * 60 * 60)) {
v.next_event_difference_time.measure(0, 0)
views.setImageViewBitmap(R.id.next_event_difference_time_rect, Util.getBitmapFromView(v.next_event_difference_time))
views.setImageViewBitmap(R.id.next_event_difference_time_rect, BitmapHelper.getBitmapFromView(v.next_event_difference_time))
views.setViewVisibility(R.id.next_event_difference_time_rect, View.VISIBLE)
} else {
views.setViewVisibility(R.id.next_event_difference_time_rect, View.GONE)
}
if (nextEvent.address != "" && Preferences.secondRowInformation == 1) {
val mapIntent = PendingIntent.getActivity(context, widgetID, Util.getGoogleMapsIntentFromAddress(context, nextEvent.address), 0)
val mapIntent = PendingIntent.getActivity(context, widgetID, IntentHelper.getGoogleMapsIntentFromAddress(context, nextEvent.address), 0)
views.setOnClickPendingIntent(R.id.second_row_rect, mapIntent)
} else {
views.setOnClickPendingIntent(R.id.next_event_rect, pIntent)
}
v.next_event.measure(0, 0)
views.setImageViewBitmap(R.id.next_event_rect, Util.getBitmapFromView(v.next_event))
views.setImageViewBitmap(R.id.next_event_rect, BitmapHelper.getBitmapFromView(v.next_event))
v.second_row.measure(0, 0)
views.setImageViewBitmap(R.id.second_row_rect, Util.getBitmapFromView(v.second_row))
views.setImageViewBitmap(R.id.second_row_rect, BitmapHelper.getBitmapFromView(v.second_row))
views.setViewVisibility(R.id.second_row_rect, View.VISIBLE)
views.setViewVisibility(R.id.empty_layout_rect, View.GONE)
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
} else if (Preferences.secondRowInformation == 2 && nextAlarm != "") {
val clockIntent = PendingIntent.getActivity(context, widgetID, Util.getClockIntent(context), 0)
} else if (Preferences.showNextAlarm && nextAlarm != "") {
val clockIntent = PendingIntent.getActivity(context, widgetID, IntentHelper.getClockIntent(context), 0)
views.setOnClickPendingIntent(R.id.second_row_rect, clockIntent)
v.next_event.measure(0, 0)
views.setImageViewBitmap(R.id.next_event_rect, Util.getBitmapFromView(v.next_event))
views.setImageViewBitmap(R.id.next_event_rect, BitmapHelper.getBitmapFromView(v.next_event))
v.second_row.measure(0, 0)
views.setImageViewBitmap(R.id.second_row_rect, Util.getBitmapFromView(v.second_row))
views.setImageViewBitmap(R.id.second_row_rect, BitmapHelper.getBitmapFromView(v.second_row))
views.setViewVisibility(R.id.second_row_rect, View.VISIBLE)
views.setViewVisibility(R.id.empty_layout_rect, View.GONE)
@ -189,10 +208,10 @@ class TheWidget : AppWidgetProvider() {
views.setOnClickPendingIntent(R.id.calendar_weather_rect, weatherPIntent)
v.weather.measure(0, 0)
views.setImageViewBitmap(R.id.weather_rect, Util.getBitmapFromView(v.weather))
views.setImageViewBitmap(R.id.weather_rect, BitmapHelper.getBitmapFromView(v.weather))
v.calendar_weather.measure(0, 0)
views.setImageViewBitmap(R.id.calendar_weather_rect, Util.getBitmapFromView(v.calendar_weather))
views.setImageViewBitmap(R.id.calendar_weather_rect, BitmapHelper.getBitmapFromView(v.calendar_weather))
} else {
views.setViewVisibility(R.id.weather_rect, View.GONE)
views.setViewVisibility(R.id.calendar_weather_rect, View.GONE)
@ -204,9 +223,9 @@ class TheWidget : AppWidgetProvider() {
if (!Preferences.showClock) {
views.setViewVisibility(R.id.time, View.GONE)
} else {
views.setTextColor(R.id.time, Util.getFontColor())
views.setTextColor(R.id.time, ColorHelper.getFontColor())
views.setTextViewTextSize(R.id.time, TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(context))
val clockPIntent = PendingIntent.getActivity(context, widgetID, Util.getClockIntent(context), 0)
val clockPIntent = PendingIntent.getActivity(context, widgetID, IntentHelper.getClockIntent(context), 0)
views.setOnClickPendingIntent(R.id.time, clockPIntent)
views.setViewVisibility(R.id.time, View.VISIBLE)
}
@ -214,29 +233,42 @@ class TheWidget : AppWidgetProvider() {
return views
}
fun generateWidgetView(context: Context, maxWidth: Int): View {
// Generates the widget bitmap from the view
fun generateWidgetView(context: Context): View {
val eventRepository = EventRepository(context)
val v = View.inflate(context, R.layout.the_widget, null)
val now = Calendar.getInstance()
v.empty_layout.visibility = View.VISIBLE
v.calendar_layout.visibility = View.GONE
v.action_next.isVisible = false
v.action_previous.isVisible = false
val flags: Int = DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR or DateUtils.FORMAT_ABBREV_MONTH
v.empty_date.text = Util.getCapWordString("${SimpleDateFormat("EEEE", Locale.getDefault()).format(now.time)}, ${DateUtils.formatDateTime(context, now.timeInMillis, flags)}")
v.empty_date.text = DateHelper.getDateText(context, now)
val nextEvent = CalendarUtil.getNextEvent()
val nextAlarm = Util.getNextAlarm(context)
val nextEvent = eventRepository.getNextEvent()
val nextAlarm = AlarmHelper.getNextAlarm(context)
if (Preferences.showEvents && Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR) && nextEvent != null) {
if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null) {
// Multiple counter
v.action_next.isVisible = Preferences.showNextEvent && CalendarUtil.getEventsCount() > 1
v.action_previous.isVisible = Preferences.showNextEvent && CalendarUtil.getEventsCount() > 1
v.action_next.isVisible = Preferences.showNextEvent && eventRepository.getEventsCount() > 1
v.action_previous.isVisible = Preferences.showNextEvent && eventRepository.getEventsCount() > 1
v.next_event.text = nextEvent.title
if (Preferences.showDiffTime && now.timeInMillis < nextEvent.startDate) {
v.next_event_difference_time.text = Util.getDifferenceText(context, now.timeInMillis, nextEvent.startDate).toLowerCase(Locale.getDefault())
if (Preferences.showDiffTime && now.timeInMillis < (nextEvent.startDate - 1000 * 60 * 60)) {
v.next_event_difference_time.text = if (!nextEvent.allDay) {
SettingsStringHelper.getDifferenceText(
context,
now.timeInMillis,
nextEvent.startDate
)
.toLowerCase(Locale.getDefault())
} else {
SettingsStringHelper.getAllDayEventDifferenceText(context, now.timeInMillis, nextEvent.startDate).toLowerCase(Locale.getDefault())
}
v.next_event_difference_time.visibility = View.VISIBLE
} else {
v.next_event_difference_time.visibility = View.GONE
@ -271,21 +303,22 @@ class TheWidget : AppWidgetProvider() {
v.next_event_date.text = String.format("%s - %s%s", startHour, endHour, multipleDay)
} else {
v.next_event_date.text = Util.getCapWordString(DateUtils.formatDateTime(context, now.timeInMillis, flags))
val flags: Int = DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR or DateUtils.FORMAT_ABBREV_MONTH
v.next_event_date.text = DateUtils.formatDateTime(context, now.timeInMillis, flags).getCapWordString()
}
}
v.empty_layout.visibility = View.GONE
v.calendar_layout.visibility = View.VISIBLE
} else if (Preferences.secondRowInformation == 2 && nextAlarm != "") {
} else if (Preferences.showNextAlarm && nextAlarm != "") {
v.second_row_icon.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.round_alarm
)
)
v.next_event.text = Util.getCapWordString("${SimpleDateFormat("EEEE", Locale.getDefault()).format(now.time)}, ${DateUtils.formatDateTime(context, now.timeInMillis, flags)}")
v.next_event_date.text = Util.getNextAlarm(context)
v.next_event.text = DateHelper.getDateText(context, now)
v.next_event_date.text = AlarmHelper.getNextAlarm(context)
v.empty_layout.visibility = View.GONE
v.calendar_layout.visibility = View.VISIBLE
}
@ -293,11 +326,11 @@ class TheWidget : AppWidgetProvider() {
// Color
listOf<TextView>(v.empty_date, v.divider1, v.temp, v.next_event, v.next_event_difference_time, v.next_event_date, v.divider2, v.calendar_temp).forEach {
it.setTextColor(Util.getFontColor())
it.setTextColor(ColorHelper.getFontColor())
}
listOf<ImageView>(v.second_row_icon, v.action_next, v.action_previous).forEach {
it.setColorFilter(Util.getFontColor())
it.setColorFilter(ColorHelper.getFontColor())
}
// Text Size
@ -318,8 +351,8 @@ class TheWidget : AppWidgetProvider() {
v.second_row_icon.scaleX = Preferences.textSecondSize / 18f
v.second_row_icon.scaleY = Preferences.textSecondSize / 18f
v.weather_icon.scaleX = Preferences.textSecondSize / 18f
v.weather_icon.scaleY = Preferences.textSecondSize / 18f
v.weather_icon.scaleX = Preferences.textSecondSize / 16f
v.weather_icon.scaleY = Preferences.textSecondSize / 16f
v.empty_weather_icon.scaleX = Preferences.textMainSize / 20f
v.empty_weather_icon.scaleY = Preferences.textMainSize / 20f
@ -374,8 +407,8 @@ class TheWidget : AppWidgetProvider() {
v.weather_icon.visibility = View.GONE
v.empty_weather_icon.visibility = View.GONE
} else {
v.weather_icon.setImageResource(WeatherUtil.getWeatherIconResource(icon))
v.empty_weather_icon.setImageResource(WeatherUtil.getWeatherIconResource(icon))
v.weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(icon))
v.empty_weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(icon))
v.weather_icon.visibility = View.VISIBLE
v.empty_weather_icon.visibility = View.VISIBLE
}
@ -387,9 +420,6 @@ class TheWidget : AppWidgetProvider() {
v.calendar_weather.visibility = View.GONE
}
// Apply max width
v.main_layout.layoutParams = RelativeLayout.LayoutParams(maxWidth, RelativeLayout.LayoutParams.WRAP_CONTENT)
return v
}
}