Compare commits
40 Commits
v2.2.2-bet
...
v2.3.2
Author | SHA1 | Date | |
---|---|---|---|
1ac53e09a8 | |||
3412e044df | |||
80023da430 | |||
e2a2d17506 | |||
b93443b736 | |||
9842ba3ea9 | |||
75aba66987 | |||
f325af26f8 | |||
b61fbd193c | |||
03d9446369 | |||
23f94e63c6 | |||
01775d3a3a | |||
67abd14bb1 | |||
854cfac28c | |||
8fafe591e8 | |||
a85fefe4dc | |||
974185a89b | |||
bbe1497f8b | |||
1f22426dec | |||
40644f3657 | |||
a01c8eff63 | |||
1ee25bcc89 | |||
1bd18ac486 | |||
d24ac198a4 | |||
81578f5f4a | |||
8234a87a2a | |||
0774c6bdbe | |||
57eecd630d | |||
cce86a970c | |||
6ea40a51fe | |||
1721dff3cf | |||
c389d50b09 | |||
0ea55db4b1 | |||
3fba50fd2c | |||
06583197c7 | |||
5176331e84 | |||
65f83caeb5 | |||
60e8c267bf | |||
10a3204808 | |||
98c509ef27 |
BIN
.idea/caches/build_file_checksums.ser
generated
2
.idea/misc.xml
generated
@ -61,7 +61,7 @@
|
|||||||
</profile-state>
|
</profile-state>
|
||||||
</entry>
|
</entry>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
1
.idea/runConfigurations.xml
generated
@ -3,6 +3,7 @@
|
|||||||
<component name="RunConfigurationProducerService">
|
<component name="RunConfigurationProducerService">
|
||||||
<option name="ignoredProducers">
|
<option name="ignoredProducers">
|
||||||
<set>
|
<set>
|
||||||
|
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
||||||
|
@ -22,8 +22,8 @@ android {
|
|||||||
applicationId "com.tommasoberlose.anotherwidget"
|
applicationId "com.tommasoberlose.anotherwidget"
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 121
|
versionCode 135
|
||||||
versionName "2.2.2"
|
versionName "2.3.1"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
buildConfigField("String", "GOOGLE_API_KEY", apikeyProperties['GOOGLE_API_KEY'])
|
buildConfigField("String", "GOOGLE_API_KEY", apikeyProperties['GOOGLE_API_KEY'])
|
||||||
@ -65,14 +65,14 @@ dependencies {
|
|||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
testImplementation 'junit:junit:4.13.1'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||||
|
|
||||||
// UI
|
// UI
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||||
implementation 'com.google.android.material:material:1.3.0-beta01'
|
implementation 'com.google.android.material:material:1.3.0'
|
||||||
implementation 'androidx.browser:browser:1.3.0'
|
implementation 'androidx.browser:browser:1.3.0'
|
||||||
implementation 'net.idik:slimadapter:2.1.2'
|
implementation 'net.idik:slimadapter:2.1.2'
|
||||||
implementation 'com.google.android:flexbox:2.0.1'
|
implementation 'com.google.android:flexbox:2.0.1'
|
||||||
@ -80,17 +80,17 @@ dependencies {
|
|||||||
|
|
||||||
// Lifecycle
|
// Lifecycle
|
||||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
|
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
|
||||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||||
|
|
||||||
implementation "androidx.work:work-runtime-ktx:2.4.0"
|
implementation "androidx.work:work-runtime-ktx:2.5.0"
|
||||||
|
|
||||||
// EventBus
|
// EventBus
|
||||||
implementation 'org.greenrobot:eventbus:3.2.0'
|
implementation 'org.greenrobot:eventbus:3.2.0'
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.2'
|
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
|
||||||
implementation 'androidx.navigation:navigation-ui-ktx:2.3.2'
|
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
implementation 'androidx.multidex:multidex:2.0.1'
|
implementation 'androidx.multidex:multidex:2.0.1'
|
||||||
@ -99,24 +99,24 @@ dependencies {
|
|||||||
implementation 'com.github.warkiz.widget:indicatorseekbar:2.1.2'
|
implementation 'com.github.warkiz.widget:indicatorseekbar:2.1.2'
|
||||||
|
|
||||||
//Glide
|
//Glide
|
||||||
implementation 'com.github.bumptech.glide:glide:4.11.0'
|
implementation 'com.github.bumptech.glide:glide:4.12.0'
|
||||||
kapt 'com.github.bumptech.glide:compiler:4.11.0'
|
kapt 'com.github.bumptech.glide:compiler:4.11.0'
|
||||||
|
|
||||||
// Fitness
|
// Fitness
|
||||||
implementation 'com.google.android.gms:play-services-fitness:20.0.0'
|
implementation 'com.google.android.gms:play-services-fitness:20.0.0'
|
||||||
implementation 'com.google.android.gms:play-services-auth:18.1.0'
|
implementation 'com.google.android.gms:play-services-auth:19.0.0'
|
||||||
|
|
||||||
//Weather
|
//Weather
|
||||||
implementation 'com.github.KwabenBerko:OpenWeatherMap-Android-Library:2.0.2'
|
implementation 'com.github.KwabenBerko:OpenWeatherMap-Android-Library:2.0.2'
|
||||||
implementation 'com.google.android.gms:play-services-location:17.1.0'
|
implementation 'com.google.android.gms:play-services-location:18.0.0'
|
||||||
|
|
||||||
// Billing
|
// Billing
|
||||||
implementation 'com.android.billingclient:billing:3.0.2'
|
implementation 'com.android.billingclient:billing:3.0.3'
|
||||||
implementation 'com.android.billingclient:billing-ktx:3.0.2'
|
implementation 'com.android.billingclient:billing-ktx:3.0.3'
|
||||||
|
|
||||||
// KTX
|
// KTX
|
||||||
implementation "androidx.core:core-ktx:1.3.2"
|
implementation "androidx.core:core-ktx:1.3.2"
|
||||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
|
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
|
||||||
implementation "androidx.palette:palette-ktx:1.0.0"
|
implementation "androidx.palette:palette-ktx:1.0.0"
|
||||||
implementation 'androidx.core:core-ktx:1.3.2'
|
implementation 'androidx.core:core-ktx:1.3.2'
|
||||||
|
|
||||||
@ -128,14 +128,14 @@ dependencies {
|
|||||||
implementation "com.github.haroldadmin:NetworkResponseAdapter:4.0.1"
|
implementation "com.github.haroldadmin:NetworkResponseAdapter:4.0.1"
|
||||||
|
|
||||||
//Coroutines
|
//Coroutines
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
|
||||||
|
|
||||||
// Add the Firebase SDK for Crashlytics.
|
// Add the Firebase SDK for Crashlytics.
|
||||||
implementation 'com.google.firebase:firebase-crashlytics:17.3.0'
|
implementation 'com.google.firebase:firebase-crashlytics:17.4.1'
|
||||||
|
|
||||||
// Preferences
|
// Preferences
|
||||||
implementation 'com.chibatching.kotpref:kotpref:2.11.0'
|
implementation 'com.chibatching.kotpref:kotpref:2.13.1'
|
||||||
implementation 'com.chibatching.kotpref:livedata-support:2.10.0'
|
implementation 'com.chibatching.kotpref:livedata-support:2.13.1'
|
||||||
implementation 'androidx.preference:preference-ktx:1.1.1'
|
implementation 'androidx.preference:preference-ktx:1.1.1'
|
||||||
|
|
||||||
// Permissions
|
// Permissions
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
<activity android:name=".ui.activities.tabs.MusicPlayersFilterActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
<activity android:name=".ui.activities.tabs.MusicPlayersFilterActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
||||||
<activity android:name=".ui.activities.tabs.AppNotificationsFilterActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
<activity android:name=".ui.activities.tabs.AppNotificationsFilterActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
||||||
<activity android:name=".ui.activities.tabs.MediaInfoFormatActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
<activity android:name=".ui.activities.tabs.MediaInfoFormatActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
||||||
|
<activity android:name=".ui.activities.tabs.TimeZoneSelectorActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
||||||
|
|
||||||
<receiver android:name=".ui.widgets.MainWidget">
|
<receiver android:name=".ui.widgets.MainWidget">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
@ -8,9 +8,7 @@ import android.content.Intent
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.navigation.Navigation
|
|
||||||
import com.google.android.gms.auth.api.signin.GoogleSignIn
|
import com.google.android.gms.auth.api.signin.GoogleSignIn
|
||||||
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
|
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
|
||||||
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
|
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
|
||||||
@ -119,7 +117,7 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
|
|||||||
binding.actionChangeNotificationTimer.setOnClickListener {
|
binding.actionChangeNotificationTimer.setOnClickListener {
|
||||||
val dialog = BottomSheetMenu<Int>(context, header = context.getString(R.string.glance_notification_hide_timeout_title)).setSelectedValue(Preferences.hideNotificationAfter)
|
val dialog = BottomSheetMenu<Int>(context, header = context.getString(R.string.glance_notification_hide_timeout_title)).setSelectedValue(Preferences.hideNotificationAfter)
|
||||||
Constants.GlanceNotificationTimer.values().forEachIndexed { index, timeout ->
|
Constants.GlanceNotificationTimer.values().forEachIndexed { index, timeout ->
|
||||||
dialog.addItem(stringArray[index], timeout.value)
|
dialog.addItem(stringArray[index], timeout.rawValue)
|
||||||
}
|
}
|
||||||
dialog.addOnSelectItemListener { value ->
|
dialog.addOnSelectItemListener { value ->
|
||||||
Preferences.hideNotificationAfter = value
|
Preferences.hideNotificationAfter = value
|
||||||
|
@ -2,7 +2,6 @@ package com.tommasoberlose.anotherwidget.components
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
@ -28,13 +27,13 @@ class IconPackSelector(context: Context, private val header: String? = null) : B
|
|||||||
// Menu
|
// Menu
|
||||||
for (item in Constants.WeatherIconPack.values()) {
|
for (item in Constants.WeatherIconPack.values()) {
|
||||||
val itemBinding = IconPackMenuItemBinding.inflate(LayoutInflater.from(context))
|
val itemBinding = IconPackMenuItemBinding.inflate(LayoutInflater.from(context))
|
||||||
itemBinding.label.text = context.getString(R.string.settings_weather_icon_pack_default).format(item.value + 1)
|
itemBinding.label.text = context.getString(R.string.settings_weather_icon_pack_default).format(item.rawValue + 1)
|
||||||
itemBinding.root.isSelected = item.value == Preferences.weatherIconPack
|
itemBinding.root.isSelected = item.rawValue == Preferences.weatherIconPack
|
||||||
|
|
||||||
itemBinding.icon1.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "01d", item.value)))
|
itemBinding.icon1.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "01d", item.rawValue)))
|
||||||
itemBinding.icon2.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "01n", item.value)))
|
itemBinding.icon2.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "01n", item.rawValue)))
|
||||||
itemBinding.icon3.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "10d", item.value)))
|
itemBinding.icon3.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "10d", item.rawValue)))
|
||||||
itemBinding.icon4.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "09n", item.value)))
|
itemBinding.icon4.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "09n", item.rawValue)))
|
||||||
|
|
||||||
listOf<ImageView>(itemBinding.icon1, itemBinding.icon2, itemBinding.icon3, itemBinding.icon4).forEach {
|
listOf<ImageView>(itemBinding.icon1, itemBinding.icon2, itemBinding.icon3, itemBinding.icon4).forEach {
|
||||||
if (item == Constants.WeatherIconPack.MINIMAL) {
|
if (item == Constants.WeatherIconPack.MINIMAL) {
|
||||||
@ -45,7 +44,7 @@ class IconPackSelector(context: Context, private val header: String? = null) : B
|
|||||||
}
|
}
|
||||||
|
|
||||||
itemBinding.root.setOnClickListener {
|
itemBinding.root.setOnClickListener {
|
||||||
Preferences.weatherIconPack = item.value
|
Preferences.weatherIconPack = item.rawValue
|
||||||
this.dismiss()
|
this.dismiss()
|
||||||
}
|
}
|
||||||
binding.menu.addView(itemBinding.root)
|
binding.menu.addView(itemBinding.root)
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.components
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
|
||||||
|
class OnSingleClickListener : View.OnClickListener {
|
||||||
|
|
||||||
|
private val onClickListener: View.OnClickListener
|
||||||
|
|
||||||
|
constructor(listener: View.OnClickListener) {
|
||||||
|
onClickListener = listener
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(listener: (View) -> Unit) {
|
||||||
|
onClickListener = View.OnClickListener { listener.invoke(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(v: View) {
|
||||||
|
val currentTimeMillis = System.currentTimeMillis()
|
||||||
|
|
||||||
|
if (currentTimeMillis >= previousClickTimeMillis + DELAY_MILLIS) {
|
||||||
|
previousClickTimeMillis = currentTimeMillis
|
||||||
|
onClickListener.onClick(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val DELAY_MILLIS = 200L
|
||||||
|
private var previousClickTimeMillis = 0L
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,7 +2,6 @@ package com.tommasoberlose.anotherwidget.global
|
|||||||
|
|
||||||
object Actions {
|
object Actions {
|
||||||
const val ACTION_EXTRA_OPEN_WEATHER_PROVIDER = "ACTION_EXTRA_OPEN_WEATHER_PROVIDER"
|
const val ACTION_EXTRA_OPEN_WEATHER_PROVIDER = "ACTION_EXTRA_OPEN_WEATHER_PROVIDER"
|
||||||
const val ACTION_EXTRA_DISABLE_GPS_NOTIFICATION = "ACTION_EXTRA_DISABLE_GPS_NOTIFICATION"
|
|
||||||
|
|
||||||
const val ACTION_TIME_UPDATE = "com.tommasoberlose.anotherwidget.action.TIME_UPDATE"
|
const val ACTION_TIME_UPDATE = "com.tommasoberlose.anotherwidget.action.TIME_UPDATE"
|
||||||
const val ACTION_ALARM_UPDATE = "com.tommasoberlose.anotherwidget.action.ALARM_UPDATE"
|
const val ACTION_ALARM_UPDATE = "com.tommasoberlose.anotherwidget.action.ALARM_UPDATE"
|
||||||
@ -14,4 +13,6 @@ object Actions {
|
|||||||
const val ACTION_REPORT_CRASH = "com.tommasoberlose.anotherwidget.action.REPORT_CRASH"
|
const val ACTION_REPORT_CRASH = "com.tommasoberlose.anotherwidget.action.REPORT_CRASH"
|
||||||
const val ACTION_CLEAR_NOTIFICATION = "com.tommasoberlose.anotherwidget.action.CLEAR_NOTIFICATION"
|
const val ACTION_CLEAR_NOTIFICATION = "com.tommasoberlose.anotherwidget.action.CLEAR_NOTIFICATION"
|
||||||
const val ACTION_UPDATE_GREETINGS = "com.tommasoberlose.anotherwidget.action.UPDATE_GREETINGS"
|
const val ACTION_UPDATE_GREETINGS = "com.tommasoberlose.anotherwidget.action.UPDATE_GREETINGS"
|
||||||
|
|
||||||
|
const val ACTION_REFRESH = "com.tommasoberlose.anotherwidget.action.REFRESH"
|
||||||
}
|
}
|
@ -1,7 +1,5 @@
|
|||||||
package com.tommasoberlose.anotherwidget.global
|
package com.tommasoberlose.anotherwidget.global
|
||||||
|
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
|
|
||||||
object Constants {
|
object Constants {
|
||||||
const val RESULT_CODE_CUSTOM_LOCATION = 45
|
const val RESULT_CODE_CUSTOM_LOCATION = 45
|
||||||
const val RESULT_APP_NAME = "RESULT_APP_NAME"
|
const val RESULT_APP_NAME = "RESULT_APP_NAME"
|
||||||
@ -11,14 +9,14 @@ object Constants {
|
|||||||
const val CUSTOM_FONT_DOWNLOADED = 2
|
const val CUSTOM_FONT_DOWNLOADED = 2
|
||||||
const val CUSTOM_FONT_DOWNLOAD_NEW = 3
|
const val CUSTOM_FONT_DOWNLOAD_NEW = 3
|
||||||
|
|
||||||
enum class ClockBottomMargin(val value: Int) {
|
enum class ClockBottomMargin(val rawValue: Int) {
|
||||||
NONE(0),
|
NONE(0),
|
||||||
SMALL(1),
|
SMALL(1),
|
||||||
MEDIUM(2),
|
MEDIUM(2),
|
||||||
LARGE(3)
|
LARGE(3)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class SecondRowTopMargin(val value: Int) {
|
enum class SecondRowTopMargin(val rawValue: Int) {
|
||||||
NONE(0),
|
NONE(0),
|
||||||
SMALL(1),
|
SMALL(1),
|
||||||
MEDIUM(2),
|
MEDIUM(2),
|
||||||
@ -41,13 +39,13 @@ object Constants {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class WidgetUpdateFrequency(val value: Int) {
|
enum class WidgetUpdateFrequency(val rawValue: Int) {
|
||||||
LOW(0),
|
LOW(0),
|
||||||
DEFAULT(1),
|
DEFAULT(1),
|
||||||
HIGH(2)
|
HIGH(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class WeatherProvider(val value: Int) {
|
enum class WeatherProvider(val rawValue: Int) {
|
||||||
OPEN_WEATHER(0),
|
OPEN_WEATHER(0),
|
||||||
WEATHER_BIT(1),
|
WEATHER_BIT(1),
|
||||||
WEATHER_API(2),
|
WEATHER_API(2),
|
||||||
@ -57,12 +55,12 @@ object Constants {
|
|||||||
YR(6);
|
YR(6);
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val map = WeatherProvider.values().associateBy(WeatherProvider::value)
|
private val map = WeatherProvider.values().associateBy(WeatherProvider::rawValue)
|
||||||
fun fromInt(type: Int) = map[type]
|
fun fromInt(type: Int) = map[type]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class GlanceNotificationTimer(val value: Int) {
|
enum class GlanceNotificationTimer(val rawValue: Int) {
|
||||||
HALF_MINUTE(0),
|
HALF_MINUTE(0),
|
||||||
ONE_MINUTE(1),
|
ONE_MINUTE(1),
|
||||||
FIVE_MINUTES(2),
|
FIVE_MINUTES(2),
|
||||||
@ -71,15 +69,21 @@ object Constants {
|
|||||||
WHEN_DISMISSED(5);
|
WHEN_DISMISSED(5);
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val map = values().associateBy(GlanceNotificationTimer::value)
|
private val map = values().associateBy(GlanceNotificationTimer::rawValue)
|
||||||
fun fromInt(type: Int) = map[type]
|
fun fromInt(type: Int) = map[type]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class WeatherIconPack(val value: Int) {
|
enum class WeatherIconPack(val rawValue: Int) {
|
||||||
DEFAULT(0),
|
DEFAULT(0),
|
||||||
MINIMAL(1),
|
MINIMAL(1),
|
||||||
COOL(2),
|
COOL(2),
|
||||||
GOOGLE_NEWS(3)
|
GOOGLE_NEWS(3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class WidgetAlign(val rawValue: Int) {
|
||||||
|
LEFT(0),
|
||||||
|
RIGHT(1),
|
||||||
|
CENTER(2)
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,13 +1,11 @@
|
|||||||
package com.tommasoberlose.anotherwidget.global
|
package com.tommasoberlose.anotherwidget.global
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import androidx.appcompat.app.AppCompatDelegate.*
|
import androidx.appcompat.app.AppCompatDelegate.*
|
||||||
import androidx.core.os.ConfigurationCompat
|
import androidx.core.os.ConfigurationCompat
|
||||||
import com.chibatching.kotpref.KotprefModel
|
import com.chibatching.kotpref.KotprefModel
|
||||||
import com.tommasoberlose.anotherwidget.helpers.IntentHelper
|
import com.tommasoberlose.anotherwidget.helpers.IntentHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
||||||
import com.tommasoberlose.anotherwidget.utils.isMetric
|
import com.tommasoberlose.anotherwidget.utils.isMetric
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
object Preferences : KotprefModel() {
|
object Preferences : KotprefModel() {
|
||||||
override val commitAllPropertiesByDefault: Boolean = true
|
override val commitAllPropertiesByDefault: Boolean = true
|
||||||
@ -48,14 +46,14 @@ object Preferences : KotprefModel() {
|
|||||||
var weatherProviderApiWeatherApi by stringPref(default = "")
|
var weatherProviderApiWeatherApi by stringPref(default = "")
|
||||||
var weatherProviderApiWeatherBit by stringPref(default = "")
|
var weatherProviderApiWeatherBit by stringPref(default = "")
|
||||||
var weatherProviderApiAccuweather by stringPref(default = "")
|
var weatherProviderApiAccuweather by stringPref(default = "")
|
||||||
var weatherProvider by intPref(default = if (ConfigurationCompat.getLocales(context.resources.configuration)[0].isMetric()) Constants.WeatherProvider.YR.value else Constants.WeatherProvider.WEATHER_GOV.value)
|
var weatherProvider by intPref(default = if (ConfigurationCompat.getLocales(context.resources.configuration)[0].isMetric()) Constants.WeatherProvider.YR.rawValue else Constants.WeatherProvider.WEATHER_GOV.rawValue)
|
||||||
var weatherProviderError by stringPref(default = "")
|
var weatherProviderError by stringPref(default = "")
|
||||||
var weatherProviderLocationError by stringPref(default = "")
|
var weatherProviderLocationError by stringPref(default = "")
|
||||||
var eventAppName by stringPref(key = "PREF_EVENT_APP_NAME", default = "")
|
var eventAppName by stringPref(key = "PREF_EVENT_APP_NAME", default = "")
|
||||||
var eventAppPackage by stringPref(key = "PREF_EVENT_APP_PACKAGE", default = "")
|
var eventAppPackage by stringPref(key = "PREF_EVENT_APP_PACKAGE", default = "")
|
||||||
var openEventDetails by booleanPref(default = true)
|
var openEventDetails by booleanPref(default = true)
|
||||||
|
|
||||||
var widgetUpdateFrequency by intPref(default = Constants.WidgetUpdateFrequency.DEFAULT.value)
|
var widgetUpdateFrequency by intPref(default = Constants.WidgetUpdateFrequency.DEFAULT.rawValue)
|
||||||
|
|
||||||
var textGlobalColor by stringPref(key = "PREF_TEXT_COLOR", default = "#FFFFFF")
|
var textGlobalColor by stringPref(key = "PREF_TEXT_COLOR", default = "#FFFFFF")
|
||||||
var textGlobalAlpha by stringPref(default = "FF")
|
var textGlobalAlpha by stringPref(default = "FF")
|
||||||
@ -84,14 +82,18 @@ object Preferences : KotprefModel() {
|
|||||||
|
|
||||||
var showAMPMIndicator by booleanPref(default = true)
|
var showAMPMIndicator by booleanPref(default = true)
|
||||||
|
|
||||||
var weatherIconPack by intPref(default = Constants.WeatherIconPack.DEFAULT.value)
|
var weatherIconPack by intPref(default = Constants.WeatherIconPack.DEFAULT.rawValue)
|
||||||
|
|
||||||
|
// Clock
|
||||||
|
var altTimezoneLabel by stringPref(default = "")
|
||||||
|
var altTimezoneId by stringPref(default = "")
|
||||||
|
|
||||||
// Global
|
// Global
|
||||||
var textMainSize by floatPref(key = "PREF_TEXT_MAIN_SIZE", default = 26f)
|
var textMainSize by floatPref(key = "PREF_TEXT_MAIN_SIZE", default = 26f)
|
||||||
var textSecondSize by floatPref(key = "PREF_TEXT_SECOND_SIZE", default = 18f)
|
var textSecondSize by floatPref(key = "PREF_TEXT_SECOND_SIZE", default = 18f)
|
||||||
var clockTextSize by floatPref(key = "PREF_TEXT_CLOCK_SIZE", default = 90f)
|
var clockTextSize by floatPref(key = "PREF_TEXT_CLOCK_SIZE", default = 90f)
|
||||||
var clockBottomMargin by intPref(default = Constants.ClockBottomMargin.MEDIUM.value)
|
var clockBottomMargin by intPref(default = Constants.ClockBottomMargin.MEDIUM.rawValue)
|
||||||
var secondRowTopMargin by intPref(default = Constants.SecondRowTopMargin.NONE.value)
|
var secondRowTopMargin by intPref(default = Constants.SecondRowTopMargin.NONE.rawValue)
|
||||||
var showClock by booleanPref(key = "PREF_SHOW_CLOCK", default = false)
|
var showClock by booleanPref(key = "PREF_SHOW_CLOCK", default = false)
|
||||||
var clockAppName by stringPref(key = "PREF_CLOCK_APP_NAME", default = "")
|
var clockAppName by stringPref(key = "PREF_CLOCK_APP_NAME", default = "")
|
||||||
var clockAppPackage by stringPref(key = "PREF_CLOCK_APP_PACKAGE", default = "")
|
var clockAppPackage by stringPref(key = "PREF_CLOCK_APP_PACKAGE", default = "")
|
||||||
@ -111,6 +113,8 @@ object Preferences : KotprefModel() {
|
|||||||
|
|
||||||
var showDividers by booleanPref(default = true)
|
var showDividers by booleanPref(default = true)
|
||||||
|
|
||||||
|
var widgetAlign by intPref(default = Constants.WidgetAlign.CENTER.rawValue)
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
var showWallpaper by booleanPref(default = true)
|
var showWallpaper by booleanPref(default = true)
|
||||||
var showPreview by booleanPref(default = true)
|
var showPreview by booleanPref(default = true)
|
||||||
@ -127,7 +131,7 @@ object Preferences : KotprefModel() {
|
|||||||
var showDailySteps by booleanPref(default = false)
|
var showDailySteps by booleanPref(default = false)
|
||||||
var showGreetings by booleanPref(default = false)
|
var showGreetings by booleanPref(default = false)
|
||||||
var showNotifications by booleanPref(default = false)
|
var showNotifications by booleanPref(default = false)
|
||||||
var hideNotificationAfter by intPref(default = Constants.GlanceNotificationTimer.ONE_MINUTE.value)
|
var hideNotificationAfter by intPref(default = Constants.GlanceNotificationTimer.ONE_MINUTE.rawValue)
|
||||||
|
|
||||||
var lastNotificationId by intPref(default = -1)
|
var lastNotificationId by intPref(default = -1)
|
||||||
var lastNotificationTitle by stringPref(default = "")
|
var lastNotificationTitle by stringPref(default = "")
|
||||||
|
@ -20,7 +20,7 @@ object ImageHelper {
|
|||||||
else -> 0f * factor
|
else -> 0f * factor
|
||||||
}, resources.displayMetrics)
|
}, resources.displayMetrics)
|
||||||
|
|
||||||
if (originalView.drawable != null) {
|
if (originalView.drawable != null && originalView.drawable.intrinsicWidth > 0 && originalView.drawable.intrinsicHeight > 0) {
|
||||||
val btm = originalView.drawable.toBitmap().copy(Bitmap.Config.ARGB_8888, true)
|
val btm = originalView.drawable.toBitmap().copy(Bitmap.Config.ARGB_8888, true)
|
||||||
val comb = Bitmap.createBitmap(btm)
|
val comb = Bitmap.createBitmap(btm)
|
||||||
val shadowBitmap = generateShadowBitmap(context, cElevation, btm, factor)
|
val shadowBitmap = generateShadowBitmap(context, cElevation, btm, factor)
|
||||||
|
@ -12,8 +12,10 @@ import android.provider.CalendarContract
|
|||||||
import android.provider.CalendarContract.Events
|
import android.provider.CalendarContract.Events
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Actions
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.models.Event
|
import com.tommasoberlose.anotherwidget.models.Event
|
||||||
|
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
import com.tommasoberlose.anotherwidget.utils.toast
|
import com.tommasoberlose.anotherwidget.utils.toast
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -35,6 +37,13 @@ object IntentHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getWidgetRefreshIntent(context: Context): Intent {
|
||||||
|
return Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
|
action = Actions.ACTION_REFRESH
|
||||||
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getGoogleMapsIntentFromAddress(context: Context, address: String): Intent {
|
fun getGoogleMapsIntentFromAddress(context: Context, address: String): Intent {
|
||||||
val gmmIntentUri: Uri = Uri.parse("geo:0,0?q=$address")
|
val gmmIntentUri: Uri = Uri.parse("geo:0,0?q=$address")
|
||||||
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
|
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
|
||||||
@ -57,13 +66,14 @@ object IntentHelper {
|
|||||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
data = Uri.parse("dynact://velour/weather/ProxyActivity")
|
data = Uri.parse("dynact://velour/weather/ProxyActivity")
|
||||||
component = ComponentName("com.google.android.googlequicksearchbox", "com.google.android.apps.gsa.velour.DynamicActivityTrampoline")
|
component = ComponentName("com.google.android.googlequicksearchbox", "com.google.android.apps.gsa.velour.DynamicActivityTrampoline")
|
||||||
|
setClassName("com.google.android.googlequicksearchbox", "com.google.android.apps.gsa.velour.DynamicActivityTrampoline")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DO_NOTHING_OPTION -> {
|
DO_NOTHING_OPTION -> {
|
||||||
Intent()
|
Intent()
|
||||||
}
|
}
|
||||||
REFRESH_WIDGET_OPTION -> {
|
REFRESH_WIDGET_OPTION -> {
|
||||||
getWidgetUpdateIntent(context)
|
getWidgetRefreshIntent(context)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val pm: PackageManager = context.packageManager
|
val pm: PackageManager = context.packageManager
|
||||||
@ -95,7 +105,7 @@ object IntentHelper {
|
|||||||
Intent()
|
Intent()
|
||||||
}
|
}
|
||||||
REFRESH_WIDGET_OPTION -> {
|
REFRESH_WIDGET_OPTION -> {
|
||||||
getWidgetUpdateIntent(context)
|
getWidgetRefreshIntent(context)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val pm: PackageManager = context.packageManager
|
val pm: PackageManager = context.packageManager
|
||||||
@ -183,7 +193,7 @@ object IntentHelper {
|
|||||||
Intent()
|
Intent()
|
||||||
}
|
}
|
||||||
REFRESH_WIDGET_OPTION -> {
|
REFRESH_WIDGET_OPTION -> {
|
||||||
getWidgetUpdateIntent(context)
|
getWidgetRefreshIntent(context)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val pm: PackageManager = context.packageManager
|
val pm: PackageManager = context.packageManager
|
||||||
|
@ -33,12 +33,14 @@ object MediaPlayerHelper {
|
|||||||
DEFAULT_MEDIA_INFO_FORMAT.replace(MEDIA_INFO_TITLE, title)
|
DEFAULT_MEDIA_INFO_FORMAT.replace(MEDIA_INFO_TITLE, title)
|
||||||
.replace(MEDIA_INFO_ARTIST, artist)
|
.replace(MEDIA_INFO_ARTIST, artist)
|
||||||
.replace(MEDIA_INFO_ALBUM, album)
|
.replace(MEDIA_INFO_ALBUM, album)
|
||||||
|
.replace("\\n", System.getProperty("line.separator") ?: " ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
format.replace(MEDIA_INFO_TITLE, title)
|
format.replace(MEDIA_INFO_TITLE, title)
|
||||||
.replace(MEDIA_INFO_ARTIST, artist)
|
.replace(MEDIA_INFO_ARTIST, artist)
|
||||||
.replace(MEDIA_INFO_ALBUM, album)
|
.replace(MEDIA_INFO_ALBUM, album)
|
||||||
|
.replace("\\n", System.getProperty("line.separator") ?: " ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,13 +96,13 @@ object SettingsStringHelper {
|
|||||||
difference <= 0 -> {
|
difference <= 0 -> {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
TimeUnit.MILLISECONDS.toHours(difference) < 1 && Preferences.widgetUpdateFrequency == Constants.WidgetUpdateFrequency.HIGH.value && TimeUnit.MILLISECONDS.toMinutes(difference) > 5 -> {
|
TimeUnit.MILLISECONDS.toHours(difference) < 1 && Preferences.widgetUpdateFrequency == Constants.WidgetUpdateFrequency.HIGH.rawValue && TimeUnit.MILLISECONDS.toMinutes(difference) > 5 -> {
|
||||||
return DateUtils.getRelativeTimeSpanString(start, start - 1000 * 60 * (TimeUnit.MILLISECONDS.toMinutes(difference) - 1 - (TimeUnit.MILLISECONDS.toMinutes(difference) - 1) % 5), DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE).toString()
|
return DateUtils.getRelativeTimeSpanString(start, start - 1000 * 60 * (TimeUnit.MILLISECONDS.toMinutes(difference) - 1 - (TimeUnit.MILLISECONDS.toMinutes(difference) - 1) % 5), DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE).toString()
|
||||||
}
|
}
|
||||||
TimeUnit.MILLISECONDS.toHours(difference) < 1 && Preferences.widgetUpdateFrequency == Constants.WidgetUpdateFrequency.DEFAULT.value && TimeUnit.MILLISECONDS.toMinutes(difference) > 5 -> {
|
TimeUnit.MILLISECONDS.toHours(difference) < 1 && Preferences.widgetUpdateFrequency == Constants.WidgetUpdateFrequency.DEFAULT.rawValue && TimeUnit.MILLISECONDS.toMinutes(difference) > 5 -> {
|
||||||
return DateUtils.getRelativeTimeSpanString(start, start - 1000 * 60 * (TimeUnit.MILLISECONDS.toMinutes(difference) - 1 - (TimeUnit.MILLISECONDS.toMinutes(difference) - 1) % 15), DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE).toString()
|
return DateUtils.getRelativeTimeSpanString(start, start - 1000 * 60 * (TimeUnit.MILLISECONDS.toMinutes(difference) - 1 - (TimeUnit.MILLISECONDS.toMinutes(difference) - 1) % 15), DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE).toString()
|
||||||
}
|
}
|
||||||
TimeUnit.MILLISECONDS.toHours(difference) < 1 && Preferences.widgetUpdateFrequency == Constants.WidgetUpdateFrequency.LOW.value -> {
|
TimeUnit.MILLISECONDS.toHours(difference) < 1 && Preferences.widgetUpdateFrequency == Constants.WidgetUpdateFrequency.LOW.rawValue -> {
|
||||||
return context.getString(R.string.soon)
|
return context.getString(R.string.soon)
|
||||||
}
|
}
|
||||||
TimeUnit.MILLISECONDS.toHours(difference) < 1 -> {
|
TimeUnit.MILLISECONDS.toHours(difference) < 1 -> {
|
||||||
|
@ -2,23 +2,15 @@ package com.tommasoberlose.anotherwidget.helpers
|
|||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
|
||||||
import android.util.Log
|
|
||||||
import com.chibatching.kotpref.Kotpref
|
import com.chibatching.kotpref.Kotpref
|
||||||
import com.google.android.gms.location.LocationServices
|
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
import com.tommasoberlose.anotherwidget.global.Constants
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
|
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
|
||||||
import com.tommasoberlose.anotherwidget.services.LocationService
|
import com.tommasoberlose.anotherwidget.services.LocationService
|
||||||
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 com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -122,97 +114,97 @@ object WeatherHelper {
|
|||||||
return when (icon) {
|
return when (icon) {
|
||||||
"01d" -> {
|
"01d" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.clear_day_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.clear_day_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.clear_day_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.clear_day_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.clear_day_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.clear_day_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.clear_day_5 else R.drawable.clear_day_5_light
|
else -> if (context.isDarkTheme()) R.drawable.clear_day_5 else R.drawable.clear_day_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"02d" -> {
|
"02d" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.partly_cloudy_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.partly_cloudy_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.partly_cloudy_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.partly_cloudy_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.partly_cloudy_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.partly_cloudy_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.partly_cloudy_5 else R.drawable.partly_cloudy_5_light
|
else -> if (context.isDarkTheme()) R.drawable.partly_cloudy_5 else R.drawable.partly_cloudy_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"03d" -> {
|
"03d" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.mostly_cloudy_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.mostly_cloudy_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.mostly_cloudy_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.mostly_cloudy_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.mostly_cloudy_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.mostly_cloudy_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.mostly_cloudy_5 else R.drawable.mostly_cloudy_5_light
|
else -> if (context.isDarkTheme()) R.drawable.mostly_cloudy_5 else R.drawable.mostly_cloudy_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"04d" -> {
|
"04d" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.cloudy_weather_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.cloudy_weather_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.cloudy_weather_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.cloudy_weather_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.cloudy_weather_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.cloudy_weather_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.cloudy_weather_5 else R.drawable.cloudy_weather_5_light
|
else -> if (context.isDarkTheme()) R.drawable.cloudy_weather_5 else R.drawable.cloudy_weather_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"09d" -> {
|
"09d" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.storm_weather_day_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.storm_weather_day_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.storm_weather_day_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.storm_weather_day_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.storm_weather_day_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.storm_weather_day_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.storm_weather_day_5 else R.drawable.storm_weather_day_5_light
|
else -> if (context.isDarkTheme()) R.drawable.storm_weather_day_5 else R.drawable.storm_weather_day_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"10d" -> {
|
"10d" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.rainy_day_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.rainy_day_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rainy_day_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.rainy_day_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rainy_day_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.rainy_day_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.rainy_day_5 else R.drawable.rainy_day_5_light
|
else -> if (context.isDarkTheme()) R.drawable.rainy_day_5 else R.drawable.rainy_day_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"11d" -> {
|
"11d" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.thunder_day_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.thunder_day_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.thunder_day_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.thunder_day_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.thunder_day_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.thunder_day_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.thunder_day_5 else R.drawable.thunder_day_5_light
|
else -> if (context.isDarkTheme()) R.drawable.thunder_day_5 else R.drawable.thunder_day_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"13d" -> {
|
"13d" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.snow_day_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.snow_day_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.snow_day_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.snow_day_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.snow_day_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.snow_day_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.snow_day_5 else R.drawable.snow_day_5_light
|
else -> if (context.isDarkTheme()) R.drawable.snow_day_5 else R.drawable.snow_day_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"50d" -> {
|
"50d" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.haze_day_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.haze_day_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_day_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.haze_day_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_day_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.haze_day_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.haze_day_5 else R.drawable.haze_day_5_light
|
else -> if (context.isDarkTheme()) R.drawable.haze_day_5 else R.drawable.haze_day_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"80d" -> {
|
"80d" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.windy_day_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.windy_day_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.windy_day_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.windy_day_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.windy_day_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.windy_day_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.windy_day_5 else R.drawable.windy_day_5_light
|
else -> if (context.isDarkTheme()) R.drawable.windy_day_5 else R.drawable.windy_day_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"81d" -> {
|
"81d" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.rain_snow_day_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.rain_snow_day_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rain_snow_day_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.rain_snow_day_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rain_snow_day_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.rain_snow_day_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.rain_snow_day_5 else R.drawable.rain_snow_day_5_light
|
else -> if (context.isDarkTheme()) R.drawable.rain_snow_day_5 else R.drawable.rain_snow_day_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"82d" -> {
|
"82d" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.haze_weather_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.haze_weather_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_weather_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.haze_weather_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_weather_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.haze_weather_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.haze_weather_5 else R.drawable.haze_weather_5_light
|
else -> if (context.isDarkTheme()) R.drawable.haze_weather_5 else R.drawable.haze_weather_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,97 +213,97 @@ object WeatherHelper {
|
|||||||
|
|
||||||
"01n" -> {
|
"01n" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.clear_night_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.clear_night_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.clear_night_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.clear_night_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.clear_night_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.clear_night_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.clear_night_5 else R.drawable.clear_night_5_light
|
else -> if (context.isDarkTheme()) R.drawable.clear_night_5 else R.drawable.clear_night_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"02n" -> {
|
"02n" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.partly_cloudy_night_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.partly_cloudy_night_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.partly_cloudy_night_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.partly_cloudy_night_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.partly_cloudy_night_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.partly_cloudy_night_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.partly_cloudy_night_5 else R.drawable.partly_cloudy_night_5_light
|
else -> if (context.isDarkTheme()) R.drawable.partly_cloudy_night_5 else R.drawable.partly_cloudy_night_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"03n" -> {
|
"03n" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.mostly_cloudy_night_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.mostly_cloudy_night_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.mostly_cloudy_night_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.mostly_cloudy_night_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.mostly_cloudy_night_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.mostly_cloudy_night_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.mostly_cloudy_night_5 else R.drawable.mostly_cloudy_night_5_light
|
else -> if (context.isDarkTheme()) R.drawable.mostly_cloudy_night_5 else R.drawable.mostly_cloudy_night_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"04n" -> {
|
"04n" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.cloudy_weather_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.cloudy_weather_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.cloudy_weather_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.cloudy_weather_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.cloudy_weather_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.cloudy_weather_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.cloudy_weather_5 else R.drawable.cloudy_weather_5_light
|
else -> if (context.isDarkTheme()) R.drawable.cloudy_weather_5 else R.drawable.cloudy_weather_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"09n" -> {
|
"09n" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.storm_weather_night_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.storm_weather_night_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.storm_weather_night_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.storm_weather_night_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.storm_weather_night_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.storm_weather_night_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.storm_weather_night_5 else R.drawable.storm_weather_night_5_light
|
else -> if (context.isDarkTheme()) R.drawable.storm_weather_night_5 else R.drawable.storm_weather_night_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"10n" -> {
|
"10n" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.rainy_night_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.rainy_night_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rainy_night_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.rainy_night_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rainy_night_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.rainy_night_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.rainy_night_5 else R.drawable.rainy_night_5_light
|
else -> if (context.isDarkTheme()) R.drawable.rainy_night_5 else R.drawable.rainy_night_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"11n" -> {
|
"11n" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.thunder_night_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.thunder_night_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.thunder_night_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.thunder_night_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.thunder_night_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.thunder_night_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.thunder_night_5 else R.drawable.thunder_night_5_light
|
else -> if (context.isDarkTheme()) R.drawable.thunder_night_5 else R.drawable.thunder_night_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"13n" -> {
|
"13n" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.snow_night_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.snow_night_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.snow_night_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.snow_night_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.snow_night_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.snow_night_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.snow_night_5 else R.drawable.snow_night_5_light
|
else -> if (context.isDarkTheme()) R.drawable.snow_night_5 else R.drawable.snow_night_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"50n" -> {
|
"50n" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.haze_night_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.haze_night_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_night_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.haze_night_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_night_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.haze_night_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.haze_night_5 else R.drawable.haze_night_5_light
|
else -> if (context.isDarkTheme()) R.drawable.haze_night_5 else R.drawable.haze_night_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"80n" -> {
|
"80n" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.windy_night_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.windy_night_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.windy_night_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.windy_night_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.windy_night_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.windy_night_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.windy_night_5 else R.drawable.windy_night_5_light
|
else -> if (context.isDarkTheme()) R.drawable.windy_night_5 else R.drawable.windy_night_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"81n" -> {
|
"81n" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.rain_snow_night_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.rain_snow_night_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rain_snow_night_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.rain_snow_night_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rain_snow_night_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.rain_snow_night_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.rain_snow_night_5 else R.drawable.rain_snow_night_5_light
|
else -> if (context.isDarkTheme()) R.drawable.rain_snow_night_5 else R.drawable.rain_snow_night_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"82n" -> {
|
"82n" -> {
|
||||||
when (style) {
|
when (style) {
|
||||||
Constants.WeatherIconPack.COOL.value -> R.drawable.haze_weather_3
|
Constants.WeatherIconPack.COOL.rawValue -> R.drawable.haze_weather_3
|
||||||
Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_weather_2
|
Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.haze_weather_2
|
||||||
Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_weather_4
|
Constants.WeatherIconPack.GOOGLE_NEWS.rawValue -> R.drawable.haze_weather_4
|
||||||
else -> if (context.isDarkTheme()) R.drawable.haze_weather_5 else R.drawable.haze_weather_5_light
|
else -> if (context.isDarkTheme()) R.drawable.haze_weather_5 else R.drawable.haze_weather_5_light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.network
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.Log
|
||||||
|
import com.chibatching.kotpref.Kotpref
|
||||||
|
import com.google.gson.internal.LinkedTreeMap
|
||||||
|
import com.haroldadmin.cnradapter.NetworkResponse
|
||||||
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.network.repository.TimeZonesRepository
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import java.lang.Exception
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class TimeZonesApi(val context: Context) {
|
||||||
|
suspend fun getTimeZone(lat: String, long: String): String? {
|
||||||
|
Kotpref.init(context)
|
||||||
|
val repository = TimeZonesRepository()
|
||||||
|
var id: String? = null
|
||||||
|
|
||||||
|
when (val response = repository.getTimeZone(lat, long)) {
|
||||||
|
is NetworkResponse.Success -> {
|
||||||
|
try {
|
||||||
|
Log.d("ciao", response.body.toString())
|
||||||
|
id = response.body["timezoneId"] as String
|
||||||
|
|
||||||
|
} catch(ex: Exception) {
|
||||||
|
ex.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
}
|
@ -71,4 +71,13 @@ object ApiServices {
|
|||||||
@Query("lon") lon: String,
|
@Query("lon") lon: String,
|
||||||
): NetworkResponse<HashMap<String, Any>, HashMap<String, Any>>
|
): NetworkResponse<HashMap<String, Any>, HashMap<String, Any>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface TimeZonesService {
|
||||||
|
@GET("timezoneJSON")
|
||||||
|
suspend fun getTimeZone(
|
||||||
|
@Query("lat") lat: String,
|
||||||
|
@Query("lng") lon: String,
|
||||||
|
@Query("username") username: String = "tommaso.berlose",
|
||||||
|
): NetworkResponse<HashMap<String, Any>, HashMap<String, Any>>
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.network.repository
|
||||||
|
|
||||||
|
import com.haroldadmin.cnradapter.NetworkResponseAdapterFactory
|
||||||
|
import com.tommasoberlose.anotherwidget.network.api.ApiServices
|
||||||
|
import retrofit2.Retrofit
|
||||||
|
import retrofit2.converter.gson.GsonConverterFactory
|
||||||
|
|
||||||
|
class TimeZonesRepository {
|
||||||
|
|
||||||
|
/* YR */
|
||||||
|
private val apiService: ApiServices.TimeZonesService = getRetrofit().create(ApiServices.TimeZonesService::class.java)
|
||||||
|
suspend fun getTimeZone(lat: String, long: String) = apiService.getTimeZone(lat, long)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val BASE_URL_YR = "http://api.geonames.org/"
|
||||||
|
|
||||||
|
private fun getRetrofit(): Retrofit {
|
||||||
|
return Retrofit.Builder()
|
||||||
|
.baseUrl(BASE_URL_YR)
|
||||||
|
.addConverterFactory(GsonConverterFactory.create())
|
||||||
|
.addCallAdapterFactory(NetworkResponseAdapterFactory())
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@ import android.service.notification.NotificationListenerService
|
|||||||
import android.service.notification.StatusBarNotification
|
import android.service.notification.StatusBarNotification
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import com.google.gson.Gson
|
||||||
import com.tommasoberlose.anotherwidget.global.Actions
|
import com.tommasoberlose.anotherwidget.global.Actions
|
||||||
import com.tommasoberlose.anotherwidget.global.Constants
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
@ -5,19 +5,16 @@ import android.app.PendingIntent
|
|||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.util.Log
|
|
||||||
import androidx.core.app.AlarmManagerCompat
|
|
||||||
import androidx.core.content.ContextCompat.getSystemService
|
|
||||||
import com.tommasoberlose.anotherwidget.db.EventRepository
|
import com.tommasoberlose.anotherwidget.db.EventRepository
|
||||||
import com.tommasoberlose.anotherwidget.global.Actions
|
import com.tommasoberlose.anotherwidget.global.Actions
|
||||||
import com.tommasoberlose.anotherwidget.global.Constants
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper
|
import com.tommasoberlose.anotherwidget.helpers.*
|
||||||
import com.tommasoberlose.anotherwidget.helpers.BatteryHelper
|
|
||||||
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
|
|
||||||
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
|
||||||
import com.tommasoberlose.anotherwidget.models.Event
|
import com.tommasoberlose.anotherwidget.models.Event
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.joda.time.Period
|
import org.joda.time.Period
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@ -55,6 +52,14 @@ class UpdatesReceiver : BroadcastReceiver() {
|
|||||||
Actions.ACTION_UPDATE_GREETINGS -> {
|
Actions.ACTION_UPDATE_GREETINGS -> {
|
||||||
MainWidget.updateWidget(context)
|
MainWidget.updateWidget(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Actions.ACTION_REFRESH -> {
|
||||||
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
|
CalendarHelper.updateEventList(context)
|
||||||
|
MediaPlayerHelper.updatePlayingMediaInfo(context)
|
||||||
|
WeatherHelper.updateWeather(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +107,7 @@ class UpdatesReceiver : BroadcastReceiver() {
|
|||||||
if (diff.hours == 0) {
|
if (diff.hours == 0) {
|
||||||
var minutes = 0
|
var minutes = 0
|
||||||
when (Preferences.widgetUpdateFrequency) {
|
when (Preferences.widgetUpdateFrequency) {
|
||||||
Constants.WidgetUpdateFrequency.DEFAULT.value -> {
|
Constants.WidgetUpdateFrequency.DEFAULT.rawValue -> {
|
||||||
minutes = when {
|
minutes = when {
|
||||||
diff.minutes > 50 -> 50
|
diff.minutes > 50 -> 50
|
||||||
diff.minutes > 30 -> 30
|
diff.minutes > 30 -> 30
|
||||||
@ -110,7 +115,7 @@ class UpdatesReceiver : BroadcastReceiver() {
|
|||||||
else -> 0
|
else -> 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Constants.WidgetUpdateFrequency.HIGH.value -> {
|
Constants.WidgetUpdateFrequency.HIGH.rawValue -> {
|
||||||
minutes = diff.minutes - (diff.minutes % 5)
|
minutes = diff.minutes - (diff.minutes % 5)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import android.content.Intent
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
import com.tommasoberlose.anotherwidget.global.Actions
|
import com.tommasoberlose.anotherwidget.global.Actions
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.helpers.IntentHelper
|
import com.tommasoberlose.anotherwidget.helpers.IntentHelper
|
||||||
import com.tommasoberlose.anotherwidget.utils.toast
|
import com.tommasoberlose.anotherwidget.utils.toast
|
||||||
|
|
||||||
@ -15,19 +16,20 @@ class WidgetClickListenerReceiver : BroadcastReceiver() {
|
|||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
if (intent.action == Actions.ACTION_OPEN_WEATHER_INTENT) {
|
if (intent.action == Actions.ACTION_OPEN_WEATHER_INTENT) {
|
||||||
try {
|
try {
|
||||||
context.startActivity(IntentHelper.getWeatherIntent(context))
|
if (Preferences.weatherAppPackage == IntentHelper.REFRESH_WIDGET_OPTION) {
|
||||||
|
context.sendBroadcast(IntentHelper.getWeatherIntent(context))
|
||||||
|
} else {
|
||||||
|
context.startActivity(IntentHelper.getWeatherIntent(context))
|
||||||
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
val uri = Uri.parse("http://www.google.com/search?q=weather")
|
||||||
|
val i = Intent(Intent.ACTION_VIEW, uri)
|
||||||
|
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
try {
|
try {
|
||||||
context.applicationContext.startActivity(IntentHelper.getWeatherIntent(context.applicationContext))
|
context.startActivity(i)
|
||||||
} catch (e: Exception) {
|
} catch (ignored: Exception) {
|
||||||
val uri = Uri.parse("http://www.google.com/#q=weather")
|
context.toast(context.getString(R.string.error_opening_app))
|
||||||
val i = Intent(Intent.ACTION_VIEW, uri)
|
|
||||||
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
try {
|
|
||||||
context.startActivity(i)
|
|
||||||
} catch (ignored: Exception) {
|
|
||||||
context.toast(context.getString(R.string.error_opening_app))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ class LocationService : Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
|
startForeground(LOCATION_ACCESS_NOTIFICATION_ID, getLocationAccessNotification())
|
||||||
job?.cancel()
|
job?.cancel()
|
||||||
job = GlobalScope.launch(Dispatchers.IO) {
|
job = GlobalScope.launch(Dispatchers.IO) {
|
||||||
if (ActivityCompat.checkSelfPermission(
|
if (ActivityCompat.checkSelfPermission(
|
||||||
@ -85,11 +86,7 @@ class LocationService : Service() {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun requestNewLocation(context: Context) {
|
fun requestNewLocation(context: Context) {
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
ContextCompat.startForegroundService(context, Intent(context, LocationService::class.java))
|
||||||
context.startForegroundService(Intent(context, LocationService::class.java))
|
|
||||||
} else {
|
|
||||||
context.startService(Intent(context, LocationService::class.java))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,14 +33,9 @@ import kotlin.collections.ArrayList
|
|||||||
class UpdateCalendarService : Service() {
|
class UpdateCalendarService : Service() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val CALENDAR_SYNC_NOTIFICATION_ID = 28466
|
const val CALENDAR_SYNC_NOTIFICATION_ID = 28468
|
||||||
fun enqueueWork(context: Context) {
|
fun enqueueWork(context: Context) {
|
||||||
context.startService(Intent(context, UpdateCalendarService::class.java))
|
ContextCompat.startForegroundService(context, Intent(context, UpdateCalendarService::class.java))
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
|
||||||
context.startForegroundService(Intent(context, UpdateCalendarService::class.java))
|
|
||||||
} else {
|
|
||||||
context.startService(Intent(context, UpdateCalendarService::class.java))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +51,7 @@ class UpdateCalendarService : Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
|
startForeground(CALENDAR_SYNC_NOTIFICATION_ID, getCalendarSyncNotification())
|
||||||
job?.cancel()
|
job?.cancel()
|
||||||
job = GlobalScope.launch(Dispatchers.IO) {
|
job = GlobalScope.launch(Dispatchers.IO) {
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ import com.google.android.material.card.MaterialCardView
|
|||||||
import com.tommasoberlose.anotherwidget.databinding.ActivityChooseApplicationBinding
|
import com.tommasoberlose.anotherwidget.databinding.ActivityChooseApplicationBinding
|
||||||
import com.tommasoberlose.anotherwidget.global.Constants
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
import com.tommasoberlose.anotherwidget.helpers.IntentHelper
|
import com.tommasoberlose.anotherwidget.helpers.IntentHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
||||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.tabs.ChooseApplicationViewModel
|
import com.tommasoberlose.anotherwidget.ui.viewmodels.tabs.ChooseApplicationViewModel
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import net.idik.lib.slimadapter.SlimAdapter
|
import net.idik.lib.slimadapter.SlimAdapter
|
||||||
@ -171,6 +172,18 @@ class ChooseApplicationActivity : AppCompatActivity() {
|
|||||||
list.filter {
|
list.filter {
|
||||||
it.loadLabel(viewModel.pm).contains(search, true)
|
it.loadLabel(viewModel.pm).contains(search, true)
|
||||||
}
|
}
|
||||||
|
}.sortedWith { app1, app2 ->
|
||||||
|
when (selectedPackage) {
|
||||||
|
app1.activityInfo.packageName -> {
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
app2.activityInfo.packageName -> {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
app1.loadLabel(viewModel.pm).toString().compareTo(app2.loadLabel(viewModel.pm).toString(), ignoreCase = true)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
adapter.updateData(listOf(IntentHelper.DO_NOTHING_OPTION, IntentHelper.DEFAULT_OPTION, IntentHelper.REFRESH_WIDGET_OPTION) + filteredList)
|
adapter.updateData(listOf(IntentHelper.DO_NOTHING_OPTION, IntentHelper.DEFAULT_OPTION, IntentHelper.REFRESH_WIDGET_OPTION) + filteredList)
|
||||||
|
@ -5,6 +5,7 @@ import android.app.Activity
|
|||||||
import android.location.Address
|
import android.location.Address
|
||||||
import android.location.Geocoder
|
import android.location.Geocoder
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
@ -0,0 +1,155 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.ui.activities.tabs
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.app.Activity
|
||||||
|
import android.location.Address
|
||||||
|
import android.location.Geocoder
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.method.LinkMovementMethod
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import com.chibatching.kotpref.bulk
|
||||||
|
import com.karumi.dexter.Dexter
|
||||||
|
import com.karumi.dexter.MultiplePermissionsReport
|
||||||
|
import com.karumi.dexter.PermissionToken
|
||||||
|
import com.karumi.dexter.listener.PermissionRequest
|
||||||
|
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
|
||||||
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.databinding.ActivityTimeZoneSelectorBinding
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import com.tommasoberlose.anotherwidget.network.TimeZonesApi
|
||||||
|
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.viewmodels.tabs.TimeZoneSelectorViewModel
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.toast
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import net.idik.lib.slimadapter.SlimAdapter
|
||||||
|
|
||||||
|
class TimeZoneSelectorActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private lateinit var adapter: SlimAdapter
|
||||||
|
private lateinit var viewModel: TimeZoneSelectorViewModel
|
||||||
|
private lateinit var binding: ActivityTimeZoneSelectorBinding
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
viewModel = ViewModelProvider(this).get(TimeZoneSelectorViewModel::class.java)
|
||||||
|
binding = ActivityTimeZoneSelectorBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
|
binding.geonameCredits.movementMethod = LinkMovementMethod.getInstance()
|
||||||
|
|
||||||
|
binding.listView.setHasFixedSize(true)
|
||||||
|
val mLayoutManager = LinearLayoutManager(this)
|
||||||
|
binding.listView.layoutManager = mLayoutManager
|
||||||
|
|
||||||
|
adapter = SlimAdapter.create()
|
||||||
|
adapter
|
||||||
|
.register<String>(R.layout.custom_location_item) { _, injector ->
|
||||||
|
injector
|
||||||
|
.text(R.id.text, getString(R.string.no_time_zone_label))
|
||||||
|
.clicked(R.id.text) {
|
||||||
|
Preferences.bulk {
|
||||||
|
altTimezoneId = ""
|
||||||
|
altTimezoneLabel = ""
|
||||||
|
}
|
||||||
|
MainWidget.updateWidget(this@TimeZoneSelectorActivity)
|
||||||
|
setResult(Activity.RESULT_OK)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.register<Address>(R.layout.custom_location_item) { item, injector ->
|
||||||
|
injector.text(R.id.text, item.getAddressLine(0))
|
||||||
|
injector.clicked(R.id.item) {
|
||||||
|
binding.loader.visibility = View.VISIBLE
|
||||||
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
val networkApi = TimeZonesApi(this@TimeZoneSelectorActivity)
|
||||||
|
val id = networkApi.getTimeZone(item.latitude.toString(), item.longitude.toString())
|
||||||
|
|
||||||
|
if (id != null) {
|
||||||
|
Preferences.bulk {
|
||||||
|
altTimezoneId = id
|
||||||
|
altTimezoneLabel = try {
|
||||||
|
item.locality
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
item.getAddressLine(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MainWidget.updateWidget(this@TimeZoneSelectorActivity)
|
||||||
|
setResult(Activity.RESULT_OK)
|
||||||
|
finish()
|
||||||
|
} else {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
binding.loader.visibility = View.INVISIBLE
|
||||||
|
toast(getString(R.string.time_zone_search_error_message))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.attachTo(binding.listView)
|
||||||
|
|
||||||
|
|
||||||
|
viewModel.addresses.observe(this, Observer {
|
||||||
|
adapter.updateData(listOf("Default") + it)
|
||||||
|
})
|
||||||
|
|
||||||
|
setupListener()
|
||||||
|
subscribeUi(binding, viewModel)
|
||||||
|
|
||||||
|
binding.location.requestFocus()
|
||||||
|
|
||||||
|
setContentView(binding.root)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var searchJob: Job? = null
|
||||||
|
|
||||||
|
private fun subscribeUi(binding: ActivityTimeZoneSelectorBinding, viewModel: TimeZoneSelectorViewModel) {
|
||||||
|
binding.viewModel = viewModel
|
||||||
|
binding.lifecycleOwner = this
|
||||||
|
|
||||||
|
viewModel.addresses.observe(this, Observer {
|
||||||
|
adapter.updateData(listOf("Default") + it)
|
||||||
|
binding.loader.visibility = View.INVISIBLE
|
||||||
|
})
|
||||||
|
|
||||||
|
viewModel.locationInput.observe(this, Observer { location ->
|
||||||
|
binding.loader.visibility = View.VISIBLE
|
||||||
|
searchJob?.cancel()
|
||||||
|
searchJob = lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
delay(200)
|
||||||
|
val list = if (location == null || location == "") {
|
||||||
|
viewModel.addresses.value!!
|
||||||
|
} else {
|
||||||
|
val coder = Geocoder(this@TimeZoneSelectorActivity)
|
||||||
|
try {
|
||||||
|
coder.getFromLocationName(location, 10) as ArrayList<Address>
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
emptyList<Address>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
viewModel.addresses.value = list
|
||||||
|
binding.loader.visibility = View.INVISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
binding.clearSearch.isVisible = location.isNotBlank()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupListener() {
|
||||||
|
binding.actionBack.setOnClickListener {
|
||||||
|
onBackPressed()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.clearSearch.setOnClickListener {
|
||||||
|
viewModel.locationInput.value = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -47,12 +47,12 @@ class WeatherProviderActivity : AppCompatActivity() {
|
|||||||
injector
|
injector
|
||||||
.text(R.id.text, WeatherHelper.getProviderName(this, provider))
|
.text(R.id.text, WeatherHelper.getProviderName(this, provider))
|
||||||
.clicked(R.id.item) {
|
.clicked(R.id.item) {
|
||||||
if (Preferences.weatherProvider != provider.value) {
|
if (Preferences.weatherProvider != provider.rawValue) {
|
||||||
Preferences.weatherProviderError = "-"
|
Preferences.weatherProviderError = "-"
|
||||||
Preferences.weatherProviderLocationError = ""
|
Preferences.weatherProviderLocationError = ""
|
||||||
}
|
}
|
||||||
val oldValue = Preferences.weatherProvider
|
val oldValue = Preferences.weatherProvider
|
||||||
Preferences.weatherProvider = provider.value
|
Preferences.weatherProvider = provider.rawValue
|
||||||
updateListItem(oldValue)
|
updateListItem(oldValue)
|
||||||
updateListItem()
|
updateListItem()
|
||||||
binding.loader.isVisible = true
|
binding.loader.isVisible = true
|
||||||
@ -62,12 +62,12 @@ class WeatherProviderActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.clicked(R.id.radioButton) {
|
.clicked(R.id.radioButton) {
|
||||||
if (Preferences.weatherProvider != provider.value) {
|
if (Preferences.weatherProvider != provider.rawValue) {
|
||||||
Preferences.weatherProviderError = "-"
|
Preferences.weatherProviderError = "-"
|
||||||
Preferences.weatherProviderLocationError = ""
|
Preferences.weatherProviderLocationError = ""
|
||||||
}
|
}
|
||||||
val oldValue = Preferences.weatherProvider
|
val oldValue = Preferences.weatherProvider
|
||||||
Preferences.weatherProvider = provider.value
|
Preferences.weatherProvider = provider.rawValue
|
||||||
updateListItem(oldValue)
|
updateListItem(oldValue)
|
||||||
updateListItem()
|
updateListItem()
|
||||||
binding.loader.isVisible = true
|
binding.loader.isVisible = true
|
||||||
@ -76,7 +76,7 @@ class WeatherProviderActivity : AppCompatActivity() {
|
|||||||
WeatherHelper.updateWeather(this@WeatherProviderActivity)
|
WeatherHelper.updateWeather(this@WeatherProviderActivity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.checked(R.id.radioButton, provider.value == Preferences.weatherProvider)
|
.checked(R.id.radioButton, provider.rawValue == Preferences.weatherProvider)
|
||||||
.with<TextView>(R.id.text2) {
|
.with<TextView>(R.id.text2) {
|
||||||
if (WeatherHelper.isKeyRequired(provider)) {
|
if (WeatherHelper.isKeyRequired(provider)) {
|
||||||
it.text = getString(R.string.api_key_required_message)
|
it.text = getString(R.string.api_key_required_message)
|
||||||
@ -98,14 +98,14 @@ class WeatherProviderActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
.visibility(R.id.action_configure, if (/*WeatherHelper.isKeyRequired(provider) && */provider.value == Preferences.weatherProvider) View.VISIBLE else View.GONE)
|
.visibility(R.id.action_configure, if (/*WeatherHelper.isKeyRequired(provider) && */provider.rawValue == Preferences.weatherProvider) View.VISIBLE else View.GONE)
|
||||||
.with<TextView>(R.id.provider_error) {
|
.with<TextView>(R.id.provider_error) {
|
||||||
if (Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-") {
|
if (Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-") {
|
||||||
it.text = Preferences.weatherProviderError
|
it.text = Preferences.weatherProviderError
|
||||||
it.isVisible = provider.value == Preferences.weatherProvider
|
it.isVisible = provider.rawValue == Preferences.weatherProvider
|
||||||
} else if (Preferences.weatherProviderLocationError != "") {
|
} else if (Preferences.weatherProviderLocationError != "") {
|
||||||
it.text = Preferences.weatherProviderLocationError
|
it.text = Preferences.weatherProviderLocationError
|
||||||
it.isVisible = provider.value == Preferences.weatherProvider
|
it.isVisible = provider.rawValue == Preferences.weatherProvider
|
||||||
} else {
|
} else {
|
||||||
it.isVisible = false
|
it.isVisible = false
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ class WeatherProviderActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private fun updateListItem(provider: Int = Preferences.weatherProvider) {
|
private fun updateListItem(provider: Int = Preferences.weatherProvider) {
|
||||||
(adapter.data).forEachIndexed { index, item ->
|
(adapter.data).forEachIndexed { index, item ->
|
||||||
if (item is Constants.WeatherProvider && item.value == provider) {
|
if (item is Constants.WeatherProvider && item.rawValue == provider) {
|
||||||
adapter.notifyItemChanged(index)
|
adapter.notifyItemChanged(index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package com.tommasoberlose.anotherwidget.ui.fragments
|
package com.tommasoberlose.anotherwidget.ui.fragments
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.animation.ValueAnimator
|
import android.animation.ValueAnimator
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@ -11,26 +9,20 @@ import android.provider.Settings
|
|||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
|
import android.view.Gravity
|
||||||
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.FrameLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.RelativeLayout
|
import android.widget.RelativeLayout
|
||||||
import androidx.core.animation.addListener
|
|
||||||
import androidx.core.app.NotificationManagerCompat
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.view.children
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.Observer
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.NavController
|
|
||||||
import androidx.navigation.Navigation
|
import androidx.navigation.Navigation
|
||||||
import androidx.navigation.fragment.FragmentNavigatorExtras
|
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
import com.google.android.material.badge.BadgeDrawable
|
|
||||||
import com.google.android.material.card.MaterialCardView
|
|
||||||
import com.google.android.material.tabs.TabLayoutMediator
|
|
||||||
import com.google.android.material.transition.MaterialSharedAxis
|
import com.google.android.material.transition.MaterialSharedAxis
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog
|
import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog
|
||||||
@ -39,11 +31,10 @@ import com.tommasoberlose.anotherwidget.global.Constants
|
|||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.helpers.*
|
import com.tommasoberlose.anotherwidget.helpers.*
|
||||||
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
|
||||||
import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver
|
|
||||||
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.viewmodels.MainViewModel
|
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.widgets.StandardWidget
|
||||||
import com.tommasoberlose.anotherwidget.utils.*
|
import com.tommasoberlose.anotherwidget.utils.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
@ -54,7 +45,8 @@ class MainFragment : Fragment() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun newInstance() = MainFragment()
|
fun newInstance() = MainFragment()
|
||||||
private const val PREVIEW_BASE_HEIGHT = 120
|
private val PREVIEW_BASE_HEIGHT: Int
|
||||||
|
get() = if (Preferences.widgetAlign == Constants.WidgetAlign.CENTER.rawValue) 120 else 180
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var viewModel: MainViewModel
|
private lateinit var viewModel: MainViewModel
|
||||||
@ -94,14 +86,18 @@ class MainFragment : Fragment() {
|
|||||||
navHost?.navController?.addOnDestinationChangedListener { controller, destination, _ ->
|
navHost?.navController?.addOnDestinationChangedListener { controller, destination, _ ->
|
||||||
val show = destination.id != R.id.tabSelectorFragment
|
val show = destination.id != R.id.tabSelectorFragment
|
||||||
binding.actionBack.animate().alpha(if (show) 1f else 0f).setDuration(200).translationX((if (show) 0f else 4f).convertDpToPixel(requireContext())).start()
|
binding.actionBack.animate().alpha(if (show) 1f else 0f).setDuration(200).translationX((if (show) 0f else 4f).convertDpToPixel(requireContext())).start()
|
||||||
binding.actionBack.setOnClickListener {
|
binding.actionBack.setOnSingleClickListener {
|
||||||
controller.navigateUp()
|
controller.navigateUp()
|
||||||
}
|
}
|
||||||
|
binding.actionBack.isClickable = show
|
||||||
|
binding.actionBack.isFocusable = show
|
||||||
binding.actionSettings.animate().alpha(if (!show) 1f else 0f).setDuration(200).translationX((if (!show) 0f else -4f).convertDpToPixel(requireContext())).start()
|
binding.actionSettings.animate().alpha(if (!show) 1f else 0f).setDuration(200).translationX((if (!show) 0f else -4f).convertDpToPixel(requireContext())).start()
|
||||||
|
binding.actionSettings.isClickable = !show
|
||||||
|
binding.actionSettings.isFocusable = !show
|
||||||
binding.fragmentTitle.text = if (show) destination.label.toString() else getString(R.string.app_name)
|
binding.fragmentTitle.text = if (show) destination.label.toString() else getString(R.string.app_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.actionSettings.setOnClickListener {
|
binding.actionSettings.setOnSingleClickListener {
|
||||||
Navigation.findNavController(it).navigate(R.id.action_appMainFragment_to_appSettingsFragment,)
|
Navigation.findNavController(it).navigate(R.id.action_appMainFragment_to_appSettingsFragment,)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,6 +156,14 @@ class MainFragment : Fragment() {
|
|||||||
binding.toolbar.cardElevation = if (it > 0) 24f else 0f
|
binding.toolbar.cardElevation = if (it > 0) 24f else 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewModel.widgetAlign.observe(viewLifecycleOwner) {
|
||||||
|
updatePreviewVisibility()
|
||||||
|
lifecycleScope.launch {
|
||||||
|
delay(350)
|
||||||
|
updateClock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
viewModel.showPreview.observe(viewLifecycleOwner) {
|
viewModel.showPreview.observe(viewLifecycleOwner) {
|
||||||
updatePreviewVisibility()
|
updatePreviewVisibility()
|
||||||
}
|
}
|
||||||
@ -180,8 +184,6 @@ class MainFragment : Fragment() {
|
|||||||
private var uiJob: Job? = null
|
private var uiJob: Job? = null
|
||||||
|
|
||||||
private fun updateUI() {
|
private fun updateUI() {
|
||||||
uiJob?.cancel()
|
|
||||||
|
|
||||||
if (Preferences.showPreview) {
|
if (Preferences.showPreview) {
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
val bgColor: Int = ContextCompat.getColor(
|
val bgColor: Int = ContextCompat.getColor(
|
||||||
@ -204,28 +206,33 @@ class MainFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
WidgetHelper.runWithCustomTypeface(requireContext()) { typeface ->
|
WidgetHelper.runWithCustomTypeface(requireContext()) { typeface ->
|
||||||
|
uiJob?.cancel()
|
||||||
uiJob = lifecycleScope.launch(Dispatchers.IO) {
|
uiJob = lifecycleScope.launch(Dispatchers.IO) {
|
||||||
val generatedView = MainWidget.generateWidgetView(requireContext(), typeface).root
|
val generatedView = MainWidget.getWidgetView(requireContext(), typeface)?.root
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
if (generatedView != null) {
|
||||||
generatedView.measure(0, 0)
|
withContext(Dispatchers.Main) {
|
||||||
binding.preview.measure(0, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
val bitmap = BitmapHelper.getBitmapFromView(
|
binding.widgetDetail.content.removeAllViews()
|
||||||
generatedView,
|
val container = LinearLayout(requireContext()).apply {
|
||||||
if (binding.preview.width > 0) binding.preview.width else generatedView.measuredWidth,
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
generatedView.measuredHeight
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
)
|
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
container.gravity = when (Preferences.widgetAlign) {
|
||||||
|
Constants.WidgetAlign.CENTER.rawValue -> Gravity.CENTER_HORIZONTAL
|
||||||
|
Constants.WidgetAlign.LEFT.rawValue -> Gravity.START
|
||||||
|
Constants.WidgetAlign.RIGHT.rawValue -> Gravity.END
|
||||||
|
else -> Gravity.NO_GRAVITY
|
||||||
|
}
|
||||||
|
container.addView(generatedView)
|
||||||
|
binding.widgetDetail.content.addView(container)
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
binding.widgetLoader.animate().scaleX(0f).scaleY(0f).alpha(0f)
|
||||||
binding.widgetDetail.bitmapContainer.apply {
|
.setDuration(200L).start()
|
||||||
setImageBitmap(bitmap)
|
binding.widget.animate().alpha(1f).start()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.widgetLoader.animate().scaleX(0f).scaleY(0f).alpha(0f)
|
|
||||||
.setDuration(200L).start()
|
|
||||||
binding.widget.animate().alpha(1f).start()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,16 +253,74 @@ class MainFragment : Fragment() {
|
|||||||
)
|
)
|
||||||
binding.widgetDetail.timeAmPm.isVisible = Preferences.showAMPMIndicator
|
binding.widgetDetail.timeAmPm.isVisible = Preferences.showAMPMIndicator
|
||||||
|
|
||||||
|
// Timezones
|
||||||
|
if (Preferences.altTimezoneId != "" && Preferences.altTimezoneLabel != "") {
|
||||||
|
// Clock
|
||||||
|
binding.widgetDetail.altTimezoneTime.timeZone = Preferences.altTimezoneId
|
||||||
|
binding.widgetDetail.altTimezoneTimeAmPm.timeZone = Preferences.altTimezoneId
|
||||||
|
binding.widgetDetail.altTimezoneLabel.text = Preferences.altTimezoneLabel
|
||||||
|
binding.widgetDetail.altTimezoneTime.setTextColor(ColorHelper.getClockFontColor(requireActivity().isDarkTheme()))
|
||||||
|
binding.widgetDetail.altTimezoneTimeAmPm.setTextColor(ColorHelper.getClockFontColor(requireActivity().isDarkTheme()))
|
||||||
|
binding.widgetDetail.altTimezoneLabel.setTextColor(ColorHelper.getClockFontColor(requireActivity().isDarkTheme()))
|
||||||
|
binding.widgetDetail.altTimezoneTime.setTextSize(
|
||||||
|
TypedValue.COMPLEX_UNIT_SP,
|
||||||
|
Preferences.clockTextSize.toPixel(requireContext()) / 3
|
||||||
|
)
|
||||||
|
binding.widgetDetail.altTimezoneTimeAmPm.setTextSize(
|
||||||
|
TypedValue.COMPLEX_UNIT_SP,
|
||||||
|
(Preferences.clockTextSize.toPixel(requireContext()) / 3) / 5 * 2
|
||||||
|
)
|
||||||
|
binding.widgetDetail.altTimezoneLabel.setTextSize(
|
||||||
|
TypedValue.COMPLEX_UNIT_SP,
|
||||||
|
(Preferences.clockTextSize.toPixel(requireContext()) / 3) / 5 * 2
|
||||||
|
)
|
||||||
|
binding.widgetDetail.timezonesContainer.isVisible = true
|
||||||
|
} else {
|
||||||
|
binding.widgetDetail.timezonesContainer.isVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
// Clock bottom margin
|
// Clock bottom margin
|
||||||
binding.widgetDetail.clockBottomMarginNone.isVisible =
|
binding.widgetDetail.clockBottomMarginNone.isVisible =
|
||||||
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.value
|
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.rawValue
|
||||||
binding.widgetDetail.clockBottomMarginSmall.isVisible =
|
binding.widgetDetail.clockBottomMarginSmall.isVisible =
|
||||||
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.value
|
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.rawValue
|
||||||
binding.widgetDetail.clockBottomMarginMedium.isVisible =
|
binding.widgetDetail.clockBottomMarginMedium.isVisible =
|
||||||
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.value
|
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.rawValue
|
||||||
binding.widgetDetail.clockBottomMarginLarge.isVisible =
|
binding.widgetDetail.clockBottomMarginLarge.isVisible =
|
||||||
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.value
|
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.rawValue
|
||||||
|
|
||||||
|
// Align
|
||||||
|
binding.widgetDetail.timeContainer.layoutParams = (binding.widgetDetail.timeContainer.layoutParams as LinearLayout.LayoutParams).apply {
|
||||||
|
gravity = when (Preferences.widgetAlign) {
|
||||||
|
Constants.WidgetAlign.CENTER.rawValue -> Gravity.CENTER_HORIZONTAL
|
||||||
|
Constants.WidgetAlign.LEFT.rawValue -> Gravity.START
|
||||||
|
Constants.WidgetAlign.RIGHT.rawValue -> Gravity.END
|
||||||
|
else -> Gravity.NO_GRAVITY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Preferences.widgetAlign == Constants.WidgetAlign.RIGHT.rawValue) {
|
||||||
|
with (binding.widgetDetail.timeContainer) {
|
||||||
|
val child = getChildAt(2)
|
||||||
|
if (child.id == R.id.timezones_container) {
|
||||||
|
removeViewAt(2)
|
||||||
|
child.layoutParams = (child.layoutParams as ViewGroup.MarginLayoutParams).apply {
|
||||||
|
marginEnd = 16f.convertDpToPixel(requireContext()).toInt()
|
||||||
|
}
|
||||||
|
addView(child, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
with (binding.widgetDetail.timeContainer) {
|
||||||
|
val child = getChildAt(0)
|
||||||
|
if (child.id == R.id.timezones_container) {
|
||||||
|
removeViewAt(0)
|
||||||
|
child.layoutParams = (child.layoutParams as ViewGroup.MarginLayoutParams).apply {
|
||||||
|
marginEnd = 0
|
||||||
|
}
|
||||||
|
addView(child, 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateClockVisibility(showClock: Boolean) {
|
private fun updateClockVisibility(showClock: Boolean) {
|
||||||
@ -265,7 +330,7 @@ class MainFragment : Fragment() {
|
|||||||
updatePreviewVisibility()
|
updatePreviewVisibility()
|
||||||
|
|
||||||
if (showClock) {
|
if (showClock) {
|
||||||
binding.widgetDetail.timeContainer.layoutParams = binding.widgetDetail.timeContainer.layoutParams.apply {
|
binding.widgetDetail.timeContainer.layoutParams = (binding.widgetDetail.timeContainer.layoutParams as LinearLayout.LayoutParams).apply {
|
||||||
height = RelativeLayout.LayoutParams.WRAP_CONTENT
|
height = RelativeLayout.LayoutParams.WRAP_CONTENT
|
||||||
}
|
}
|
||||||
binding.widgetDetail.timeContainer.measure(0, 0)
|
binding.widgetDetail.timeContainer.measure(0, 0)
|
||||||
@ -277,7 +342,7 @@ class MainFragment : Fragment() {
|
|||||||
if (showClock) 0f else 1f,
|
if (showClock) 0f else 1f,
|
||||||
if (showClock) 1f else 0f
|
if (showClock) 1f else 0f
|
||||||
).apply {
|
).apply {
|
||||||
duration = 300L
|
duration = 500L
|
||||||
addUpdateListener {
|
addUpdateListener {
|
||||||
val animatedValue = animatedValue as Float
|
val animatedValue = animatedValue as Float
|
||||||
binding.widgetDetail.timeContainer.layoutParams =
|
binding.widgetDetail.timeContainer.layoutParams =
|
||||||
@ -285,6 +350,10 @@ class MainFragment : Fragment() {
|
|||||||
height = (initialHeight * animatedValue).toInt()
|
height = (initialHeight * animatedValue).toInt()
|
||||||
}
|
}
|
||||||
binding.widgetDetail.time.alpha = animatedValue
|
binding.widgetDetail.time.alpha = animatedValue
|
||||||
|
binding.widgetDetail.timeAmPm.alpha = animatedValue
|
||||||
|
binding.widgetDetail.altTimezoneTime.alpha = animatedValue
|
||||||
|
binding.widgetDetail.altTimezoneTimeAmPm.alpha = animatedValue
|
||||||
|
binding.widgetDetail.altTimezoneLabel.alpha = animatedValue
|
||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
@ -301,7 +370,7 @@ class MainFragment : Fragment() {
|
|||||||
requireContext()
|
requireContext()
|
||||||
) else 0)
|
) else 0)
|
||||||
).apply {
|
).apply {
|
||||||
duration = 300L
|
duration = 500L
|
||||||
addUpdateListener {
|
addUpdateListener {
|
||||||
val animatedValue = animatedValue as Int
|
val animatedValue = animatedValue as Int
|
||||||
val layoutParams = binding.preview.layoutParams
|
val layoutParams = binding.preview.layoutParams
|
||||||
|
@ -36,6 +36,7 @@ import com.tommasoberlose.anotherwidget.ui.activities.settings.SupportDevActivit
|
|||||||
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.openURI
|
import com.tommasoberlose.anotherwidget.utils.openURI
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.setOnSingleClickListener
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -76,7 +77,7 @@ class SettingsFragment : Fragment() {
|
|||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
|
||||||
binding.actionBack.setOnClickListener {
|
binding.actionBack.setOnSingleClickListener {
|
||||||
Navigation.findNavController(it).popBackStack()
|
Navigation.findNavController(it).popBackStack()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,19 +1,14 @@
|
|||||||
package com.tommasoberlose.anotherwidget.ui.fragments.tabs
|
package com.tommasoberlose.anotherwidget.ui.fragments.tabs
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.Activity
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.CalendarContract
|
import android.provider.CalendarContract
|
||||||
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 androidx.databinding.DataBindingUtil
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.Observer
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.chibatching.kotpref.bulk
|
|
||||||
import com.google.android.material.transition.MaterialSharedAxis
|
import com.google.android.material.transition.MaterialSharedAxis
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
|
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
|
||||||
@ -21,20 +16,15 @@ import com.tommasoberlose.anotherwidget.models.CalendarSelector
|
|||||||
import com.tommasoberlose.anotherwidget.databinding.FragmentTabCalendarBinding
|
import com.tommasoberlose.anotherwidget.databinding.FragmentTabCalendarBinding
|
||||||
import com.tommasoberlose.anotherwidget.global.Constants
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.global.RequestCode
|
|
||||||
import com.tommasoberlose.anotherwidget.ui.activities.tabs.ChooseApplicationActivity
|
|
||||||
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.helpers.CalendarHelper
|
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.IntentHelper
|
|
||||||
import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper
|
import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper
|
||||||
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.isDefaultSet
|
|
||||||
import com.tommasoberlose.anotherwidget.utils.toast
|
import com.tommasoberlose.anotherwidget.utils.toast
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlin.Comparator
|
|
||||||
|
|
||||||
class CalendarFragment : Fragment() {
|
class CalendarFragment : Fragment() {
|
||||||
|
|
||||||
@ -110,9 +100,9 @@ class CalendarFragment : Fragment() {
|
|||||||
viewModel.widgetUpdateFrequency.observe(viewLifecycleOwner) {
|
viewModel.widgetUpdateFrequency.observe(viewLifecycleOwner) {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
binding.widgetUpdateFrequencyLabel.text = when (it) {
|
binding.widgetUpdateFrequencyLabel.text = when (it) {
|
||||||
Constants.WidgetUpdateFrequency.HIGH.value -> getString(R.string.settings_widget_update_frequency_high)
|
Constants.WidgetUpdateFrequency.HIGH.rawValue -> getString(R.string.settings_widget_update_frequency_high)
|
||||||
Constants.WidgetUpdateFrequency.DEFAULT.value -> getString(R.string.settings_widget_update_frequency_default)
|
Constants.WidgetUpdateFrequency.DEFAULT.rawValue -> getString(R.string.settings_widget_update_frequency_default)
|
||||||
Constants.WidgetUpdateFrequency.LOW.value -> getString(R.string.settings_widget_update_frequency_low)
|
Constants.WidgetUpdateFrequency.LOW.rawValue -> getString(R.string.settings_widget_update_frequency_low)
|
||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,9 +234,9 @@ class CalendarFragment : Fragment() {
|
|||||||
binding.actionWidgetUpdateFrequency.setOnClickListener {
|
binding.actionWidgetUpdateFrequency.setOnClickListener {
|
||||||
if (Preferences.showEvents && Preferences.showDiffTime) {
|
if (Preferences.showEvents && Preferences.showDiffTime) {
|
||||||
BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_widget_update_frequency_title), message = getString(R.string.settings_widget_update_frequency_subtitle)).setSelectedValue(Preferences.widgetUpdateFrequency)
|
BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_widget_update_frequency_title), message = getString(R.string.settings_widget_update_frequency_subtitle)).setSelectedValue(Preferences.widgetUpdateFrequency)
|
||||||
.addItem(getString(R.string.settings_widget_update_frequency_high), Constants.WidgetUpdateFrequency.HIGH.value)
|
.addItem(getString(R.string.settings_widget_update_frequency_high), Constants.WidgetUpdateFrequency.HIGH.rawValue)
|
||||||
.addItem(getString(R.string.settings_widget_update_frequency_default), Constants.WidgetUpdateFrequency.DEFAULT.value)
|
.addItem(getString(R.string.settings_widget_update_frequency_default), Constants.WidgetUpdateFrequency.DEFAULT.rawValue)
|
||||||
.addItem(getString(R.string.settings_widget_update_frequency_low), Constants.WidgetUpdateFrequency.LOW.value)
|
.addItem(getString(R.string.settings_widget_update_frequency_low), Constants.WidgetUpdateFrequency.LOW.rawValue)
|
||||||
.addOnSelectItemListener { value ->
|
.addOnSelectItemListener { value ->
|
||||||
Preferences.widgetUpdateFrequency = value
|
Preferences.widgetUpdateFrequency = value
|
||||||
}.show()
|
}.show()
|
||||||
|
@ -28,6 +28,7 @@ import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue
|
|||||||
import com.tommasoberlose.anotherwidget.helpers.IntentHelper
|
import com.tommasoberlose.anotherwidget.helpers.IntentHelper
|
||||||
import com.tommasoberlose.anotherwidget.ui.activities.tabs.ChooseApplicationActivity
|
import com.tommasoberlose.anotherwidget.ui.activities.tabs.ChooseApplicationActivity
|
||||||
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.activities.tabs.TimeZoneSelectorActivity
|
||||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||||
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||||
import com.tommasoberlose.anotherwidget.utils.isDefaultSet
|
import com.tommasoberlose.anotherwidget.utils.isDefaultSet
|
||||||
@ -100,6 +101,17 @@ class ClockFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewModel.altTimezoneLabel.observe(viewLifecycleOwner) {
|
||||||
|
maintainScrollPosition {
|
||||||
|
if (it != "") {
|
||||||
|
binding.altTimezoneClockLabel.text =
|
||||||
|
String.format("%s (%s)", it, Preferences.altTimezoneId)
|
||||||
|
} else {
|
||||||
|
binding.altTimezoneClockLabel.text = getString(R.string.no_time_zone_label)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
viewModel.showAMPMIndicator.observe(viewLifecycleOwner) {
|
viewModel.showAMPMIndicator.observe(viewLifecycleOwner) {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
binding.ampmIndicatorLabel.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
|
binding.ampmIndicatorLabel.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
|
||||||
@ -144,6 +156,10 @@ class ClockFragment : Fragment() {
|
|||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.actionAltTimezoneClock.setOnClickListener {
|
||||||
|
startActivity(Intent(requireContext(), TimeZoneSelectorActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
binding.actionAmpmIndicatorSize.setOnClickListener {
|
binding.actionAmpmIndicatorSize.setOnClickListener {
|
||||||
binding.ampmIndicatorToggle.isChecked = !binding.ampmIndicatorToggle.isChecked
|
binding.ampmIndicatorToggle.isChecked = !binding.ampmIndicatorToggle.isChecked
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ class GesturesFragment : Fragment() {
|
|||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
binding.calendarAppLabel.text = when {
|
binding.calendarAppLabel.text = when {
|
||||||
it == IntentHelper.DO_NOTHING_OPTION -> getString(R.string.gestures_do_nothing)
|
it == IntentHelper.DO_NOTHING_OPTION -> getString(R.string.gestures_do_nothing)
|
||||||
it == IntentHelper.REFRESH_WIDGET_OPTION -> "None, the widget will be refreshed"
|
it == IntentHelper.REFRESH_WIDGET_OPTION -> getString(R.string.gestures_refresh_widget)
|
||||||
it != IntentHelper.DEFAULT_OPTION -> it
|
it != IntentHelper.DEFAULT_OPTION -> it
|
||||||
else -> {
|
else -> {
|
||||||
if (IntentHelper.getCalendarIntent(requireContext()).isDefaultSet(requireContext())) {
|
if (IntentHelper.getCalendarIntent(requireContext()).isDefaultSet(requireContext())) {
|
||||||
@ -125,7 +125,7 @@ class GesturesFragment : Fragment() {
|
|||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
binding.clockAppLabel.text = when {
|
binding.clockAppLabel.text = when {
|
||||||
it == IntentHelper.DO_NOTHING_OPTION -> getString(R.string.gestures_do_nothing)
|
it == IntentHelper.DO_NOTHING_OPTION -> getString(R.string.gestures_do_nothing)
|
||||||
it == IntentHelper.REFRESH_WIDGET_OPTION -> "None, the widget will be refreshed"
|
it == IntentHelper.REFRESH_WIDGET_OPTION -> getString(R.string.gestures_refresh_widget)
|
||||||
it != IntentHelper.DEFAULT_OPTION -> it
|
it != IntentHelper.DEFAULT_OPTION -> it
|
||||||
else -> {
|
else -> {
|
||||||
if (IntentHelper.getClockIntent(requireContext()).isDefaultSet(requireContext())) {
|
if (IntentHelper.getClockIntent(requireContext()).isDefaultSet(requireContext())) {
|
||||||
@ -144,7 +144,7 @@ class GesturesFragment : Fragment() {
|
|||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
binding.weatherAppLabel.text = when {
|
binding.weatherAppLabel.text = when {
|
||||||
it == IntentHelper.DO_NOTHING_OPTION -> getString(R.string.gestures_do_nothing)
|
it == IntentHelper.DO_NOTHING_OPTION -> getString(R.string.gestures_do_nothing)
|
||||||
it == IntentHelper.REFRESH_WIDGET_OPTION -> "None, the widget will be refreshed"
|
it == IntentHelper.REFRESH_WIDGET_OPTION -> getString(R.string.gestures_refresh_widget)
|
||||||
it != IntentHelper.DEFAULT_OPTION -> it
|
it != IntentHelper.DEFAULT_OPTION -> it
|
||||||
else -> getString(R.string.default_weather_app)
|
else -> getString(R.string.default_weather_app)
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
package com.tommasoberlose.anotherwidget.ui.fragments.tabs
|
package com.tommasoberlose.anotherwidget.ui.fragments.tabs
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
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 androidx.databinding.DataBindingUtil
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
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.google.android.material.transition.MaterialSharedAxis
|
import com.google.android.material.transition.MaterialSharedAxis
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
import com.tommasoberlose.anotherwidget.components.BottomSheetColorPicker
|
import com.tommasoberlose.anotherwidget.components.BottomSheetColorPicker
|
||||||
@ -22,8 +20,6 @@ import com.tommasoberlose.anotherwidget.global.Preferences
|
|||||||
import com.tommasoberlose.anotherwidget.helpers.ColorHelper
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toHexValue
|
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.ui.activities.tabs.CustomDateActivity
|
|
||||||
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.utils.isDarkTheme
|
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||||
@ -31,7 +27,6 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
|
|
||||||
class LayoutFragment : Fragment() {
|
class LayoutFragment : Fragment() {
|
||||||
@ -94,20 +89,38 @@ class LayoutFragment : Fragment() {
|
|||||||
viewModel.secondRowTopMargin.observe(viewLifecycleOwner) {
|
viewModel.secondRowTopMargin.observe(viewLifecycleOwner) {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
binding.secondRowTopMarginLabel.text = when (it) {
|
binding.secondRowTopMarginLabel.text = when (it) {
|
||||||
Constants.SecondRowTopMargin.NONE.value -> getString(R.string.settings_clock_bottom_margin_subtitle_none)
|
Constants.SecondRowTopMargin.NONE.rawValue -> getString(R.string.settings_clock_bottom_margin_subtitle_none)
|
||||||
Constants.SecondRowTopMargin.SMALL.value -> getString(R.string.settings_clock_bottom_margin_subtitle_small)
|
Constants.SecondRowTopMargin.SMALL.rawValue -> getString(R.string.settings_clock_bottom_margin_subtitle_small)
|
||||||
Constants.SecondRowTopMargin.LARGE.value -> getString(R.string.settings_clock_bottom_margin_subtitle_large)
|
Constants.SecondRowTopMargin.LARGE.rawValue -> getString(R.string.settings_clock_bottom_margin_subtitle_large)
|
||||||
else -> getString(R.string.settings_clock_bottom_margin_subtitle_medium)
|
else -> getString(R.string.settings_clock_bottom_margin_subtitle_medium)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewModel.widgetAlign.observe(viewLifecycleOwner) {
|
||||||
|
maintainScrollPosition {
|
||||||
|
binding.widgetAlignIcon.setImageDrawable(when (it) {
|
||||||
|
Constants.WidgetAlign.LEFT.rawValue -> ContextCompat.getDrawable(requireContext(), R.drawable.round_align_horizontal_left_24)
|
||||||
|
Constants.WidgetAlign.RIGHT.rawValue -> ContextCompat.getDrawable(requireContext(), R.drawable.round_align_horizontal_right_24)
|
||||||
|
Constants.WidgetAlign.CENTER.rawValue -> ContextCompat.getDrawable(requireContext(), R.drawable.round_align_horizontal_center_24)
|
||||||
|
else -> ContextCompat.getDrawable(requireContext(), R.drawable.round_align_horizontal_center_24)
|
||||||
|
})
|
||||||
|
|
||||||
|
binding.widgetAlignLabel.text = when (it) {
|
||||||
|
Constants.WidgetAlign.LEFT.rawValue -> getString(R.string.settings_widget_align_left_subtitle)
|
||||||
|
Constants.WidgetAlign.RIGHT.rawValue -> getString(R.string.settings_widget_align_right_subtitle)
|
||||||
|
Constants.WidgetAlign.CENTER.rawValue -> getString(R.string.settings_widget_align_center_subtitle)
|
||||||
|
else -> getString(R.string.settings_widget_align_center_subtitle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
viewModel.clockBottomMargin.observe(viewLifecycleOwner) {
|
viewModel.clockBottomMargin.observe(viewLifecycleOwner) {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
binding.clockBottomMarginLabel.text = when (it) {
|
binding.clockBottomMarginLabel.text = when (it) {
|
||||||
Constants.ClockBottomMargin.NONE.value -> getString(R.string.settings_clock_bottom_margin_subtitle_none)
|
Constants.ClockBottomMargin.NONE.rawValue -> getString(R.string.settings_clock_bottom_margin_subtitle_none)
|
||||||
Constants.ClockBottomMargin.SMALL.value -> getString(R.string.settings_clock_bottom_margin_subtitle_small)
|
Constants.ClockBottomMargin.SMALL.rawValue -> getString(R.string.settings_clock_bottom_margin_subtitle_small)
|
||||||
Constants.ClockBottomMargin.LARGE.value -> getString(R.string.settings_clock_bottom_margin_subtitle_large)
|
Constants.ClockBottomMargin.LARGE.rawValue -> getString(R.string.settings_clock_bottom_margin_subtitle_large)
|
||||||
else -> getString(R.string.settings_clock_bottom_margin_subtitle_medium)
|
else -> getString(R.string.settings_clock_bottom_margin_subtitle_medium)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +128,7 @@ class LayoutFragment : Fragment() {
|
|||||||
|
|
||||||
viewModel.backgroundCardColor.observe(viewLifecycleOwner) {
|
viewModel.backgroundCardColor.observe(viewLifecycleOwner) {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
if (Preferences.backgroundCardAlpha == "00") {
|
if (ColorHelper.getBackgroundAlpha(requireActivity().isDarkTheme()) == 0) {
|
||||||
binding.backgroundColorLabel.text = getString(R.string.transparent)
|
binding.backgroundColorLabel.text = getString(R.string.transparent)
|
||||||
} else {
|
} else {
|
||||||
binding.backgroundColorLabel.text =
|
binding.backgroundColorLabel.text =
|
||||||
@ -141,19 +154,19 @@ class LayoutFragment : Fragment() {
|
|||||||
).setSelectedValue(Preferences.secondRowTopMargin)
|
).setSelectedValue(Preferences.secondRowTopMargin)
|
||||||
.addItem(
|
.addItem(
|
||||||
getString(R.string.settings_clock_bottom_margin_subtitle_none),
|
getString(R.string.settings_clock_bottom_margin_subtitle_none),
|
||||||
Constants.SecondRowTopMargin.NONE.value
|
Constants.SecondRowTopMargin.NONE.rawValue
|
||||||
)
|
)
|
||||||
.addItem(
|
.addItem(
|
||||||
getString(R.string.settings_clock_bottom_margin_subtitle_small),
|
getString(R.string.settings_clock_bottom_margin_subtitle_small),
|
||||||
Constants.SecondRowTopMargin.SMALL.value
|
Constants.SecondRowTopMargin.SMALL.rawValue
|
||||||
)
|
)
|
||||||
.addItem(
|
.addItem(
|
||||||
getString(R.string.settings_clock_bottom_margin_subtitle_medium),
|
getString(R.string.settings_clock_bottom_margin_subtitle_medium),
|
||||||
Constants.SecondRowTopMargin.MEDIUM.value
|
Constants.SecondRowTopMargin.MEDIUM.rawValue
|
||||||
)
|
)
|
||||||
.addItem(
|
.addItem(
|
||||||
getString(R.string.settings_clock_bottom_margin_subtitle_large),
|
getString(R.string.settings_clock_bottom_margin_subtitle_large),
|
||||||
Constants.SecondRowTopMargin.LARGE.value
|
Constants.SecondRowTopMargin.LARGE.rawValue
|
||||||
)
|
)
|
||||||
.addOnSelectItemListener { value ->
|
.addOnSelectItemListener { value ->
|
||||||
Preferences.secondRowTopMargin = value
|
Preferences.secondRowTopMargin = value
|
||||||
@ -167,25 +180,47 @@ class LayoutFragment : Fragment() {
|
|||||||
).setSelectedValue(Preferences.clockBottomMargin)
|
).setSelectedValue(Preferences.clockBottomMargin)
|
||||||
.addItem(
|
.addItem(
|
||||||
getString(R.string.settings_clock_bottom_margin_subtitle_none),
|
getString(R.string.settings_clock_bottom_margin_subtitle_none),
|
||||||
Constants.ClockBottomMargin.NONE.value
|
Constants.ClockBottomMargin.NONE.rawValue
|
||||||
)
|
)
|
||||||
.addItem(
|
.addItem(
|
||||||
getString(R.string.settings_clock_bottom_margin_subtitle_small),
|
getString(R.string.settings_clock_bottom_margin_subtitle_small),
|
||||||
Constants.ClockBottomMargin.SMALL.value
|
Constants.ClockBottomMargin.SMALL.rawValue
|
||||||
)
|
)
|
||||||
.addItem(
|
.addItem(
|
||||||
getString(R.string.settings_clock_bottom_margin_subtitle_medium),
|
getString(R.string.settings_clock_bottom_margin_subtitle_medium),
|
||||||
Constants.ClockBottomMargin.MEDIUM.value
|
Constants.ClockBottomMargin.MEDIUM.rawValue
|
||||||
)
|
)
|
||||||
.addItem(
|
.addItem(
|
||||||
getString(R.string.settings_clock_bottom_margin_subtitle_large),
|
getString(R.string.settings_clock_bottom_margin_subtitle_large),
|
||||||
Constants.ClockBottomMargin.LARGE.value
|
Constants.ClockBottomMargin.LARGE.rawValue
|
||||||
)
|
)
|
||||||
.addOnSelectItemListener { value ->
|
.addOnSelectItemListener { value ->
|
||||||
Preferences.clockBottomMargin = value
|
Preferences.clockBottomMargin = value
|
||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.actionWidgetAlign.setOnClickListener {
|
||||||
|
BottomSheetMenu<Int>(
|
||||||
|
requireContext(),
|
||||||
|
header = getString(R.string.settings_widget_align_title)
|
||||||
|
).setSelectedValue(Preferences.widgetAlign)
|
||||||
|
.addItem(
|
||||||
|
getString(R.string.settings_widget_align_center_subtitle),
|
||||||
|
Constants.WidgetAlign.CENTER.rawValue
|
||||||
|
)
|
||||||
|
.addItem(
|
||||||
|
getString(R.string.settings_widget_align_left_subtitle),
|
||||||
|
Constants.WidgetAlign.LEFT.rawValue
|
||||||
|
)
|
||||||
|
.addItem(
|
||||||
|
getString(R.string.settings_widget_align_right_subtitle),
|
||||||
|
Constants.WidgetAlign.RIGHT.rawValue
|
||||||
|
)
|
||||||
|
.addOnSelectItemListener { value ->
|
||||||
|
Preferences.widgetAlign = value
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
|
||||||
binding.actionBackgroundColor.setOnClickListener {
|
binding.actionBackgroundColor.setOnClickListener {
|
||||||
BottomSheetColorPicker(requireContext(),
|
BottomSheetColorPicker(requireContext(),
|
||||||
colors = colors,
|
colors = colors,
|
||||||
|
@ -106,15 +106,15 @@ class PreferencesFragment : Fragment() {
|
|||||||
|
|
||||||
private fun setupListener() {
|
private fun setupListener() {
|
||||||
|
|
||||||
binding.actionTypography.setOnClickListener {
|
binding.actionTypography.setOnSingleClickListener {
|
||||||
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_typographyTabFragment)
|
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_typographyTabFragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.actionGeneralSettings.setOnClickListener {
|
binding.actionGeneralSettings.setOnSingleClickListener {
|
||||||
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_generalTabFragment)
|
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_generalTabFragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.actionShowEvents.setOnClickListener {
|
binding.actionShowEvents.setOnSingleClickListener {
|
||||||
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_calendarTabFragment)
|
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_calendarTabFragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ class PreferencesFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.actionShowWeather.setOnClickListener {
|
binding.actionShowWeather.setOnSingleClickListener {
|
||||||
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_weatherTabFragment)
|
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_weatherTabFragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ class PreferencesFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.actionShowClock.setOnClickListener {
|
binding.actionShowClock.setOnSingleClickListener {
|
||||||
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_clockTabFragment)
|
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_clockTabFragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,11 +147,11 @@ class PreferencesFragment : Fragment() {
|
|||||||
Preferences.showClock = enabled
|
Preferences.showClock = enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.actionShowGlance.setOnClickListener {
|
binding.actionShowGlance.setOnSingleClickListener {
|
||||||
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_glanceTabFragment)
|
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_glanceTabFragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.actionTabDefaultApp.setOnClickListener {
|
binding.actionTabDefaultApp.setOnSingleClickListener {
|
||||||
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_gesturesFragment)
|
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_gesturesFragment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ class MainViewModel(context: Application) : AndroidViewModel(context) {
|
|||||||
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)
|
||||||
|
val widgetAlign = Preferences.asLiveData(Preferences::widgetAlign)
|
||||||
|
|
||||||
// Calendar Settings
|
// Calendar Settings
|
||||||
val showEvents = Preferences.asLiveData(Preferences::showEvents)
|
val showEvents = Preferences.asLiveData(Preferences::showEvents)
|
||||||
@ -64,6 +65,7 @@ class MainViewModel(context: Application) : AndroidViewModel(context) {
|
|||||||
// Clock Settings
|
// Clock Settings
|
||||||
val showClock = Preferences.asLiveData(Preferences::showClock)
|
val showClock = Preferences.asLiveData(Preferences::showClock)
|
||||||
val clockTextSize = Preferences.asLiveData(Preferences::clockTextSize)
|
val clockTextSize = Preferences.asLiveData(Preferences::clockTextSize)
|
||||||
|
val altTimezoneLabel = Preferences.asLiveData(Preferences::altTimezoneLabel)
|
||||||
val clockTextColor = MediatorLiveData<Boolean>().apply {
|
val clockTextColor = MediatorLiveData<Boolean>().apply {
|
||||||
addSource(Preferences.asLiveData(Preferences::clockTextColor)) { value = true }
|
addSource(Preferences.asLiveData(Preferences::clockTextColor)) { value = true }
|
||||||
addSource(Preferences.asLiveData(Preferences::clockTextAlpha)) { value = true }
|
addSource(Preferences.asLiveData(Preferences::clockTextAlpha)) { value = true }
|
||||||
@ -107,6 +109,7 @@ class MainViewModel(context: Application) : AndroidViewModel(context) {
|
|||||||
addSource(Preferences.asLiveData(Preferences::clockTextAlphaDark)) { value = true }
|
addSource(Preferences.asLiveData(Preferences::clockTextAlphaDark)) { value = true }
|
||||||
addSource(Preferences.asLiveData(Preferences::showAMPMIndicator)) { value = true }
|
addSource(Preferences.asLiveData(Preferences::showAMPMIndicator)) { value = true }
|
||||||
addSource(Preferences.asLiveData(Preferences::clockBottomMargin)) { value = true }
|
addSource(Preferences.asLiveData(Preferences::clockBottomMargin)) { value = true }
|
||||||
|
addSource(Preferences.asLiveData(Preferences::altTimezoneLabel)) { value = true }
|
||||||
}
|
}
|
||||||
val widgetPreferencesUpdate = MediatorLiveData<Boolean>().apply {
|
val widgetPreferencesUpdate = MediatorLiveData<Boolean>().apply {
|
||||||
addSource(Preferences.asLiveData(Preferences::textGlobalColor)) { value = true }
|
addSource(Preferences.asLiveData(Preferences::textGlobalColor)) { value = true }
|
||||||
@ -131,6 +134,7 @@ class MainViewModel(context: Application) : AndroidViewModel(context) {
|
|||||||
addSource(Preferences.asLiveData(Preferences::customFontName)) { value = true }
|
addSource(Preferences.asLiveData(Preferences::customFontName)) { value = true }
|
||||||
addSource(Preferences.asLiveData(Preferences::customFontVariant)) { value = true }
|
addSource(Preferences.asLiveData(Preferences::customFontVariant)) { value = true }
|
||||||
addSource(Preferences.asLiveData(Preferences::secondRowInformation)) { value = true }
|
addSource(Preferences.asLiveData(Preferences::secondRowInformation)) { value = true }
|
||||||
|
addSource(Preferences.asLiveData(Preferences::widgetAlign)) { value = true }
|
||||||
addSource(Preferences.asLiveData(Preferences::showDividers)) { value = true }
|
addSource(Preferences.asLiveData(Preferences::showDividers)) { value = true }
|
||||||
addSource(Preferences.asLiveData(Preferences::secondRowTopMargin)) { value = true }
|
addSource(Preferences.asLiveData(Preferences::secondRowTopMargin)) { value = true }
|
||||||
addSource(Preferences.asLiveData(Preferences::isDateCapitalize)) { value = true }
|
addSource(Preferences.asLiveData(Preferences::isDateCapitalize)) { value = true }
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.ui.viewmodels.tabs
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.location.Address
|
||||||
|
import androidx.lifecycle.AndroidViewModel
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
|
||||||
|
class TimeZoneSelectorViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
|
|
||||||
|
val addresses: MutableLiveData<List<Address>> = MutableLiveData(emptyList())
|
||||||
|
val locationInput: MutableLiveData<String> = MutableLiveData(Preferences.altTimezoneLabel)
|
||||||
|
}
|
@ -0,0 +1,909 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.ui.widgets
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import android.text.format.DateUtils
|
||||||
|
import android.util.Log
|
||||||
|
import android.util.TypedValue
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.*
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.core.view.updateMargins
|
||||||
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.databinding.LeftAlignedWidgetBinding
|
||||||
|
import com.tommasoberlose.anotherwidget.db.EventRepository
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Actions
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.*
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.ImageHelper.applyShadow
|
||||||
|
import com.tommasoberlose.anotherwidget.receivers.CrashlyticsReceiver
|
||||||
|
import com.tommasoberlose.anotherwidget.receivers.NewCalendarEventReceiver
|
||||||
|
import com.tommasoberlose.anotherwidget.receivers.WidgetClickListenerReceiver
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.convertDpToPixel
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||||
|
import java.text.DateFormat
|
||||||
|
import java.util.*
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
||||||
|
fun generateWidget(appWidgetId: Int, w: Int, typeface: Typeface? = null): RemoteViews? {
|
||||||
|
|
||||||
|
var views = RemoteViews(context.packageName, if (!rightAligned) R.layout.left_aligned_widget_sans else R.layout.right_aligned_widget_sans)
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Background
|
||||||
|
views.setInt(
|
||||||
|
R.id.widget_shape_background,
|
||||||
|
"setColorFilter",
|
||||||
|
ColorHelper.getBackgroundColorRgb(context.isDarkTheme())
|
||||||
|
)
|
||||||
|
views.setInt(
|
||||||
|
R.id.widget_shape_background,
|
||||||
|
"setImageAlpha",
|
||||||
|
ColorHelper.getBackgroundAlpha(context.isDarkTheme())
|
||||||
|
)
|
||||||
|
val refreshIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
appWidgetId,
|
||||||
|
IntentHelper.getWidgetUpdateIntent(context),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.widget_shape_background, refreshIntent)
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
ex.printStackTrace()
|
||||||
|
CrashlyticsReceiver.sendCrash(context, ex)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clock
|
||||||
|
views = ClockWidget(context).updateClockView(views, appWidgetId)
|
||||||
|
|
||||||
|
// Setup listener
|
||||||
|
try {
|
||||||
|
val generatedBinding = generateWidgetView(typeface) ?: return null
|
||||||
|
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.bitmap_container,
|
||||||
|
BitmapHelper.getBitmapFromView(generatedBinding.root, width = w)
|
||||||
|
)
|
||||||
|
views = updateGridView(generatedBinding, views, appWidgetId)
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
ex.printStackTrace()
|
||||||
|
CrashlyticsReceiver.sendCrash(context, ex)
|
||||||
|
}
|
||||||
|
|
||||||
|
return views
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateGridView(bindingView: LeftAlignedWidgetBinding, views: RemoteViews, widgetID: Int): RemoteViews {
|
||||||
|
try {
|
||||||
|
val eventRepository = EventRepository(context)
|
||||||
|
val nextEvent = eventRepository.getNextEvent()
|
||||||
|
val eventsCount = eventRepository.getEventsCount()
|
||||||
|
eventRepository.close()
|
||||||
|
|
||||||
|
// Weather
|
||||||
|
if (Preferences.showWeather && Preferences.weatherIcon != "") {
|
||||||
|
views.setViewVisibility(R.id.weather_rect, View.VISIBLE)
|
||||||
|
views.setViewVisibility(R.id.weather_sub_line, View.GONE)
|
||||||
|
|
||||||
|
val i = Intent(context, WidgetClickListenerReceiver::class.java)
|
||||||
|
i.action = Actions.ACTION_OPEN_WEATHER_INTENT
|
||||||
|
val weatherPIntent = PendingIntent.getBroadcast(context, widgetID, i, 0)
|
||||||
|
|
||||||
|
views.setOnClickPendingIntent(R.id.weather_rect, weatherPIntent)
|
||||||
|
views.setOnClickPendingIntent(R.id.weather_sub_line_rect, weatherPIntent)
|
||||||
|
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.weather_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(bindingView.weatherDateLine, draw = false)
|
||||||
|
)
|
||||||
|
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.weather_sub_line_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(bindingView.weatherSubLine, draw = false)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
views.setViewVisibility(R.id.weather_rect, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.weather_sub_line, View.GONE)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Calendar
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.date_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(bindingView.date, draw = false)
|
||||||
|
)
|
||||||
|
|
||||||
|
val calPIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getCalendarIntent(context),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.date_rect, calPIntent)
|
||||||
|
views.setViewVisibility(R.id.first_line_rect, View.VISIBLE)
|
||||||
|
|
||||||
|
val nextAlarm = AlarmHelper.getNextAlarm(context)
|
||||||
|
|
||||||
|
// Spacing
|
||||||
|
views.setViewVisibility(
|
||||||
|
R.id.sub_line_top_margin_small_sans,
|
||||||
|
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.SMALL.rawValue) View.VISIBLE else View.GONE
|
||||||
|
)
|
||||||
|
views.setViewVisibility(
|
||||||
|
R.id.sub_line_top_margin_medium_sans,
|
||||||
|
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.MEDIUM.rawValue) View.VISIBLE else View.GONE
|
||||||
|
)
|
||||||
|
views.setViewVisibility(
|
||||||
|
R.id.sub_line_top_margin_large_sans,
|
||||||
|
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.rawValue) View.VISIBLE else View.GONE
|
||||||
|
)
|
||||||
|
|
||||||
|
if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null && !Preferences.showEventsAsGlanceProvider) {
|
||||||
|
if (Preferences.showNextEvent && eventsCount > 1) {
|
||||||
|
|
||||||
|
// Action next event
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.action_next_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(bindingView.actionNext, draw = false)
|
||||||
|
)
|
||||||
|
views.setViewVisibility(R.id.action_next_rect, View.VISIBLE)
|
||||||
|
views.setOnClickPendingIntent(
|
||||||
|
R.id.action_next_rect,
|
||||||
|
PendingIntent.getBroadcast(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
Intent(
|
||||||
|
context,
|
||||||
|
NewCalendarEventReceiver::class.java
|
||||||
|
).apply { action = Actions.ACTION_GO_TO_NEXT_EVENT },
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
views.setViewVisibility(R.id.action_next_rect, View.VISIBLE)
|
||||||
|
} else {
|
||||||
|
views.setViewVisibility(R.id.action_next_rect, View.GONE)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event intent
|
||||||
|
val eventIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getEventIntent(context, nextEvent),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.next_event_rect, eventIntent)
|
||||||
|
views.setViewVisibility(R.id.next_event_rect, View.VISIBLE)
|
||||||
|
|
||||||
|
// Event time difference
|
||||||
|
if (Preferences.showDiffTime && Calendar.getInstance().timeInMillis < nextEvent.startDate) {
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.next_event_difference_time_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(
|
||||||
|
bindingView.nextEventDifferenceTime,
|
||||||
|
draw = false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
views.setOnClickPendingIntent(R.id.next_event_difference_time_rect, eventIntent)
|
||||||
|
views.setViewVisibility(R.id.next_event_difference_time_rect, View.VISIBLE)
|
||||||
|
} else {
|
||||||
|
views.setViewVisibility(R.id.next_event_difference_time_rect, View.GONE)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event information
|
||||||
|
if (nextEvent.address != "" && Preferences.secondRowInformation == 1) {
|
||||||
|
val mapIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getGoogleMapsIntentFromAddress(context, nextEvent.address),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.sub_line_rect, mapIntent)
|
||||||
|
} else {
|
||||||
|
val pIntentDetail = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getEventIntent(
|
||||||
|
context,
|
||||||
|
nextEvent,
|
||||||
|
forceEventDetails = true
|
||||||
|
),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.sub_line_rect, pIntentDetail)
|
||||||
|
}
|
||||||
|
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.next_event_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(bindingView.nextEvent, draw = false)
|
||||||
|
)
|
||||||
|
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
|
||||||
|
|
||||||
|
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
|
||||||
|
views.setViewVisibility(R.id.sub_line_rect, View.VISIBLE)
|
||||||
|
views.setViewVisibility(R.id.weather_sub_line_rect, View.VISIBLE)
|
||||||
|
views.setViewVisibility(R.id.first_line_rect, View.GONE)
|
||||||
|
|
||||||
|
views.setViewVisibility(R.id.sub_line_top_margin_small_sans, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.sub_line_top_margin_medium_sans, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.sub_line_top_margin_large_sans, View.GONE)
|
||||||
|
} else if (GlanceProviderHelper.showGlanceProviders(context)) {
|
||||||
|
var showSomething = false
|
||||||
|
loop@ for (provider: Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders(context)) {
|
||||||
|
when (provider) {
|
||||||
|
Constants.GlanceProviderId.PLAYING_SONG -> {
|
||||||
|
if (MediaPlayerHelper.isSomeonePlaying(context)) {
|
||||||
|
val musicIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getMusicIntent(context),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.sub_line_rect, musicIntent)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> {
|
||||||
|
if (Preferences.showNextAlarm && nextAlarm != "") {
|
||||||
|
val alarmIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getClockIntent(context),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.sub_line_rect, alarmIntent)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
|
||||||
|
if (Preferences.showBatteryCharging) {
|
||||||
|
BatteryHelper.updateBatteryInfo(context)
|
||||||
|
if (Preferences.isCharging || Preferences.isBatteryLevelLow) {
|
||||||
|
val batteryIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getBatteryIntent(),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.sub_line_rect, batteryIntent)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.CUSTOM_INFO -> {
|
||||||
|
if (Preferences.customNotes.isNotEmpty()) {
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
|
||||||
|
if (Preferences.showDailySteps && Preferences.googleFitSteps > 0) {
|
||||||
|
val fitIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getFitIntent(context),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.sub_line_rect, fitIntent)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.NOTIFICATIONS -> {
|
||||||
|
if (Preferences.showNotifications && ActiveNotificationsHelper.showLastNotification()) {
|
||||||
|
try {
|
||||||
|
if (Preferences.lastNotificationIcon != 0) {
|
||||||
|
val remotePackageContext = context.createPackageContext(
|
||||||
|
Preferences.lastNotificationPackage, 0)
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
remotePackageContext,
|
||||||
|
Preferences.lastNotificationIcon)
|
||||||
|
}
|
||||||
|
val notificationIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getNotificationIntent(context),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(
|
||||||
|
R.id.sub_line_rect,
|
||||||
|
notificationIntent
|
||||||
|
)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
} catch (ex: Exception) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.GREETINGS -> {
|
||||||
|
if (Preferences.showGreetings && GreetingsHelper.showGreetings() && GreetingsHelper.getRandomString(context).isNotBlank()) {
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.EVENTS -> {
|
||||||
|
if (Preferences.showEventsAsGlanceProvider&& Preferences.showEvents && context.checkGrantedPermission(
|
||||||
|
Manifest.permission.READ_CALENDAR) && nextEvent != null) {
|
||||||
|
val pIntentDetail = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getEventIntent(
|
||||||
|
context,
|
||||||
|
nextEvent,
|
||||||
|
forceEventDetails = true
|
||||||
|
),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(
|
||||||
|
R.id.sub_line_rect,
|
||||||
|
pIntentDetail
|
||||||
|
)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (showSomething) {
|
||||||
|
views.setViewVisibility(R.id.first_line_rect, View.VISIBLE)
|
||||||
|
views.setViewVisibility(R.id.weather_rect, View.VISIBLE)
|
||||||
|
views.setViewVisibility(R.id.sub_line_rect, View.VISIBLE)
|
||||||
|
|
||||||
|
views.setViewVisibility(R.id.calendar_layout_rect, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.weather_sub_line_rect, View.GONE)
|
||||||
|
} else {
|
||||||
|
// Spacing
|
||||||
|
views.setViewVisibility(R.id.sub_line_top_margin_small_sans, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.sub_line_top_margin_medium_sans, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.sub_line_top_margin_large_sans, View.GONE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second row
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.sub_line_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(bindingView.subLine, draw = false)
|
||||||
|
)
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
ex.printStackTrace()
|
||||||
|
CrashlyticsReceiver.sendCrash(context, ex)
|
||||||
|
}
|
||||||
|
|
||||||
|
return views
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Generates the widget bitmap from the view
|
||||||
|
fun generateWidgetView(typeface: Typeface? = null): LeftAlignedWidgetBinding? {
|
||||||
|
try {
|
||||||
|
val eventRepository = EventRepository(context)
|
||||||
|
val nextEvent = eventRepository.getNextEvent()
|
||||||
|
val eventsCount = eventRepository.getEventsCount()
|
||||||
|
eventRepository.close()
|
||||||
|
|
||||||
|
val bindingView = LeftAlignedWidgetBinding.inflate(LayoutInflater.from(context))
|
||||||
|
|
||||||
|
bindingView.loader.isVisible = false
|
||||||
|
|
||||||
|
// Weather
|
||||||
|
if (Preferences.showWeather && Preferences.weatherIcon != "") {
|
||||||
|
bindingView.weatherDateLine.isVisible = true
|
||||||
|
val currentTemp = String.format(
|
||||||
|
Locale.getDefault(),
|
||||||
|
"%d°%s",
|
||||||
|
Preferences.weatherTemp.roundToInt(),
|
||||||
|
Preferences.weatherRealTempUnit
|
||||||
|
)
|
||||||
|
|
||||||
|
val icon: String = Preferences.weatherIcon
|
||||||
|
if (icon == "") {
|
||||||
|
bindingView.weatherSubLineWeatherIcon.isVisible = false
|
||||||
|
bindingView.weatherDateLineWeatherIcon.isVisible = false
|
||||||
|
} else {
|
||||||
|
bindingView.weatherSubLineWeatherIcon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon))
|
||||||
|
bindingView.weatherDateLineWeatherIcon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon))
|
||||||
|
bindingView.weatherSubLineWeatherIcon.isVisible = true
|
||||||
|
bindingView.weatherDateLineWeatherIcon.isVisible = true
|
||||||
|
}
|
||||||
|
|
||||||
|
bindingView.weatherDateLineTemperature.text = currentTemp
|
||||||
|
bindingView.weatherSubLineTemperature.text = currentTemp
|
||||||
|
|
||||||
|
if (GlanceProviderHelper.showGlanceProviders(context)) {
|
||||||
|
bindingView.weatherSubLine.isVisible = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bindingView.weatherDateLine.isVisible = false
|
||||||
|
bindingView.weatherSubLine.isVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
val now = Calendar.getInstance().apply {
|
||||||
|
set(Calendar.SECOND, 0)
|
||||||
|
set(Calendar.MILLISECOND, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
bindingView.dateLayout.isVisible = true
|
||||||
|
bindingView.calendarLayout.isVisible = false
|
||||||
|
bindingView.nextEventDifferenceTime.isVisible = false
|
||||||
|
bindingView.actionNext.isVisible = false
|
||||||
|
|
||||||
|
bindingView.date.text = DateHelper.getDateText(context, now)
|
||||||
|
|
||||||
|
val nextAlarm = AlarmHelper.getNextAlarm(context)
|
||||||
|
|
||||||
|
if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null && !Preferences.showEventsAsGlanceProvider) {
|
||||||
|
// Multiple counter
|
||||||
|
bindingView.actionNext.isVisible =
|
||||||
|
Preferences.showNextEvent && eventsCount > 1
|
||||||
|
|
||||||
|
bindingView.nextEvent.text = nextEvent.title
|
||||||
|
|
||||||
|
if (Preferences.showDiffTime && now.timeInMillis < nextEvent.startDate) {
|
||||||
|
bindingView.nextEventDifferenceTime.text = if (!nextEvent.allDay) {
|
||||||
|
SettingsStringHelper.getDifferenceText(
|
||||||
|
context,
|
||||||
|
now.timeInMillis,
|
||||||
|
nextEvent.startDate
|
||||||
|
)
|
||||||
|
.toLowerCase(Locale.getDefault())
|
||||||
|
} else {
|
||||||
|
SettingsStringHelper.getAllDayEventDifferenceText(
|
||||||
|
context,
|
||||||
|
now.timeInMillis,
|
||||||
|
nextEvent.startDate
|
||||||
|
).toLowerCase(Locale.getDefault())
|
||||||
|
}
|
||||||
|
bindingView.nextEventDifferenceTime.isVisible = true
|
||||||
|
} else {
|
||||||
|
bindingView.nextEventDifferenceTime.isVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextEvent.address != "" && Preferences.secondRowInformation == 1) {
|
||||||
|
bindingView.subLineIcon.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
context,
|
||||||
|
R.drawable.round_place_24
|
||||||
|
)
|
||||||
|
)
|
||||||
|
bindingView.subLineText.text = nextEvent.address
|
||||||
|
} else {
|
||||||
|
bindingView.subLineIcon.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
context,
|
||||||
|
R.drawable.round_today_24
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if (!nextEvent.allDay) {
|
||||||
|
val startHour =
|
||||||
|
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)
|
||||||
|
|
||||||
|
val startCal = Calendar.getInstance()
|
||||||
|
startCal.timeInMillis = nextEvent.startDate
|
||||||
|
|
||||||
|
val endCal = Calendar.getInstance()
|
||||||
|
endCal.timeInMillis = nextEvent.endDate
|
||||||
|
|
||||||
|
if (startCal.get(Calendar.HOUR_OF_DAY) > endCal.get(Calendar.HOUR_OF_DAY)) {
|
||||||
|
dayDiff++
|
||||||
|
} else if (startCal.get(Calendar.HOUR_OF_DAY) == endCal.get(Calendar.HOUR_OF_DAY) && startCal.get(
|
||||||
|
Calendar.MINUTE
|
||||||
|
) > endCal.get(Calendar.MINUTE)
|
||||||
|
) {
|
||||||
|
dayDiff++
|
||||||
|
}
|
||||||
|
var multipleDay = ""
|
||||||
|
if (dayDiff > 0) {
|
||||||
|
multipleDay = String.format(
|
||||||
|
" (+%s%s)",
|
||||||
|
dayDiff,
|
||||||
|
context.getString(R.string.day_char)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextEvent.startDate != nextEvent.endDate) {
|
||||||
|
bindingView.subLineText.text =
|
||||||
|
String.format("%s - %s%s", startHour, endHour, multipleDay)
|
||||||
|
} else {
|
||||||
|
bindingView.subLineText.text =
|
||||||
|
String.format("%s", startHour)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
val flags: Int =
|
||||||
|
DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR or DateUtils.FORMAT_ABBREV_MONTH
|
||||||
|
val start = Calendar.getInstance().apply { timeInMillis = nextEvent.startDate }
|
||||||
|
|
||||||
|
bindingView.subLineText.text = if (now.get(Calendar.DAY_OF_YEAR) == start.get(
|
||||||
|
Calendar.DAY_OF_YEAR)) {
|
||||||
|
DateUtils.formatDateTime(context, nextEvent.startDate, flags)
|
||||||
|
} else if (now.get(Calendar.DAY_OF_YEAR) > start.get(Calendar.DAY_OF_YEAR) || now.get(
|
||||||
|
Calendar.YEAR) > start.get(Calendar.YEAR)) {
|
||||||
|
DateUtils.formatDateTime(context, now.timeInMillis, flags)
|
||||||
|
} else {
|
||||||
|
DateUtils.formatDateTime(context, nextEvent.startDate, flags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bindingView.dateLayout.isVisible = false
|
||||||
|
bindingView.calendarLayout.isVisible = true
|
||||||
|
bindingView.subLine.isVisible = true
|
||||||
|
bindingView.weatherSubLine.isVisible = true
|
||||||
|
|
||||||
|
bindingView.subLineTopMarginSmall.visibility = View.GONE
|
||||||
|
bindingView.subLineTopMarginMedium.visibility = View.GONE
|
||||||
|
bindingView.subLineTopMarginLarge.visibility = View.GONE
|
||||||
|
} else if (GlanceProviderHelper.showGlanceProviders(context)) {
|
||||||
|
bindingView.subLineIcon.isVisible = true
|
||||||
|
var showSomething = false
|
||||||
|
loop@ for (provider: Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders(
|
||||||
|
context
|
||||||
|
)) {
|
||||||
|
when (provider) {
|
||||||
|
Constants.GlanceProviderId.PLAYING_SONG -> {
|
||||||
|
if (MediaPlayerHelper.isSomeonePlaying(context)) {
|
||||||
|
bindingView.subLineIcon.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
context,
|
||||||
|
R.drawable.round_music_note_24
|
||||||
|
)
|
||||||
|
)
|
||||||
|
bindingView.subLineText.text = MediaPlayerHelper.getMediaInfo()
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> {
|
||||||
|
if (Preferences.showNextAlarm && nextAlarm != "") {
|
||||||
|
bindingView.subLineIcon.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
context,
|
||||||
|
R.drawable.round_alarm_24
|
||||||
|
)
|
||||||
|
)
|
||||||
|
bindingView.subLineText.text = AlarmHelper.getNextAlarm(context)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
|
||||||
|
if (Preferences.showBatteryCharging) {
|
||||||
|
BatteryHelper.updateBatteryInfo(context)
|
||||||
|
if (Preferences.isCharging) {
|
||||||
|
bindingView.subLineIcon.isVisible = false
|
||||||
|
val batteryLevel = BatteryHelper.getBatteryLevel(context)
|
||||||
|
if (batteryLevel != 100) {
|
||||||
|
bindingView.subLineText.text = context.getString(R.string.charging)
|
||||||
|
} else {
|
||||||
|
bindingView.subLineText.text =
|
||||||
|
context.getString(R.string.charged)
|
||||||
|
}
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
} else if (Preferences.isBatteryLevelLow) {
|
||||||
|
bindingView.subLineIcon.isVisible = false
|
||||||
|
bindingView.subLineText.text =
|
||||||
|
context.getString(R.string.battery_low_warning)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.CUSTOM_INFO -> {
|
||||||
|
if (Preferences.customNotes.isNotEmpty()) {
|
||||||
|
bindingView.subLineIcon.isVisible = false
|
||||||
|
bindingView.subLineText.text = Preferences.customNotes
|
||||||
|
bindingView.subLineText.maxLines = 2
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
|
||||||
|
if (Preferences.showDailySteps && Preferences.googleFitSteps > 0) {
|
||||||
|
bindingView.subLineIcon.isVisible = false
|
||||||
|
bindingView.subLineText.text =
|
||||||
|
context.getString(R.string.daily_steps_counter)
|
||||||
|
.format(Preferences.googleFitSteps)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.NOTIFICATIONS -> {
|
||||||
|
if (Preferences.showNotifications && ActiveNotificationsHelper.showLastNotification()) {
|
||||||
|
try {
|
||||||
|
if (Preferences.lastNotificationIcon != 0) {
|
||||||
|
val remotePackageContext = context.createPackageContext(
|
||||||
|
Preferences.lastNotificationPackage, 0)
|
||||||
|
val icon = ContextCompat.getDrawable(remotePackageContext,
|
||||||
|
Preferences.lastNotificationIcon)
|
||||||
|
bindingView.subLineIcon.isVisible = true
|
||||||
|
bindingView.subLineIcon.setImageDrawable(icon)
|
||||||
|
} else {
|
||||||
|
bindingView.subLineIcon.isVisible = false
|
||||||
|
}
|
||||||
|
bindingView.subLineText.text = Preferences.lastNotificationTitle
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
} catch (ex: Exception) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.GREETINGS -> {
|
||||||
|
val greetingsText = GreetingsHelper.getRandomString(context)
|
||||||
|
if (Preferences.showGreetings && GreetingsHelper.showGreetings() && greetingsText.isNotBlank()) {
|
||||||
|
bindingView.subLineText.text = greetingsText
|
||||||
|
bindingView.subLineText.maxLines = 2
|
||||||
|
bindingView.subLineIcon.isVisible = false
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.EVENTS -> {
|
||||||
|
if (Preferences.showEventsAsGlanceProvider && Preferences.showEvents && context.checkGrantedPermission(
|
||||||
|
Manifest.permission.READ_CALENDAR) && nextEvent != null) {
|
||||||
|
bindingView.subLineText.text = context.getString(R.string.events_glance_provider_format).format(nextEvent.title, if (Preferences.showDiffTime && now.timeInMillis < nextEvent.startDate) {
|
||||||
|
if (!nextEvent.allDay) {
|
||||||
|
SettingsStringHelper.getDifferenceText(
|
||||||
|
context,
|
||||||
|
now.timeInMillis,
|
||||||
|
nextEvent.startDate
|
||||||
|
)
|
||||||
|
.toLowerCase(Locale.getDefault())
|
||||||
|
} else {
|
||||||
|
SettingsStringHelper.getAllDayEventDifferenceText(
|
||||||
|
context,
|
||||||
|
now.timeInMillis,
|
||||||
|
nextEvent.startDate
|
||||||
|
).toLowerCase(Locale.getDefault())
|
||||||
|
}
|
||||||
|
} else "").trimEnd()
|
||||||
|
bindingView.subLineIcon.isVisible = true
|
||||||
|
bindingView.subLineIcon.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
context,
|
||||||
|
R.drawable.round_today_24
|
||||||
|
)
|
||||||
|
)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showSomething) {
|
||||||
|
bindingView.dateLayout.isVisible = true
|
||||||
|
bindingView.calendarLayout.isVisible = false
|
||||||
|
bindingView.subLine.isVisible = true
|
||||||
|
bindingView.weatherSubLine.isVisible = false
|
||||||
|
|
||||||
|
bindingView.subLineTopMarginSmall.visibility =
|
||||||
|
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.SMALL.rawValue) View.VISIBLE else View.GONE
|
||||||
|
bindingView.subLineTopMarginMedium.visibility =
|
||||||
|
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.MEDIUM.rawValue) View.VISIBLE else View.GONE
|
||||||
|
bindingView.subLineTopMarginLarge.visibility =
|
||||||
|
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.rawValue) View.VISIBLE else View.GONE
|
||||||
|
} else {
|
||||||
|
bindingView.subLineIcon.isVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Color
|
||||||
|
listOf<TextView>(
|
||||||
|
bindingView.date,
|
||||||
|
bindingView.weatherDateLineTemperature,
|
||||||
|
bindingView.nextEvent,
|
||||||
|
bindingView.nextEventDifferenceTime,
|
||||||
|
).forEach {
|
||||||
|
it.setTextColor(ColorHelper.getFontColor(context.applicationContext.isDarkTheme()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Preferences.weatherIconPack != Constants.WeatherIconPack.MINIMAL.rawValue) {
|
||||||
|
listOf<ImageView>(bindingView.actionNext)
|
||||||
|
} else {
|
||||||
|
listOf<ImageView>(
|
||||||
|
bindingView.actionNext,
|
||||||
|
bindingView.weatherDateLineWeatherIcon,
|
||||||
|
bindingView.weatherSubLineWeatherIcon
|
||||||
|
)
|
||||||
|
}.forEach {
|
||||||
|
it.setColorFilter(ColorHelper.getFontColorRgb(context.applicationContext.isDarkTheme()))
|
||||||
|
it.alpha =
|
||||||
|
(if (context.isDarkTheme()) Preferences.textGlobalAlphaDark.toIntValue()
|
||||||
|
.toFloat() else Preferences.textGlobalAlpha.toIntValue()
|
||||||
|
.toFloat()) / 100
|
||||||
|
}
|
||||||
|
|
||||||
|
listOf<TextView>(bindingView.subLineText, bindingView.weatherSubLineDivider, bindingView.weatherSubLineTemperature).forEach {
|
||||||
|
it.setTextColor(ColorHelper.getSecondaryFontColor(context.applicationContext.isDarkTheme()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Preferences.weatherIconPack != Constants.WeatherIconPack.MINIMAL.rawValue) {
|
||||||
|
listOf<ImageView>(bindingView.subLineIcon, bindingView.subLineIconShadow)
|
||||||
|
} else {
|
||||||
|
listOf<ImageView>(bindingView.subLineIcon, bindingView.weatherSubLineWeatherIcon, bindingView.subLineIconShadow)
|
||||||
|
}.forEach {
|
||||||
|
it.setColorFilter(ColorHelper.getSecondaryFontColorRgb(context.applicationContext.isDarkTheme()))
|
||||||
|
it.alpha =
|
||||||
|
(if (context.isDarkTheme()) Preferences.textSecondaryAlphaDark.toIntValue()
|
||||||
|
.toFloat() else Preferences.textSecondaryAlpha.toIntValue()
|
||||||
|
.toFloat()) / 100
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text Size
|
||||||
|
listOf<Pair<TextView, Float>>(
|
||||||
|
bindingView.date to Preferences.textMainSize,
|
||||||
|
bindingView.weatherDateLineTemperature to ((Preferences.textMainSize + Preferences.textSecondSize) / 2),
|
||||||
|
bindingView.nextEvent to Preferences.textMainSize,
|
||||||
|
bindingView.nextEventDifferenceTime to Preferences.textMainSize,
|
||||||
|
bindingView.subLineText to Preferences.textSecondSize,
|
||||||
|
bindingView.weatherSubLineDivider to (Preferences.textSecondSize - 2),
|
||||||
|
bindingView.weatherSubLineTemperature to Preferences.textSecondSize,
|
||||||
|
).forEach {
|
||||||
|
it.first.setTextSize(TypedValue.COMPLEX_UNIT_SP, it.second)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Icons scale
|
||||||
|
bindingView.subLineIcon.scaleX = Preferences.textSecondSize / 18f
|
||||||
|
bindingView.subLineIcon.scaleY = Preferences.textSecondSize / 18f
|
||||||
|
|
||||||
|
bindingView.weatherSubLineWeatherIcon.scaleX = Preferences.textSecondSize / 18f
|
||||||
|
bindingView.weatherSubLineWeatherIcon.scaleY = Preferences.textSecondSize / 18f
|
||||||
|
|
||||||
|
bindingView.weatherDateLineWeatherIcon.scaleX = ((Preferences.textMainSize + Preferences.textSecondSize) / 2) / 20f
|
||||||
|
bindingView.weatherDateLineWeatherIcon.scaleY = ((Preferences.textMainSize + Preferences.textSecondSize) / 2) / 20f
|
||||||
|
|
||||||
|
bindingView.actionNext.scaleX = Preferences.textMainSize / 28f
|
||||||
|
bindingView.actionNext.scaleY = Preferences.textMainSize / 28f
|
||||||
|
|
||||||
|
|
||||||
|
// Shadows
|
||||||
|
val shadowRadius =
|
||||||
|
when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) {
|
||||||
|
0 -> 0f
|
||||||
|
1 -> 5f
|
||||||
|
2 -> 5f
|
||||||
|
else -> 5f
|
||||||
|
}
|
||||||
|
val shadowColor =
|
||||||
|
when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) {
|
||||||
|
0 -> Color.TRANSPARENT
|
||||||
|
1 -> R.color.black_50
|
||||||
|
2 -> Color.BLACK
|
||||||
|
else -> R.color.black_50
|
||||||
|
}
|
||||||
|
val shadowDy =
|
||||||
|
when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) {
|
||||||
|
0 -> 0f
|
||||||
|
1 -> 0f
|
||||||
|
2 -> 1f
|
||||||
|
else -> 0f
|
||||||
|
}
|
||||||
|
|
||||||
|
listOf<TextView>(
|
||||||
|
bindingView.date,
|
||||||
|
bindingView.weatherDateLineTemperature,
|
||||||
|
bindingView.nextEvent,
|
||||||
|
bindingView.nextEventDifferenceTime,
|
||||||
|
bindingView.subLineText,
|
||||||
|
bindingView.weatherSubLineDivider,
|
||||||
|
bindingView.weatherSubLineTemperature,
|
||||||
|
).forEach {
|
||||||
|
it.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Icons shadow
|
||||||
|
|
||||||
|
listOf(
|
||||||
|
Pair(bindingView.subLineIcon, bindingView.subLineIconShadow),
|
||||||
|
).forEach {
|
||||||
|
if ((if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) == 0) {
|
||||||
|
it.second.isVisible = false
|
||||||
|
} else {
|
||||||
|
it.second.isVisible = it.first.isVisible
|
||||||
|
it.second.scaleX = it.first.scaleX
|
||||||
|
it.second.scaleY = it.first.scaleY
|
||||||
|
it.second.applyShadow(it.first)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listOf(
|
||||||
|
Pair(bindingView.actionNext, bindingView.actionNextShadow),
|
||||||
|
).forEach {
|
||||||
|
if ((if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) == 0) {
|
||||||
|
it.second.isVisible = false
|
||||||
|
} else {
|
||||||
|
it.second.isVisible = it.first.isVisible
|
||||||
|
it.second.scaleX = it.first.scaleX
|
||||||
|
it.second.scaleY = it.first.scaleY
|
||||||
|
it.second.applyShadow(it.first, 0.6f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom Font
|
||||||
|
if (Preferences.customFont == Constants.CUSTOM_FONT_GOOGLE_SANS) {
|
||||||
|
val googleSans: Typeface = when (Preferences.customFontVariant) {
|
||||||
|
"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>(
|
||||||
|
bindingView.date,
|
||||||
|
bindingView.weatherDateLineTemperature,
|
||||||
|
bindingView.nextEvent,
|
||||||
|
bindingView.nextEventDifferenceTime,
|
||||||
|
bindingView.subLineText,
|
||||||
|
bindingView.weatherSubLineDivider,
|
||||||
|
bindingView.weatherSubLineTemperature,
|
||||||
|
).forEach {
|
||||||
|
it.typeface = googleSans
|
||||||
|
}
|
||||||
|
} else if (Preferences.customFont == Constants.CUSTOM_FONT_DOWNLOADED && typeface != null) {
|
||||||
|
listOf<TextView>(
|
||||||
|
bindingView.date,
|
||||||
|
bindingView.weatherDateLineTemperature,
|
||||||
|
bindingView.nextEvent,
|
||||||
|
bindingView.nextEventDifferenceTime,
|
||||||
|
bindingView.subLineText,
|
||||||
|
bindingView.weatherSubLineDivider,
|
||||||
|
bindingView.weatherSubLineTemperature,
|
||||||
|
).forEach {
|
||||||
|
it.typeface = typeface
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dividers
|
||||||
|
arrayOf(bindingView.weatherSubLineDivider).forEach {
|
||||||
|
it.visibility = if (Preferences.showDividers) View.VISIBLE else View.INVISIBLE
|
||||||
|
it.layoutParams = (it.layoutParams as ViewGroup.MarginLayoutParams).apply {
|
||||||
|
this.marginEnd = if (Preferences.showDividers) 8f.convertDpToPixel(context).toInt() else 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right Aligned
|
||||||
|
if (rightAligned) {
|
||||||
|
bindingView.mainContent.layoutParams = (bindingView.mainContent.layoutParams as RelativeLayout.LayoutParams).apply {
|
||||||
|
addRule(RelativeLayout.ALIGN_PARENT_END)
|
||||||
|
}
|
||||||
|
bindingView.mainContent.gravity = Gravity.END
|
||||||
|
bindingView.dateLayout.gravity = Gravity.END
|
||||||
|
bindingView.calendarLayout.gravity = Gravity.END or Gravity.CENTER_VERTICAL
|
||||||
|
bindingView.subLineContainer.gravity = Gravity.END or Gravity.CENTER_VERTICAL
|
||||||
|
}
|
||||||
|
|
||||||
|
return bindingView
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
ex.printStackTrace()
|
||||||
|
CrashlyticsReceiver.sendCrash(context, ex)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,109 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.ui.widgets
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.TypedValue
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.RemoteViews
|
||||||
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.IntentHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.receivers.CrashlyticsReceiver
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.toPixel
|
||||||
|
|
||||||
|
class ClockWidget(val context: Context) {
|
||||||
|
fun updateClockView(views: RemoteViews, widgetID: Int): RemoteViews {
|
||||||
|
try {
|
||||||
|
if (!Preferences.showClock) {
|
||||||
|
views.setViewVisibility(R.id.time, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.time_am_pm, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.clock_bottom_margin_none, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.clock_bottom_margin_small, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.clock_bottom_margin_medium, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.clock_bottom_margin_large, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.timezones_container, View.GONE)
|
||||||
|
} else {
|
||||||
|
views.setTextColor(R.id.time, ColorHelper.getClockFontColor(context.isDarkTheme()))
|
||||||
|
views.setTextColor(R.id.time_am_pm, ColorHelper.getClockFontColor(context.isDarkTheme()))
|
||||||
|
views.setTextViewTextSize(
|
||||||
|
R.id.time,
|
||||||
|
TypedValue.COMPLEX_UNIT_SP,
|
||||||
|
Preferences.clockTextSize.toPixel(context)
|
||||||
|
)
|
||||||
|
views.setTextViewTextSize(
|
||||||
|
R.id.time_am_pm,
|
||||||
|
TypedValue.COMPLEX_UNIT_SP,
|
||||||
|
Preferences.clockTextSize.toPixel(context) / 5 * 2
|
||||||
|
)
|
||||||
|
val clockPIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getClockIntent(context),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.time, clockPIntent)
|
||||||
|
views.setOnClickPendingIntent(R.id.time_am_pm, clockPIntent)
|
||||||
|
views.setViewVisibility(R.id.time, View.VISIBLE)
|
||||||
|
views.setViewVisibility(R.id.time_am_pm, if (Preferences.showAMPMIndicator) View.VISIBLE else View.GONE)
|
||||||
|
|
||||||
|
views.setViewVisibility(
|
||||||
|
R.id.clock_bottom_margin_none,
|
||||||
|
if (Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.rawValue) View.VISIBLE else View.GONE
|
||||||
|
)
|
||||||
|
views.setViewVisibility(
|
||||||
|
R.id.clock_bottom_margin_small,
|
||||||
|
if (Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.rawValue) View.VISIBLE else View.GONE
|
||||||
|
)
|
||||||
|
views.setViewVisibility(
|
||||||
|
R.id.clock_bottom_margin_medium,
|
||||||
|
if (Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.rawValue) View.VISIBLE else View.GONE
|
||||||
|
)
|
||||||
|
views.setViewVisibility(
|
||||||
|
R.id.clock_bottom_margin_large,
|
||||||
|
if (Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.rawValue) View.VISIBLE else View.GONE
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// Timezones
|
||||||
|
if (Preferences.altTimezoneId != "" && Preferences.altTimezoneLabel != "") {
|
||||||
|
views.setString(R.id.alt_timezone_time, "setTimeZone", Preferences.altTimezoneId)
|
||||||
|
views.setString(R.id.alt_timezone_time_am_pm, "setTimeZone", Preferences.altTimezoneId)
|
||||||
|
views.setTextViewText(R.id.alt_timezone_label, Preferences.altTimezoneLabel)
|
||||||
|
|
||||||
|
views.setTextColor(R.id.alt_timezone_time, ColorHelper.getClockFontColor(context.isDarkTheme()))
|
||||||
|
views.setTextColor(R.id.alt_timezone_time_am_pm, ColorHelper.getClockFontColor(context.isDarkTheme()))
|
||||||
|
views.setTextColor(R.id.alt_timezone_label, ColorHelper.getClockFontColor(context.isDarkTheme()))
|
||||||
|
views.setTextViewTextSize(
|
||||||
|
R.id.alt_timezone_time,
|
||||||
|
TypedValue.COMPLEX_UNIT_SP,
|
||||||
|
Preferences.clockTextSize.toPixel(context) / 3
|
||||||
|
)
|
||||||
|
views.setTextViewTextSize(
|
||||||
|
R.id.alt_timezone_time_am_pm,
|
||||||
|
TypedValue.COMPLEX_UNIT_SP,
|
||||||
|
(Preferences.clockTextSize.toPixel(context) / 3) / 5 * 2
|
||||||
|
)
|
||||||
|
views.setTextViewTextSize(
|
||||||
|
R.id.alt_timezone_label,
|
||||||
|
TypedValue.COMPLEX_UNIT_SP,
|
||||||
|
(Preferences.clockTextSize.toPixel(context) / 3) / 5 * 2
|
||||||
|
)
|
||||||
|
|
||||||
|
views.setOnClickPendingIntent(R.id.timezones_container, clockPIntent)
|
||||||
|
views.setViewVisibility(R.id.timezones_container, View.VISIBLE)
|
||||||
|
} else {
|
||||||
|
views.setViewVisibility(R.id.timezones_container, View.GONE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
ex.printStackTrace()
|
||||||
|
CrashlyticsReceiver.sendCrash(context, ex)
|
||||||
|
}
|
||||||
|
|
||||||
|
return views
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,941 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.ui.widgets
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.appwidget.AppWidgetManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import android.text.format.DateUtils
|
||||||
|
import android.util.Log
|
||||||
|
import android.util.TypedValue
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.RemoteViews
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.databinding.TheWidgetBinding
|
||||||
|
import com.tommasoberlose.anotherwidget.db.EventRepository
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Actions
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.*
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.ImageHelper.applyShadow
|
||||||
|
import com.tommasoberlose.anotherwidget.receivers.CrashlyticsReceiver
|
||||||
|
import com.tommasoberlose.anotherwidget.receivers.NewCalendarEventReceiver
|
||||||
|
import com.tommasoberlose.anotherwidget.receivers.WidgetClickListenerReceiver
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.convertDpToPixel
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.toPixel
|
||||||
|
import java.text.DateFormat
|
||||||
|
import java.util.*
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
class StandardWidget(val context: Context) {
|
||||||
|
fun generateWidget(appWidgetId: Int, w: Int, typeface: Typeface? = null): RemoteViews? {
|
||||||
|
|
||||||
|
var views = RemoteViews(context.packageName, R.layout.the_widget_sans)
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Background
|
||||||
|
views.setInt(
|
||||||
|
R.id.widget_shape_background,
|
||||||
|
"setColorFilter",
|
||||||
|
ColorHelper.getBackgroundColorRgb(context.isDarkTheme())
|
||||||
|
)
|
||||||
|
views.setInt(
|
||||||
|
R.id.widget_shape_background,
|
||||||
|
"setImageAlpha",
|
||||||
|
ColorHelper.getBackgroundAlpha(context.isDarkTheme())
|
||||||
|
)
|
||||||
|
val refreshIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
appWidgetId,
|
||||||
|
IntentHelper.getWidgetUpdateIntent(context),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.widget_shape_background, refreshIntent)
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
ex.printStackTrace()
|
||||||
|
CrashlyticsReceiver.sendCrash(context, ex)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clock
|
||||||
|
views = ClockWidget(context).updateClockView(views, appWidgetId)
|
||||||
|
|
||||||
|
// Setup listener
|
||||||
|
try {
|
||||||
|
val generatedBinding = generateWidgetView(typeface) ?: return null
|
||||||
|
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.bitmap_container,
|
||||||
|
BitmapHelper.getBitmapFromView(generatedBinding.root, width = w)
|
||||||
|
)
|
||||||
|
views = updateGridView(generatedBinding, views, appWidgetId)
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
ex.printStackTrace()
|
||||||
|
CrashlyticsReceiver.sendCrash(context, ex)
|
||||||
|
}
|
||||||
|
|
||||||
|
return views
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateGridView(bindingView: TheWidgetBinding, views: RemoteViews, widgetID: Int): RemoteViews {
|
||||||
|
try {
|
||||||
|
val eventRepository = EventRepository(context)
|
||||||
|
val nextEvent = eventRepository.getNextEvent()
|
||||||
|
val eventsCount = eventRepository.getEventsCount()
|
||||||
|
eventRepository.close()
|
||||||
|
|
||||||
|
// Weather
|
||||||
|
if (Preferences.showWeather && Preferences.weatherIcon != "") {
|
||||||
|
views.setViewVisibility(R.id.weather_rect, View.VISIBLE)
|
||||||
|
views.setViewVisibility(R.id.weather_sub_line, View.GONE)
|
||||||
|
|
||||||
|
val i = Intent(context, WidgetClickListenerReceiver::class.java)
|
||||||
|
i.action = Actions.ACTION_OPEN_WEATHER_INTENT
|
||||||
|
val weatherPIntent = PendingIntent.getBroadcast(context, widgetID, i, 0)
|
||||||
|
|
||||||
|
views.setOnClickPendingIntent(R.id.weather_rect, weatherPIntent)
|
||||||
|
views.setOnClickPendingIntent(R.id.weather_sub_line_rect, weatherPIntent)
|
||||||
|
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.weather_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(bindingView.weatherDateLine, draw = false)
|
||||||
|
)
|
||||||
|
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.weather_sub_line_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(bindingView.weatherSubLine, draw = false)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
views.setViewVisibility(R.id.weather_rect, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.weather_sub_line, View.GONE)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Calendar
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.date_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(bindingView.date, draw = false)
|
||||||
|
)
|
||||||
|
|
||||||
|
val calPIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getCalendarIntent(context),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.date_rect, calPIntent)
|
||||||
|
views.setViewVisibility(R.id.first_line_rect, View.VISIBLE)
|
||||||
|
|
||||||
|
// Second row
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.sub_line_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(bindingView.subLine, draw = false)
|
||||||
|
)
|
||||||
|
|
||||||
|
val nextAlarm = AlarmHelper.getNextAlarm(context)
|
||||||
|
|
||||||
|
// Spacing
|
||||||
|
views.setViewVisibility(
|
||||||
|
R.id.sub_line_top_margin_small_sans,
|
||||||
|
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.SMALL.rawValue) View.VISIBLE else View.GONE
|
||||||
|
)
|
||||||
|
views.setViewVisibility(
|
||||||
|
R.id.sub_line_top_margin_medium_sans,
|
||||||
|
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.MEDIUM.rawValue) View.VISIBLE else View.GONE
|
||||||
|
)
|
||||||
|
views.setViewVisibility(
|
||||||
|
R.id.sub_line_top_margin_large_sans,
|
||||||
|
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.rawValue) View.VISIBLE else View.GONE
|
||||||
|
)
|
||||||
|
|
||||||
|
if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null && !Preferences.showEventsAsGlanceProvider) {
|
||||||
|
if (Preferences.showNextEvent && eventsCount > 1) {
|
||||||
|
|
||||||
|
// Action next event
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.action_next_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(bindingView.actionNext, draw = false)
|
||||||
|
)
|
||||||
|
views.setViewVisibility(R.id.action_next_rect, View.VISIBLE)
|
||||||
|
views.setOnClickPendingIntent(
|
||||||
|
R.id.action_next_rect,
|
||||||
|
PendingIntent.getBroadcast(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
Intent(
|
||||||
|
context,
|
||||||
|
NewCalendarEventReceiver::class.java
|
||||||
|
).apply { action = Actions.ACTION_GO_TO_NEXT_EVENT },
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Action previous event
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.action_previous_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(bindingView.actionPrevious, draw = false)
|
||||||
|
)
|
||||||
|
views.setViewVisibility(R.id.action_previous_rect, View.VISIBLE)
|
||||||
|
views.setOnClickPendingIntent(
|
||||||
|
R.id.action_previous_rect,
|
||||||
|
PendingIntent.getBroadcast(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
Intent(
|
||||||
|
context,
|
||||||
|
NewCalendarEventReceiver::class.java
|
||||||
|
).apply { action = Actions.ACTION_GO_TO_PREVIOUS_EVENT },
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
views.setViewVisibility(R.id.action_next_rect, View.VISIBLE)
|
||||||
|
views.setViewVisibility(R.id.action_previous_rect, View.VISIBLE)
|
||||||
|
} else {
|
||||||
|
views.setViewVisibility(R.id.action_next_rect, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.action_previous_rect, View.GONE)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event intent
|
||||||
|
val eventIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getEventIntent(context, nextEvent),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.next_event_rect, eventIntent)
|
||||||
|
views.setViewVisibility(R.id.next_event_rect, View.VISIBLE)
|
||||||
|
|
||||||
|
// Event time difference
|
||||||
|
if (Preferences.showDiffTime && Calendar.getInstance().timeInMillis < nextEvent.startDate) {
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.next_event_difference_time_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(
|
||||||
|
bindingView.nextEventDifferenceTime,
|
||||||
|
draw = false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
views.setViewVisibility(R.id.next_event_difference_time_rect, View.VISIBLE)
|
||||||
|
views.setOnClickPendingIntent(R.id.next_event_difference_time_rect, eventIntent)
|
||||||
|
} else {
|
||||||
|
views.setViewVisibility(R.id.next_event_difference_time_rect, View.GONE)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event information
|
||||||
|
if (nextEvent.address != "" && Preferences.secondRowInformation == 1) {
|
||||||
|
val mapIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getGoogleMapsIntentFromAddress(context, nextEvent.address),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.sub_line_rect, mapIntent)
|
||||||
|
} else {
|
||||||
|
val pIntentDetail = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getEventIntent(
|
||||||
|
context,
|
||||||
|
nextEvent,
|
||||||
|
forceEventDetails = true
|
||||||
|
),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.sub_line_rect, pIntentDetail)
|
||||||
|
}
|
||||||
|
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.next_event_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(bindingView.nextEvent, draw = false)
|
||||||
|
)
|
||||||
|
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
|
||||||
|
views.setViewVisibility(R.id.sub_line_rect, View.VISIBLE)
|
||||||
|
views.setViewVisibility(R.id.weather_sub_line_rect, View.VISIBLE)
|
||||||
|
|
||||||
|
views.setViewVisibility(R.id.first_line_rect, View.GONE)
|
||||||
|
|
||||||
|
} else if (GlanceProviderHelper.showGlanceProviders(context)) {
|
||||||
|
var showSomething = false
|
||||||
|
loop@ for (provider: Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders(context)) {
|
||||||
|
when (provider) {
|
||||||
|
Constants.GlanceProviderId.PLAYING_SONG -> {
|
||||||
|
if (MediaPlayerHelper.isSomeonePlaying(context)) {
|
||||||
|
val musicIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getMusicIntent(context),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.sub_line_rect, musicIntent)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> {
|
||||||
|
if (Preferences.showNextAlarm && nextAlarm != "") {
|
||||||
|
val alarmIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getClockIntent(context),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.sub_line_rect, alarmIntent)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
|
||||||
|
if (Preferences.showBatteryCharging) {
|
||||||
|
BatteryHelper.updateBatteryInfo(context)
|
||||||
|
if (Preferences.isCharging || Preferences.isBatteryLevelLow) {
|
||||||
|
val batteryIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getBatteryIntent(),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.sub_line_rect, batteryIntent)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.CUSTOM_INFO -> {
|
||||||
|
if (Preferences.customNotes.isNotEmpty()) {
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
|
||||||
|
if (Preferences.showDailySteps && Preferences.googleFitSteps > 0) {
|
||||||
|
val fitIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getFitIntent(context),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.sub_line_rect, fitIntent)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.NOTIFICATIONS -> {
|
||||||
|
if (Preferences.showNotifications && ActiveNotificationsHelper.showLastNotification()) {
|
||||||
|
try {
|
||||||
|
if (Preferences.lastNotificationIcon != 0) {
|
||||||
|
val remotePackageContext = context.createPackageContext(
|
||||||
|
Preferences.lastNotificationPackage, 0)
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
remotePackageContext,
|
||||||
|
Preferences.lastNotificationIcon)
|
||||||
|
}
|
||||||
|
val notificationIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getNotificationIntent(context),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(
|
||||||
|
R.id.sub_line_rect,
|
||||||
|
notificationIntent
|
||||||
|
)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
} catch (ex: Exception) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.GREETINGS -> {
|
||||||
|
if (Preferences.showGreetings && GreetingsHelper.showGreetings() && GreetingsHelper.getRandomString(context).isNotBlank()) {
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.EVENTS -> {
|
||||||
|
if (Preferences.showEventsAsGlanceProvider&& Preferences.showEvents && context.checkGrantedPermission(
|
||||||
|
Manifest.permission.READ_CALENDAR) && nextEvent != null) {
|
||||||
|
val pIntentDetail = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getEventIntent(
|
||||||
|
context,
|
||||||
|
nextEvent,
|
||||||
|
forceEventDetails = true
|
||||||
|
),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(
|
||||||
|
R.id.sub_line_rect,
|
||||||
|
pIntentDetail
|
||||||
|
)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (showSomething) {
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.sub_line_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(bindingView.subLine, draw = false)
|
||||||
|
)
|
||||||
|
|
||||||
|
views.setViewVisibility(R.id.first_line_rect, View.VISIBLE)
|
||||||
|
views.setViewVisibility(R.id.sub_line_rect, View.VISIBLE)
|
||||||
|
|
||||||
|
views.setViewVisibility(R.id.calendar_layout_rect, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.weather_sub_line_rect, View.GONE)
|
||||||
|
} else {
|
||||||
|
// Spacing
|
||||||
|
views.setViewVisibility(R.id.sub_line_top_margin_small_sans, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.sub_line_top_margin_medium_sans, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.sub_line_top_margin_large_sans, View.GONE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
ex.printStackTrace()
|
||||||
|
CrashlyticsReceiver.sendCrash(context, ex)
|
||||||
|
}
|
||||||
|
|
||||||
|
return views
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Generates the widget bitmap from the view
|
||||||
|
fun generateWidgetView(typeface: Typeface? = null): TheWidgetBinding? {
|
||||||
|
try {
|
||||||
|
val eventRepository = EventRepository(context)
|
||||||
|
val nextEvent = eventRepository.getNextEvent()
|
||||||
|
val eventsCount = eventRepository.getEventsCount()
|
||||||
|
eventRepository.close()
|
||||||
|
|
||||||
|
val bindingView = TheWidgetBinding.inflate(LayoutInflater.from(context))
|
||||||
|
|
||||||
|
bindingView.loader.isVisible = false
|
||||||
|
|
||||||
|
// Weather
|
||||||
|
if (Preferences.showWeather && Preferences.weatherIcon != "") {
|
||||||
|
bindingView.weatherDateLine.isVisible = true
|
||||||
|
val currentTemp = String.format(
|
||||||
|
Locale.getDefault(),
|
||||||
|
"%d°%s",
|
||||||
|
Preferences.weatherTemp.roundToInt(),
|
||||||
|
Preferences.weatherRealTempUnit
|
||||||
|
)
|
||||||
|
|
||||||
|
val icon: String = Preferences.weatherIcon
|
||||||
|
if (icon == "") {
|
||||||
|
bindingView.weatherSubLineWeatherIcon.isVisible = false
|
||||||
|
bindingView.weatherDateLineWeatherIcon.isVisible = false
|
||||||
|
} else {
|
||||||
|
bindingView.weatherSubLineWeatherIcon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon))
|
||||||
|
bindingView.weatherDateLineWeatherIcon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon))
|
||||||
|
bindingView.weatherSubLineWeatherIcon.isVisible = true
|
||||||
|
bindingView.weatherDateLineWeatherIcon.isVisible = true
|
||||||
|
}
|
||||||
|
|
||||||
|
bindingView.weatherDateLineTemperature.text = currentTemp
|
||||||
|
bindingView.weatherSubLineTemperature.text = currentTemp
|
||||||
|
|
||||||
|
if (GlanceProviderHelper.showGlanceProviders(context)) {
|
||||||
|
bindingView.weatherSubLine.isVisible = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bindingView.weatherDateLine.isVisible = false
|
||||||
|
bindingView.weatherSubLine.isVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
val now = Calendar.getInstance().apply {
|
||||||
|
set(Calendar.SECOND, 0)
|
||||||
|
set(Calendar.MILLISECOND, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
bindingView.dateLayout.isVisible = true
|
||||||
|
bindingView.calendarLayout.isVisible = false
|
||||||
|
bindingView.nextEventDifferenceTime.isVisible = false
|
||||||
|
bindingView.actionNext.isVisible = false
|
||||||
|
bindingView.actionPrevious.isVisible = false
|
||||||
|
|
||||||
|
bindingView.date.text = DateHelper.getDateText(context, now)
|
||||||
|
|
||||||
|
val nextAlarm = AlarmHelper.getNextAlarm(context)
|
||||||
|
|
||||||
|
if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null && !Preferences.showEventsAsGlanceProvider) {
|
||||||
|
// Multiple counter
|
||||||
|
bindingView.actionNext.isVisible =
|
||||||
|
Preferences.showNextEvent && eventsCount > 1
|
||||||
|
bindingView.actionPrevious.isVisible =
|
||||||
|
Preferences.showNextEvent && eventsCount > 1
|
||||||
|
|
||||||
|
bindingView.nextEvent.text = nextEvent.title
|
||||||
|
|
||||||
|
if (Preferences.showDiffTime && now.timeInMillis < nextEvent.startDate) {
|
||||||
|
bindingView.nextEventDifferenceTime.text = if (!nextEvent.allDay) {
|
||||||
|
SettingsStringHelper.getDifferenceText(
|
||||||
|
context,
|
||||||
|
now.timeInMillis,
|
||||||
|
nextEvent.startDate
|
||||||
|
)
|
||||||
|
.toLowerCase(Locale.getDefault())
|
||||||
|
} else {
|
||||||
|
SettingsStringHelper.getAllDayEventDifferenceText(
|
||||||
|
context,
|
||||||
|
now.timeInMillis,
|
||||||
|
nextEvent.startDate
|
||||||
|
).toLowerCase(Locale.getDefault())
|
||||||
|
}
|
||||||
|
bindingView.nextEventDifferenceTime.isVisible = true
|
||||||
|
} else {
|
||||||
|
bindingView.nextEventDifferenceTime.isVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextEvent.address != "" && Preferences.secondRowInformation == 1) {
|
||||||
|
bindingView.subLineIcon.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
context,
|
||||||
|
R.drawable.round_place_24
|
||||||
|
)
|
||||||
|
)
|
||||||
|
bindingView.subLineText.text = nextEvent.address
|
||||||
|
} else {
|
||||||
|
bindingView.subLineIcon.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
context,
|
||||||
|
R.drawable.round_today_24
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if (!nextEvent.allDay) {
|
||||||
|
val startHour =
|
||||||
|
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)
|
||||||
|
|
||||||
|
val startCal = Calendar.getInstance()
|
||||||
|
startCal.timeInMillis = nextEvent.startDate
|
||||||
|
|
||||||
|
val endCal = Calendar.getInstance()
|
||||||
|
endCal.timeInMillis = nextEvent.endDate
|
||||||
|
|
||||||
|
if (startCal.get(Calendar.HOUR_OF_DAY) > endCal.get(Calendar.HOUR_OF_DAY)) {
|
||||||
|
dayDiff++
|
||||||
|
} else if (startCal.get(Calendar.HOUR_OF_DAY) == endCal.get(Calendar.HOUR_OF_DAY) && startCal.get(
|
||||||
|
Calendar.MINUTE
|
||||||
|
) > endCal.get(Calendar.MINUTE)
|
||||||
|
) {
|
||||||
|
dayDiff++
|
||||||
|
}
|
||||||
|
var multipleDay = ""
|
||||||
|
if (dayDiff > 0) {
|
||||||
|
multipleDay = String.format(
|
||||||
|
" (+%s%s)",
|
||||||
|
dayDiff,
|
||||||
|
context.getString(R.string.day_char)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextEvent.startDate != nextEvent.endDate) {
|
||||||
|
bindingView.subLineText.text =
|
||||||
|
String.format("%s - %s%s", startHour, endHour, multipleDay)
|
||||||
|
} else {
|
||||||
|
bindingView.subLineText.text =
|
||||||
|
String.format("%s", startHour)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
val flags: Int =
|
||||||
|
DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR or DateUtils.FORMAT_ABBREV_MONTH
|
||||||
|
val start = Calendar.getInstance().apply { timeInMillis = nextEvent.startDate }
|
||||||
|
|
||||||
|
bindingView.subLineText.text = if (now.get(Calendar.DAY_OF_YEAR) == start.get(
|
||||||
|
Calendar.DAY_OF_YEAR)) {
|
||||||
|
DateUtils.formatDateTime(context, nextEvent.startDate, flags)
|
||||||
|
} else if (now.get(Calendar.DAY_OF_YEAR) > start.get(Calendar.DAY_OF_YEAR) || now.get(
|
||||||
|
Calendar.YEAR) > start.get(Calendar.YEAR)) {
|
||||||
|
DateUtils.formatDateTime(context, now.timeInMillis, flags)
|
||||||
|
} else {
|
||||||
|
DateUtils.formatDateTime(context, nextEvent.startDate, flags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bindingView.dateLayout.isVisible = false
|
||||||
|
bindingView.calendarLayout.isVisible = true
|
||||||
|
bindingView.subLine.isVisible = true
|
||||||
|
bindingView.weatherSubLine.isVisible = true
|
||||||
|
|
||||||
|
bindingView.subLineTopMarginSmall.visibility =
|
||||||
|
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.SMALL.rawValue) View.VISIBLE else View.GONE
|
||||||
|
bindingView.subLineTopMarginMedium.visibility =
|
||||||
|
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.MEDIUM.rawValue) View.VISIBLE else View.GONE
|
||||||
|
bindingView.subLineTopMarginLarge.visibility =
|
||||||
|
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.rawValue) View.VISIBLE else View.GONE
|
||||||
|
} else if (GlanceProviderHelper.showGlanceProviders(context)) {
|
||||||
|
bindingView.subLineIcon.isVisible = true
|
||||||
|
var showSomething = false
|
||||||
|
loop@ for (provider: Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders(
|
||||||
|
context
|
||||||
|
)) {
|
||||||
|
when (provider) {
|
||||||
|
Constants.GlanceProviderId.PLAYING_SONG -> {
|
||||||
|
if (MediaPlayerHelper.isSomeonePlaying(context)) {
|
||||||
|
bindingView.subLineIcon.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
context,
|
||||||
|
R.drawable.round_music_note_24
|
||||||
|
)
|
||||||
|
)
|
||||||
|
bindingView.subLineText.text = MediaPlayerHelper.getMediaInfo()
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> {
|
||||||
|
if (Preferences.showNextAlarm && nextAlarm != "") {
|
||||||
|
bindingView.subLineIcon.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
context,
|
||||||
|
R.drawable.round_alarm_24
|
||||||
|
)
|
||||||
|
)
|
||||||
|
bindingView.subLineText.text = AlarmHelper.getNextAlarm(context)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
|
||||||
|
if (Preferences.showBatteryCharging) {
|
||||||
|
BatteryHelper.updateBatteryInfo(context)
|
||||||
|
if (Preferences.isCharging) {
|
||||||
|
bindingView.subLineIcon.isVisible = false
|
||||||
|
val batteryLevel = BatteryHelper.getBatteryLevel(context)
|
||||||
|
if (batteryLevel != 100) {
|
||||||
|
bindingView.subLineText.text = context.getString(R.string.charging)
|
||||||
|
} else {
|
||||||
|
bindingView.subLineText.text =
|
||||||
|
context.getString(R.string.charged)
|
||||||
|
}
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
} else if (Preferences.isBatteryLevelLow) {
|
||||||
|
bindingView.subLineIcon.isVisible = false
|
||||||
|
bindingView.subLineText.text =
|
||||||
|
context.getString(R.string.battery_low_warning)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.CUSTOM_INFO -> {
|
||||||
|
if (Preferences.customNotes.isNotEmpty()) {
|
||||||
|
bindingView.subLineIcon.isVisible = false
|
||||||
|
bindingView.subLineText.text = Preferences.customNotes
|
||||||
|
bindingView.subLineText.maxLines = 2
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
|
||||||
|
if (Preferences.showDailySteps && Preferences.googleFitSteps > 0) {
|
||||||
|
bindingView.subLineIcon.isVisible = false
|
||||||
|
bindingView.subLineText.text =
|
||||||
|
context.getString(R.string.daily_steps_counter)
|
||||||
|
.format(Preferences.googleFitSteps)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.NOTIFICATIONS -> {
|
||||||
|
if (Preferences.showNotifications && ActiveNotificationsHelper.showLastNotification()) {
|
||||||
|
try {
|
||||||
|
if (Preferences.lastNotificationIcon != 0) {
|
||||||
|
val remotePackageContext = context.createPackageContext(
|
||||||
|
Preferences.lastNotificationPackage, 0)
|
||||||
|
val icon = ContextCompat.getDrawable(remotePackageContext,
|
||||||
|
Preferences.lastNotificationIcon)
|
||||||
|
bindingView.subLineIcon.isVisible = true
|
||||||
|
bindingView.subLineIcon.setImageDrawable(icon)
|
||||||
|
} else {
|
||||||
|
bindingView.subLineIcon.isVisible = false
|
||||||
|
}
|
||||||
|
bindingView.subLineText.text = Preferences.lastNotificationTitle
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
} catch (ex: Exception) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.GREETINGS -> {
|
||||||
|
val greetingsText = GreetingsHelper.getRandomString(context)
|
||||||
|
if (Preferences.showGreetings && GreetingsHelper.showGreetings() && greetingsText.isNotBlank()) {
|
||||||
|
bindingView.subLineText.text = greetingsText
|
||||||
|
bindingView.subLineText.maxLines = 2
|
||||||
|
bindingView.subLineIcon.isVisible = false
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.EVENTS -> {
|
||||||
|
if (Preferences.showEventsAsGlanceProvider && Preferences.showEvents && context.checkGrantedPermission(
|
||||||
|
Manifest.permission.READ_CALENDAR) && nextEvent != null) {
|
||||||
|
bindingView.subLineText.text = context.getString(R.string.events_glance_provider_format).format(nextEvent.title, if (Preferences.showDiffTime && now.timeInMillis < nextEvent.startDate) {
|
||||||
|
if (!nextEvent.allDay) {
|
||||||
|
SettingsStringHelper.getDifferenceText(
|
||||||
|
context,
|
||||||
|
now.timeInMillis,
|
||||||
|
nextEvent.startDate
|
||||||
|
)
|
||||||
|
.toLowerCase(Locale.getDefault())
|
||||||
|
} else {
|
||||||
|
SettingsStringHelper.getAllDayEventDifferenceText(
|
||||||
|
context,
|
||||||
|
now.timeInMillis,
|
||||||
|
nextEvent.startDate
|
||||||
|
).toLowerCase(Locale.getDefault())
|
||||||
|
}
|
||||||
|
} else "").trimEnd()
|
||||||
|
bindingView.subLineIcon.isVisible = true
|
||||||
|
bindingView.subLineIcon.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
context,
|
||||||
|
R.drawable.round_today_24
|
||||||
|
)
|
||||||
|
)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showSomething) {
|
||||||
|
bindingView.dateLayout.isVisible = true
|
||||||
|
bindingView.calendarLayout.isVisible = false
|
||||||
|
bindingView.subLine.isVisible = true
|
||||||
|
bindingView.weatherSubLine.isVisible = false
|
||||||
|
|
||||||
|
bindingView.subLineTopMarginSmall.visibility =
|
||||||
|
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.SMALL.rawValue) View.VISIBLE else View.GONE
|
||||||
|
bindingView.subLineTopMarginMedium.visibility =
|
||||||
|
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.MEDIUM.rawValue) View.VISIBLE else View.GONE
|
||||||
|
bindingView.subLineTopMarginLarge.visibility =
|
||||||
|
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.rawValue) View.VISIBLE else View.GONE
|
||||||
|
} else {
|
||||||
|
bindingView.subLineIcon.isVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Color
|
||||||
|
listOf<TextView>(
|
||||||
|
bindingView.date,
|
||||||
|
bindingView.weatherDateLineDivider,
|
||||||
|
bindingView.weatherDateLineTemperature,
|
||||||
|
bindingView.nextEvent,
|
||||||
|
bindingView.nextEventDifferenceTime,
|
||||||
|
).forEach {
|
||||||
|
it.setTextColor(ColorHelper.getFontColor(context.applicationContext.isDarkTheme()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Preferences.weatherIconPack != Constants.WeatherIconPack.MINIMAL.rawValue) {
|
||||||
|
listOf<ImageView>(bindingView.actionNext, bindingView.actionPrevious)
|
||||||
|
} else {
|
||||||
|
listOf<ImageView>(
|
||||||
|
bindingView.actionNext,
|
||||||
|
bindingView.actionPrevious,
|
||||||
|
bindingView.weatherDateLineWeatherIcon,
|
||||||
|
bindingView.weatherSubLineWeatherIcon
|
||||||
|
)
|
||||||
|
}.forEach {
|
||||||
|
it.setColorFilter(ColorHelper.getFontColorRgb(context.applicationContext.isDarkTheme()))
|
||||||
|
it.alpha =
|
||||||
|
(if (context.isDarkTheme()) Preferences.textGlobalAlphaDark.toIntValue()
|
||||||
|
.toFloat() else Preferences.textGlobalAlpha.toIntValue()
|
||||||
|
.toFloat()) / 100
|
||||||
|
}
|
||||||
|
|
||||||
|
listOf<TextView>(bindingView.subLineText, bindingView.weatherSubLineDivider, bindingView.weatherSubLineTemperature).forEach {
|
||||||
|
it.setTextColor(ColorHelper.getSecondaryFontColor(context.applicationContext.isDarkTheme()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Preferences.weatherIconPack != Constants.WeatherIconPack.MINIMAL.rawValue) {
|
||||||
|
listOf<ImageView>(bindingView.subLineIcon, bindingView.subLineIconShadow)
|
||||||
|
} else {
|
||||||
|
listOf<ImageView>(bindingView.subLineIcon, bindingView.weatherSubLineWeatherIcon, bindingView.subLineIconShadow)
|
||||||
|
}.forEach {
|
||||||
|
it.setColorFilter(ColorHelper.getSecondaryFontColorRgb(context.applicationContext.isDarkTheme()))
|
||||||
|
it.alpha =
|
||||||
|
(if (context.isDarkTheme()) Preferences.textSecondaryAlphaDark.toIntValue()
|
||||||
|
.toFloat() else Preferences.textSecondaryAlpha.toIntValue()
|
||||||
|
.toFloat()) / 100
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text Size
|
||||||
|
listOf<Pair<TextView, Float>>(
|
||||||
|
bindingView.date to Preferences.textMainSize,
|
||||||
|
bindingView.weatherDateLineDivider to (Preferences.textMainSize - 2),
|
||||||
|
bindingView.weatherDateLineTemperature to Preferences.textMainSize,
|
||||||
|
bindingView.nextEvent to Preferences.textMainSize,
|
||||||
|
bindingView.nextEventDifferenceTime to Preferences.textMainSize,
|
||||||
|
bindingView.subLineText to Preferences.textSecondSize,
|
||||||
|
bindingView.weatherSubLineDivider to (Preferences.textSecondSize - 2),
|
||||||
|
bindingView.weatherSubLineTemperature to Preferences.textSecondSize,
|
||||||
|
).forEach {
|
||||||
|
it.first.setTextSize(TypedValue.COMPLEX_UNIT_SP, it.second)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Icons scale
|
||||||
|
bindingView.subLineIcon.scaleX = Preferences.textSecondSize / 18f
|
||||||
|
bindingView.subLineIcon.scaleY = Preferences.textSecondSize / 18f
|
||||||
|
|
||||||
|
bindingView.weatherSubLineWeatherIcon.scaleX = Preferences.textSecondSize / 18f
|
||||||
|
bindingView.weatherSubLineWeatherIcon.scaleY = Preferences.textSecondSize / 18f
|
||||||
|
|
||||||
|
bindingView.weatherDateLineWeatherIcon.scaleX = Preferences.textMainSize / 18f
|
||||||
|
bindingView.weatherDateLineWeatherIcon.scaleY = Preferences.textMainSize / 18f
|
||||||
|
|
||||||
|
bindingView.actionNext.scaleX = Preferences.textMainSize / 28f
|
||||||
|
bindingView.actionNext.scaleY = Preferences.textMainSize / 28f
|
||||||
|
|
||||||
|
bindingView.actionPrevious.scaleX = Preferences.textMainSize / 28f
|
||||||
|
bindingView.actionPrevious.scaleY = Preferences.textMainSize / 28f
|
||||||
|
|
||||||
|
|
||||||
|
// Shadows
|
||||||
|
val shadowRadius =
|
||||||
|
when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) {
|
||||||
|
0 -> 0f
|
||||||
|
1 -> 5f
|
||||||
|
2 -> 5f
|
||||||
|
else -> 5f
|
||||||
|
}
|
||||||
|
val shadowColor =
|
||||||
|
when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) {
|
||||||
|
0 -> Color.TRANSPARENT
|
||||||
|
1 -> R.color.black_50
|
||||||
|
2 -> Color.BLACK
|
||||||
|
else -> R.color.black_50
|
||||||
|
}
|
||||||
|
val shadowDy =
|
||||||
|
when (if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) {
|
||||||
|
0 -> 0f
|
||||||
|
1 -> 0f
|
||||||
|
2 -> 1f
|
||||||
|
else -> 0f
|
||||||
|
}
|
||||||
|
|
||||||
|
listOf<TextView>(
|
||||||
|
bindingView.date,
|
||||||
|
bindingView.weatherDateLineDivider,
|
||||||
|
bindingView.weatherDateLineTemperature,
|
||||||
|
bindingView.nextEvent,
|
||||||
|
bindingView.nextEventDifferenceTime,
|
||||||
|
bindingView.subLineText,
|
||||||
|
bindingView.weatherSubLineDivider,
|
||||||
|
bindingView.weatherSubLineTemperature,
|
||||||
|
).forEach {
|
||||||
|
it.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Icons shadow
|
||||||
|
|
||||||
|
listOf(
|
||||||
|
Pair(bindingView.subLineIcon, bindingView.subLineIconShadow),
|
||||||
|
).forEach {
|
||||||
|
if ((if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) == 0) {
|
||||||
|
it.second.isVisible = false
|
||||||
|
} else {
|
||||||
|
it.second.isVisible = it.first.isVisible
|
||||||
|
it.second.scaleX = it.first.scaleX
|
||||||
|
it.second.scaleY = it.first.scaleY
|
||||||
|
it.second.applyShadow(it.first)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listOf(
|
||||||
|
Pair(bindingView.actionNext, bindingView.actionNextShadow),
|
||||||
|
Pair(bindingView.actionPrevious, bindingView.actionPreviousShadow),
|
||||||
|
).forEach {
|
||||||
|
if ((if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) == 0) {
|
||||||
|
it.second.isVisible = false
|
||||||
|
} else {
|
||||||
|
it.second.isVisible = it.first.isVisible
|
||||||
|
it.second.scaleX = it.first.scaleX
|
||||||
|
it.second.scaleY = it.first.scaleY
|
||||||
|
it.second.applyShadow(it.first, 0.6f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bindingView.actionPrevious.scaleX = bindingView.actionPrevious.scaleX * -1
|
||||||
|
bindingView.actionPreviousShadow.scaleX = bindingView.actionPreviousShadow.scaleX * -1
|
||||||
|
|
||||||
|
// Custom Font
|
||||||
|
if (Preferences.customFont == Constants.CUSTOM_FONT_GOOGLE_SANS) {
|
||||||
|
val googleSans: Typeface = when (Preferences.customFontVariant) {
|
||||||
|
"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>(
|
||||||
|
bindingView.date,
|
||||||
|
bindingView.weatherDateLineDivider,
|
||||||
|
bindingView.weatherDateLineTemperature,
|
||||||
|
bindingView.nextEvent,
|
||||||
|
bindingView.nextEventDifferenceTime,
|
||||||
|
bindingView.subLineText,
|
||||||
|
bindingView.weatherSubLineDivider,
|
||||||
|
bindingView.weatherSubLineTemperature,
|
||||||
|
).forEach {
|
||||||
|
it.typeface = googleSans
|
||||||
|
}
|
||||||
|
} else if (Preferences.customFont == Constants.CUSTOM_FONT_DOWNLOADED && typeface != null) {
|
||||||
|
listOf<TextView>(
|
||||||
|
bindingView.date,
|
||||||
|
bindingView.weatherDateLineDivider,
|
||||||
|
bindingView.weatherDateLineTemperature,
|
||||||
|
bindingView.nextEvent,
|
||||||
|
bindingView.nextEventDifferenceTime,
|
||||||
|
bindingView.subLineText,
|
||||||
|
bindingView.weatherSubLineDivider,
|
||||||
|
bindingView.weatherSubLineTemperature,
|
||||||
|
).forEach {
|
||||||
|
it.typeface = typeface
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dividers
|
||||||
|
arrayOf(bindingView.weatherDateLineDivider, bindingView.weatherSubLineDivider).forEach {
|
||||||
|
it.visibility = if (Preferences.showDividers) View.VISIBLE else View.INVISIBLE
|
||||||
|
it.layoutParams = (it.layoutParams as ViewGroup.MarginLayoutParams).apply {
|
||||||
|
this.marginEnd = if (Preferences.showDividers) 8f.convertDpToPixel(context).toInt() else 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return bindingView
|
||||||
|
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
ex.printStackTrace()
|
||||||
|
CrashlyticsReceiver.sendCrash(context, ex)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -21,11 +21,14 @@ import android.content.res.Resources
|
|||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
|
import android.view.animation.AlphaAnimation
|
||||||
import android.widget.RelativeLayout
|
import android.widget.RelativeLayout
|
||||||
|
import androidx.annotation.UiThread
|
||||||
import androidx.browser.customtabs.CustomTabColorSchemeParams
|
import androidx.browser.customtabs.CustomTabColorSchemeParams
|
||||||
import androidx.core.animation.addListener
|
import androidx.core.animation.addListener
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.components.OnSingleClickListener
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
@ -253,4 +256,12 @@ fun Locale.isMetric(): Boolean {
|
|||||||
"US", "LR", "MM", "GB" -> false
|
"US", "LR", "MM", "GB" -> false
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun View.setOnSingleClickListener(l: View.OnClickListener) {
|
||||||
|
setOnClickListener(OnSingleClickListener(l))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun View.setOnSingleClickListener(l: (View) -> Unit) {
|
||||||
|
setOnClickListener(OnSingleClickListener(l))
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 207 B |
After Width: | Height: | Size: 210 B |
After Width: | Height: | Size: 203 B |
After Width: | Height: | Size: 292 B |
After Width: | Height: | Size: 245 B |
After Width: | Height: | Size: 184 B |
After Width: | Height: | Size: 186 B |
After Width: | Height: | Size: 174 B |
After Width: | Height: | Size: 275 B |
After Width: | Height: | Size: 251 B |
After Width: | Height: | Size: 187 B |
After Width: | Height: | Size: 189 B |
After Width: | Height: | Size: 174 B |
After Width: | Height: | Size: 275 B |
After Width: | Height: | Size: 253 B |
BIN
app/src/main/res/drawable-hdpi/round_more_time_white_18.png
Normal file
After Width: | Height: | Size: 428 B |
BIN
app/src/main/res/drawable-hdpi/round_more_time_white_20.png
Normal file
After Width: | Height: | Size: 448 B |
BIN
app/src/main/res/drawable-hdpi/round_more_time_white_24.png
Normal file
After Width: | Height: | Size: 436 B |
BIN
app/src/main/res/drawable-hdpi/round_more_time_white_36.png
Normal file
After Width: | Height: | Size: 779 B |
BIN
app/src/main/res/drawable-hdpi/round_more_time_white_48.png
Normal file
After Width: | Height: | Size: 867 B |
After Width: | Height: | Size: 166 B |
After Width: | Height: | Size: 172 B |
After Width: | Height: | Size: 123 B |
After Width: | Height: | Size: 203 B |
After Width: | Height: | Size: 172 B |
After Width: | Height: | Size: 142 B |
After Width: | Height: | Size: 159 B |
After Width: | Height: | Size: 122 B |
After Width: | Height: | Size: 174 B |
After Width: | Height: | Size: 176 B |
After Width: | Height: | Size: 147 B |
After Width: | Height: | Size: 163 B |
After Width: | Height: | Size: 125 B |
After Width: | Height: | Size: 174 B |
After Width: | Height: | Size: 175 B |
BIN
app/src/main/res/drawable-mdpi/round_more_time_white_18.png
Normal file
After Width: | Height: | Size: 261 B |
BIN
app/src/main/res/drawable-mdpi/round_more_time_white_20.png
Normal file
After Width: | Height: | Size: 213 B |
BIN
app/src/main/res/drawable-mdpi/round_more_time_white_24.png
Normal file
After Width: | Height: | Size: 288 B |
BIN
app/src/main/res/drawable-mdpi/round_more_time_white_36.png
Normal file
After Width: | Height: | Size: 436 B |
BIN
app/src/main/res/drawable-mdpi/round_more_time_white_48.png
Normal file
After Width: | Height: | Size: 564 B |
After Width: | Height: | Size: 213 B |
After Width: | Height: | Size: 188 B |
After Width: | Height: | Size: 187 B |
BIN
app/src/main/res/drawable-night-hdpi/round_more_time_24.png
Normal file
After Width: | Height: | Size: 445 B |
After Width: | Height: | Size: 124 B |
After Width: | Height: | Size: 124 B |
After Width: | Height: | Size: 126 B |
BIN
app/src/main/res/drawable-night-mdpi/round_more_time_24.png
Normal file
After Width: | Height: | Size: 295 B |
After Width: | Height: | Size: 176 B |
After Width: | Height: | Size: 181 B |
After Width: | Height: | Size: 179 B |
BIN
app/src/main/res/drawable-night-xhdpi/round_more_time_24.png
Normal file
After Width: | Height: | Size: 566 B |
After Width: | Height: | Size: 285 B |
After Width: | Height: | Size: 274 B |
After Width: | Height: | Size: 272 B |
BIN
app/src/main/res/drawable-night-xxhdpi/round_more_time_24.png
Normal file
After Width: | Height: | Size: 871 B |
After Width: | Height: | Size: 329 B |
After Width: | Height: | Size: 328 B |