This commit is contained in:
Tommaso Berlose 2020-10-05 14:36:56 +02:00
commit e9c0cdd61c
114 changed files with 1322 additions and 245 deletions

1
.gitignore vendored
View File

@ -8,3 +8,4 @@
.externalNativeBuild .externalNativeBuild
/tasksintegration/build /tasksintegration/build
/app/google-services.json /app/google-services.json
apikey.properties

View File

@ -10,7 +10,12 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'realm-android' apply plugin: 'realm-android'
def apikeyPropertiesFile = rootProject.file("apikey.properties")
def apikeyProperties = new Properties()
apikeyProperties.load(new FileInputStream(apikeyPropertiesFile))
android { android {
compileSdkVersion 29 compileSdkVersion 29
buildToolsVersion "29.0.3" buildToolsVersion "29.0.3"
@ -22,6 +27,7 @@ android {
versionName "2.0.13" versionName "2.0.13"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
buildConfigField("String", "GOOGLE_API_KEY", apikeyProperties['GOOGLE_API_KEY'])
} }
buildTypes { buildTypes {
@ -131,4 +137,7 @@ dependencies {
// Permissions // Permissions
implementation 'com.karumi:dexter:6.1.0' implementation 'com.karumi:dexter:6.1.0'
// Fonts
implementation 'com.github.firatkarababa:downloadable-font-list-library:1.0.2'
} }

View File

@ -32,11 +32,13 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".ui.activities.ChooseApplicationActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" /> <activity android:name=".ui.activities.ChooseApplicationActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
<activity android:name=".ui.activities.CustomFontActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
<activity android:name=".ui.activities.CustomLocationActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" /> <activity android:name=".ui.activities.CustomLocationActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
<activity android:name=".ui.activities.WeatherProviderActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" /> <activity android:name=".ui.activities.WeatherProviderActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
<activity android:name=".ui.activities.SupportDevActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" /> <activity android:name=".ui.activities.SupportDevActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
<activity android:name=".ui.activities.CustomDateActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" /> <activity android:name=".ui.activities.CustomDateActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
<activity android:name=".ui.activities.IntegrationsActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" /> <activity android:name=".ui.activities.IntegrationsActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
<activity android:name=".ui.activities.MusicPlayersFilterActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
<receiver android:name=".ui.widgets.MainWidget"> <receiver android:name=".ui.widgets.MainWidget">

View File

@ -2,6 +2,7 @@ package com.tommasoberlose.anotherwidget.components
import android.content.Context import android.content.Context
import android.view.View import android.view.View
import android.widget.TextView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
@ -9,6 +10,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.R
import kotlinx.android.synthetic.main.bottom_sheet_menu.view.* import kotlinx.android.synthetic.main.bottom_sheet_menu.view.*
import kotlinx.android.synthetic.main.bottom_sheet_menu_item.view.* import kotlinx.android.synthetic.main.bottom_sheet_menu_item.view.*
import org.w3c.dom.Text
/** /**
* [BottomSheetDialogFragment] that uses a custom * [BottomSheetDialogFragment] that uses a custom
@ -32,8 +34,8 @@ open class BottomSheetMenu<T>(context: Context, private val header: String? = nu
return this return this
} }
fun addItem(title: String, value: T? = null): BottomSheetMenu<T> { fun addItem(title: String, value: T? = null, renderCallback: ((view: TextView) -> Unit)? = null): BottomSheetMenu<T> {
items.add(MenuItem(title, value)) items.add(MenuItem(title, value, renderCallback))
return this return this
} }
@ -94,7 +96,10 @@ open class BottomSheetMenu<T>(context: Context, private val header: String? = nu
) else ContextCompat.getColor(context, R.color.colorSecondaryText) ) else ContextCompat.getColor(context, R.color.colorSecondaryText)
) )
} }
item.renderCallback?.invoke(itemView.label)
} }
view.menu.addView(itemView) view.menu.addView(itemView)
} else { } else {
val itemView = View.inflate(context, R.layout.bottom_sheet_menu_divider, null) val itemView = View.inflate(context, R.layout.bottom_sheet_menu_divider, null)
@ -106,6 +111,6 @@ open class BottomSheetMenu<T>(context: Context, private val header: String? = nu
super.show() super.show()
} }
class MenuItem<T>(val title: String, val value: T? = null) class MenuItem<T>(val title: String, val value: T? = null, val renderCallback: ((view: TextView) -> Unit)? = null)
} }

View File

@ -32,10 +32,10 @@ class IconPackSelector(context: Context, private val header: String? = null) : B
itemView.label.text = context.getString(R.string.settings_weather_icon_pack_default).format(item.value + 1) itemView.label.text = context.getString(R.string.settings_weather_icon_pack_default).format(item.value + 1)
itemView.isSelected = item.value == Preferences.weatherIconPack itemView.isSelected = item.value == Preferences.weatherIconPack
itemView.icon_1.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource("01d", item.value))) itemView.icon_1.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "01d", item.value)))
itemView.icon_2.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource("01n", item.value))) itemView.icon_2.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "01n", item.value)))
itemView.icon_3.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource("10d", item.value))) itemView.icon_3.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "10d", item.value)))
itemView.icon_4.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource("09n", item.value))) itemView.icon_4.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "09n", item.value)))
listOf<ImageView>(itemView.icon_1, itemView.icon_2, itemView.icon_3, itemView.icon_4).forEach { listOf<ImageView>(itemView.icon_1, itemView.icon_2, itemView.icon_3, itemView.icon_4).forEach {
if (item == Constants.WeatherIconPack.MINIMAL) { if (item == Constants.WeatherIconPack.MINIMAL) {

View File

@ -8,6 +8,9 @@ object Constants {
const val RESULT_APP_PACKAGE = "RESULT_APP_PACKAGE" const val RESULT_APP_PACKAGE = "RESULT_APP_PACKAGE"
const val CUSTOM_FONT_GOOGLE_SANS = 1 const val CUSTOM_FONT_GOOGLE_SANS = 1
const val CUSTOM_FONT_DOWNLOADED = 2
const val CUSTOM_FONT_DOWNLOAD_NEW = 3
enum class ClockBottomMargin(val value: Int) { enum class ClockBottomMargin(val value: Int) {
NONE(0), NONE(0),
SMALL(1), SMALL(1),

View File

@ -95,7 +95,9 @@ object Preferences : KotprefModel() {
var showOnlyBusyEvents by booleanPref(default = false) var showOnlyBusyEvents by booleanPref(default = false)
var secondRowInformation by intPref(key = "PREF_SECOND_ROW_INFORMATION", default = 0) var secondRowInformation by intPref(key = "PREF_SECOND_ROW_INFORMATION", default = 0)
var customFont by intPref(key = "PREF_CUSTOM_FONT", default = Constants.CUSTOM_FONT_GOOGLE_SANS) var customFont by intPref(key = "PREF_CUSTOM_FONT", default = Constants.CUSTOM_FONT_GOOGLE_SANS)
var customFontFile by stringPref(key = "PREF_CUSTOM_FONT_FILE") var customFontFile by stringPref(default = "")
var customFontName by stringPref(default = "")
var customFontVariant by stringPref(default = "regular")
var showNextEvent by booleanPref(key = "PREF_SHOW_NEXT_EVENT", default = true) var showNextEvent by booleanPref(key = "PREF_SHOW_NEXT_EVENT", default = true)
var showDividers by booleanPref(default = true) var showDividers by booleanPref(default = true)
@ -124,6 +126,7 @@ object Preferences : KotprefModel() {
var mediaPlayerAlbum by stringPref(default = "") var mediaPlayerAlbum by stringPref(default = "")
var mediaPlayerArtist by stringPref(default = "") var mediaPlayerArtist by stringPref(default = "")
var mediaPlayerPackage by stringPref(default = "") var mediaPlayerPackage by stringPref(default = "")
var musicPlayersFilter by stringPref(default = "")
// Integrations // Integrations
var installedIntegrations by intPref(default = 0) var installedIntegrations by intPref(default = 0)

View File

@ -38,6 +38,8 @@ object MediaPlayerHelper {
) )
} catch (ex: Exception) { } catch (ex: Exception) {
emptyList<MediaController>() emptyList<MediaController>()
}.filter {
Preferences.musicPlayersFilter == "" || isMusicPlayerAccepted(it.packageName)
} }
if (list.isNotEmpty()) { if (list.isNotEmpty()) {
@ -89,4 +91,14 @@ object MediaPlayerHelper {
remove(Preferences::mediaPlayerPackage) remove(Preferences::mediaPlayerPackage)
} }
} }
fun isMusicPlayerAccepted(appPkg: String): Boolean = Preferences.musicPlayersFilter.contains(appPkg)
fun toggleMusicPlayerFilter(appPkg: String) {
if (Preferences.musicPlayersFilter == "" || !Preferences.musicPlayersFilter.contains(appPkg)) {
Preferences.musicPlayersFilter = Preferences.musicPlayersFilter.split(",").union(listOf(appPkg)).joinToString(separator = ",")
} else {
Preferences.musicPlayersFilter = Preferences.musicPlayersFilter.split(",").filter { it != appPkg }.joinToString(separator = ",")
}
}
} }

View File

@ -54,14 +54,27 @@ object SettingsStringHelper {
} }
} }
fun getCustomFontLabel(shadow: Int): Int { fun getCustomFontLabel(context: Context, font: Int): String {
return when (shadow) { return when (font) {
0 -> R.string.custom_font_subtitle_0 Constants.CUSTOM_FONT_GOOGLE_SANS -> context.getString(R.string.custom_font_subtitle_1) + " - ${getVariantLabel(context, Preferences.customFontVariant)}"
1 -> R.string.custom_font_subtitle_1 Constants.CUSTOM_FONT_DOWNLOADED -> Preferences.customFontName + " - ${getVariantLabel(context, Preferences.customFontVariant)}"
else -> R.string.custom_font_subtitle_1 else -> context.getString(R.string.custom_font_subtitle_0)
} }
} }
fun getVariantLabel(context: Context, variant: String): String = when {
variant.contains("100") -> context.getString(R.string.font_100)
variant.contains("200") -> context.getString(R.string.font_200)
variant.contains("300") -> context.getString(R.string.font_300)
variant.contains("regular") || variant.contains("400") -> context.getString(R.string.font_400)
variant.contains("500") -> context.getString(R.string.font_500)
variant.contains("600") -> context.getString(R.string.font_600)
variant.contains("700") -> context.getString(R.string.font_700)
variant.contains("800") -> context.getString(R.string.font_800)
variant.contains("900") -> context.getString(R.string.font_900)
else -> context.getString(R.string.font_400)
}
fun getDifferenceText(context: Context, now: Long, start: Long): String { fun getDifferenceText(context: Context, now: Long, start: Long): String {
val nowDate = DateTime(now) val nowDate = DateTime(now)
val eventDate = DateTime(start) val eventDate = DateTime(start)

View File

@ -11,6 +11,7 @@ import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
@ -112,14 +113,14 @@ object WeatherHelper {
else -> true else -> true
} }
fun getWeatherIconResource(icon: String, style: Int = Preferences.weatherIconPack): Int { fun getWeatherIconResource(context: Context, icon: String, style: Int = Preferences.weatherIconPack): Int {
return when (icon) { return when (icon) {
"01d" -> { "01d" -> {
when (style) { when (style) {
Constants.WeatherIconPack.COOL.value -> R.drawable.clear_day_3 Constants.WeatherIconPack.COOL.value -> R.drawable.clear_day_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.clear_day_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.clear_day_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.clear_day_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.clear_day_4
else -> R.drawable.clear_day else -> if (context.isDarkTheme()) R.drawable.clear_day_5 else R.drawable.clear_day_5_light
} }
} }
"02d" -> { "02d" -> {
@ -127,7 +128,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.partly_cloudy_3 Constants.WeatherIconPack.COOL.value -> R.drawable.partly_cloudy_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.partly_cloudy_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.partly_cloudy_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.partly_cloudy_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.partly_cloudy_4
else -> R.drawable.partly_cloudy else -> if (context.isDarkTheme()) R.drawable.partly_cloudy_5 else R.drawable.partly_cloudy_5_light
} }
} }
"03d" -> { "03d" -> {
@ -135,7 +136,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.mostly_cloudy_3 Constants.WeatherIconPack.COOL.value -> R.drawable.mostly_cloudy_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.mostly_cloudy_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.mostly_cloudy_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.mostly_cloudy_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.mostly_cloudy_4
else -> R.drawable.mostly_cloudy else -> if (context.isDarkTheme()) R.drawable.mostly_cloudy_5 else R.drawable.mostly_cloudy_5_light
} }
} }
"04d" -> { "04d" -> {
@ -143,7 +144,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.cloudy_weather_3 Constants.WeatherIconPack.COOL.value -> R.drawable.cloudy_weather_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.cloudy_weather_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.cloudy_weather_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.cloudy_weather_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.cloudy_weather_4
else -> R.drawable.cloudy_weather else -> if (context.isDarkTheme()) R.drawable.cloudy_weather_5 else R.drawable.cloudy_weather_5_light
} }
} }
"09d" -> { "09d" -> {
@ -151,7 +152,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.storm_weather_day_3 Constants.WeatherIconPack.COOL.value -> R.drawable.storm_weather_day_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.storm_weather_day_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.storm_weather_day_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.storm_weather_day_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.storm_weather_day_4
else -> R.drawable.storm_weather_day else -> if (context.isDarkTheme()) R.drawable.storm_weather_day_5 else R.drawable.storm_weather_day_5_light
} }
} }
"10d" -> { "10d" -> {
@ -159,7 +160,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.rainy_day_3 Constants.WeatherIconPack.COOL.value -> R.drawable.rainy_day_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rainy_day_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rainy_day_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rainy_day_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rainy_day_4
else -> R.drawable.rainy_day else -> if (context.isDarkTheme()) R.drawable.rainy_day_5 else R.drawable.rainy_day_5_light
} }
} }
"11d" -> { "11d" -> {
@ -167,7 +168,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.thunder_day_3 Constants.WeatherIconPack.COOL.value -> R.drawable.thunder_day_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.thunder_day_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.thunder_day_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.thunder_day_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.thunder_day_4
else -> R.drawable.thunder_day else -> if (context.isDarkTheme()) R.drawable.thunder_day_5 else R.drawable.thunder_day_5_light
} }
} }
"13d" -> { "13d" -> {
@ -175,7 +176,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.snow_day_3 Constants.WeatherIconPack.COOL.value -> R.drawable.snow_day_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.snow_day_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.snow_day_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.snow_day_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.snow_day_4
else -> R.drawable.snow_day else -> if (context.isDarkTheme()) R.drawable.snow_day_5 else R.drawable.snow_day_5_light
} }
} }
"50d" -> { "50d" -> {
@ -183,7 +184,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.haze_day_3 Constants.WeatherIconPack.COOL.value -> R.drawable.haze_day_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_day_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_day_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_day_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_day_4
else -> R.drawable.haze_day else -> if (context.isDarkTheme()) R.drawable.haze_day_5 else R.drawable.haze_day_5_light
} }
} }
"80d" -> { "80d" -> {
@ -191,7 +192,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.windy_day_3 Constants.WeatherIconPack.COOL.value -> R.drawable.windy_day_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.windy_day_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.windy_day_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.windy_day_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.windy_day_4
else -> R.drawable.windy_day else -> if (context.isDarkTheme()) R.drawable.windy_day_5 else R.drawable.windy_day_5_light
} }
} }
"81d" -> { "81d" -> {
@ -199,7 +200,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.rain_snow_day_3 Constants.WeatherIconPack.COOL.value -> R.drawable.rain_snow_day_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rain_snow_day_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rain_snow_day_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rain_snow_day_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rain_snow_day_4
else -> R.drawable.rain_snow_day else -> if (context.isDarkTheme()) R.drawable.rain_snow_day_5 else R.drawable.rain_snow_day_5_light
} }
} }
"82d" -> { "82d" -> {
@ -207,7 +208,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.haze_weather_3 Constants.WeatherIconPack.COOL.value -> R.drawable.haze_weather_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_weather_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_weather_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_weather_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_weather_4
else -> R.drawable.haze_weather else -> if (context.isDarkTheme()) R.drawable.haze_weather_5 else R.drawable.haze_weather_5_light
} }
} }
@ -218,7 +219,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.clear_night_3 Constants.WeatherIconPack.COOL.value -> R.drawable.clear_night_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.clear_night_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.clear_night_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.clear_night_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.clear_night_4
else -> R.drawable.clear_night else -> if (context.isDarkTheme()) R.drawable.clear_night_5 else R.drawable.clear_night_5_light
} }
} }
"02n" -> { "02n" -> {
@ -226,7 +227,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.partly_cloudy_night_3 Constants.WeatherIconPack.COOL.value -> R.drawable.partly_cloudy_night_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.partly_cloudy_night_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.partly_cloudy_night_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.partly_cloudy_night_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.partly_cloudy_night_4
else -> R.drawable.partly_cloudy_night else -> if (context.isDarkTheme()) R.drawable.partly_cloudy_night_5 else R.drawable.partly_cloudy_night_5_light
} }
} }
"03n" -> { "03n" -> {
@ -234,7 +235,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.mostly_cloudy_night_3 Constants.WeatherIconPack.COOL.value -> R.drawable.mostly_cloudy_night_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.mostly_cloudy_night_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.mostly_cloudy_night_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.mostly_cloudy_night_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.mostly_cloudy_night_4
else -> R.drawable.mostly_cloudy_night else -> if (context.isDarkTheme()) R.drawable.mostly_cloudy_night_5 else R.drawable.mostly_cloudy_night_5_light
} }
} }
"04n" -> { "04n" -> {
@ -242,7 +243,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.cloudy_weather_3 Constants.WeatherIconPack.COOL.value -> R.drawable.cloudy_weather_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.cloudy_weather_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.cloudy_weather_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.cloudy_weather_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.cloudy_weather_4
else -> R.drawable.cloudy_weather else -> if (context.isDarkTheme()) R.drawable.cloudy_weather_5 else R.drawable.cloudy_weather_5_light
} }
} }
"09n" -> { "09n" -> {
@ -250,7 +251,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.storm_weather_night_3 Constants.WeatherIconPack.COOL.value -> R.drawable.storm_weather_night_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.storm_weather_night_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.storm_weather_night_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.storm_weather_night_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.storm_weather_night_4
else -> R.drawable.storm_weather_night else -> if (context.isDarkTheme()) R.drawable.storm_weather_night_5 else R.drawable.storm_weather_night_5_light
} }
} }
"10n" -> { "10n" -> {
@ -258,7 +259,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.rainy_night_3 Constants.WeatherIconPack.COOL.value -> R.drawable.rainy_night_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rainy_night_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rainy_night_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rainy_night_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rainy_night_4
else -> R.drawable.rainy_night else -> if (context.isDarkTheme()) R.drawable.rainy_night_5 else R.drawable.rainy_night_5_light
} }
} }
"11n" -> { "11n" -> {
@ -266,7 +267,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.thunder_night_3 Constants.WeatherIconPack.COOL.value -> R.drawable.thunder_night_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.thunder_night_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.thunder_night_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.thunder_night_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.thunder_night_4
else -> R.drawable.thunder_night else -> if (context.isDarkTheme()) R.drawable.thunder_night_5 else R.drawable.thunder_night_5_light
} }
} }
"13n" -> { "13n" -> {
@ -274,7 +275,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.snow_night_3 Constants.WeatherIconPack.COOL.value -> R.drawable.snow_night_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.snow_night_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.snow_night_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.snow_night_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.snow_night_4
else -> R.drawable.snow_night else -> if (context.isDarkTheme()) R.drawable.snow_night_5 else R.drawable.snow_night_5_light
} }
} }
"50n" -> { "50n" -> {
@ -282,7 +283,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.haze_night_3 Constants.WeatherIconPack.COOL.value -> R.drawable.haze_night_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_night_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_night_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_night_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_night_4
else -> R.drawable.haze_night else -> if (context.isDarkTheme()) R.drawable.haze_night_5 else R.drawable.haze_night_5_light
} }
} }
"80n" -> { "80n" -> {
@ -290,7 +291,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.windy_night_3 Constants.WeatherIconPack.COOL.value -> R.drawable.windy_night_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.windy_night_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.windy_night_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.windy_night_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.windy_night_4
else -> R.drawable.windy_night else -> if (context.isDarkTheme()) R.drawable.windy_night_5 else R.drawable.windy_night_5_light
} }
} }
"81n" -> { "81n" -> {
@ -298,7 +299,7 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.rain_snow_night_3 Constants.WeatherIconPack.COOL.value -> R.drawable.rain_snow_night_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rain_snow_night_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rain_snow_night_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rain_snow_night_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rain_snow_night_4
else -> R.drawable.rain_snow_night else -> if (context.isDarkTheme()) R.drawable.rain_snow_night_5 else R.drawable.rain_snow_night_5_light
} }
} }
"82n" -> { "82n" -> {
@ -306,11 +307,11 @@ object WeatherHelper {
Constants.WeatherIconPack.COOL.value -> R.drawable.haze_weather_3 Constants.WeatherIconPack.COOL.value -> R.drawable.haze_weather_3
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_weather_2 Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_weather_2
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_weather_4 Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_weather_4
else -> R.drawable.haze_weather else -> if (context.isDarkTheme()) R.drawable.haze_weather_5 else R.drawable.haze_weather_5_light
} }
} }
else -> { else -> {
return R.drawable.unknown return if (context.isDarkTheme()) R.drawable.unknown_dark else R.drawable.unknown_light
} }
} }
} }

View File

@ -3,10 +3,20 @@ package com.tommasoberlose.anotherwidget.helpers
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.content.Context import android.content.Context
import android.content.res.Configuration.ORIENTATION_PORTRAIT import android.content.res.Configuration.ORIENTATION_PORTRAIT
import android.graphics.Typeface
import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import android.util.Log import android.util.Log
import androidx.core.provider.FontRequest
import androidx.core.provider.FontsContractCompat
import com.google.firebase.crashlytics.FirebaseCrashlytics import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.db.EventRepository import com.tommasoberlose.anotherwidget.db.EventRepository
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import com.tommasoberlose.anotherwidget.utils.toPixel
import kotlin.math.min
object WidgetHelper { object WidgetHelper {
class WidgetSizeProvider( class WidgetSizeProvider(
@ -44,4 +54,37 @@ object WidgetHelper {
width to second * factor width to second * factor
} }
} }
fun runWithCustomTypeface(context: Context, function: (typeface: Typeface?) -> Unit) {
if (Preferences.customFontFile != "") {
val request = FontRequest(
"com.google.android.gms.fonts",
"com.google.android.gms",
Preferences.customFontFile,
R.array.com_google_android_gms_fonts_certs
)
val callback = object : FontsContractCompat.FontRequestCallback() {
override fun onTypefaceRetrieved(typeface: Typeface) {
function.invoke(typeface)
}
override fun onTypefaceRequestFailed(reason: Int) {
function.invoke(null)
}
}
val handlerThread = HandlerThread("generateView")
handlerThread.start()
if (Looper.myLooper() == null) {
Looper.prepare()
}
Handler(handlerThread.looper).run {
FontsContractCompat.requestFont(context, request, callback, this)
}
} else {
function.invoke(null)
}
}
} }

View File

@ -108,19 +108,19 @@ class UpdateCalendarJob : JobIntentService() {
if (date.get(Calendar.DAY_OF_YEAR) == date1.get(Calendar.DAY_OF_YEAR) && date.get(Calendar.YEAR) == date1.get(Calendar.YEAR)) { if (date.get(Calendar.DAY_OF_YEAR) == date1.get(Calendar.DAY_OF_YEAR) && date.get(Calendar.YEAR) == date1.get(Calendar.YEAR)) {
if (event.allDay && event1.allDay) { if (event.allDay && event1.allDay) {
event1.startDate.compareTo(event.startDate) event.startDate.compareTo(event1.startDate)
} else if (event.allDay) { } else if (event.allDay) {
-1
} else if (event1.allDay) {
1 1
} else if (event1.allDay) {
-1
} else { } else {
event1.startDate.compareTo(event.startDate) event.startDate.compareTo(event1.startDate)
} }
} else { } else {
event1.startDate.compareTo(event.startDate) event.startDate.compareTo(event1.startDate)
} }
}) })
eventList.reverse()
eventRepository.saveEvents( eventRepository.saveEvents(
eventList eventList
) )

View File

@ -0,0 +1,239 @@
package com.tommasoberlose.anotherwidget.ui.activities
import android.app.Activity
import android.content.Intent
import android.graphics.Typeface
import android.os.Bundle
import android.os.Handler
import android.os.HandlerThread
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.provider.FontRequest
import androidx.core.provider.FontsContractCompat
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.blockingBulk
import com.koolio.library.Font
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
import com.tommasoberlose.anotherwidget.databinding.ActivityCustomFontBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.DateHelper
import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper
import com.tommasoberlose.anotherwidget.ui.viewmodels.CustomFontViewModel
import kotlinx.android.synthetic.main.activity_choose_application.*
import kotlinx.coroutines.*
import net.idik.lib.slimadapter.SlimAdapter
import net.idik.lib.slimadapter.diff.DefaultDiffCallback
class CustomFontActivity : AppCompatActivity() {
private lateinit var adapter: SlimAdapter
private lateinit var viewModel: CustomFontViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(CustomFontViewModel::class.java)
val binding = DataBindingUtil.setContentView<ActivityCustomFontBinding>(
this,
R.layout.activity_custom_font
)
list_view.setHasFixedSize(true)
val mLayoutManager = LinearLayoutManager(this)
list_view.layoutManager = mLayoutManager
adapter = SlimAdapter.create()
adapter.enableDiff(object: DefaultDiffCallback() {
override fun areItemsTheSame(oldItem: Any?, newItem: Any?): Boolean {
return oldItem is Font && newItem is Font && oldItem.fontFamily == newItem.fontFamily
}
override fun areContentsTheSame(oldItem: Any?, newItem: Any?): Boolean {
return oldItem is Font && newItem is Font && oldItem.fontFamily == newItem.fontFamily
}
})
adapter
.register<String>(R.layout.list_item) { item, injector ->
injector
.text(R.id.text, item)
.with<TextView>(R.id.text) {
val googleSans: Typeface = when (Preferences.customFontVariant) {
"100" -> Typeface.createFromAsset(this.assets, "fonts/google_sans_thin.ttf")
"200" -> Typeface.createFromAsset(this.assets, "fonts/google_sans_light.ttf")
"500" -> Typeface.createFromAsset(this.assets, "fonts/google_sans_medium.ttf")
"700" -> Typeface.createFromAsset(this.assets, "fonts/google_sans_bold.ttf")
"800" -> Typeface.createFromAsset(this.assets, "fonts/google_sans_black.ttf")
else -> Typeface.createFromAsset(this.assets, "fonts/google_sans_regular.ttf")
}
it.typeface = googleSans
}
injector.clicked(R.id.text) {
val dialog = BottomSheetMenu<String>(this, header = item)
listOf("100", "200", "regular", "500", "700", "800").forEachIndexed { index, s ->
dialog.addItem(SettingsStringHelper.getVariantLabel(this, s), s)
}
dialog.addOnSelectItemListener { value ->
saveGoogleSansFont(value)
}.show()
}
}
.register<Font>(R.layout.list_item) { item, injector ->
injector
.text(R.id.text, item.fontFamily)
.with<TextView>(R.id.text) {
val request = FontRequest(
"com.google.android.gms.fonts",
"com.google.android.gms",
item.queryString,
R.array.com_google_android_gms_fonts_certs
)
val callback = object : FontsContractCompat.FontRequestCallback() {
override fun onTypefaceRetrieved(typeface: Typeface) {
it.typeface = typeface
it.isVisible = true
it.measure(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
override fun onTypefaceRequestFailed(reason: Int) {
it.isVisible = false
it.layoutParams = it.layoutParams.apply {
height = 0
}
}
}
val handlerThread = HandlerThread(item.fontFamily)
handlerThread.start()
val mHandler = Handler(handlerThread.looper)
FontsContractCompat.requestFont(this, request, callback, mHandler)
}
injector.clicked(R.id.text) {
val dialog = BottomSheetMenu<Int>(this, header = item.fontFamily)
if (item.fontVariants.isEmpty()) {
dialog.addItem(SettingsStringHelper.getVariantLabel(this, "regular"), -1)
} else {
item.fontVariants.filter { !it.contains("italic") }
.forEachIndexed { index, s ->
dialog.addItem(SettingsStringHelper.getVariantLabel(this, s), index)
}
}
dialog.addOnSelectItemListener { value ->
saveFont(item, value)
}.show()
}
}
.attachTo(list_view)
setupListener()
subscribeUi(binding, viewModel)
search.requestFocus()
}
private var filterJob: Job? = null
private fun subscribeUi(binding: ActivityCustomFontBinding, viewModel: CustomFontViewModel) {
binding.viewModel = viewModel
viewModel.fontList.observe(this, Observer {
updateList(list = it)
loader.visibility = View.INVISIBLE
})
viewModel.searchInput.observe(this, Observer { search ->
updateList(search = search)
})
}
private fun updateList(
list: ArrayList<Font>? = viewModel.fontList.value,
search: String? = viewModel.searchInput.value
) {
loader.visibility = View.VISIBLE
filterJob?.cancel()
filterJob = lifecycleScope.launch(Dispatchers.IO) {
if (list != null && list.isNotEmpty()) {
delay(200)
val filteredList: List<Any> = if (search == null || search == "") {
listOf(getString(R.string.custom_font_subtitle_1)) + list.distinctBy { it.fontFamily }
} else {
(listOf(getString(R.string.custom_font_subtitle_1)) + list.distinctBy { it.fontFamily }).filter {
when (it) {
is Font -> {
it.fontFamily.contains(search, true)
}
is String -> {
it.contains(search, ignoreCase = true)
}
else -> {
true
}
}
}
}.sortedWith { el1, el2 ->
if (el1 is Font && el2 is Font) {
el1.fontFamily.compareTo(el2.fontFamily)
} else if (el1 is Font && el2 is String) {
el1.fontFamily.compareTo(el2)
} else if (el1 is String && el2 is Font) {
el1.compareTo(el2.fontFamily)
} else {
1
}
}
withContext(Dispatchers.Main) {
adapter.updateData(filteredList)
loader.visibility = View.INVISIBLE
}
}
}
}
private fun setupListener() {
action_back.setOnClickListener {
onBackPressed()
}
}
private fun saveFont(font: Font, variantPos: Int? = null) {
val resultIntent = Intent()
Preferences.blockingBulk {
customFont = Constants.CUSTOM_FONT_DOWNLOADED
customFontName = font.fontFamily
customFontFile = if (variantPos != null && variantPos > -1) font.getQueryString(variantPos) else font.queryString
customFontVariant = if (variantPos != null && variantPos > -1) font.fontVariants[variantPos] else "regular"
}
setResult(Activity.RESULT_OK, resultIntent)
finish()
}
private fun saveGoogleSansFont(variant: String) {
val resultIntent = Intent()
Preferences.blockingBulk {
customFont = Constants.CUSTOM_FONT_GOOGLE_SANS
customFontName = ""
customFontFile = ""
customFontVariant = variant
}
setResult(Activity.RESULT_OK, resultIntent)
finish()
}
}

View File

@ -0,0 +1,141 @@
package com.tommasoberlose.anotherwidget.ui.activities
import android.app.Activity
import android.os.Bundle
import com.tommasoberlose.anotherwidget.R
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.ResolveInfo
import android.util.Log
import android.view.View
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.bumptech.glide.Glide
import com.tommasoberlose.anotherwidget.databinding.ActivityChooseApplicationBinding
import com.tommasoberlose.anotherwidget.databinding.ActivityMusicPlayersFilterBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
import com.tommasoberlose.anotherwidget.ui.viewmodels.ChooseApplicationViewModel
import com.tommasoberlose.anotherwidget.ui.viewmodels.MusicPlayersFilterViewModel
import kotlinx.android.synthetic.main.activity_choose_application.*
import kotlinx.android.synthetic.main.activity_choose_application.list_view
import kotlinx.coroutines.*
import net.idik.lib.slimadapter.SlimAdapter
import kotlin.Comparator as Comparator1
class MusicPlayersFilterActivity : AppCompatActivity() {
private lateinit var adapter: SlimAdapter
private lateinit var viewModel: MusicPlayersFilterViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(MusicPlayersFilterViewModel::class.java)
val binding = DataBindingUtil.setContentView<ActivityMusicPlayersFilterBinding>(this, R.layout.activity_music_players_filter)
list_view.setHasFixedSize(true)
val mLayoutManager = LinearLayoutManager(this)
list_view.layoutManager = mLayoutManager
adapter = SlimAdapter.create()
adapter
.register<ResolveInfo>(R.layout.application_info_layout) { item, injector ->
injector
.text(R.id.text, item.loadLabel(viewModel.pm))
.with<ImageView>(R.id.icon) {
Glide
.with(this)
.load(item.loadIcon(viewModel.pm))
.centerCrop()
.into(it)
}
.visible(R.id.checkBox)
.clicked(R.id.item) {
toggleApp(item)
adapter.notifyItemRangeChanged(0, adapter.data.size)
}
.clicked(R.id.checkBox) {
toggleApp(item)
adapter.notifyItemRangeChanged(0, adapter.data.size)
}
.checked(R.id.checkBox, MediaPlayerHelper.isMusicPlayerAccepted(item.activityInfo.packageName))
}
.attachTo(list_view)
setupListener()
subscribeUi(binding, viewModel)
search.requestFocus()
}
private var filterJob: Job? = null
private fun subscribeUi(binding: ActivityMusicPlayersFilterBinding, viewModel: MusicPlayersFilterViewModel) {
binding.viewModel = viewModel
viewModel.appList.observe(this, Observer {
updateList(list = it)
loader.visibility = View.INVISIBLE
})
viewModel.searchInput.observe(this, Observer { search ->
updateList(search = search)
})
viewModel.musicPlayersFilter.observe(this, {
updateList()
})
}
private fun updateList(list: List<ResolveInfo>? = viewModel.appList.value, search: String? = viewModel.searchInput.value) {
loader.visibility = View.VISIBLE
filterJob?.cancel()
filterJob = lifecycleScope.launch(Dispatchers.IO) {
if (list != null && list.isNotEmpty()) {
delay(200)
val filteredList: List<ResolveInfo> = if (search == null || search == "") {
list
} else {
list.filter {
it.loadLabel(viewModel.pm).contains(search, true)
}
}.sortedWith { app1, app2 ->
if (MediaPlayerHelper.isMusicPlayerAccepted(app1.activityInfo.packageName) && MediaPlayerHelper.isMusicPlayerAccepted(app2.activityInfo.packageName)) {
app1.loadLabel(viewModel.pm).toString().compareTo(app2.loadLabel(viewModel.pm).toString(), ignoreCase = true)
} else if (MediaPlayerHelper.isMusicPlayerAccepted(app1.activityInfo.packageName)) {
-1
} else if (MediaPlayerHelper.isMusicPlayerAccepted(app2.activityInfo.packageName)) {
1
} else {
app1.loadLabel(viewModel.pm).toString().compareTo(app2.loadLabel(viewModel.pm).toString(), ignoreCase = true)
}
}
withContext(Dispatchers.Main) {
adapter.updateData(filteredList)
loader.visibility = View.INVISIBLE
}
}
}
}
private fun setupListener() {
action_back.setOnClickListener {
onBackPressed()
}
}
private fun toggleApp(app: ResolveInfo) {
MediaPlayerHelper.toggleMusicPlayerFilter(app.activityInfo.packageName)
}
}

View File

@ -3,16 +3,24 @@ package com.tommasoberlose.anotherwidget.ui.fragments
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.graphics.Typeface
import android.os.Bundle import android.os.Bundle
import android.os.Handler
import android.os.HandlerThread
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast
import androidx.core.provider.FontRequest
import androidx.core.provider.FontsContractCompat
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.chibatching.kotpref.blockingBulk import com.chibatching.kotpref.blockingBulk
import com.chibatching.kotpref.bulk
import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetColorPicker import com.tommasoberlose.anotherwidget.components.BottomSheetColorPicker
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
@ -25,9 +33,13 @@ import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toHexValue
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue
import com.tommasoberlose.anotherwidget.helpers.DateHelper import com.tommasoberlose.anotherwidget.helpers.DateHelper
import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper
import com.tommasoberlose.anotherwidget.helpers.WidgetHelper
import com.tommasoberlose.anotherwidget.ui.activities.ChooseApplicationActivity
import com.tommasoberlose.anotherwidget.ui.activities.CustomDateActivity import com.tommasoberlose.anotherwidget.ui.activities.CustomDateActivity
import com.tommasoberlose.anotherwidget.ui.activities.CustomFontActivity
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import com.tommasoberlose.anotherwidget.utils.isDarkTheme import com.tommasoberlose.anotherwidget.utils.isDarkTheme
import kotlinx.android.synthetic.main.fragment_clock_settings.* import kotlinx.android.synthetic.main.fragment_clock_settings.*
import kotlinx.android.synthetic.main.fragment_general_settings.* import kotlinx.android.synthetic.main.fragment_general_settings.*
@ -271,7 +283,29 @@ class GeneralTabFragment : Fragment() {
viewModel.customFont.observe(viewLifecycleOwner, Observer { viewModel.customFont.observe(viewLifecycleOwner, Observer {
maintainScrollPosition { maintainScrollPosition {
custom_font_label?.text = getString(SettingsStringHelper.getCustomFontLabel(it)) custom_font_label?.text = SettingsStringHelper.getCustomFontLabel(requireContext(), it)
MainWidget.updateWidget(requireContext())
}
})
viewModel.customFontFile.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
custom_font_label?.text = SettingsStringHelper.getCustomFontLabel(requireContext(), Preferences.customFont)
MainWidget.updateWidget(requireContext())
}
})
viewModel.customFontName.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
custom_font_label?.text = SettingsStringHelper.getCustomFontLabel(requireContext(), Preferences.customFont)
MainWidget.updateWidget(requireContext())
}
})
viewModel.customFontVariant.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
custom_font_label?.text = SettingsStringHelper.getCustomFontLabel(requireContext(), Preferences.customFont)
MainWidget.updateWidget(requireContext())
} }
}) })
@ -454,24 +488,31 @@ class GeneralTabFragment : Fragment() {
action_custom_font.setOnClickListener { action_custom_font.setOnClickListener {
val dialog = BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_custom_font_title)).setSelectedValue(Preferences.customFont) val dialog = BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_custom_font_title)).setSelectedValue(Preferences.customFont)
(0..1).forEach { dialog.addItem(SettingsStringHelper.getCustomFontLabel(requireContext(), 0), 0)
dialog.addItem(getString(SettingsStringHelper.getCustomFontLabel(it)), it)
if (Preferences.customFont == Constants.CUSTOM_FONT_GOOGLE_SANS) {
dialog.addItem(SettingsStringHelper.getCustomFontLabel(requireContext(), Constants.CUSTOM_FONT_GOOGLE_SANS), Constants.CUSTOM_FONT_GOOGLE_SANS)
} }
if (Preferences.customFontFile != "") {
dialog.addItem(SettingsStringHelper.getCustomFontLabel(requireContext(), Preferences.customFont), Constants.CUSTOM_FONT_DOWNLOADED)
}
dialog.addItem(getString(R.string.action_custom_font_to_search), Constants.CUSTOM_FONT_DOWNLOAD_NEW)
dialog.addOnSelectItemListener { value -> dialog.addOnSelectItemListener { value ->
Preferences.customFont = value if (value == Constants.CUSTOM_FONT_DOWNLOAD_NEW) {
}.show() startActivityForResult(
Intent(requireContext(), CustomFontActivity::class.java),
/* RequestCode.CUSTOM_FONT_CHOOSER_REQUEST_CODE.code
val intent = Intent(Intent.ACTION_GET_CONTENT) )
intent.type = "* / *" TO FIX WITHOUT SPACE } else if (value != Constants.CUSTOM_FONT_DOWNLOADED) {
intent.addCategory(Intent.CATEGORY_OPENABLE) Preferences.bulk {
customFont = value
try { customFontFile = ""
startActivityForResult(Intent.createChooser(intent, "Select a File to Upload"), Constants.CUSTOM_FONT_CHOOSER_REQUEST_CODE) customFontName = ""
} catch (ex: android.content.ActivityNotFoundException) { customFontVariant = ""
Toast.makeText(this, "Please install a File Manager.", Toast.LENGTH_SHORT).show()
} }
*/ }
}.show()
} }
action_show_dividers.setOnClickListener { action_show_dividers.setOnClickListener {
@ -483,25 +524,6 @@ class GeneralTabFragment : Fragment() {
} }
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
RequestCode.CUSTOM_FONT_CHOOSER_REQUEST_CODE.code -> {
/*val uri = data.data
Log.d("AW", "File Uri: " + uri.toString())
val path = Util.getPath(this, uri)
Log.d("AW", "File Path: " + path)
SP.edit()
.putString(Constants.PREF_CUSTOM_FONT_FILE, path)
.commit()
sendBroadcast(Intent(Constants.ACTION_TIME_UPDATE))
updateSettings()*/
}
}
}
super.onActivityResult(requestCode, resultCode, data)
}
private fun maintainScrollPosition(callback: () -> Unit) { private fun maintainScrollPosition(callback: () -> Unit) {
scrollView.isScrollable = false scrollView.isScrollable = false
callback.invoke() callback.invoke()

View File

@ -44,6 +44,7 @@ import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver
import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver.Companion.FITNESS_OPTIONS import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver.Companion.FITNESS_OPTIONS
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.activities.MusicPlayersFilterActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import com.tommasoberlose.anotherwidget.utils.checkIfFitInstalled import com.tommasoberlose.anotherwidget.utils.checkIfFitInstalled
@ -136,6 +137,9 @@ class GlanceTabFragment : Fragment() {
} }
}) })
viewModel.musicPlayersFilter.observe(viewLifecycleOwner, Observer {
})
} }
private fun setupListener() { private fun setupListener() {
@ -242,6 +246,10 @@ class GlanceTabFragment : Fragment() {
CustomNotesDialog(requireContext()).show() CustomNotesDialog(requireContext()).show()
} }
} }
action_filter_music_players.setOnClickListener {
startActivity(Intent(requireContext(), MusicPlayersFilterActivity::class.java))
}
} }
private fun updateNextAlarmWarningUi() { private fun updateNextAlarmWarningUi() {

View File

@ -37,6 +37,7 @@ import com.tommasoberlose.anotherwidget.helpers.BitmapHelper
import com.tommasoberlose.anotherwidget.helpers.ColorHelper import com.tommasoberlose.anotherwidget.helpers.ColorHelper
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
import com.tommasoberlose.anotherwidget.helpers.WidgetHelper
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.adapters.ViewPagerAdapter import com.tommasoberlose.anotherwidget.ui.adapters.ViewPagerAdapter
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
@ -148,8 +149,9 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
ColorHelper.getBackgroundColor(activity?.isDarkTheme() == true) ColorHelper.getBackgroundColor(activity?.isDarkTheme() == true)
) )
) )
WidgetHelper.runWithCustomTypeface(requireContext()) { typeface ->
uiJob = lifecycleScope.launch(Dispatchers.IO) { uiJob = lifecycleScope.launch(Dispatchers.IO) {
val generatedView = MainWidget.generateWidgetView(requireContext()) val generatedView = MainWidget.generateWidgetView(requireContext(), typeface)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
generatedView.measure(0, 0) generatedView.measure(0, 0)
@ -268,7 +270,8 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
}.start() }.start()
} }
widget_loader?.animate()?.scaleX(0f)?.scaleY(0f)?.alpha(0f)?.setDuration(200L)?.start() widget_loader?.animate()?.scaleX(0f)?.scaleY(0f)?.alpha(0f)
?.setDuration(200L)?.start()
bitmap_container?.apply { bitmap_container?.apply {
setImageBitmap(bitmap) setImageBitmap(bitmap)
scaleX = 0.9f scaleX = 0.9f
@ -277,6 +280,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
widget?.animate()?.alpha(1f)?.start() widget?.animate()?.alpha(1f)?.start()
} }
} }
}
} else { } else {
if (preview != null) { if (preview != null) {
ValueAnimator.ofInt( ValueAnimator.ofInt(

View File

@ -0,0 +1,40 @@
package com.tommasoberlose.anotherwidget.ui.viewmodels
import android.app.Application
import android.content.Intent
import android.content.pm.ResolveInfo
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.koolio.library.DownloadableFontList
import com.koolio.library.Font
import com.koolio.library.FontList
import com.tommasoberlose.anotherwidget.BuildConfig
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class CustomFontViewModel(application: Application) : AndroidViewModel(application) {
val fontList: MutableLiveData<ArrayList<Font>> = MutableLiveData()
val searchInput: MutableLiveData<String> = MutableLiveData("")
init {
viewModelScope.launch(Dispatchers.IO) {
val fontListCallback: DownloadableFontList.FontListCallback =
object : DownloadableFontList.FontListCallback {
override fun onFontListRetrieved(downloadedList: FontList?) {
fontList.postValue(downloadedList?.fontArrayList)
}
override fun onTypefaceRequestFailed(reason: Int) {
}
}
DownloadableFontList.requestDownloadableFontList(fontListCallback, BuildConfig.GOOGLE_API_KEY)
}
}
}

View File

@ -24,6 +24,9 @@ class MainViewModel : ViewModel() {
val textShadow = Preferences.asLiveData(Preferences::textShadow) val textShadow = Preferences.asLiveData(Preferences::textShadow)
val textShadowDark = Preferences.asLiveData(Preferences::textShadowDark) val textShadowDark = Preferences.asLiveData(Preferences::textShadowDark)
val customFont = Preferences.asLiveData(Preferences::customFont) val customFont = Preferences.asLiveData(Preferences::customFont)
val customFontFile = Preferences.asLiveData(Preferences::customFontFile)
val customFontName = Preferences.asLiveData(Preferences::customFontName)
val customFontVariant = Preferences.asLiveData(Preferences::customFontVariant)
val secondRowInformation = Preferences.asLiveData(Preferences::secondRowInformation) val secondRowInformation = Preferences.asLiveData(Preferences::secondRowInformation)
val showDividers = Preferences.asLiveData(Preferences::showDividers) val showDividers = Preferences.asLiveData(Preferences::showDividers)
val secondRowTopMargin = Preferences.asLiveData(Preferences::secondRowTopMargin) val secondRowTopMargin = Preferences.asLiveData(Preferences::secondRowTopMargin)
@ -78,6 +81,7 @@ class MainViewModel : ViewModel() {
val showBatteryCharging = Preferences.asLiveData(Preferences::showBatteryCharging) val showBatteryCharging = Preferences.asLiveData(Preferences::showBatteryCharging)
val showDailySteps = Preferences.asLiveData(Preferences::showDailySteps) val showDailySteps = Preferences.asLiveData(Preferences::showDailySteps)
val customInfo = Preferences.asLiveData(Preferences::customNotes) val customInfo = Preferences.asLiveData(Preferences::customNotes)
val musicPlayersFilter = Preferences.asLiveData(Preferences::musicPlayersFilter)
// Advanced Settings // Advanced Settings
val darkThemePreference = Preferences.asLiveData(Preferences::darkThemePreference) val darkThemePreference = Preferences.asLiveData(Preferences::darkThemePreference)

View File

@ -0,0 +1,38 @@
package com.tommasoberlose.anotherwidget.ui.viewmodels
import android.app.Application
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.util.Log
import androidx.lifecycle.*
import com.chibatching.kotpref.livedata.asLiveData
import com.tommasoberlose.anotherwidget.global.Preferences
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class MusicPlayersFilterViewModel(application: Application) : AndroidViewModel(application) {
val pm: PackageManager by lazy { application.packageManager }
val appList: MutableLiveData<List<ResolveInfo>> = MutableLiveData()
val searchInput: MutableLiveData<String> = MutableLiveData("")
var musicPlayersFilter = Preferences.asLiveData(Preferences::musicPlayersFilter)
init {
viewModelScope.launch(Dispatchers.IO) {
val mainIntent = Intent(Intent.ACTION_MAIN, null).apply {
addCategory(Intent.CATEGORY_LAUNCHER)
}
val app = application.packageManager.queryIntentActivities(mainIntent, 0)
val sortedApp = app.sortedWith(Comparator { app1: ResolveInfo, app2: ResolveInfo ->
app1.loadLabel(pm).toString().compareTo(app2.loadLabel(pm).toString())
})
withContext(Dispatchers.Main) {
appList.postValue(sortedApp)
}
}
}
}

View File

@ -11,12 +11,18 @@ import android.content.res.Resources
import android.graphics.Color import android.graphics.Color
import android.graphics.Typeface import android.graphics.Typeface
import android.os.Bundle import android.os.Bundle
import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import android.text.format.DateUtils import android.text.format.DateUtils
import android.util.Log import android.util.Log
import android.util.TypedValue import android.util.TypedValue
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.* import android.widget.*
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.provider.FontRequest
import androidx.core.provider.FontsContractCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.db.EventRepository import com.tommasoberlose.anotherwidget.db.EventRepository
@ -90,10 +96,14 @@ class MainWidget : AppWidgetProvider() {
val height = displayMetrics.heightPixels val height = displayMetrics.heightPixels
val dimensions = WidgetHelper.WidgetSizeProvider(context, appWidgetManager).getWidgetsSize(appWidgetId) val dimensions = WidgetHelper.WidgetSizeProvider(context, appWidgetManager).getWidgetsSize(appWidgetId)
generateWidgetView(context, appWidgetId, appWidgetManager, min(dimensions.first - 8.toPixel(context), min(width, height) - 16.toPixel(context)))
WidgetHelper.runWithCustomTypeface(context) {
generateWidgetView(context, appWidgetId, appWidgetManager, min(dimensions.first - 8.toPixel(context), min(width, height) - 16.toPixel(context)), it)
}
} }
private fun generateWidgetView(context: Context, appWidgetId: Int, appWidgetManager: AppWidgetManager, w: Int) { private fun generateWidgetView(context: Context, appWidgetId: Int, appWidgetManager: AppWidgetManager, w: Int, typeface: Typeface? = null) {
var views = RemoteViews(context.packageName, R.layout.the_widget_sans) var views = RemoteViews(context.packageName, R.layout.the_widget_sans)
try { try {
@ -125,7 +135,8 @@ class MainWidget : AppWidgetProvider() {
// Setup listener // Setup listener
try { try {
val generatedView = generateWidgetView(context)
val generatedView = generateWidgetView(context, typeface)
views.setImageViewBitmap( views.setImageViewBitmap(
R.id.bitmap_container, R.id.bitmap_container,
BitmapHelper.getBitmapFromView(generatedView, width = w) BitmapHelper.getBitmapFromView(generatedView, width = w)
@ -492,10 +503,12 @@ class MainWidget : AppWidgetProvider() {
// Generates the widget bitmap from the view // Generates the widget bitmap from the view
fun generateWidgetView(context: Context): View { fun generateWidgetView(context: Context, typeface: Typeface? = null): View {
val eventRepository = EventRepository(context) val eventRepository = EventRepository(context)
val v = View.inflate(context, R.layout.the_widget, null) val v = View.inflate(context, R.layout.the_widget, null)
v.loader.isVisible = false
val now = Calendar.getInstance().apply { val now = Calendar.getInstance().apply {
set(Calendar.SECOND, 0) set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0) set(Calendar.MILLISECOND, 0)
@ -514,8 +527,10 @@ class MainWidget : AppWidgetProvider() {
if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null) { if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null) {
// Multiple counter // Multiple counter
v.action_next.isVisible = Preferences.showNextEvent && eventRepository.getEventsCount() > 1 v.action_next.isVisible =
v.action_previous.isVisible = Preferences.showNextEvent && eventRepository.getEventsCount() > 1 Preferences.showNextEvent && eventRepository.getEventsCount() > 1
v.action_previous.isVisible =
Preferences.showNextEvent && eventRepository.getEventsCount() > 1
v.next_event.text = nextEvent.title v.next_event.text = nextEvent.title
@ -528,7 +543,11 @@ class MainWidget : AppWidgetProvider() {
) )
.toLowerCase(Locale.getDefault()) .toLowerCase(Locale.getDefault())
} else { } else {
SettingsStringHelper.getAllDayEventDifferenceText(context, now.timeInMillis, nextEvent.startDate).toLowerCase(Locale.getDefault()) SettingsStringHelper.getAllDayEventDifferenceText(
context,
now.timeInMillis,
nextEvent.startDate
).toLowerCase(Locale.getDefault())
} }
v.next_event_difference_time.visibility = View.VISIBLE v.next_event_difference_time.visibility = View.VISIBLE
} else { } else {
@ -536,15 +555,30 @@ class MainWidget : AppWidgetProvider() {
} }
if (nextEvent.address != "" && Preferences.secondRowInformation == 1) { if (nextEvent.address != "" && Preferences.secondRowInformation == 1) {
v.second_row_icon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.round_place)) v.second_row_icon.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.round_place
)
)
v.next_event_date.text = nextEvent.address v.next_event_date.text = nextEvent.address
} else { } else {
v.second_row_icon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.round_today)) v.second_row_icon.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.round_today
)
)
if (!nextEvent.allDay) { if (!nextEvent.allDay) {
val startHour = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.getDefault()).format(nextEvent.startDate) val startHour =
val endHour = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.getDefault()).format(nextEvent.endDate) DateFormat.getTimeInstance(DateFormat.SHORT, Locale.getDefault())
.format(nextEvent.startDate)
val endHour =
DateFormat.getTimeInstance(DateFormat.SHORT, Locale.getDefault())
.format(nextEvent.endDate)
var dayDiff = TimeUnit.MILLISECONDS.toDays(nextEvent.endDate - nextEvent.startDate) var dayDiff =
TimeUnit.MILLISECONDS.toDays(nextEvent.endDate - nextEvent.startDate)
val startCal = Calendar.getInstance() val startCal = Calendar.getInstance()
startCal.timeInMillis = nextEvent.startDate startCal.timeInMillis = nextEvent.startDate
@ -554,31 +588,46 @@ class MainWidget : AppWidgetProvider() {
if (startCal.get(Calendar.HOUR_OF_DAY) > endCal.get(Calendar.HOUR_OF_DAY)) { if (startCal.get(Calendar.HOUR_OF_DAY) > endCal.get(Calendar.HOUR_OF_DAY)) {
dayDiff++ dayDiff++
} else if (startCal.get(Calendar.HOUR_OF_DAY) == endCal.get(Calendar.HOUR_OF_DAY) && startCal.get(Calendar.MINUTE) >= endCal.get(Calendar.MINUTE)) { } else if (startCal.get(Calendar.HOUR_OF_DAY) == endCal.get(Calendar.HOUR_OF_DAY) && startCal.get(
Calendar.MINUTE
) >= endCal.get(Calendar.MINUTE)
) {
dayDiff++ dayDiff++
} }
var multipleDay = "" var multipleDay = ""
if (dayDiff > 0) { if (dayDiff > 0) {
multipleDay = String.format(" (+%s%s)", dayDiff, context.getString(R.string.day_char)) multipleDay = String.format(
" (+%s%s)",
dayDiff,
context.getString(R.string.day_char)
)
} }
v.next_event_date.text = String.format("%s - %s%s", startHour, endHour, multipleDay) v.next_event_date.text =
String.format("%s - %s%s", startHour, endHour, multipleDay)
} else { } else {
val flags: Int = DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR or DateUtils.FORMAT_ABBREV_MONTH val flags: Int =
v.next_event_date.text = DateUtils.formatDateTime(context, nextEvent.startDate, flags) DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR or DateUtils.FORMAT_ABBREV_MONTH
v.next_event_date.text =
DateUtils.formatDateTime(context, nextEvent.startDate, flags)
} }
} }
v.empty_layout.visibility = View.GONE v.empty_layout.visibility = View.GONE
v.calendar_layout.visibility = View.VISIBLE v.calendar_layout.visibility = View.VISIBLE
v.second_row_top_margin_small.visibility = if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.SMALL.value) View.VISIBLE else View.GONE v.second_row_top_margin_small.visibility =
v.second_row_top_margin_medium.visibility = if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.MEDIUM.value) View.VISIBLE else View.GONE if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.SMALL.value) View.VISIBLE else View.GONE
v.second_row_top_margin_large.visibility = if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.value) View.VISIBLE else View.GONE v.second_row_top_margin_medium.visibility =
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.MEDIUM.value) View.VISIBLE else View.GONE
v.second_row_top_margin_large.visibility =
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.value) View.VISIBLE else View.GONE
} else if (GlanceProviderHelper.showGlanceProviders(context)) { } else if (GlanceProviderHelper.showGlanceProviders(context)) {
v.second_row_icon.isVisible = true v.second_row_icon.isVisible = true
var showSomething = false var showSomething = false
loop@ for (provider:Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders(context)) { loop@ for (provider: Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders(
context
)) {
when (provider) { when (provider) {
Constants.GlanceProviderId.PLAYING_SONG -> { Constants.GlanceProviderId.PLAYING_SONG -> {
if (MediaPlayerHelper.isSomeonePlaying(context)) { if (MediaPlayerHelper.isSomeonePlaying(context)) {
@ -613,9 +662,13 @@ class MainWidget : AppWidgetProvider() {
v.second_row_icon.isVisible = false v.second_row_icon.isVisible = false
val batteryLevel = BatteryHelper.getBatteryLevel(context) val batteryLevel = BatteryHelper.getBatteryLevel(context)
if (batteryLevel == 100) { if (batteryLevel == 100) {
v.next_event_date.text = "%s - %d%%".format(context.getString(R.string.charging), batteryLevel) v.next_event_date.text = "%s - %d%%".format(
context.getString(R.string.charging),
batteryLevel
)
} else { } else {
v.next_event_date.text = context.getString(R.string.charging) v.next_event_date.text =
context.getString(R.string.charging)
} }
showSomething = true showSomething = true
break@loop break@loop
@ -641,7 +694,9 @@ class MainWidget : AppWidgetProvider() {
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> { Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
if (Preferences.showDailySteps && Preferences.googleFitSteps > 0) { if (Preferences.showDailySteps && Preferences.googleFitSteps > 0) {
v.second_row_icon.isVisible = false v.second_row_icon.isVisible = false
v.next_event_date.text = context.getString(R.string.daily_steps_counter).format(Preferences.googleFitSteps) v.next_event_date.text =
context.getString(R.string.daily_steps_counter)
.format(Preferences.googleFitSteps)
showSomething = true showSomething = true
break@loop break@loop
} }
@ -654,9 +709,12 @@ class MainWidget : AppWidgetProvider() {
v.empty_layout.visibility = View.GONE v.empty_layout.visibility = View.GONE
v.calendar_layout.visibility = View.VISIBLE v.calendar_layout.visibility = View.VISIBLE
v.second_row_top_margin_small.visibility = if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.SMALL.value) View.VISIBLE else View.GONE v.second_row_top_margin_small.visibility =
v.second_row_top_margin_medium.visibility = if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.MEDIUM.value) View.VISIBLE else View.GONE if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.SMALL.value) View.VISIBLE else View.GONE
v.second_row_top_margin_large.visibility = if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.value) View.VISIBLE else View.GONE v.second_row_top_margin_medium.visibility =
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.MEDIUM.value) View.VISIBLE else View.GONE
v.second_row_top_margin_large.visibility =
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.value) View.VISIBLE else View.GONE
} else { } else {
v.second_row_icon.isVisible = false v.second_row_icon.isVisible = false
} }
@ -664,17 +722,33 @@ class MainWidget : AppWidgetProvider() {
// Color // Color
listOf<TextView>(v.empty_date, v.divider1, v.temp, v.next_event, v.next_event_difference_time, v.divider3, v.special_temp).forEach { listOf<TextView>(
v.empty_date,
v.divider1,
v.temp,
v.next_event,
v.next_event_difference_time,
v.divider3,
v.special_temp
).forEach {
it.setTextColor(ColorHelper.getFontColor(context.applicationContext.isDarkTheme())) it.setTextColor(ColorHelper.getFontColor(context.applicationContext.isDarkTheme()))
} }
if (Preferences.weatherIconPack != Constants.WeatherIconPack.MINIMAL.value) { if (Preferences.weatherIconPack != Constants.WeatherIconPack.MINIMAL.value) {
listOf<ImageView>(v.action_next, v.action_previous) listOf<ImageView>(v.action_next, v.action_previous)
} else { } else {
listOf<ImageView>(v.action_next, v.action_previous, v.empty_weather_icon, v.special_weather_icon) listOf<ImageView>(
v.action_next,
v.action_previous,
v.empty_weather_icon,
v.special_weather_icon
)
}.forEach { }.forEach {
it.setColorFilter(ColorHelper.getFontColorRgb(context.applicationContext.isDarkTheme())) it.setColorFilter(ColorHelper.getFontColorRgb(context.applicationContext.isDarkTheme()))
it.alpha = (if (context.isDarkTheme()) Preferences.textGlobalAlphaDark.toIntValue().toFloat() else Preferences.textGlobalAlpha.toIntValue().toFloat()) / 100 it.alpha =
(if (context.isDarkTheme()) Preferences.textGlobalAlphaDark.toIntValue()
.toFloat() else Preferences.textGlobalAlpha.toIntValue()
.toFloat()) / 100
} }
listOf<TextView>(v.next_event_date, v.divider2, v.calendar_temp).forEach { listOf<TextView>(v.next_event_date, v.divider2, v.calendar_temp).forEach {
@ -687,7 +761,10 @@ class MainWidget : AppWidgetProvider() {
listOf<ImageView>(v.second_row_icon, v.weather_icon) listOf<ImageView>(v.second_row_icon, v.weather_icon)
}.forEach { }.forEach {
it.setColorFilter(ColorHelper.getSecondaryFontColorRgb(context.applicationContext.isDarkTheme())) it.setColorFilter(ColorHelper.getSecondaryFontColorRgb(context.applicationContext.isDarkTheme()))
it.alpha = (if (context.isDarkTheme()) Preferences.textSecondaryAlphaDark.toIntValue().toFloat() else Preferences.textSecondaryAlpha.toIntValue().toFloat()) / 100 it.alpha =
(if (context.isDarkTheme()) Preferences.textSecondaryAlphaDark.toIntValue()
.toFloat() else Preferences.textSecondaryAlpha.toIntValue()
.toFloat()) / 100
} }
// Text Size // Text Size
@ -727,35 +804,83 @@ class MainWidget : AppWidgetProvider() {
// Shadows // Shadows
val shadowRadius = when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) { val shadowRadius =
when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) {
0 -> 0f 0 -> 0f
1 -> 5f 1 -> 5f
2 -> 5f 2 -> 5f
else -> 5f else -> 5f
} }
val shadowColor = when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) { val shadowColor =
when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) {
0 -> Color.TRANSPARENT 0 -> Color.TRANSPARENT
1 -> R.color.black_50 1 -> R.color.black_50
2 -> Color.BLACK 2 -> Color.BLACK
else -> R.color.black_50 else -> R.color.black_50
} }
val shadowDy = when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) { val shadowDy =
when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) {
0 -> 0f 0 -> 0f
1 -> 0f 1 -> 0f
2 -> 1f 2 -> 1f
else -> 0f else -> 0f
} }
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, v.divider3, v.special_temp).forEach { 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,
v.divider3,
v.special_temp
).forEach {
it.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor) it.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
} }
// Custom Font // Custom Font
if (Preferences.customFont == Constants.CUSTOM_FONT_GOOGLE_SANS) { if (Preferences.customFont == Constants.CUSTOM_FONT_GOOGLE_SANS) {
val googleSans: Typeface = Typeface.createFromAsset(context.assets, "fonts/google_sans_regular.ttf") val googleSans: Typeface = when (Preferences.customFontVariant) {
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, v.divider3, v.special_temp).forEach { "100" -> Typeface.createFromAsset(context.assets, "fonts/google_sans_thin.ttf")
"200" -> Typeface.createFromAsset(context.assets, "fonts/google_sans_light.ttf")
"500" -> Typeface.createFromAsset(context.assets, "fonts/google_sans_medium.ttf")
"700" -> Typeface.createFromAsset(context.assets, "fonts/google_sans_bold.ttf")
"800" -> Typeface.createFromAsset(context.assets, "fonts/google_sans_black.ttf")
else -> Typeface.createFromAsset(context.assets, "fonts/google_sans_regular.ttf")
}
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,
v.divider3,
v.special_temp
).forEach {
it.typeface = googleSans it.typeface = googleSans
} }
} else if (Preferences.customFont == Constants.CUSTOM_FONT_DOWNLOADED && typeface != null) {
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,
v.divider3,
v.special_temp
).forEach {
it.typeface = typeface
}
} }
// Weather // Weather
@ -763,7 +888,12 @@ class MainWidget : AppWidgetProvider() {
v.weather.visibility = View.VISIBLE v.weather.visibility = View.VISIBLE
v.calendar_weather.visibility = View.VISIBLE v.calendar_weather.visibility = View.VISIBLE
v.special_weather.visibility = View.VISIBLE v.special_weather.visibility = View.VISIBLE
val currentTemp = String.format(Locale.getDefault(), "%d °%s", Preferences.weatherTemp.roundToInt(), Preferences.weatherRealTempUnit) val currentTemp = String.format(
Locale.getDefault(),
"%d °%s",
Preferences.weatherTemp.roundToInt(),
Preferences.weatherRealTempUnit
)
val icon: String = Preferences.weatherIcon val icon: String = Preferences.weatherIcon
if (icon == "") { if (icon == "") {
@ -771,9 +901,9 @@ class MainWidget : AppWidgetProvider() {
v.empty_weather_icon.visibility = View.GONE v.empty_weather_icon.visibility = View.GONE
v.special_weather_icon.visibility = View.GONE v.special_weather_icon.visibility = View.GONE
} else { } else {
v.weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(icon)) v.weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon))
v.empty_weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(icon)) v.empty_weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon))
v.special_weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(icon)) v.special_weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon))
v.weather_icon.visibility = View.VISIBLE v.weather_icon.visibility = View.VISIBLE
v.empty_weather_icon.visibility = View.VISIBLE v.empty_weather_icon.visibility = View.VISIBLE
v.special_weather_icon.visibility = View.VISIBLE v.special_weather_icon.visibility = View.VISIBLE

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 493 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 493 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 869 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M3.24,6.15C2.51,6.43 2,7.17 2,8v12c0,1.1 0.9,2 2,2h16c1.11,0 2,-0.9 2,-2L22,8c0,-1.1 -0.9,-2 -2,-2L8.3,6l7.43,-3c0.46,-0.19 0.68,-0.71 0.49,-1.17 -0.19,-0.46 -0.71,-0.68 -1.17,-0.49L3.24,6.15zM7,20c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM20,12h-2v-1c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v1L4,12L4,9c0,-0.55 0.45,-1 1,-1h14c0.55,0 1,0.45 1,1v3z"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

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