Compare commits

...

40 Commits

Author SHA1 Message Date
5b2d245e80 Merge develop 2021-01-04 12:07:59 +01:00
0aec34dcd2 Bugfixes 2021-01-04 12:04:25 +01:00
b2a9b9fbb3 Fix #255 2021-01-03 17:51:31 +01:00
768f04825e Building 2021-01-03 17:25:00 +01:00
80ee877bf2 Merge pull request #252 from devindang/master
Update new strings for Chinese Simplified
2021-01-03 17:24:18 +01:00
ac7839ecdc Merge pull request #244 from Moutony/patch-25
Update French Greetings
2021-01-03 17:24:11 +01:00
66d0214cd9 Move the location updates to a foreground service and fix multiple bugs 2021-01-03 17:23:22 +01:00
e069b8f6ab greetings 2020-11-27 23:47:13 +08:00
8a681f0cd7 Update New Strings 2020-11-25 20:46:02 +08:00
92158ec5f2 Update strings.xml 2020-11-22 12:21:56 +01:00
ebb37f21ed Remove useless icons 2020-10-30 19:26:01 +01:00
2a389cb422 Update strings.xml 2020-10-29 12:12:27 +01:00
4504a0617e Update Fitness in Glance 2020-10-28 14:58:22 +01:00
9ed34ee17e Update French Greetings
Thanks for adding antislash before apostrophes. I always forget it haha
But, in French typography, there is a (narrow) no-break space U+202F before these punctuations ! ? ; :
2020-10-28 14:47:11 +01:00
a7294edfd4 Fix notification listener 2020-10-27 18:28:21 +01:00
49ca17803e Update translations 2020-10-27 18:21:55 +01:00
97ab72081d Update the UI 2020-10-27 18:13:27 +01:00
e6fee0dfe1 Merge branch 'master' of github.com:tommasoberlose/another-widget into develop 2020-10-27 18:13:15 +01:00
e0c4f24c43 Merge pull request #239 from Vgbhieel/master
Added Portuguese translation (values-pt)
2020-10-27 18:13:02 +01:00
2a7d0f171b Create strings,xml for portuguese values
translated all strings to portuguese
2020-10-23 00:55:39 -03:00
00dcfc3149 Merge branch 'master' of github.com:tommasoberlose/another-widget into develop 2020-10-20 10:39:19 +02:00
eb11b603aa Merge pull request #235 from Moutony/patch-24
Update French 2
2020-10-20 10:39:01 +02:00
4d2f624448 Merge branch 'master' of github.com:tommasoberlose/another-widget into develop 2020-10-20 10:38:47 +02:00
7581af4dd2 Merge branch 'english-strings' 2020-10-20 10:38:19 +02:00
0325af6582 Fix uppercase labels 2020-10-20 10:35:54 +02:00
4de0413a35 Fix multiple bugs 2020-10-20 10:27:05 +02:00
c54a24c889 Update strings.xml 2020-10-19 21:54:51 +02:00
98eccd2833 Update strings.xml 2020-10-19 21:54:17 +02:00
0119a20765 Update strings.xml 2020-10-19 21:51:12 +02:00
a1e54892fd Update strings.xml 2020-10-19 16:28:38 +02:00
17801fd164 Update strings.xml 2020-10-19 16:26:57 +02:00
e6087b2969 Merge pull request #234 from Moutony/patch-23
Update French
2020-10-19 15:35:06 +02:00
59b8ba26a2 Merge pull request #232 from d-l-n/master
Added and translated new strings
2020-10-19 15:35:01 +02:00
f190ee5d15 Merge pull request #231 from Drumber/translation
Update German translation
2020-10-19 15:34:48 +02:00
2f266ffcf8 Update strings.xml 2020-10-19 11:07:05 +02:00
0e376aba80 Update strings.xml 2020-10-19 11:06:29 +02:00
313e4fa92d Update French 2020-10-19 11:01:21 +02:00
a8ec754bc4 Added and translated new strings 2020-10-19 01:04:33 -03:00
f8d1188634 Update strings.xml
Added greetings and notification timeout strings
2020-10-18 18:47:52 +02:00
8216fc96b9 Update English strings.xml
Removed OpenWeatherMap former instructions.
Capitalized all action buttons.
name="action_save" translatable="false">OK
2020-10-18 16:15:22 +02:00
2480 changed files with 1282 additions and 469 deletions

View File

@ -123,6 +123,29 @@
</PersistentState> </PersistentState>
</value> </value>
</entry> </entry>
<entry key="vectorWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="vectorAssetStep">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="assetSourceType" value="FILE" />
<entry key="outputName" value="round_aspect_ratio_24" />
<entry key="sourceFile" value="$USER_HOME$/Desktop/round_aspect_ratio_24.svg" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map> </map>
</option> </option>
</component> </component>

Binary file not shown.

View File

@ -16,15 +16,15 @@ apikeyProperties.load(new FileInputStream(apikeyPropertiesFile))
android { android {
compileSdkVersion 29 compileSdkVersion 30
buildToolsVersion "29.0.3" buildToolsVersion "29.0.3"
defaultConfig { defaultConfig {
applicationId "com.tommasoberlose.anotherwidget" applicationId "com.tommasoberlose.anotherwidget"
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 29 targetSdkVersion 30
versionCode 109 versionCode 114
versionName "2.0.15" versionName "2.1.0"
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'])
@ -72,9 +72,9 @@ dependencies {
// UI // UI
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.2' implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'com.google.android.material:material:1.3.0-alpha03' implementation 'com.google.android.material:material:1.3.0-beta01'
implementation 'androidx.browser:browser:1.2.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'
@ -89,8 +89,8 @@ dependencies {
implementation 'org.greenrobot:eventbus:3.2.0' implementation 'org.greenrobot:eventbus:3.2.0'
// Navigation // Navigation
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0' implementation 'androidx.navigation:navigation-fragment-ktx:2.3.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.0' implementation 'androidx.navigation:navigation-ui-ktx:2.3.2'
// Other // Other
implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.multidex:multidex:2.0.1'
@ -103,7 +103,7 @@ dependencies {
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:18.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:18.1.0'
//Weather //Weather
@ -111,8 +111,8 @@ dependencies {
implementation 'com.google.android.gms:play-services-location:17.1.0' implementation 'com.google.android.gms:play-services-location:17.1.0'
// Billing // Billing
implementation 'com.android.billingclient:billing:3.0.1' implementation 'com.android.billingclient:billing:3.0.2'
implementation 'com.android.billingclient:billing-ktx:3.0.1' implementation 'com.android.billingclient:billing-ktx:3.0.2'
// KTX // KTX
implementation "androidx.core:core-ktx:1.3.2" implementation "androidx.core:core-ktx:1.3.2"
@ -128,10 +128,10 @@ 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.5' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
// Add the Firebase SDK for Crashlytics. // Add the Firebase SDK for Crashlytics.
implementation 'com.google.firebase:firebase-crashlytics:17.2.2' implementation 'com.google.firebase:firebase-crashlytics:17.3.0'
// Preferences // Preferences
implementation 'com.chibatching.kotpref:kotpref:2.11.0' implementation 'com.chibatching.kotpref:kotpref:2.11.0'

Binary file not shown.

View File

@ -5,7 +5,6 @@
<uses-permission android:name="android.permission.READ_CALENDAR" /> <uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.android.vending.BILLING" /> <uses-permission android:name="com.android.vending.BILLING" />
@ -13,6 +12,7 @@
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" /> <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.gms.permission.ACTIVITY_RECOGNITION"/> <uses-permission android:name="android.gms.permission.ACTIVITY_RECOGNITION"/>
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" /> <uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application <application
@ -154,6 +154,14 @@
android:name=".services.UpdateCalendarJob" android:name=".services.UpdateCalendarJob"
android:permission="android.permission.BIND_JOB_SERVICE" android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true"/> android:exported="true"/>
<service
android:name=".services.LocationService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="location" />
</application> </application>
<queries>
<package android:name="com.google.android.apps.fitness"/>
</queries>
</manifest> </manifest>

View File

@ -24,6 +24,7 @@ import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.helpers.ColorHelper import com.tommasoberlose.anotherwidget.helpers.ColorHelper
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
import com.tommasoberlose.anotherwidget.utils.expand import com.tommasoberlose.anotherwidget.utils.expand
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
import com.tommasoberlose.anotherwidget.utils.reveal import com.tommasoberlose.anotherwidget.utils.reveal
import com.tommasoberlose.anotherwidget.utils.toPixel import com.tommasoberlose.anotherwidget.utils.toPixel
import com.warkiz.widget.IndicatorSeekBar import com.warkiz.widget.IndicatorSeekBar
@ -93,6 +94,7 @@ class BottomSheetColorPicker(
injector injector
.with<MaterialCardView>(R.id.color) { .with<MaterialCardView>(R.id.color) {
it.setCardBackgroundColor(ColorStateList.valueOf(item)) it.setCardBackgroundColor(ColorStateList.valueOf(item))
it.strokeWidth = if ((colors.indexOf(item) == 0 && !context.isDarkTheme()) || (colors.indexOf(item) == 10 && context.isDarkTheme())) 2 else 0
} }
.with<AppCompatImageView>(R.id.check) { .with<AppCompatImageView>(R.id.check) {
if (getSelected?.invoke() == item) { if (getSelected?.invoke() == item) {

View File

@ -9,7 +9,7 @@ import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
import kotlinx.android.synthetic.main.custom_notes_dialog_layout.view.* import kotlinx.android.synthetic.main.custom_notes_dialog_layout.view.*
class CustomNotesDialog(context: Context) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) { class CustomNotesDialog(context: Context, callback: (() -> Unit)?) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) {
init { init {
val view = View.inflate(context, R.layout.custom_notes_dialog_layout, null) val view = View.inflate(context, R.layout.custom_notes_dialog_layout, null)
@ -18,6 +18,7 @@ class CustomNotesDialog(context: Context) : BottomSheetDialog(context, R.style.B
view.action_positive.setOnClickListener { view.action_positive.setOnClickListener {
Preferences.customNotes = view.notes.text.toString() Preferences.customNotes = view.notes.text.toString()
this.dismiss() this.dismiss()
callback?.invoke()
} }
view.notes.requestFocus() view.notes.requestFocus()

View File

@ -7,6 +7,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Build import android.os.Build
import android.util.EventLog
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
@ -30,9 +31,11 @@ import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver
import com.tommasoberlose.anotherwidget.ui.activities.AppNotificationsFilterActivity import com.tommasoberlose.anotherwidget.ui.activities.AppNotificationsFilterActivity
import com.tommasoberlose.anotherwidget.ui.activities.MusicPlayersFilterActivity import com.tommasoberlose.anotherwidget.ui.activities.MusicPlayersFilterActivity
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import kotlinx.android.synthetic.main.glance_provider_settings_layout.view.* import kotlinx.android.synthetic.main.glance_provider_settings_layout.view.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import org.greenrobot.eventbus.EventBus
class GlanceSettingsDialog(val context: Activity, val provider: Constants.GlanceProviderId, private val statusCallback: (() -> Unit)?) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) { class GlanceSettingsDialog(val context: Activity, val provider: Constants.GlanceProviderId, private val statusCallback: (() -> Unit)?) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) {
@ -48,6 +51,7 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> context.getString(R.string.settings_daily_steps_title) Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> context.getString(R.string.settings_daily_steps_title)
Constants.GlanceProviderId.NOTIFICATIONS -> context.getString(R.string.settings_show_notifications_title) Constants.GlanceProviderId.NOTIFICATIONS -> context.getString(R.string.settings_show_notifications_title)
Constants.GlanceProviderId.GREETINGS -> context.getString(R.string.settings_show_greetings_title) Constants.GlanceProviderId.GREETINGS -> context.getString(R.string.settings_show_greetings_title)
Constants.GlanceProviderId.EVENTS -> context.getString(R.string.settings_show_events_as_glance_provider_title)
} }
/* SUBTITLE*/ /* SUBTITLE*/
@ -59,6 +63,7 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> context.getString(R.string.settings_daily_steps_subtitle) Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> context.getString(R.string.settings_daily_steps_subtitle)
Constants.GlanceProviderId.NOTIFICATIONS -> context.getString(R.string.settings_show_notifications_subtitle) Constants.GlanceProviderId.NOTIFICATIONS -> context.getString(R.string.settings_show_notifications_subtitle)
Constants.GlanceProviderId.GREETINGS -> context.getString(R.string.settings_show_greetings_subtitle) Constants.GlanceProviderId.GREETINGS -> context.getString(R.string.settings_show_greetings_subtitle)
Constants.GlanceProviderId.EVENTS -> context.getString(R.string.settings_show_events_as_glance_provider_subtitle)
} }
/* SONG */ /* SONG */
@ -124,6 +129,13 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
view.divider.isVisible = false view.divider.isVisible = false
} }
/* EVENTS */
if (provider == Constants.GlanceProviderId.EVENTS) {
view.header.isVisible = false
view.divider.isVisible = false
checkCalendarConfig(view)
}
/* TOGGLE */ /* TOGGLE */
view.provider_switch.isChecked = when (provider) { view.provider_switch.isChecked = when (provider) {
Constants.GlanceProviderId.PLAYING_SONG -> Preferences.showMusic Constants.GlanceProviderId.PLAYING_SONG -> Preferences.showMusic
@ -133,6 +145,7 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> Preferences.showDailySteps Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> Preferences.showDailySteps
Constants.GlanceProviderId.NOTIFICATIONS -> Preferences.showNotifications Constants.GlanceProviderId.NOTIFICATIONS -> Preferences.showNotifications
Constants.GlanceProviderId.GREETINGS -> Preferences.showGreetings Constants.GlanceProviderId.GREETINGS -> Preferences.showGreetings
Constants.GlanceProviderId.EVENTS -> Preferences.showEventsAsGlanceProvider
} }
var job: Job? = null var job: Job? = null
@ -188,6 +201,9 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
checkFitnessPermission(view) checkFitnessPermission(view)
checkGoogleFitConnection(view) checkGoogleFitConnection(view)
} }
Constants.GlanceProviderId.EVENTS -> {
Preferences.showEventsAsGlanceProvider = isChecked
}
else -> { else -> {
} }
} }
@ -220,6 +236,19 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
statusCallback?.invoke() statusCallback?.invoke()
} }
private fun checkCalendarConfig(view: View) {
if (!Preferences.showEvents || !context.checkGrantedPermission(Manifest.permission.READ_CALENDAR)) {
view.warning_container.isVisible = true
view.warning_title.text = context.getString(R.string.settings_show_events_as_glance_provider_error)
view.warning_container.setOnClickListener {
dismiss()
EventBus.getDefault().post(MainFragment.ChangeTabEvent(1))
}
} else {
view.warning_container.isVisible = false
}
}
private fun checkNotificationPermission(view: View) { private fun checkNotificationPermission(view: View) {
when { when {
ActiveNotificationsHelper.checkNotificationAccess(context) -> { ActiveNotificationsHelper.checkNotificationAccess(context) -> {

View File

@ -32,7 +32,8 @@ object Constants {
CUSTOM_INFO("CUSTOM_INFO"), CUSTOM_INFO("CUSTOM_INFO"),
GOOGLE_FIT_STEPS("GOOGLE_FIT_STEPS"), GOOGLE_FIT_STEPS("GOOGLE_FIT_STEPS"),
NOTIFICATIONS("NOTIFICATIONS"), NOTIFICATIONS("NOTIFICATIONS"),
GREETINGS("GREETINGS"); GREETINGS("GREETINGS"),
EVENTS("EVENTS");
companion object { companion object {
private val map = GlanceProviderId.values().associateBy(GlanceProviderId::id) private val map = GlanceProviderId.values().associateBy(GlanceProviderId::id)

View File

@ -141,6 +141,8 @@ object Preferences : KotprefModel() {
var musicPlayersFilter by stringPref(default = "") var musicPlayersFilter by stringPref(default = "")
var appNotificationsFilter by stringPref(default = "") var appNotificationsFilter by stringPref(default = "")
var showEventsAsGlanceProvider by booleanPref(default = false)
// Integrations // Integrations
var installedIntegrations by intPref(default = 0) var installedIntegrations by intPref(default = 0)
} }

View File

@ -9,6 +9,7 @@ import com.chibatching.kotpref.Kotpref
import com.chibatching.kotpref.blockingBulk import com.chibatching.kotpref.blockingBulk
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.receivers.NotificationListener import com.tommasoberlose.anotherwidget.receivers.NotificationListener
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
object ActiveNotificationsHelper { object ActiveNotificationsHelper {
fun showLastNotification(): Boolean { fun showLastNotification(): Boolean {
@ -23,6 +24,7 @@ object ActiveNotificationsHelper {
remove(Preferences::lastNotificationPackage) remove(Preferences::lastNotificationPackage)
remove(Preferences::lastNotificationIcon) remove(Preferences::lastNotificationIcon)
} }
MainWidget.updateWidget(context)
} }
fun checkNotificationAccess(context: Context): Boolean { fun checkNotificationAccess(context: Context): Boolean {

View File

@ -1,5 +1,6 @@
package com.tommasoberlose.anotherwidget.helpers package com.tommasoberlose.anotherwidget.helpers
import android.Manifest
import android.content.Context import android.content.Context
import android.util.Log import android.util.Log
import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.R
@ -7,6 +8,7 @@ import com.tommasoberlose.anotherwidget.db.EventRepository
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.models.GlanceProvider import com.tommasoberlose.anotherwidget.models.GlanceProvider
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import com.tommasoberlose.anotherwidget.utils.checkIfFitInstalled import com.tommasoberlose.anotherwidget.utils.checkIfFitInstalled
import java.util.ArrayList import java.util.ArrayList
@ -20,7 +22,7 @@ object GlanceProviderHelper {
} }
.toTypedArray() .toTypedArray()
providers.sortWith(Comparator { p1, p2 -> return ArrayList(providers.filter { enabledProviders.contains(it.id) }.sortedWith(Comparator { p1, p2 ->
when { when {
enabledProviders.contains(p1.id) && enabledProviders.contains(p2.id) -> { enabledProviders.contains(p1.id) && enabledProviders.contains(p2.id) -> {
enabledProviders.indexOf(p1.id).compareTo(enabledProviders.indexOf(p2.id)) enabledProviders.indexOf(p1.id).compareTo(enabledProviders.indexOf(p2.id))
@ -35,8 +37,7 @@ object GlanceProviderHelper {
p1.id.compareTo(p2.id) p1.id.compareTo(p2.id)
} }
} }
}) }) + providers.filter { !enabledProviders.contains(it.id) })
return ArrayList(providers.toList())
} }
fun getGlanceProviderById(context: Context, providerId: Constants.GlanceProviderId): GlanceProvider? { fun getGlanceProviderById(context: Context, providerId: Constants.GlanceProviderId): GlanceProvider? {
@ -44,49 +45,55 @@ object GlanceProviderHelper {
Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> { Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> {
GlanceProvider(providerId.id, GlanceProvider(providerId.id,
context.getString(R.string.settings_show_next_alarm_title), context.getString(R.string.settings_show_next_alarm_title),
R.drawable.round_access_alarm R.drawable.round_access_alarm_24
) )
} }
Constants.GlanceProviderId.PLAYING_SONG -> { Constants.GlanceProviderId.PLAYING_SONG -> {
GlanceProvider(providerId.id, GlanceProvider(providerId.id,
context.getString(R.string.settings_show_music_title), context.getString(R.string.settings_show_music_title),
R.drawable.round_music_note R.drawable.round_music_note_24
) )
} }
Constants.GlanceProviderId.CUSTOM_INFO -> { Constants.GlanceProviderId.CUSTOM_INFO -> {
GlanceProvider(providerId.id, GlanceProvider(providerId.id,
context.getString(R.string.settings_custom_notes_title), context.getString(R.string.settings_custom_notes_title),
R.drawable.round_sticky_note_2 R.drawable.round_sticky_note_2_24
) )
} }
Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> { Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
GlanceProvider(providerId.id, GlanceProvider(providerId.id,
context.getString(R.string.settings_low_battery_level_title), context.getString(R.string.settings_low_battery_level_title),
R.drawable.round_battery_charging_full R.drawable.round_battery_charging_full_24
) )
} }
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> { Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
GlanceProvider(providerId.id, GlanceProvider(providerId.id,
context.getString(R.string.settings_daily_steps_title), context.getString(R.string.settings_daily_steps_title),
R.drawable.round_near_me R.drawable.round_favorite_border_24
) )
} }
Constants.GlanceProviderId.NOTIFICATIONS -> { Constants.GlanceProviderId.NOTIFICATIONS -> {
GlanceProvider(providerId.id, GlanceProvider(providerId.id,
context.getString(R.string.settings_show_notifications_title), context.getString(R.string.settings_show_notifications_title),
R.drawable.round_notifications R.drawable.round_notifications_24
) )
} }
Constants.GlanceProviderId.GREETINGS -> { Constants.GlanceProviderId.GREETINGS -> {
GlanceProvider(providerId.id, GlanceProvider(providerId.id,
context.getString(R.string.settings_show_greetings_title), context.getString(R.string.settings_show_greetings_title),
R.drawable.round_history_edu R.drawable.round_history_edu_24
)
}
Constants.GlanceProviderId.EVENTS -> {
GlanceProvider(providerId.id,
context.getString(R.string.settings_show_events_as_glance_provider_title),
R.drawable.round_event_note_24
) )
} }
} }
} }
fun saveGlanceProviderOrder(list: ArrayList<Constants.GlanceProviderId>) { fun saveGlanceProviderOrder(list: List<Constants.GlanceProviderId>) {
Preferences.enabledGlanceProviderOrder = list.joinToString(separator = ",") Preferences.enabledGlanceProviderOrder = list.joinToString(separator = ",")
} }
@ -94,7 +101,7 @@ object GlanceProviderHelper {
val eventRepository = EventRepository(context) val eventRepository = EventRepository(context)
BatteryHelper.updateBatteryInfo(context) BatteryHelper.updateBatteryInfo(context)
val showGlance = Preferences.showGlance && (eventRepository.getEventsCount() == 0 || !Preferences.showEvents) val showGlance = Preferences.showGlance && (eventRepository.getEventsCount() == 0 || !Preferences.showEvents || Preferences.showEventsAsGlanceProvider)
&& ( && (
(Preferences.showNotifications && ActiveNotificationsHelper.showLastNotification()) || (Preferences.showNotifications && ActiveNotificationsHelper.showLastNotification()) ||
(Preferences.showNextAlarm && AlarmHelper.getNextAlarm(context) != "") || (Preferences.showNextAlarm && AlarmHelper.getNextAlarm(context) != "") ||
@ -102,7 +109,9 @@ object GlanceProviderHelper {
(Preferences.showBatteryCharging && Preferences.isCharging || Preferences.isBatteryLevelLow) || (Preferences.showBatteryCharging && Preferences.isCharging || Preferences.isBatteryLevelLow) ||
(Preferences.customNotes.isNotEmpty()) || (Preferences.customNotes.isNotEmpty()) ||
(Preferences.showDailySteps && Preferences.googleFitSteps > 0) || (Preferences.showDailySteps && Preferences.googleFitSteps > 0) ||
(Preferences.showGreetings && GreetingsHelper.showGreetings()) (Preferences.showGreetings && GreetingsHelper.showGreetings()) ||
(Preferences.showEventsAsGlanceProvider && Preferences.showEvents && context.checkGrantedPermission(
Manifest.permission.READ_CALENDAR) && eventRepository.getNextEvent() != null)
) )
eventRepository.close() eventRepository.close()
return showGlance return showGlance

View File

@ -10,6 +10,7 @@ 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.ui.fragments.MainFragment import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
@ -31,26 +32,8 @@ object WeatherHelper {
val networkApi = WeatherNetworkApi(context) val networkApi = WeatherNetworkApi(context)
if (Preferences.customLocationAdd != "") { if (Preferences.customLocationAdd != "") {
networkApi.updateWeather() networkApi.updateWeather()
} else if (context.checkGrantedPermission(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION)) { } else if (context.checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
LocationServices.getFusedLocationProviderClient(context).lastLocation.addOnCompleteListener { task -> LocationService.requestNewLocation(context)
if (task.isSuccessful) {
val location = task.result
if (location != null) {
Preferences.customLocationLat = location.latitude.toString()
Preferences.customLocationLon = location.longitude.toString()
}
CoroutineScope(Dispatchers.IO).launch {
networkApi.updateWeather()
}
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
} else {
CoroutineScope(Dispatchers.IO).launch {
networkApi.updateWeather()
}
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
}
}
} }
} }

View File

@ -8,6 +8,7 @@ import android.os.Build
import android.service.notification.NotificationListenerService 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 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
@ -33,24 +34,19 @@ class NotificationListener : NotificationListenerService() {
val isGroupHeader = sbn.notification.flags and Notification.FLAG_GROUP_SUMMARY != 0 val isGroupHeader = sbn.notification.flags and Notification.FLAG_GROUP_SUMMARY != 0
val isOngoing = sbn.notification.flags and Notification.FLAG_ONGOING_EVENT != 0 val isOngoing = sbn.notification.flags and Notification.FLAG_ONGOING_EVENT != 0
if (bundle.containsKey(Notification.EXTRA_TITLE) && !isGroupHeader && !isOngoing && ActiveNotificationsHelper.isAppAccepted(sbn.packageName)) { if (bundle.containsKey(Notification.EXTRA_TITLE) && !isGroupHeader && !isOngoing && ActiveNotificationsHelper.isAppAccepted(sbn.packageName) && !sbn.packageName.contains("com.android.systemui")) {
Preferences.lastNotificationId = sbn.id Preferences.lastNotificationId = sbn.id
Preferences.lastNotificationTitle = bundle.getString(Notification.EXTRA_TITLE) ?: "" Preferences.lastNotificationTitle = bundle.getString(Notification.EXTRA_TITLE) ?: ""
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
try {
Preferences.lastNotificationIcon = sbn.notification.smallIcon.resId Preferences.lastNotificationIcon = sbn.notification.smallIcon.resId
} catch (ex: Exception) {
Preferences.lastNotificationIcon = 0
}
Preferences.lastNotificationPackage = sbn.notification.smallIcon.resPackage
} else { } else {
try {
Preferences.lastNotificationIcon = sbn.notification.icon Preferences.lastNotificationIcon = sbn.notification.icon
}
} catch (ex: Exception) { } catch (ex: Exception) {
Preferences.lastNotificationIcon = 0 Preferences.lastNotificationIcon = 0
} }
Preferences.lastNotificationPackage = sbn.packageName Preferences.lastNotificationPackage = sbn.packageName
}
MainWidget.updateWidget(this) MainWidget.updateWidget(this)
setTimeout(this) setTimeout(this)
} }

View File

@ -33,9 +33,9 @@ class UpdatesReceiver : BroadcastReceiver() {
Intent.ACTION_LOCALE_CHANGED, Intent.ACTION_LOCALE_CHANGED,
Intent.ACTION_DATE_CHANGED, Intent.ACTION_DATE_CHANGED,
Actions.ACTION_CALENDAR_UPDATE -> { Actions.ACTION_CALENDAR_UPDATE -> {
CalendarHelper.updateEventList(context)
ActiveNotificationsHelper.clearLastNotification(context) ActiveNotificationsHelper.clearLastNotification(context)
MediaPlayerHelper.updatePlayingMediaInfo(context) MediaPlayerHelper.updatePlayingMediaInfo(context)
CalendarHelper.updateEventList(context)
} }
"com.sec.android.widgetapp.APPWIDGET_RESIZE", "com.sec.android.widgetapp.APPWIDGET_RESIZE",

View File

@ -0,0 +1,129 @@
package com.tommasoberlose.anotherwidget.services
import android.Manifest
import android.app.*
import android.app.job.JobScheduler
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.location.Address
import android.location.Geocoder
import android.os.IBinder
import android.util.Log
import androidx.core.app.*
import androidx.core.content.ContextCompat
import com.google.android.gms.location.LocationServices
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
import kotlinx.coroutines.*
import org.greenrobot.eventbus.EventBus
import java.lang.Exception
import java.util.*
import kotlin.collections.ArrayList
class LocationService : Service() {
private val jobs: ArrayList<Job> = ArrayList()
override fun onCreate() {
super.onCreate()
startForeground(LOCATION_ACCESS_NOTIFICATION_ID, getLocationAccessNotification())
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
jobs += GlobalScope.launch(Dispatchers.IO) {
LocationServices.getFusedLocationProviderClient(this@LocationService).lastLocation.addOnCompleteListener { task ->
val networkApi = WeatherNetworkApi(this@LocationService)
if (task.isSuccessful) {
val location = task.result
if (location != null) {
Preferences.customLocationLat = location.latitude.toString()
Preferences.customLocationLon = location.longitude.toString()
}
CoroutineScope(Dispatchers.IO).launch {
networkApi.updateWeather()
withContext(Dispatchers.Main) {
stopSelf()
}
}
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
} else {
CoroutineScope(Dispatchers.IO).launch {
networkApi.updateWeather()
withContext(Dispatchers.Main) {
stopSelf()
}
}
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
}
}
}
} else {
stopSelf()
}
return START_STICKY
}
override fun onDestroy() {
super.onDestroy()
jobs.forEach {
it.cancel()
}
}
companion object {
const val LOCATION_ACCESS_NOTIFICATION_ID = 28465
@JvmStatic
fun requestNewLocation(context: Context) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
context.startForegroundService(Intent(context, LocationService::class.java))
} else {
context.startService(Intent(context, LocationService::class.java))
}
}
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
private fun getLocationAccessNotification(): Notification {
with(NotificationManagerCompat.from(this)) {
// Create channel
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
createNotificationChannel(
NotificationChannel(
getString(R.string.location_access_notification_channel_id),
getString(R.string.location_access_notification_channel_name),
NotificationManager.IMPORTANCE_LOW
).apply {
description = getString(R.string.location_access_notification_channel_description)
}
)
}
val builder = NotificationCompat.Builder(this@LocationService, getString(R.string.location_access_notification_channel_id))
.setSmallIcon(R.drawable.ic_stat_notification)
.setContentTitle(getString(R.string.location_access_notification_title))
.setStyle(NotificationCompat.BigTextStyle().bigText(getString(R.string.location_access_notification_subtitle)))
.setOngoing(true)
.setColor(ContextCompat.getColor(this@LocationService, R.color.colorAccent))
// Main intent that open the activity
builder.setContentIntent(PendingIntent.getActivity(this@LocationService, 0, Intent(this@LocationService, MainActivity::class.java), PendingIntent.FLAG_UPDATE_CURRENT))
return builder.build()
}
}
}

View File

@ -85,6 +85,24 @@ class UpdateCalendarJob : JobIntentService() {
instance.end = instance.end =
end.timeInMillis - end.timeZone.getOffset(end.timeInMillis) end.timeInMillis - end.timeZone.getOffset(end.timeInMillis)
} }
// Check all day events
val startDate = Calendar.getInstance()
startDate.timeInMillis = instance.begin
val endDate = Calendar.getInstance()
endDate.timeInMillis = instance.end
val isAllDay = e.allDay || (
startDate.get(Calendar.MILLISECOND) == 0
&& startDate.get(Calendar.SECOND) == 0
&& startDate.get(Calendar.MINUTE) == 0
&& startDate.get(Calendar.HOUR_OF_DAY) == 0
&& endDate.get(Calendar.MILLISECOND) == 0
&& endDate.get(Calendar.SECOND) == 0
&& endDate.get(Calendar.MINUTE) == 0
&& endDate.get(Calendar.HOUR_OF_DAY) == 0
)
eventList.add( eventList.add(
Event( Event(
id = instance.id, id = instance.id,
@ -93,7 +111,7 @@ class UpdateCalendarJob : JobIntentService() {
startDate = instance.begin, startDate = instance.begin,
endDate = instance.end, endDate = instance.end,
calendarID = e.calendarId.toInt(), calendarID = e.calendarId.toInt(),
allDay = e.allDay, allDay = isAllDay,
address = e.eventLocation ?: "", address = e.eventLocation ?: "",
selfAttendeeStatus = e.selfAttendeeStatus.toInt(), selfAttendeeStatus = e.selfAttendeeStatus.toInt(),
availability = e.availability availability = e.availability

View File

@ -53,7 +53,7 @@ class ChooseApplicationActivity : AppCompatActivity() {
.register<String>(R.layout.application_info_layout) { _, injector -> .register<String>(R.layout.application_info_layout) { _, injector ->
injector injector
.text(R.id.text, getString(R.string.default_name)) .text(R.id.text, getString(R.string.default_name))
.image(R.id.icon, R.drawable.round_add_to_home_screen) .image(R.id.icon, R.drawable.round_add_to_home_screen_24)
.with<ImageView>(R.id.icon) { .with<ImageView>(R.id.icon) {
it.scaleX = 0.8f it.scaleX = 0.8f
it.scaleY = 0.8f it.scaleY = 0.8f

View File

@ -140,7 +140,7 @@ class CustomLocationActivity : AppCompatActivity() {
private fun requirePermission() { private fun requirePermission() {
Dexter.withContext(this) Dexter.withContext(this)
.withPermissions( .withPermissions(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION Manifest.permission.ACCESS_FINE_LOCATION
).withListener(object: MultiplePermissionsListener { ).withListener(object: MultiplePermissionsListener {
override fun onPermissionsChecked(report: MultiplePermissionsReport?) { override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
report?.let { report?.let {

View File

@ -129,7 +129,7 @@ class WeatherProviderActivity : AppCompatActivity() {
it.isVisible = false it.isVisible = false
} }
} }
.image(R.id.action_configure, ContextCompat.getDrawable(this, if (WeatherHelper.isKeyRequired(provider)) R.drawable.round_settings else R.drawable.outline_info_white)) .image(R.id.action_configure, ContextCompat.getDrawable(this, if (WeatherHelper.isKeyRequired(provider)) R.drawable.round_settings_24 else R.drawable.outline_info_24))
}.attachTo(list_view) }.attachTo(list_view)
adapter.updateData( adapter.updateData(

View File

@ -15,7 +15,6 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
@ -51,7 +50,6 @@ import kotlinx.android.synthetic.main.fragment_glance_settings.*
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import net.idik.lib.slimadapter.SlimAdapter import net.idik.lib.slimadapter.SlimAdapter
import java.util.*
class GlanceTabFragment : Fragment() { class GlanceTabFragment : Fragment() {
@ -63,6 +61,7 @@ class GlanceTabFragment : Fragment() {
private var dialog: GlanceSettingsDialog? = null private var dialog: GlanceSettingsDialog? = null
private lateinit var adapter: SlimAdapter private lateinit var adapter: SlimAdapter
private lateinit var viewModel: MainViewModel private lateinit var viewModel: MainViewModel
private lateinit var list: ArrayList<Constants.GlanceProviderId>
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -84,6 +83,8 @@ class GlanceTabFragment : Fragment() {
binding.lifecycleOwner = this binding.lifecycleOwner = this
binding.viewModel = viewModel binding.viewModel = viewModel
list = GlanceProviderHelper.getGlanceProviders(requireContext())
return binding.root return binding.root
} }
@ -107,7 +108,9 @@ class GlanceTabFragment : Fragment() {
.clicked(R.id.item) { .clicked(R.id.item) {
if (Preferences.showGlance) { if (Preferences.showGlance) {
if (provider == Constants.GlanceProviderId.CUSTOM_INFO) { if (provider == Constants.GlanceProviderId.CUSTOM_INFO) {
CustomNotesDialog(requireContext()).show() CustomNotesDialog(requireContext()){
adapter.notifyItemRangeChanged(0, adapter.data.size)
}.show()
} else { } else {
dialog = GlanceSettingsDialog(requireActivity(), provider) { dialog = GlanceSettingsDialog(requireActivity(), provider) {
adapter.notifyItemRangeChanged(0, adapter.data.size) adapter.notifyItemRangeChanged(0, adapter.data.size)
@ -119,6 +122,7 @@ class GlanceTabFragment : Fragment() {
} }
} }
} }
var isVisible = false
when (provider) { when (provider) {
Constants.GlanceProviderId.PLAYING_SONG -> { Constants.GlanceProviderId.PLAYING_SONG -> {
when { when {
@ -129,16 +133,19 @@ class GlanceTabFragment : Fragment() {
injector.text(R.id.label, injector.text(R.id.label,
if (Preferences.showMusic) getString(R.string.settings_visible) else getString( if (Preferences.showMusic) getString(R.string.settings_visible) else getString(
R.string.settings_not_visible)) R.string.settings_not_visible))
isVisible = Preferences.showMusic
} }
Preferences.showMusic -> { Preferences.showMusic -> {
injector.visibility(R.id.error_icon, View.VISIBLE) injector.visibility(R.id.error_icon, View.VISIBLE)
injector.visibility(R.id.info_icon, View.GONE) injector.visibility(R.id.info_icon, View.GONE)
injector.text(R.id.label, getString(R.string.settings_not_visible)) injector.text(R.id.label, getString(R.string.settings_not_visible))
isVisible = false
} }
else -> { else -> {
injector.visibility(R.id.error_icon, View.GONE) injector.visibility(R.id.error_icon, View.GONE)
injector.visibility(R.id.info_icon, View.VISIBLE) injector.visibility(R.id.info_icon, View.VISIBLE)
injector.text(R.id.label, getString(R.string.settings_not_visible)) injector.text(R.id.label, getString(R.string.settings_not_visible))
isVisible = false
} }
} }
} }
@ -156,6 +163,8 @@ class GlanceTabFragment : Fragment() {
if (!(Preferences.showNextAlarm && AlarmHelper.isAlarmProbablyWrong( if (!(Preferences.showNextAlarm && AlarmHelper.isAlarmProbablyWrong(
requireContext())) requireContext()))
) View.VISIBLE else View.GONE) ) View.VISIBLE else View.GONE)
isVisible = !(Preferences.showNextAlarm && AlarmHelper.isAlarmProbablyWrong(
requireContext()))
} }
Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> { Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
injector.text(R.id.label, injector.text(R.id.label,
@ -163,6 +172,7 @@ class GlanceTabFragment : Fragment() {
R.string.settings_not_visible)) R.string.settings_not_visible))
injector.visibility(R.id.error_icon, View.GONE) injector.visibility(R.id.error_icon, View.GONE)
injector.visibility(R.id.info_icon, View.VISIBLE) injector.visibility(R.id.info_icon, View.VISIBLE)
isVisible = Preferences.showBatteryCharging
} }
Constants.GlanceProviderId.NOTIFICATIONS -> { Constants.GlanceProviderId.NOTIFICATIONS -> {
when { when {
@ -172,16 +182,19 @@ class GlanceTabFragment : Fragment() {
injector.text(R.id.label, injector.text(R.id.label,
if (Preferences.showNotifications) getString( if (Preferences.showNotifications) getString(
R.string.settings_visible) else getString(R.string.settings_not_visible)) R.string.settings_visible) else getString(R.string.settings_not_visible))
isVisible = Preferences.showNotifications
} }
Preferences.showNotifications -> { Preferences.showNotifications -> {
injector.visibility(R.id.error_icon, View.VISIBLE) injector.visibility(R.id.error_icon, View.VISIBLE)
injector.visibility(R.id.info_icon, View.GONE) injector.visibility(R.id.info_icon, View.GONE)
injector.text(R.id.label, getString(R.string.settings_not_visible)) injector.text(R.id.label, getString(R.string.settings_not_visible))
isVisible = false
} }
else -> { else -> {
injector.visibility(R.id.error_icon, View.GONE) injector.visibility(R.id.error_icon, View.GONE)
injector.visibility(R.id.info_icon, View.VISIBLE) injector.visibility(R.id.info_icon, View.VISIBLE)
injector.text(R.id.label, getString(R.string.settings_not_visible)) injector.text(R.id.label, getString(R.string.settings_not_visible))
isVisible = false
} }
} }
} }
@ -191,6 +204,7 @@ class GlanceTabFragment : Fragment() {
R.string.settings_not_visible)) R.string.settings_not_visible))
injector.visibility(R.id.error_icon, View.GONE) injector.visibility(R.id.error_icon, View.GONE)
injector.visibility(R.id.info_icon, View.VISIBLE) injector.visibility(R.id.info_icon, View.VISIBLE)
isVisible = Preferences.showGreetings
} }
Constants.GlanceProviderId.CUSTOM_INFO -> { Constants.GlanceProviderId.CUSTOM_INFO -> {
injector.text(R.id.label, injector.text(R.id.label,
@ -198,6 +212,7 @@ class GlanceTabFragment : Fragment() {
R.string.settings_not_visible)) R.string.settings_not_visible))
injector.visibility(R.id.error_icon, View.GONE) injector.visibility(R.id.error_icon, View.GONE)
injector.visibility(R.id.info_icon, View.VISIBLE) injector.visibility(R.id.info_icon, View.VISIBLE)
isVisible = Preferences.customNotes != ""
} }
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> { Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(context) val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(context)
@ -209,20 +224,35 @@ class GlanceTabFragment : Fragment() {
R.string.settings_not_visible)) R.string.settings_not_visible))
injector.visibility(R.id.error_icon, View.GONE) injector.visibility(R.id.error_icon, View.GONE)
injector.visibility(R.id.info_icon, View.VISIBLE) injector.visibility(R.id.info_icon, View.VISIBLE)
isVisible = Preferences.showDailySteps
} else if (Preferences.showDailySteps) { } else if (Preferences.showDailySteps) {
ActivityDetectionReceiver.unregisterFence(requireContext()) ActivityDetectionReceiver.unregisterFence(requireContext())
injector.visibility(R.id.error_icon, View.VISIBLE) injector.visibility(R.id.error_icon, View.VISIBLE)
injector.visibility(R.id.info_icon, View.GONE) injector.visibility(R.id.info_icon, View.GONE)
injector.text(R.id.label, getString(R.string.settings_not_visible)) injector.text(R.id.label, getString(R.string.settings_not_visible))
isVisible = false
} else { } else {
ActivityDetectionReceiver.unregisterFence(requireContext()) ActivityDetectionReceiver.unregisterFence(requireContext())
injector.text(R.id.label, getString(R.string.settings_not_visible)) injector.text(R.id.label, getString(R.string.settings_not_visible))
injector.visibility(R.id.error_icon, View.GONE) injector.visibility(R.id.error_icon, View.GONE)
injector.visibility(R.id.info_icon, View.VISIBLE) injector.visibility(R.id.info_icon, View.VISIBLE)
isVisible = false
} }
} }
Constants.GlanceProviderId.EVENTS -> {
isVisible = Preferences.showEventsAsGlanceProvider && Preferences.showEvents && requireContext().checkGrantedPermission(Manifest.permission.READ_CALENDAR)
injector.text(R.id.label,
if (isVisible) getString(R.string.settings_visible) else getString(
R.string.settings_not_visible))
injector.visibility(R.id.error_icon, if (isVisible) View.GONE else View.VISIBLE)
injector.visibility(R.id.info_icon, if (isVisible) View.VISIBLE else View.GONE)
} }
} }
injector.alpha(R.id.title, if (isVisible) 1f else .25f)
injector.alpha(R.id.label, if (isVisible) 1f else .25f)
injector.alpha(R.id.icon, if (isVisible) 1f else .25f)
}
.attachTo(providers_list) .attachTo(providers_list)
val mIth = ItemTouchHelper( val mIth = ItemTouchHelper(
@ -231,8 +261,6 @@ class GlanceTabFragment : Fragment() {
0 0
) { ) {
val list = GlanceProviderHelper.getGlanceProviders(requireContext())
override fun onMove( override fun onMove(
recyclerView: RecyclerView, recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder,
@ -244,10 +272,6 @@ class GlanceTabFragment : Fragment() {
return true return true
} }
override fun isItemViewSwipeEnabled(): Boolean {
return false
}
override fun onMoved( override fun onMoved(
recyclerView: RecyclerView, recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder, viewHolder: RecyclerView.ViewHolder,
@ -257,14 +281,28 @@ class GlanceTabFragment : Fragment() {
x: Int, x: Int,
y: Int y: Int
) { ) {
with(list[fromPos]) { with(list[toPos]) {
list[fromPos] = list[toPos] list[toPos] = list[fromPos]
list[toPos] = this list[fromPos] = this
} }
GlanceProviderHelper.saveGlanceProviderOrder(list)
super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y) super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y)
} }
override fun isItemViewSwipeEnabled(): Boolean {
return false
}
override fun clearView(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
) {
super.clearView(recyclerView, viewHolder)
GlanceProviderHelper.saveGlanceProviderOrder(
list
)
adapter.updateData(list.mapNotNull { GlanceProviderHelper.getGlanceProviderById(requireContext(), it) })
}
override fun onChildDraw( override fun onChildDraw(
c: Canvas, c: Canvas,
recyclerView: RecyclerView, recyclerView: RecyclerView,
@ -305,10 +343,7 @@ class GlanceTabFragment : Fragment() {
}) })
mIth.attachToRecyclerView(providers_list) mIth.attachToRecyclerView(providers_list)
adapter.updateData( adapter.updateData(list.mapNotNull { GlanceProviderHelper.getGlanceProviderById(requireContext(), it) })
GlanceProviderHelper.getGlanceProviders(requireContext())
.mapNotNull { GlanceProviderHelper.getGlanceProviderById(requireContext(), it) }
)
providers_list.isNestedScrollingEnabled = false providers_list.isNestedScrollingEnabled = false
setupListener() setupListener()
@ -338,6 +373,11 @@ class GlanceTabFragment : Fragment() {
show_glance_switch.setOnCheckedChangeListener { _, enabled: Boolean -> show_glance_switch.setOnCheckedChangeListener { _, enabled: Boolean ->
Preferences.showGlance = enabled Preferences.showGlance = enabled
} }
action_show_glance.setOnLongClickListener {
Preferences.enabledGlanceProviderOrder = ""
true
}
} }
private val nextAlarmChangeBroadcastReceiver = object : BroadcastReceiver() { private val nextAlarmChangeBroadcastReceiver = object : BroadcastReceiver() {

View File

@ -351,7 +351,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
}?.isVisible = if (Preferences.showWeather) { }?.isVisible = if (Preferences.showWeather) {
(WeatherHelper.isKeyRequired() && WeatherHelper.getApiKey() == "") (WeatherHelper.isKeyRequired() && WeatherHelper.getApiKey() == "")
|| (Preferences.customLocationAdd == "" && activity?.checkGrantedPermission( || (Preferences.customLocationAdd == "" && activity?.checkGrantedPermission(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION Manifest.permission.ACCESS_FINE_LOCATION
) != true) ) != true)
|| (Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-") || (Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-")
|| (Preferences.weatherProviderLocationError != "") || (Preferences.weatherProviderLocationError != "")
@ -365,7 +365,8 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
badgeGravity = BadgeDrawable.TOP_END badgeGravity = BadgeDrawable.TOP_END
}?.isVisible = ((Preferences.showMusic || Preferences.showNotifications) && !ActiveNotificationsHelper.checkNotificationAccess(requireContext())) || }?.isVisible = ((Preferences.showMusic || Preferences.showNotifications) && !ActiveNotificationsHelper.checkNotificationAccess(requireContext())) ||
(Preferences.showDailySteps && !(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || requireActivity().checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION))) || (Preferences.showDailySteps && !(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || requireActivity().checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION))) ||
(AlarmHelper.isAlarmProbablyWrong(requireContext())) (AlarmHelper.isAlarmProbablyWrong(requireContext())) ||
(Preferences.showEventsAsGlanceProvider && (!Preferences.showEvents || !requireContext().checkGrantedPermission(Manifest.permission.READ_CALENDAR)))
} }
override fun onResume() { override fun onResume() {
@ -396,6 +397,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
} }
class UpdateUiMessageEvent class UpdateUiMessageEvent
class ChangeTabEvent(val page: Int)
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(ignore: UpdateUiMessageEvent?) { fun onMessageEvent(ignore: UpdateUiMessageEvent?) {
@ -407,4 +409,11 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
} }
} }
} }
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: ChangeTabEvent?) {
event?.let {
pager.setCurrentItem(event.page, true)
}
}
} }

View File

@ -161,12 +161,7 @@ class WeatherTabFragment : Fragment() {
} }
private fun checkLocationPermission() { private fun checkLocationPermission() {
// Background permission if (requireActivity().checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && activity?.checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION) == true && activity?.checkGrantedPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION) != true) {
requirePermission()
}
if (activity?.checkGrantedPermission(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION) == true) {
location_permission_alert?.isVisible = false location_permission_alert?.isVisible = false
background_location_warning.isVisible = Preferences.customLocationAdd == "" background_location_warning.isVisible = Preferences.customLocationAdd == ""
WeatherReceiver.setUpdates(requireContext()) WeatherReceiver.setUpdates(requireContext())
@ -299,7 +294,7 @@ class WeatherTabFragment : Fragment() {
private fun requirePermission() { private fun requirePermission() {
Dexter.withContext(requireContext()) Dexter.withContext(requireContext())
.withPermissions( .withPermissions(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION Manifest.permission.ACCESS_FINE_LOCATION
).withListener(object: MultiplePermissionsListener { ).withListener(object: MultiplePermissionsListener {
override fun onPermissionsChecked(report: MultiplePermissionsReport?) { override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
report?.let { report?.let {

View File

@ -172,7 +172,7 @@ class MainWidget : AppWidgetProvider() {
val nextEvent = eventRepository.getNextEvent() val nextEvent = eventRepository.getNextEvent()
val nextAlarm = AlarmHelper.getNextAlarm(context) val nextAlarm = AlarmHelper.getNextAlarm(context)
if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null) { if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null && !Preferences.showEventsAsGlanceProvider) {
if (Preferences.showNextEvent && eventRepository.getEventsCount() > 1) { if (Preferences.showNextEvent && eventRepository.getEventsCount() > 1) {
views.setImageViewBitmap( views.setImageViewBitmap(
R.id.action_next_rect, R.id.action_next_rect,
@ -378,6 +378,26 @@ class MainWidget : AppWidgetProvider() {
break@loop 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.second_row_rect,
pIntentDetail
)
showSomething = true
break@loop
}
}
} }
} }
@ -552,7 +572,7 @@ class MainWidget : AppWidgetProvider() {
val nextEvent = eventRepository.getNextEvent() val nextEvent = eventRepository.getNextEvent()
val nextAlarm = AlarmHelper.getNextAlarm(context) val nextAlarm = AlarmHelper.getNextAlarm(context)
if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null) { if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null && !Preferences.showEventsAsGlanceProvider) {
// Multiple counter // Multiple counter
v.action_next.isVisible = v.action_next.isVisible =
Preferences.showNextEvent && eventRepository.getEventsCount() > 1 Preferences.showNextEvent && eventRepository.getEventsCount() > 1
@ -585,7 +605,7 @@ class MainWidget : AppWidgetProvider() {
v.second_row_icon.setImageDrawable( v.second_row_icon.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.round_place R.drawable.round_place_24
) )
) )
v.next_event_date.text = nextEvent.address v.next_event_date.text = nextEvent.address
@ -593,7 +613,7 @@ class MainWidget : AppWidgetProvider() {
v.second_row_icon.setImageDrawable( v.second_row_icon.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.round_today R.drawable.round_today_24
) )
) )
if (!nextEvent.allDay) { if (!nextEvent.allDay) {
@ -674,7 +694,7 @@ class MainWidget : AppWidgetProvider() {
v.second_row_icon.setImageDrawable( v.second_row_icon.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.round_music_note R.drawable.round_music_note_24
) )
) )
v.next_event_date.text = MediaPlayerHelper.getMediaInfo() v.next_event_date.text = MediaPlayerHelper.getMediaInfo()
@ -687,7 +707,7 @@ class MainWidget : AppWidgetProvider() {
v.second_row_icon.setImageDrawable( v.second_row_icon.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.round_alarm R.drawable.round_alarm_24
) )
) )
v.next_event_date.text = AlarmHelper.getNextAlarm(context) v.next_event_date.text = AlarmHelper.getNextAlarm(context)
@ -765,6 +785,35 @@ class MainWidget : AppWidgetProvider() {
break@loop break@loop
} }
} }
Constants.GlanceProviderId.EVENTS -> {
if (Preferences.showEventsAsGlanceProvider && Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null) {
v.next_event_date.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()
v.second_row_icon.isVisible = true
v.second_row_icon.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.round_today_24
)
)
showSomething = true
break@loop
}
}
} }
} }

View File

@ -21,6 +21,7 @@ import android.content.Intent
import android.content.res.Resources 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.Log
import android.util.TypedValue import android.util.TypedValue
import android.view.ViewPropertyAnimator import android.view.ViewPropertyAnimator
import android.view.animation.Animation import android.view.animation.Animation

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 751 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 953 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 868 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 459 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 465 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1013 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 459 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 868 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 465 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 867 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 536 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1005 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 642 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 628 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 802 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 B

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