Compare commits

...

2 Commits

Author SHA1 Message Date
26428b65da Merge crud-device 2020-05-09 17:58:03 +02:00
97d1caeabc Add dividers toggle 2020-05-09 15:11:12 +02:00
525 changed files with 1024 additions and 270 deletions

Binary file not shown.

View File

@ -18,7 +18,7 @@ android {
applicationId "com.tommasoberlose.anotherwidget"
minSdkVersion 23
targetSdkVersion 29
versionCode 80
versionCode 81
versionName "2.0.6"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

Binary file not shown.

View File

@ -1,6 +1,7 @@
package com.tommasoberlose.anotherwidget.db
import android.content.Context
import android.util.Log
import com.chibatching.kotpref.bulk
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.models.Event
@ -8,6 +9,8 @@ import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import io.realm.Realm
import io.realm.RealmResults
import java.util.*
import kotlin.collections.ArrayList
class EventRepository(val context: Context) {
private val realm by lazy { Realm.getDefaultInstance() }
@ -39,13 +42,27 @@ class EventRepository(val context: Context) {
Preferences.nextEventId = event.id
}
fun getNextEvent(): Event? = realm.where(Event::class.java).equalTo("id", Preferences.nextEventId).findFirst() ?: realm.where(Event::class.java).findFirst()
fun getNextEvent(): Event? {
val nextEvent = getEventByEventId(Preferences.nextEventId)
return if (nextEvent != null && nextEvent.endDate > Calendar.getInstance().timeInMillis) {
nextEvent
} else {
val events = getEvents()
if (events.isNotEmpty()) {
val newNextEvent = events.first()
Preferences.nextEventId = newNextEvent!!.eventID
newNextEvent
} else {
resetNextEventData()
null
}
}
}
fun getEventByEventId(id: Long): Event? = realm.where(Event::class.java).equalTo("eventID", id).findFirst()
fun goToNextEvent() {
val eventList = realm.where(Event::class.java).findAll()
val eventList = getEvents()
if (eventList.isNotEmpty()) {
val index = eventList.indexOfFirst { it.id == Preferences.nextEventId }
if (index > -1 && index < eventList.size - 1) {
@ -61,8 +78,7 @@ class EventRepository(val context: Context) {
}
fun goToPreviousEvent() {
val eventList = realm.where(Event::class.java).findAll()
val eventList = getEvents()
if (eventList.isNotEmpty()) {
val index = eventList.indexOfFirst { it.id == Preferences.nextEventId }
if (index > 0) {
@ -77,7 +93,14 @@ class EventRepository(val context: Context) {
MainWidget.updateWidget(context)
}
fun getEvents(): RealmResults<Event> = realm.where(Event::class.java).findAll()
fun getEvents(): RealmResults<Event> {
val now = Calendar.getInstance().timeInMillis
val list = realm.where(Event::class.java).greaterThan("endDate", now).findAll()
realm.executeTransactionAsync {
it.where(Event::class.java).lessThanOrEqualTo("endDate", now).findAll().deleteAllFromRealm()
}
return list
}
fun getEventsCount(): Int = realm.where(Event::class.java).findAll().size
fun getEventsCount(): Int = getEvents().size
}

View File

@ -14,4 +14,12 @@ object Constants {
MEDIUM(2),
LARGE(3)
}
enum class GlanceProviderId(val id: String) {
PLAYING_SONG("PLAYING_SONG"),
NEXT_CLOCK_ALARM("NEXT_CLOCK_ALARM"),
// BATTERY_LEVEL_LOW("BATTERY_LEVEL_LOW"),
// CUSTOM_INFO("CUSTOM_INFO"),
// GOOGLE_FIT_STEPS("GOOGLE_FIT_STEPS")
}
}

View File

@ -57,7 +57,6 @@ object Preferences : KotprefModel() {
var showClock by booleanPref(key = "PREF_SHOW_CLOCK", default = false)
var clockAppName by stringPref(key = "PREF_CLOCK_APP_NAME", default = "")
var clockAppPackage by stringPref(key = "PREF_CLOCK_APP_PACKAGE", default = "")
var showNextAlarm by booleanPref(default = false)
var textShadow by intPref(key = "PREF_TEXT_SHADOW", default = 1)
var showDiffTime by booleanPref(key = "PREF_SHOW_DIFF_TIME", default = true)
var showDeclinedEvents by booleanPref(key = "PREF_SHOW_DECLINED_EVENTS", default = false)
@ -66,6 +65,8 @@ object Preferences : KotprefModel() {
var customFontFile by stringPref(key = "PREF_CUSTOM_FONT_FILE")
var showNextEvent by booleanPref(key = "PREF_SHOW_NEXT_EVENT", default = true)
var showDividers by booleanPref(default = true)
// Settings
var showWallpaper by booleanPref(default = true)
var showBigClockWarning by booleanPref(default = true)
@ -73,7 +74,14 @@ object Preferences : KotprefModel() {
var showPreview by booleanPref(default = true)
var showXiaomiWarning by booleanPref(default = true)
// Music
// Glance
var showGlance by booleanPref(default = true)
var enabledGlanceProviderOrder by stringPref(default = "")
var customInfo by stringPref(default = "")
var showNextAlarm by booleanPref(default = false)
var isBatteryLevelLow by booleanPref(default = false)
var googleFitSteps by longPref(default = -1)
var showMusic by booleanPref(default = false)
var mediaInfoFormat by stringPref(default = "")
var mediaPlayerTitle by stringPref(default = "")

View File

@ -0,0 +1,76 @@
package com.tommasoberlose.anotherwidget.helpers
import android.content.Context
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.models.GlanceProvider
import java.util.ArrayList
object GlanceProviderHelper {
fun getGlanceProviders(): ArrayList<Constants.GlanceProviderId> {
val enabledProviders = Preferences.enabledGlanceProviderOrder.split(",").filter { it != "" }
val providers = Constants.GlanceProviderId.values()
providers.sortWith(Comparator { p1, p2 ->
when {
enabledProviders.contains(p1.id) && enabledProviders.contains(p2.id) -> {
enabledProviders.indexOf(p1.id).compareTo(enabledProviders.indexOf(p2.id))
}
enabledProviders.contains(p1.id) -> {
-1
}
enabledProviders.contains(p2.id) -> {
1
}
else -> {
p1.id.compareTo(p2.id)
}
}
})
return ArrayList(providers.toList())
}
fun getGlanceProviderById(context: Context, providerId: Constants.GlanceProviderId): GlanceProvider? {
return when(providerId) {
Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> {
GlanceProvider(providerId.id,
context.getString(R.string.settings_show_next_alarm_title),
R.drawable.round_alarm,
context.getString(R.string.settings_show_next_alarm_subtitle)
)
}
Constants.GlanceProviderId.PLAYING_SONG -> {
GlanceProvider(providerId.id,
context.getString(R.string.settings_show_music_title),
R.drawable.round_music_note,
context.getString(R.string.settings_show_music_enabled_subtitle)
)
}
// Constants.GlanceProviderId.CUSTOM_INFO -> {
// GlanceProvider(providerId.id,
// context.getString(R.string.settings_show_next_alarm_title),
// R.drawable.round_event_note
// )
// }
// Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
// GlanceProvider(providerId.id,
// context.getString(R.string.settings_show_next_alarm_title),
// R.drawable.round_battery_charging_full
// )
// }
// Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
// GlanceProvider(providerId.id,
// context.getString(R.string.settings_show_next_alarm_title),
// R.drawable.round_directions_walk
// )
// }
else -> null
}
}
fun saveGlanceProviderOrder(list: ArrayList<Constants.GlanceProviderId>) {
Preferences.enabledGlanceProviderOrder = list.joinToString(separator = ",")
}
}

View File

@ -0,0 +1,12 @@
package com.tommasoberlose.anotherwidget.models
class GlanceProvider(
val id: String,
val title: String,
val icon: Int,
val label: String = "",
val enabled: Boolean = false,
val isPermissionRequired: Boolean = false,
val isPermissionGranted: (() -> Boolean)? = null,
val requestPermission: (() -> Unit)? = null
)

View File

@ -11,6 +11,7 @@ import androidx.core.content.ContextCompat.getSystemService
import com.tommasoberlose.anotherwidget.db.EventRepository
import com.tommasoberlose.anotherwidget.global.Actions
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
import com.tommasoberlose.anotherwidget.models.Event
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import org.joda.time.Period
import java.util.*
@ -32,47 +33,69 @@ class UpdatesReceiver : BroadcastReceiver() {
AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED,
Actions.ACTION_TIME_UPDATE -> {
MainWidget.updateWidget(context)
if (intent.hasExtra(EVENT_ID)) {
setUpdates(context, intent.getLongExtra(EVENT_ID, -1))
}
}
}
}
companion object {
const val EVENT_ID = "EVENT_ID"
fun setUpdates(context: Context) {
removeUpdates(context)
fun setUpdates(context: Context, eventId: Long? = null) {
val eventRepository = EventRepository(context)
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
eventRepository.getEvents().forEach { event ->
val now = Calendar.getInstance().apply {
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}
val diff = Period(now.timeInMillis, event.startDate)
if (event.startDate > now.timeInMillis) {
// Update the widget every hour till the event
(0..diff.hours).forEach {
setExactAndAllowWhileIdle(
AlarmManager.RTC,
if (event.startDate - it * 1000 * 60 * 60 > 60 * 1000) event.startDate - it * 1000 * 60 * 60 else now.timeInMillis + 120000,
PendingIntent.getBroadcast(
context,
event.eventID.toInt() + it,
Intent(context, UpdatesReceiver::class.java).apply {
action = Actions.ACTION_TIME_UPDATE
},
0
)
)
}
}
if (eventId == null) {
removeUpdates(context)
// Update the widget one second after the event is finished
eventRepository.getEvents().forEach { event ->
setEventUpdate(context, event)
}
} else {
val event = eventRepository.getEventByEventId(eventId)
if (event != null) {
setEventUpdate(context, event)
}
}
}
private fun setEventUpdate(context: Context, event: Event) {
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
val now = Calendar.getInstance().apply {
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}
val diff = Period(now.timeInMillis, event.startDate)
if (event.startDate > now.timeInMillis) {
// Update the widget every hour till the event
setExactAndAllowWhileIdle(
AlarmManager.RTC,
if (event.endDate > 60 *1000) event.endDate else now.timeInMillis + 120000,
PendingIntent.getBroadcast(context, 1, Intent(context, UpdatesReceiver::class.java).apply { action = Actions.ACTION_TIME_UPDATE }, 0)
if (event.startDate - diff.hours * 1000 * 60 * 60 > (now.timeInMillis + 120 * 1000)) event.startDate - diff.hours * 1000 * 60 * 60 else now.timeInMillis + 120000,
PendingIntent.getBroadcast(
context,
event.eventID.toInt(),
Intent(context, UpdatesReceiver::class.java).apply {
action = Actions.ACTION_TIME_UPDATE
putExtra(EVENT_ID, event.eventID)
},
0
)
)
} else {
// Update the widget one second after the event is finished
val fireTime =
if (event.endDate > now.timeInMillis + 120 * 1000) event.endDate else now.timeInMillis + 120000
setExactAndAllowWhileIdle(
AlarmManager.RTC,
fireTime,
PendingIntent.getBroadcast(
context,
event.eventID.toInt(),
Intent(context, UpdatesReceiver::class.java).apply {
action = Actions.ACTION_TIME_UPDATE
},
0
)
)
}
}
@ -80,11 +103,8 @@ class UpdatesReceiver : BroadcastReceiver() {
fun removeUpdates(context: Context) {
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
cancel(PendingIntent.getBroadcast(context, 1, Intent(context, UpdatesReceiver::class.java), 0))
EventRepository(context).getEvents().forEach {
(0..24).forEach { hour ->
cancel(PendingIntent.getBroadcast(context, it.eventID.toInt() * hour, Intent(context, UpdatesReceiver::class.java), 0))
}
cancel(PendingIntent.getBroadcast(context, it.eventID.toInt(), Intent(context, UpdatesReceiver::class.java), 0))
}
}
}

View File

@ -15,7 +15,7 @@ class ViewPagerAdapter(fragmentActivity: FragmentActivity) :
1 -> CalendarTabFragment.newInstance()
2 -> WeatherTabFragment.newInstance()
3 -> ClockTabFragment.newInstance()
4 -> AtAGlanceTabFragment.newInstance()
4 -> GlanceTabFragment.newInstance()
else -> GeneralTabFragment.newInstance()
}
}

View File

@ -4,6 +4,7 @@ import android.Manifest
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
@ -160,6 +161,13 @@ class CalendarTabFragment : Fragment() {
}
}
show_events_switch.setOnCheckedChangeListener { _, enabled: Boolean ->
Preferences.showEvents = enabled
if (Preferences.showEvents) {
requirePermission()
}
}
action_filter_calendar.setOnClickListener {
val calendarSelectorList: List<CalendarSelector> = CalendarHelper.getCalendarList(requireContext()).map {
CalendarSelector(
@ -339,6 +347,8 @@ class CalendarTabFragment : Fragment() {
report?.let {
if (report.areAllPermissionsGranted()){
checkReadEventsPermission()
} else {
Preferences.showEvents = false
}
}
}

View File

@ -154,6 +154,10 @@ class ClockTabFragment : Fragment() {
Preferences.showClock = !Preferences.showClock
}
show_clock_switch.setOnCheckedChangeListener { _, enabled: Boolean ->
Preferences.showClock = enabled
}
action_clock_text_size.setOnClickListener {
val dialog = BottomSheetMenu<Float>(requireContext(), header = getString(R.string.settings_clock_text_size_title)).setSelectedValue(Preferences.clockTextSize)
(46 downTo 12).filter { it % 2 == 0 }.forEach {
@ -182,7 +186,7 @@ class ClockTabFragment : Fragment() {
}
action_clock_bottom_margin_size.setOnClickListener {
BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_show_next_alarm_title)).setSelectedValue(Preferences.clockBottomMargin)
BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_clock_bottom_margin_title)).setSelectedValue(Preferences.clockBottomMargin)
.addItem(getString(R.string.settings_clock_bottom_margin_subtitle_none), Constants.ClockBottomMargin.NONE.value)
.addItem(getString(R.string.settings_clock_bottom_margin_subtitle_small), Constants.ClockBottomMargin.SMALL.value)
.addItem(getString(R.string.settings_clock_bottom_margin_subtitle_medium), Constants.ClockBottomMargin.MEDIUM.value)

View File

@ -146,6 +146,10 @@ class GeneralTabFragment : Fragment() {
custom_font_label?.text = getString(SettingsStringHelper.getCustomFontLabel(it))
}
})
viewModel.showDividers.observe(viewLifecycleOwner, Observer {
show_dividers_label?.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
})
}
private fun maintainScrollPosition(callback: () -> Unit) {
@ -243,6 +247,15 @@ class GeneralTabFragment : Fragment() {
}
*/
}
action_show_dividers.setOnClickListener {
BottomSheetMenu<Boolean>(requireContext(), header = getString(R.string.settings_show_multiple_events_title)).setSelectedValue(Preferences.showDividers)
.addItem(getString(R.string.settings_visible), true)
.addItem(getString(R.string.settings_not_visible), false)
.addOnSelectItemListener { value ->
Preferences.showDividers = value
}.show()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

View File

@ -10,34 +10,45 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.app.NotificationManagerCompat
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.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
import com.tommasoberlose.anotherwidget.databinding.FragmentAtAGlanceSettingsBinding
import com.tommasoberlose.anotherwidget.databinding.FragmentGlanceSettingsBinding
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.AlarmHelper
import com.tommasoberlose.anotherwidget.helpers.GlanceProviderHelper
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
import com.tommasoberlose.anotherwidget.models.GlanceProvider
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import kotlinx.android.synthetic.main.fragment_at_a_glance_settings.*
import kotlinx.android.synthetic.main.fragment_at_a_glance_settings.scrollView
import kotlinx.android.synthetic.main.fragment_glance_settings.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.lang.Exception
import net.idik.lib.slimadapter.SlimAdapter
import java.util.*
class AtAGlanceTabFragment : Fragment() {
class GlanceTabFragment : Fragment() {
companion object {
fun newInstance() = AtAGlanceTabFragment()
fun newInstance() = GlanceTabFragment()
}
private lateinit var viewModel: MainViewModel
private lateinit var adapter: SlimAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -49,7 +60,7 @@ class AtAGlanceTabFragment : Fragment() {
): View {
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
val binding = DataBindingUtil.inflate<FragmentAtAGlanceSettingsBinding>(inflater, R.layout.fragment_at_a_glance_settings, container, false)
val binding = DataBindingUtil.inflate<FragmentGlanceSettingsBinding>(inflater, R.layout.fragment_glance_settings, container, false)
subscribeUi(binding, viewModel)
@ -62,15 +73,78 @@ class AtAGlanceTabFragment : Fragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
list.setHasFixedSize(true)
val mLayoutManager = LinearLayoutManager(requireContext())
list.layoutManager = mLayoutManager
adapter = SlimAdapter.create()
adapter
.register<String>(R.layout.glance_provider_item) { item, injector ->
injector
.text(R.id.title, item)
}
.register<GlanceProvider>(R.layout.glance_provider_item) { item, injector ->
injector
.text(R.id.title, item.title)
.with<ImageView>(R.id.icon) {
it.setImageDrawable(ContextCompat.getDrawable(requireContext(), item.icon))
}
.with<TextView>(R.id.label) {
it.isVisible = item.label != ""
it.text = item.label
}
}
.attachTo(list)
adapter.updateData(
GlanceProviderHelper.getGlanceProviders()
.mapNotNull { GlanceProviderHelper.getGlanceProviderById(requireContext(), it) }
)
val mIth = ItemTouchHelper(
object : ItemTouchHelper.SimpleCallback(
ItemTouchHelper.UP or ItemTouchHelper.DOWN,
ItemTouchHelper.LEFT
) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: ViewHolder, target: ViewHolder
): Boolean {
val fromPos = viewHolder.adapterPosition
val toPos = target.adapterPosition
// move item in `fromPos` to `toPos` in adapter.
adapter.notifyItemMoved(fromPos, toPos)
val list = GlanceProviderHelper.getGlanceProviders()
Collections.swap(list, fromPos, toPos)
GlanceProviderHelper.saveGlanceProviderOrder(list)
return true
}
override fun onSwiped(
viewHolder: ViewHolder,
direction: Int
) {
// remove from adapter
}
})
mIth.attachToRecyclerView(list)
setupListener()
updateNextAlarmWarningUi()
}
private fun subscribeUi(
binding: FragmentAtAGlanceSettingsBinding,
binding: FragmentGlanceSettingsBinding,
viewModel: MainViewModel
) {
viewModel.showGlance.observe(viewLifecycleOwner, Observer {
binding.isGlanceVisible = it
})
viewModel.showMusic.observe(viewLifecycleOwner, Observer {
checkNotificationPermission()
})
@ -78,22 +152,46 @@ class AtAGlanceTabFragment : Fragment() {
viewModel.showNextAlarm.observe(viewLifecycleOwner, Observer {
updateNextAlarmWarningUi()
})
}
private fun setupListener() {
action_show_glance.setOnClickListener {
Preferences.showGlance = !Preferences.showGlance
}
show_glance_switch.setOnCheckedChangeListener { _, enabled: Boolean ->
Preferences.showGlance = enabled
}
action_show_music.setOnClickListener {
Preferences.showMusic = !Preferences.showMusic
if (Preferences.showGlance) {
BottomSheetMenu<Boolean>(
requireContext(),
header = getString(R.string.settings_show_music_title)
).setSelectedValue(Preferences.showMusic)
.addItem(getString(R.string.settings_visible), true)
.addItem(getString(R.string.settings_not_visible), false)
.addOnSelectItemListener { value ->
Preferences.showMusic = value
}.show()
}
}
action_show_next_alarm.setOnClickListener {
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 ->
Preferences.showNextAlarm = value
}.show()
if (Preferences.showGlance) {
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 ->
Preferences.showNextAlarm = value
}.show()
}
}
}
private fun updateNextAlarmWarningUi() {
@ -106,7 +204,10 @@ class AtAGlanceTabFragment : Fragment() {
} catch (e: Exception) {
alarm.showIntent?.creatorPackage ?: ""
}
show_next_alarm_warning.text = getString(R.string.next_alarm_warning).format(appNameOrPackage)
maintainScrollPosition {
show_next_alarm_warning.text =
getString(R.string.next_alarm_warning).format(appNameOrPackage)
}
} else {
maintainScrollPosition {
show_next_alarm_label?.text = if (Preferences.showNextAlarm) getString(R.string.settings_visible) else getString(

View File

@ -9,6 +9,7 @@ import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.util.DisplayMetrics
import android.util.Log
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
@ -28,8 +29,6 @@ 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
@ -53,6 +52,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
companion object {
fun newInstance() = MainFragment()
private const val PREVIEW_BASE_HEIGHT = 120
}
private lateinit var viewModel: MainViewModel
@ -98,7 +98,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
time_container.isVisible = Preferences.showClock
preview.layoutParams = preview.layoutParams.apply {
height = 160.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(requireContext()) else 0
height = PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(requireContext()) else 0
}
subscribeUi(viewModel)
updateUI()
@ -136,7 +136,6 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
)
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) {
@ -207,7 +206,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
ValueAnimator.ofInt(
preview.height,
160.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
requireContext()
) else 0
).apply {
@ -229,7 +228,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
if (preview.height == 0) {
ValueAnimator.ofInt(
preview.height,
160.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
requireContext()
) else 0
).apply {
@ -243,8 +242,8 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
}.start()
}
widget_loader.animate().scaleX(0f).scaleY(0f).alpha(0f).setDuration(200L).start()
bitmap_container.setImageBitmap(bitmap)
widget_loader.animate().scaleX(0f).scaleY(0f).start()
widget.animate().alpha(1f).start()
}
}
@ -323,6 +322,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
Preferences.preferences.registerOnSharedPreferenceChangeListener(this)
EventBus.getDefault().register(this)
showErrorBadge()
updateUI()
}
override fun onPause() {

View File

@ -14,7 +14,6 @@ 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
@ -24,7 +23,7 @@ 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.databinding.FragmentSettingsBinding
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.activities.SupportDevActivity
@ -35,7 +34,7 @@ import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
import com.tommasoberlose.anotherwidget.ui.activities.IntegrationsActivity
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import com.tommasoberlose.anotherwidget.utils.openURI
import kotlinx.android.synthetic.main.fragment_advanced_settings.*
import kotlinx.android.synthetic.main.fragment_settings.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -60,7 +59,7 @@ class SettingsFragment : Fragment() {
): View {
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
val binding = DataBindingUtil.inflate<FragmentAdvancedSettingsBinding>(inflater, R.layout.fragment_advanced_settings, container, false)
val binding = DataBindingUtil.inflate<FragmentSettingsBinding>(inflater, R.layout.fragment_settings, container, false)
binding.lifecycleOwner = this
binding.viewModel = viewModel

View File

@ -168,6 +168,10 @@ class WeatherTabFragment : Fragment() {
Preferences.showWeather = !Preferences.showWeather
}
show_weather_switch.setOnCheckedChangeListener { _, enabled: Boolean ->
Preferences.showWeather = enabled
}
action_weather_provider_api_key.setOnClickListener {
if (Preferences.showWeather) {
startActivityForResult(

View File

@ -16,6 +16,7 @@ class MainViewModel : ViewModel() {
val textShadow = Preferences.asLiveData(Preferences::textShadow)
val customFont = Preferences.asLiveData(Preferences::customFont)
val secondRowInformation = Preferences.asLiveData(Preferences::secondRowInformation)
val showDividers = Preferences.asLiveData(Preferences::showDividers)
// Calendar Settings
val showEvents = Preferences.asLiveData(Preferences::showEvents)
@ -34,7 +35,6 @@ class MainViewModel : ViewModel() {
val clockTextAlpha = Preferences.asLiveData(Preferences::clockTextAlpha)
val clockAppName = Preferences.asLiveData(Preferences::clockAppName)
val showNextAlarm = Preferences.asLiveData(Preferences::showNextAlarm)
val dateFormat = Preferences.asLiveData(Preferences::dateFormat)
val clockBottomMargin = Preferences.asLiveData(Preferences::clockBottomMargin)
@ -52,9 +52,10 @@ class MainViewModel : ViewModel() {
val showWeatherWarning = Preferences.asLiveData(Preferences::showWeatherWarning)
// Music
// Glance
val showGlance = Preferences.asLiveData(Preferences::showGlance)
val showMusic = Preferences.asLiveData(Preferences::showMusic)
val mediaInfoFormat = Preferences.asLiveData(Preferences::mediaInfoFormat)
val showNextAlarm = Preferences.asLiveData(Preferences::showNextAlarm)
// Advanced Settings
val darkThemePreference = Preferences.asLiveData(Preferences::darkThemePreference)

View File

@ -637,6 +637,11 @@ class MainWidget : AppWidgetProvider() {
v.special_weather.visibility = View.GONE
}
// Dividers
arrayOf(v.divider1, v.divider2, v.divider3).forEach {
it.isVisible = Preferences.showDividers
}
return v
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 867 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 802 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 485 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 649 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 B

Some files were not shown because too many files have changed in this diff Show More