From 0774c6bdbe4c97483586b7b8ff236a3a882e8f8e Mon Sep 17 00:00:00 2001 From: Lambada10 <62511588+Lambada10@users.noreply.github.com> Date: Mon, 18 Jan 2021 12:12:58 +0100 Subject: [PATCH 1/6] Translations --- app/src/main/res/values-pl/strings.xml | 360 +++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 app/src/main/res/values-pl/strings.xml diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml new file mode 100644 index 0000000..ba68982 --- /dev/null +++ b/app/src/main/res/values-pl/strings.xml @@ -0,0 +1,360 @@ + + + Another Widget + Dodaj Widget + + + Wyświetlaj + | + Kolor tekstu + Kolor tekstu + Kolor tła + Rozmiar tekstu + Rozmiar tekstu + Cirń tekstu + Brak + Mały + Duży + Czcionka widgetu + Czcionka urządzenia + Google Sans + Niestandardowy format daty + Alpha + Przezroczyste + Rozdzielenie tekstu + Główny tekst + Dodatkowy tekst + Widget + Zapisz datę wielkimi literami + Format daty + Tło widgetu + Oddzidlenie rzędów + Niestandardowa czcionka… + Rodzina czcionek + + Thin + Light + Book + Regular + Medium + Semi-bold + Bold + Black + Heavy. + Italic + Thin Italic + Light Italic + Book Italic + Regular Italic + Medium Italic + Semi-bold Italic + Bold Italic + Black Italic + Heavy Italic + + + Kalendarz + Pokaż moje wydarzenia + Przyznaj uprawnienie dostępu do kalendarza\naby zobaczyć wydarzenia na widgeci. + Filtruj wydarzenia + Zmień widoczność kalendarza + Całodobowe wydarzenia + Konto kalendarza + Błąd podczas ładowanka listy kalendarza. + Całodobowe wydarzenie + Wydarzenia są widoczne + Wydarzenia są ukryte + 30 minut później + 1 godzinę później + 3 godziny później + 6 godzin później + 12 godzin później + 24 godziny później + 3 dni później + 7 dni później + Pokazuj wydarzenia co najmniej + d + Kalendarz + Nie znaleziono kalendarza. + jutro + dziś + Naciśnięcie na wydarzenie otwiera + Informacje o wydarzeniu + Adres wydarzenia + Czas wydarzenia + Pozostały czas do wydarzenia + Odrzucone wydarzenia + Szczegóły wydarzenia + Domyślna aplikacja kalendarza + Przełącznik kilku wydarzeń + wkrótce + teraz + Częstotliwość asktualizacji wydarzenia + Wysoka częstotliwość zużywa wiecej baterii. + Niska + Domyślna + Wysoka + Filtry + Informacje o wydarzeniu + Status uczestnika + Filtruj zaakceptowane lub odrzucone wydarzenia + Powiązane wydarzenia + Pokaż tylko wydarzenia, które są ustawione jako zajęty + Zaakceptowane wydarzenia + Zaproszenia + Odrzucone wydarzenia + + calendar-sync + Usługa synchronizacji wydarzeń + Usługa używana do synchronizacji wydarzeń w kalendarzu. + Synchronizowanie wydarzeń w kalendarzu… + + + Pogoda + Pokaż pogodę + Przyznaj dostęp do swojej lokalizacji\naby wyświetlać pogodę w swoim widgecie. + Jednostka temperatury + °F - Fahrenheit + °C - Celsius + częstotliwość odświeżania + 30 minut + 1 godzina + 3 godziny + 6 godzin + 12 godzin + 24 godziny + lokalizacja + Geolokalizacja + Informavje o pogodzie są widoczne + Informacje o pogodzie są ukryte + Pogoda + Klucz API dostawcy pogody + Dostawca pogody jest poprawnie skonfigurowany. + Należy skonfigurować dostawcę pogody. + Klucz API OpenWeatherMap + Google Weather + Google Awareness API został wycofany. Aby wyświetlać pogodę w widgecie, wymagane jest teraz posiadanie klucza API od zewnętrznego dostawcy. + Paczka ikon + Paczka ikon %d + Po wybraniu geolokalizacji zbieramy dane o lokalizacji, aby aktualizować informacje o pogodzie, nawet gdy aplikacja jest zamknięta lub nieużywana. \ NNie wykorzystamy tych danych w inny sposób. + Dostawca pogody + + OpenWeatherMap.org + Weatherbit.io + WeatherAPI.com + HERE.com + AccuWeather.com + Weather.gov (USA)\nby National Weather Services + YR.no/Met.no\nby Meteorologisk Institutt + + Ten dostawca pogody potrzebuje \nklucza API do poprawnego działania. + Ten dostawca pogody potrzebuje \nklucza API do poprawnego działania. + Ten dostawca pogody potrzebuje \nklucza API do poprawnego działania. + Ten dostawca pogody potrzebuje \nklucza API do poprawnego działania. + Ten dostawca pogody potrzebuje \nklucza API do poprawnego działania. + Ten dostawcs pogody działa tylko\ndla USA. + Ten dostawca pogody zezwala tylko\nna stopnie Celsjusza. + + Otwórz stronę dostawcy, stwórz konto i skopiuj domyślny klucz API tutaj. + Otwórz stronę dostawcy, stwórz konto i skopiuj domyślny klucz API tutaj. + Otwórz stronę dostawcy, stwórz konto i skopiuj domyślny klucz API tutaj. + Otwórz stronę dostawcy, stwórz konto i skopiuj domyślny klucz API tutaj. + Otwórz stronę dostawcy, stwórz konto i skopiuj domyślny klucz API tutaj. + \n + \n + + The weather provider that you\'ve selected requires an API key. + The current location is not supported. + Please select a valid location. + It seems that your API key has expired. + API key not valid, or not yet activated. + The weather provider is wrongly configured. + Connection error. + Something went wrong, check the weather provider config. + Account required + USA Only + Metric Unit Only + Select a provider + Select a weather provider from the list.\nA few providers need a free personal account,\nbut they are usually more accurate. + + location-access + Weather update service + Service used to update the weather based on the current location of the user. + Updating the weather… + We\'re updating the weather based on your current location. + + + Clock + Clock + Show Clock + Clock is visible + Clock is hidden + Text size + Default clock app + Clock bottom margin + None + Small + Medium + Large + Due to technological limitations, the clock won\'t have the custom font and the text shadows selected in the Display section. + Text color + Show AM/PM indicator + Clock text style + + + Next clock alarm + At a glance + Current playing song + We need the notification access permission to check the current playing song. + We need the notification access permission to check your last notifications. + We need a few permissions to get your daily steps from Google Fit. + Show at a glance info + Service enabled + Service disabled + Data source priority + Change the data provider priority by sorting the list below with the drag-and-drop icons. + Custom notes + Fitness + %d steps so far + Battery + Low battery level + Charging + Fully charged + Providers + Glance info will show up only when there are no events displayed and only when a few conditions are verified. + Music Players + Choose your relevant music players + We use the music players\' notification to show the current playing song. + Get advised when the device has the battery low or is charging. + View your daily steps for a brief moment after finishing a walk or a run. + View your next clock alarm.\nCheck if your default clock app is the only one setting alarms. + Alarm set by %s + The next alarm clock seems to be wrong + The next alarm clock seems to be correct + Latest notifications + Check out the latest notifications that showed up on your device. + Greetings + View some cool phrase to lighten your day when you don\'t expect it. + Account linked + Account not linked + Google Fit + Connect + Disconnect + Applications + Choose which notifications to view + + Good morning! + Have a good day! + Ready to go? + Rise and shine. + Don\'t forget your breakfast! + + + Good evening! + How did your day go? + Did you have a nice day? + After effort comes comfort. + Don\'t forget to have dinner! + + + Good night! + Sleep well! + Sweet dreams till sunbeams find you! + See you tomorrow... + Don\'t stay up too late! + + Hide the notification after + + 30 seconds + 1 minute + 5 minutes + 10 minutes + 15 minutes + Dismissal + + Events + View a sneak peek of your calendar events and always show the current date. + Please enable the show of the events in the calendar tab and grant the required permission. + %1$s %2$s + + + Share + Rate app + Support me + Feedback + About + Refresh widget + toolbar + Error opening URL: Link copied to clipboard. + Loading Data... + Error opening app. + Default app + Save + Visible + Hidden + Help with translations + Open a pull request on GitHub + Check my other projects + Same developer, many possibilities + Ooops, something went wrong! + Theme + Devs always need a lot of coffee + Light + Dark + Set by battery saver + Follow the system theme + Default + Search + App version + Show wallpaper + Force the restart of the widget service + Feel free to help our project! + Feedback and feature requests + xiaomi + Xiaomi Devices + Enable the permission to display pop-up windows when running in the background inside the "Other permission" section of the app settings. Otherwise, you will not able to open any applications tapping on the widget. + Ignore + Grant permission + Settings + Style + Actions + Provider + Appearance + Preferences + + View the privacy policy of the app + Open-source project + Information + + + Choose application + Support the developer + Thanks for supporting me! + An italian coffee + Some glazed donuts + An expensive dinner + An english breakfast + A quick lunch + Show widget preview + This is a single developer project,\nso thank you for the support! + Integrations + %d installed integrations + Nothing + Dismiss + Accept + None + Song info format + Change the visible song info + + + + Typography + Set text font, size and color + Layout + Actions, behaviour and shortcuts + Gestures + + Set size, color and time zones + Widget spacing and tweaks + Smart content + From 8234a87a2a53f488966fee1c534c464f37baaa69 Mon Sep 17 00:00:00 2001 From: Lambada10 <62511588+Lambada10@users.noreply.github.com> Date: Mon, 18 Jan 2021 14:17:27 +0100 Subject: [PATCH 2/6] Translations --- app/src/main/res/values-pl/strings.xml | 336 ++++++++++++------------- 1 file changed, 168 insertions(+), 168 deletions(-) diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index ba68982..a996d84 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -125,7 +125,7 @@ 24 godziny lokalizacja Geolokalizacja - Informavje o pogodzie są widoczne + Informacje o pogodzie są widoczne Informacje o pogodzie są ukryte Pogoda Klucz API dostawcy pogody @@ -163,198 +163,198 @@ \n \n - The weather provider that you\'ve selected requires an API key. - The current location is not supported. - Please select a valid location. - It seems that your API key has expired. - API key not valid, or not yet activated. - The weather provider is wrongly configured. - Connection error. - Something went wrong, check the weather provider config. - Account required - USA Only - Metric Unit Only - Select a provider - Select a weather provider from the list.\nA few providers need a free personal account,\nbut they are usually more accurate. + Dostawca pogody, którego wybrałeś wymaga klucza API. + Aktualna lokalizacja nie jest wspierana. + Wybierz prawidłową lokalizację. + Wygląda na to że klucz API wygasł. + Nieprawidłowy lub nieaktywowany klucz API. + Dostawca pogody jest źle skonfigurowany. + Błąd połączenia. + Coś poszło nie tak, sprawdź konfigurację dostawcy pogody. + Wymagane konto + Tylko USA + Tylko jednostki metryczne + Wybierz dostawcę + Wybierz dostawcę pogody z listy.\nNiektóre mogą wymagać darmowego konta,\nale zazwyczaj są dokładniejsze. location-access - Weather update service - Service used to update the weather based on the current location of the user. - Updating the weather… - We\'re updating the weather based on your current location. + Usługa aktualizacji pogody + Usługa używana do aktualizacji pogody opartej na lokalizacji użytkownika. + Aktualizowanie pogody… + Aktualizujemy pogodę opierając się na twojeje lokalizacji. - Clock - Clock - Show Clock - Clock is visible - Clock is hidden - Text size - Default clock app - Clock bottom margin - None - Small - Medium - Large - Due to technological limitations, the clock won\'t have the custom font and the text shadows selected in the Display section. - Text color - Show AM/PM indicator - Clock text style + Zegar + Zegar + Pokaż zegar + Zegar jest widoczny + Zegar jest ukryty + Rozmiar tekstu + Domyślna aplikacja zegara + Dolny margines zegara + Brak + Mały + Średni + Duży + Z powodu ograniczeń technologicznych, zegar nie będzie miał niestandardowej czcionki i cienii tekstów wybranych w sekcji Wyświetlaj. + Kolor tekstu + Pokaż wskaźnik AM/PM + Styl tekstu zegara - Next clock alarm - At a glance - Current playing song - We need the notification access permission to check the current playing song. - We need the notification access permission to check your last notifications. - We need a few permissions to get your daily steps from Google Fit. - Show at a glance info - Service enabled - Service disabled - Data source priority - Change the data provider priority by sorting the list below with the drag-and-drop icons. - Custom notes + Następny alarm + W skrócie + Aktualnie odtwarzany utwór + Potrzebujemy uprawnienia dostępu do powiadomień, aby wyświetlić aktuanie odtwarzany utwór. + Potrzebujemy uprawnienia dostępu do powiadomień, aby wyświetlić powiadomienia. + Potrzebujemy parę uprawnień aby wyświetlić kroki z Google Fit. + Pokaż informacje w skrócie + Usłuja włączona + Usługa wyłączona + Priorytet wyświetlania + Zmień priorytet źródeł danych sortując tą listę (przeciągnij i upuść). + Niestandardowe notatki Fitness - %d steps so far - Battery - Low battery level - Charging - Fully charged - Providers - Glance info will show up only when there are no events displayed and only when a few conditions are verified. - Music Players - Choose your relevant music players - We use the music players\' notification to show the current playing song. - Get advised when the device has the battery low or is charging. - View your daily steps for a brief moment after finishing a walk or a run. - View your next clock alarm.\nCheck if your default clock app is the only one setting alarms. - Alarm set by %s - The next alarm clock seems to be wrong - The next alarm clock seems to be correct - Latest notifications - Check out the latest notifications that showed up on your device. - Greetings - View some cool phrase to lighten your day when you don\'t expect it. - Account linked - Account not linked + %d kroków + Bateria + Niski poziom baterii + Ładowanie + Naładowano + Dostawcy + Informacje pokażą się tylko, jeśli nie wyświetlają się wydarzenia oraz spełnione jest kilka warunków. + Odtwarzacze muzyki + Wybierz swoje odtwarzacze muzyki + Używamy powiadomień odtwarzaczy, aby wyświetlić aktualnie odtwarzany utwór. + Zostań ponformowany, gdy urządzenie ma mało baterii lub się ładuje. + Wyświetl swoje dzienne kroki na krótką chwilę po ukończeniu spaceru lub biegu. + Zobacz swój następny alarm.\nSprawdź czy twoja domyślna aplikacja zegara jest jedyną, wktórej ustawiono alarmt. + Ustawiono alarm przez %s + Następny alarm wygląda na nieprawidłowy + Następny alarm wygląda na prawidłowy + Ostatnie powiadomienie + Zobacz swoje ostatnie powiadomienia. + Pozdrowienia + Wyświetlaj ciekawe zdania, które umilą ci dziań gdy się tego nie spodziewasz. + Połączono konto + Nie połączono konta Google Fit - Connect - Disconnect - Applications - Choose which notifications to view + Połącz + Rozłącz + Aplikacje + Wybierz które powiadomienia wyświetlać - Good morning! - Have a good day! - Ready to go? - Rise and shine. - Don\'t forget your breakfast! + Dzień dobry! + Miłego dnia! + Gotowy? + Wznoś się i świeć. + Nie zapomnij o śniadaniu! - Good evening! - How did your day go? - Did you have a nice day? - After effort comes comfort. - Don\'t forget to have dinner! + Dobry wieczór! + Jak ci minął dzień? + Czy miałeś miły dzień? + Po wysiłku przychodzi komfort. + Nie zapomnij o kolacji! - Good night! - Sleep well! - Sweet dreams till sunbeams find you! - See you tomorrow... - Don\'t stay up too late! + Dobrej nocy! + Śpij dobrze! + Słodkich snów, dopóki nie znajdą cię promienie słońca! + Widzimy się jutro... + Nie siedź za długo! - Hide the notification after + Ukryj powiadomienie po - 30 seconds - 1 minute - 5 minutes - 10 minutes - 15 minutes - Dismissal + 30 sekund + 1 minuta + 5 minuty + 10 minuty + 15 minuty + Odrzuceniu - Events - View a sneak peek of your calendar events and always show the current date. - Please enable the show of the events in the calendar tab and grant the required permission. + Wydarzenia + Wyświetl podgląd twoich wydarzeń i pokazuj aktualną datę. + Włącz, aby wyświetlić wydarzenia w kalendarzu i przyznać wymagane uprawnienia. %1$s %2$s - Share - Rate app - Support me + Udostępnij + Oceń aplikację + Wspomóż mnie Feedback - About - Refresh widget + O aplikacji + Odśwież widget toolbar - Error opening URL: Link copied to clipboard. - Loading Data... - Error opening app. - Default app - Save - Visible - Hidden - Help with translations - Open a pull request on GitHub - Check my other projects - Same developer, many possibilities - Ooops, something went wrong! - Theme - Devs always need a lot of coffee - Light - Dark - Set by battery saver - Follow the system theme - Default - Search - App version - Show wallpaper - Force the restart of the widget service - Feel free to help our project! - Feedback and feature requests + Błąd otwierania adresu URL: Link skopiowany do schowka. + Ładowanie danych... + Błąd otwierania aplikacji. + Domyślna aplikacja + Zapisz + Widoczne + Ukryte + Pomóż przetłumaczyć aplikację + Otwórz pull request na GitHub + Sprawdź moje inne projekty + Ten sam developer, dużo możliwości + Ooops, coś poszło nie tak! + Motyw + Deweloperzy zawsze potrzebują dużo kawy + Jasny + Ciemny + Zgodnie z oszczędzaniem bateriiSet by battery saver + Podążaj za systemem + Domyślny + Szukaj + Wersja aplikacji + Pokaż tapetę + Wymuś zresetowanie usługi widgetu + Zapraszam do pomocy w naszym projekcie! + Opinia i pomysły na funkcje xiaomi - Xiaomi Devices - Enable the permission to display pop-up windows when running in the background inside the "Other permission" section of the app settings. Otherwise, you will not able to open any applications tapping on the widget. - Ignore - Grant permission - Settings - Style - Actions - Provider - Appearance - Preferences + Urządzenia Xiaomi + Włącz uprawnienie aby wyświetlać pop-upu w tle ("Inne Ustawienia" w ustawieniach aplikacji). Inaczej nie będziesz mógł otworzyć aplikacji klikając w widget. + Ignoruj + Przyznaj uprawnienie + Ustawienia + Styl + Akcje + Dostawca + Wygląd + Preferencje - View the privacy policy of the app - Open-source project - Information + Zobacz politykę prywatności aplikacji + Projekt open-source + Informacje - Choose application - Support the developer - Thanks for supporting me! - An italian coffee - Some glazed donuts - An expensive dinner - An english breakfast - A quick lunch - Show widget preview - This is a single developer project,\nso thank you for the support! - Integrations - %d installed integrations - Nothing - Dismiss - Accept - None - Song info format - Change the visible song info + Wybierz aplikację + Wspomóż dewelopera + Dziękuję za wsparcie! + Włoska kawa + Kilka glazurowanych pączków + Droga kolacja + Angielskie śniadanie + Szybki lunch + Pokaż podgląd widgetu + To jest projekt jednego dewelopera,\nwięc dziękuję za wsparcie! + Integracje + %d zainstalowanych integracji + Nic + Odrzuć + Akceptuj + Nic + Format informacji o utworze + Zmień widoczne informacje o utworze - - Typography - Set text font, size and color - Layout - Actions, behaviour and shortcuts - Gestures - - Set size, color and time zones - Widget spacing and tweaks - Smart content + + Typografia + Zmień czcionkę, wielkość i kolor + Układ + Akcje, zachowanie i skróty + Gesty + + Ustaw wielkość, kolor i strefę czasową + Odstępy w widgecie i poprawki + Inteligentna zawartość From 40644f365766edc509cfaa8f3dc8f263ac050d43 Mon Sep 17 00:00:00 2001 From: Tommaso Berlose Date: Mon, 3 May 2021 23:01:54 +0200 Subject: [PATCH 3/6] update widget --- .idea/caches/build_file_checksums.ser | Bin 537 -> 537 bytes app/build.gradle | 32 +- .../components/GlanceSettingsDialog.kt | 4 +- .../components/IconPackSelector.kt | 15 +- .../anotherwidget/global/Constants.kt | 24 +- .../anotherwidget/global/Preferences.kt | 16 +- .../helpers/SettingsStringHelper.kt | 6 +- .../anotherwidget/helpers/WeatherHelper.kt | 152 ++- .../receivers/UpdatesReceiver.kt | 7 +- .../tabs/WeatherProviderActivity.kt | 18 +- .../ui/fragments/MainFragment.kt | 30 +- .../ui/fragments/tabs/CalendarFragment.kt | 22 +- .../ui/fragments/tabs/LayoutFragment.kt | 71 +- .../ui/viewmodels/MainViewModel.kt | 1 + .../anotherwidget/ui/widgets/ClockWidget.kt | 75 ++ .../ui/widgets/LeftAlignedWidget.kt | 886 ++++++++++++++++ .../anotherwidget/ui/widgets/MainWidget.kt | 997 +----------------- .../ui/widgets/StandardWidget.kt | 925 ++++++++++++++++ .../main/res/layout/fragment_tab_layout.xml | 37 + .../main/res/layout/left_aligned_widget.xml | 212 ++++ .../res/layout/left_aligned_widget_sans.xml | 181 ++++ .../main/res/layout/right_aligned_widget.xml | 280 +++++ .../res/layout/right_aligned_widget_sans.xml | 173 +++ app/src/main/res/layout/the_widget.xml | 178 ++-- app/src/main/res/layout/the_widget_sans.xml | 72 +- app/src/main/res/values-it/strings.xml | 4 + app/src/main/res/values/strings.xml | 4 + build.gradle | 10 +- 28 files changed, 3101 insertions(+), 1331 deletions(-) create mode 100644 app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/ClockWidget.kt create mode 100644 app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt create mode 100644 app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt create mode 100644 app/src/main/res/layout/left_aligned_widget.xml create mode 100644 app/src/main/res/layout/left_aligned_widget_sans.xml create mode 100644 app/src/main/res/layout/right_aligned_widget.xml create mode 100644 app/src/main/res/layout/right_aligned_widget_sans.xml diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 9aff3fba66d182029c4e0dc0540d9e2e9cd28fc8..64d3a40ba2006e5a13b25073a36fd41c7968e269 100644 GIT binary patch delta 54 zcmV-60LlNE1epYomj!tVE|Uk5oSzVn|GrGzyn!z;x;S>M(VIz=O98zRy-5N{W~mQ9 MyP?y9JSkm)cyy!}EC2ui delta 54 zcmV-60LlNE1epYomj!n;DSSAQoSzVZDOmw+*K!*Zwe&=g2O&R`O98zR?Xb6Ce*W6t MCX5*XrP0T|ctF(`X#fBK diff --git a/app/build.gradle b/app/build.gradle index ad1ed4b..89b5c2b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -65,14 +65,14 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 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.espresso:espresso-core:3.3.0' // UI implementation 'androidx.appcompat:appcompat:1.2.0' 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 'net.idik:slimadapter:2.1.2' implementation 'com.google.android:flexbox:2.0.1' @@ -80,17 +80,17 @@ dependencies { // Lifecycle 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.work:work-runtime-ktx:2.4.0" + implementation "androidx.work:work-runtime-ktx:2.5.0" // EventBus implementation 'org.greenrobot:eventbus:3.2.0' // Navigation - implementation 'androidx.navigation:navigation-fragment-ktx:2.3.2' - implementation 'androidx.navigation:navigation-ui-ktx:2.3.2' + implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5' + implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' // Other implementation 'androidx.multidex:multidex:2.0.1' @@ -99,24 +99,24 @@ dependencies { implementation 'com.github.warkiz.widget:indicatorseekbar:2.1.2' //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' // Fitness 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 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 - implementation 'com.android.billingclient:billing:3.0.2' - implementation 'com.android.billingclient:billing-ktx:3.0.2' + implementation 'com.android.billingclient:billing:3.0.3' + implementation 'com.android.billingclient:billing-ktx:3.0.3' // KTX 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.core:core-ktx:1.3.2' @@ -128,14 +128,14 @@ dependencies { implementation "com.github.haroldadmin:NetworkResponseAdapter:4.0.1" //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. - implementation 'com.google.firebase:firebase-crashlytics:17.3.0' + implementation 'com.google.firebase:firebase-crashlytics:17.4.1' // Preferences - implementation 'com.chibatching.kotpref:kotpref:2.11.0' - implementation 'com.chibatching.kotpref:livedata-support:2.10.0' + implementation 'com.chibatching.kotpref:kotpref:2.13.1' + implementation 'com.chibatching.kotpref:livedata-support:2.13.1' implementation 'androidx.preference:preference-ktx:1.1.1' // Permissions diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceSettingsDialog.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceSettingsDialog.kt index bde5deb..dc94327 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceSettingsDialog.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceSettingsDialog.kt @@ -8,9 +8,7 @@ import android.content.Intent import android.content.pm.PackageManager import android.os.Build import android.view.LayoutInflater -import android.view.View 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.GoogleSignInAccount 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 { val dialog = BottomSheetMenu(context, header = context.getString(R.string.glance_notification_hide_timeout_title)).setSelectedValue(Preferences.hideNotificationAfter) Constants.GlanceNotificationTimer.values().forEachIndexed { index, timeout -> - dialog.addItem(stringArray[index], timeout.value) + dialog.addItem(stringArray[index], timeout.rawValue) } dialog.addOnSelectItemListener { value -> Preferences.hideNotificationAfter = value diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/components/IconPackSelector.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/components/IconPackSelector.kt index adbf455..476cc0c 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/components/IconPackSelector.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/components/IconPackSelector.kt @@ -2,7 +2,6 @@ package com.tommasoberlose.anotherwidget.components import android.content.Context import android.view.LayoutInflater -import android.view.View import android.widget.ImageView import androidx.core.content.ContextCompat import androidx.core.view.isVisible @@ -28,13 +27,13 @@ class IconPackSelector(context: Context, private val header: String? = null) : B // Menu for (item in Constants.WeatherIconPack.values()) { val itemBinding = IconPackMenuItemBinding.inflate(LayoutInflater.from(context)) - itemBinding.label.text = context.getString(R.string.settings_weather_icon_pack_default).format(item.value + 1) - itemBinding.root.isSelected = item.value == Preferences.weatherIconPack + itemBinding.label.text = context.getString(R.string.settings_weather_icon_pack_default).format(item.rawValue + 1) + itemBinding.root.isSelected = item.rawValue == Preferences.weatherIconPack - itemBinding.icon1.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "01d", item.value))) - itemBinding.icon2.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "01n", item.value))) - itemBinding.icon3.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "10d", item.value))) - itemBinding.icon4.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "09n", 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.rawValue))) + itemBinding.icon3.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "10d", item.rawValue))) + itemBinding.icon4.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "09n", item.rawValue))) listOf(itemBinding.icon1, itemBinding.icon2, itemBinding.icon3, itemBinding.icon4).forEach { if (item == Constants.WeatherIconPack.MINIMAL) { @@ -45,7 +44,7 @@ class IconPackSelector(context: Context, private val header: String? = null) : B } itemBinding.root.setOnClickListener { - Preferences.weatherIconPack = item.value + Preferences.weatherIconPack = item.rawValue this.dismiss() } binding.menu.addView(itemBinding.root) diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/global/Constants.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/global/Constants.kt index 8bc81ab..a4eab88 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/global/Constants.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/global/Constants.kt @@ -1,7 +1,5 @@ package com.tommasoberlose.anotherwidget.global -import java.text.SimpleDateFormat - object Constants { const val RESULT_CODE_CUSTOM_LOCATION = 45 const val RESULT_APP_NAME = "RESULT_APP_NAME" @@ -11,14 +9,14 @@ object Constants { const val CUSTOM_FONT_DOWNLOADED = 2 const val CUSTOM_FONT_DOWNLOAD_NEW = 3 - enum class ClockBottomMargin(val value: Int) { + enum class ClockBottomMargin(val rawValue: Int) { NONE(0), SMALL(1), MEDIUM(2), LARGE(3) } - enum class SecondRowTopMargin(val value: Int) { + enum class SecondRowTopMargin(val rawValue: Int) { NONE(0), SMALL(1), MEDIUM(2), @@ -41,13 +39,13 @@ object Constants { } } - enum class WidgetUpdateFrequency(val value: Int) { + enum class WidgetUpdateFrequency(val rawValue: Int) { LOW(0), DEFAULT(1), HIGH(2) } - enum class WeatherProvider(val value: Int) { + enum class WeatherProvider(val rawValue: Int) { OPEN_WEATHER(0), WEATHER_BIT(1), WEATHER_API(2), @@ -57,12 +55,12 @@ object Constants { YR(6); companion object { - private val map = WeatherProvider.values().associateBy(WeatherProvider::value) + private val map = WeatherProvider.values().associateBy(WeatherProvider::rawValue) fun fromInt(type: Int) = map[type] } } - enum class GlanceNotificationTimer(val value: Int) { + enum class GlanceNotificationTimer(val rawValue: Int) { HALF_MINUTE(0), ONE_MINUTE(1), FIVE_MINUTES(2), @@ -71,15 +69,21 @@ object Constants { WHEN_DISMISSED(5); companion object { - private val map = values().associateBy(GlanceNotificationTimer::value) + private val map = values().associateBy(GlanceNotificationTimer::rawValue) fun fromInt(type: Int) = map[type] } } - enum class WeatherIconPack(val value: Int) { + enum class WeatherIconPack(val rawValue: Int) { DEFAULT(0), MINIMAL(1), COOL(2), GOOGLE_NEWS(3) } + + enum class WidgetAlign(val rawValue: Int) { + LEFT(0), + RIGHT(1), + CENTER(2) + } } \ No newline at end of file diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/global/Preferences.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/global/Preferences.kt index 289b9d4..ac21240 100755 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/global/Preferences.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/global/Preferences.kt @@ -1,13 +1,11 @@ package com.tommasoberlose.anotherwidget.global -import android.os.Build import androidx.appcompat.app.AppCompatDelegate.* import androidx.core.os.ConfigurationCompat import com.chibatching.kotpref.KotprefModel import com.tommasoberlose.anotherwidget.helpers.IntentHelper import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper import com.tommasoberlose.anotherwidget.utils.isMetric -import java.util.* object Preferences : KotprefModel() { override val commitAllPropertiesByDefault: Boolean = true @@ -48,14 +46,14 @@ object Preferences : KotprefModel() { var weatherProviderApiWeatherApi by stringPref(default = "") var weatherProviderApiWeatherBit 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 weatherProviderLocationError by stringPref(default = "") var eventAppName by stringPref(key = "PREF_EVENT_APP_NAME", default = "") var eventAppPackage by stringPref(key = "PREF_EVENT_APP_PACKAGE", default = "") 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 textGlobalAlpha by stringPref(default = "FF") @@ -84,14 +82,14 @@ object Preferences : KotprefModel() { var showAMPMIndicator by booleanPref(default = true) - var weatherIconPack by intPref(default = Constants.WeatherIconPack.DEFAULT.value) + var weatherIconPack by intPref(default = Constants.WeatherIconPack.DEFAULT.rawValue) // Global var textMainSize by floatPref(key = "PREF_TEXT_MAIN_SIZE", default = 26f) var textSecondSize by floatPref(key = "PREF_TEXT_SECOND_SIZE", default = 18f) var clockTextSize by floatPref(key = "PREF_TEXT_CLOCK_SIZE", default = 90f) - var clockBottomMargin by intPref(default = Constants.ClockBottomMargin.MEDIUM.value) - var secondRowTopMargin by intPref(default = Constants.SecondRowTopMargin.NONE.value) + var clockBottomMargin by intPref(default = Constants.ClockBottomMargin.MEDIUM.rawValue) + var secondRowTopMargin by intPref(default = Constants.SecondRowTopMargin.NONE.rawValue) var showClock by booleanPref(key = "PREF_SHOW_CLOCK", default = false) var clockAppName by stringPref(key = "PREF_CLOCK_APP_NAME", default = "") var clockAppPackage by stringPref(key = "PREF_CLOCK_APP_PACKAGE", default = "") @@ -111,6 +109,8 @@ object Preferences : KotprefModel() { var showDividers by booleanPref(default = true) + var widgetAlign by intPref(default = Constants.WidgetAlign.CENTER.rawValue) + // Settings var showWallpaper by booleanPref(default = true) var showPreview by booleanPref(default = true) @@ -127,7 +127,7 @@ object Preferences : KotprefModel() { var showDailySteps by booleanPref(default = false) var showGreetings 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 lastNotificationTitle by stringPref(default = "") diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/SettingsStringHelper.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/SettingsStringHelper.kt index f80505c..5e38c04 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/SettingsStringHelper.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/SettingsStringHelper.kt @@ -96,13 +96,13 @@ object SettingsStringHelper { difference <= 0 -> { 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() } - 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() } - 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) } TimeUnit.MILLISECONDS.toHours(difference) < 1 -> { diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/WeatherHelper.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/WeatherHelper.kt index 59241ba..26b3ce7 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/WeatherHelper.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/WeatherHelper.kt @@ -2,23 +2,15 @@ package com.tommasoberlose.anotherwidget.helpers import android.Manifest import android.content.Context -import android.os.Build -import android.util.Log import com.chibatching.kotpref.Kotpref -import com.google.android.gms.location.LocationServices import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.global.Constants import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi import com.tommasoberlose.anotherwidget.services.LocationService -import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission 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) { "01d" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.clear_day_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.clear_day_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.clear_day_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.clear_day_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.clear_day_2 + 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 } } "02d" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.partly_cloudy_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.partly_cloudy_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.partly_cloudy_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.partly_cloudy_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.partly_cloudy_2 + 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 } } "03d" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.mostly_cloudy_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.mostly_cloudy_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.mostly_cloudy_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.mostly_cloudy_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.mostly_cloudy_2 + 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 } } "04d" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.cloudy_weather_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.cloudy_weather_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.cloudy_weather_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.cloudy_weather_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.cloudy_weather_2 + 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 } } "09d" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.storm_weather_day_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.storm_weather_day_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.storm_weather_day_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.storm_weather_day_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.storm_weather_day_2 + 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 } } "10d" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.rainy_day_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rainy_day_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rainy_day_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.rainy_day_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.rainy_day_2 + 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 } } "11d" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.thunder_day_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.thunder_day_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.thunder_day_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.thunder_day_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.thunder_day_2 + 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 } } "13d" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.snow_day_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.snow_day_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.snow_day_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.snow_day_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.snow_day_2 + 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 } } "50d" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.haze_day_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_day_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_day_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.haze_day_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.haze_day_2 + 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 } } "80d" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.windy_day_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.windy_day_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.windy_day_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.windy_day_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.windy_day_2 + 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 } } "81d" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.rain_snow_day_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rain_snow_day_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rain_snow_day_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.rain_snow_day_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.rain_snow_day_2 + 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 } } "82d" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.haze_weather_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_weather_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_weather_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.haze_weather_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.haze_weather_2 + 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 } } @@ -221,97 +213,97 @@ object WeatherHelper { "01n" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.clear_night_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.clear_night_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.clear_night_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.clear_night_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.clear_night_2 + 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 } } "02n" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.partly_cloudy_night_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.partly_cloudy_night_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.partly_cloudy_night_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.partly_cloudy_night_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.partly_cloudy_night_2 + 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 } } "03n" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.mostly_cloudy_night_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.mostly_cloudy_night_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.mostly_cloudy_night_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.mostly_cloudy_night_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.mostly_cloudy_night_2 + 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 } } "04n" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.cloudy_weather_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.cloudy_weather_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.cloudy_weather_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.cloudy_weather_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.cloudy_weather_2 + 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 } } "09n" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.storm_weather_night_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.storm_weather_night_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.storm_weather_night_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.storm_weather_night_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.storm_weather_night_2 + 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 } } "10n" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.rainy_night_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rainy_night_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rainy_night_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.rainy_night_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.rainy_night_2 + 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 } } "11n" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.thunder_night_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.thunder_night_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.thunder_night_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.thunder_night_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.thunder_night_2 + 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 } } "13n" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.snow_night_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.snow_night_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.snow_night_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.snow_night_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.snow_night_2 + 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 } } "50n" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.haze_night_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_night_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_night_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.haze_night_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.haze_night_2 + 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 } } "80n" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.windy_night_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.windy_night_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.windy_night_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.windy_night_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.windy_night_2 + 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 } } "81n" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.rain_snow_night_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.rain_snow_night_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.rain_snow_night_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.rain_snow_night_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.rain_snow_night_2 + 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 } } "82n" -> { when (style) { - Constants.WeatherIconPack.COOL.value -> R.drawable.haze_weather_3 - Constants.WeatherIconPack.MINIMAL.value -> R.drawable.haze_weather_2 - Constants.WeatherIconPack.GOOGLE_NEWS.value -> R.drawable.haze_weather_4 + Constants.WeatherIconPack.COOL.rawValue -> R.drawable.haze_weather_3 + Constants.WeatherIconPack.MINIMAL.rawValue -> R.drawable.haze_weather_2 + 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 } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/UpdatesReceiver.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/UpdatesReceiver.kt index 73c458d..36330f4 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/UpdatesReceiver.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/UpdatesReceiver.kt @@ -5,9 +5,6 @@ import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.Context 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.global.Actions import com.tommasoberlose.anotherwidget.global.Constants @@ -110,7 +107,7 @@ class UpdatesReceiver : BroadcastReceiver() { if (diff.hours == 0) { var minutes = 0 when (Preferences.widgetUpdateFrequency) { - Constants.WidgetUpdateFrequency.DEFAULT.value -> { + Constants.WidgetUpdateFrequency.DEFAULT.rawValue -> { minutes = when { diff.minutes > 50 -> 50 diff.minutes > 30 -> 30 @@ -118,7 +115,7 @@ class UpdatesReceiver : BroadcastReceiver() { else -> 0 } } - Constants.WidgetUpdateFrequency.HIGH.value -> { + Constants.WidgetUpdateFrequency.HIGH.rawValue -> { minutes = diff.minutes - (diff.minutes % 5) } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/WeatherProviderActivity.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/WeatherProviderActivity.kt index 544334f..ec5297a 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/WeatherProviderActivity.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/WeatherProviderActivity.kt @@ -47,12 +47,12 @@ class WeatherProviderActivity : AppCompatActivity() { injector .text(R.id.text, WeatherHelper.getProviderName(this, provider)) .clicked(R.id.item) { - if (Preferences.weatherProvider != provider.value) { + if (Preferences.weatherProvider != provider.rawValue) { Preferences.weatherProviderError = "-" Preferences.weatherProviderLocationError = "" } val oldValue = Preferences.weatherProvider - Preferences.weatherProvider = provider.value + Preferences.weatherProvider = provider.rawValue updateListItem(oldValue) updateListItem() binding.loader.isVisible = true @@ -62,12 +62,12 @@ class WeatherProviderActivity : AppCompatActivity() { } } .clicked(R.id.radioButton) { - if (Preferences.weatherProvider != provider.value) { + if (Preferences.weatherProvider != provider.rawValue) { Preferences.weatherProviderError = "-" Preferences.weatherProviderLocationError = "" } val oldValue = Preferences.weatherProvider - Preferences.weatherProvider = provider.value + Preferences.weatherProvider = provider.rawValue updateListItem(oldValue) updateListItem() binding.loader.isVisible = true @@ -76,7 +76,7 @@ class WeatherProviderActivity : AppCompatActivity() { WeatherHelper.updateWeather(this@WeatherProviderActivity) } } - .checked(R.id.radioButton, provider.value == Preferences.weatherProvider) + .checked(R.id.radioButton, provider.rawValue == Preferences.weatherProvider) .with(R.id.text2) { if (WeatherHelper.isKeyRequired(provider)) { it.text = getString(R.string.api_key_required_message) @@ -98,14 +98,14 @@ class WeatherProviderActivity : AppCompatActivity() { } }.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(R.id.provider_error) { if (Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-") { it.text = Preferences.weatherProviderError - it.isVisible = provider.value == Preferences.weatherProvider + it.isVisible = provider.rawValue == Preferences.weatherProvider } else if (Preferences.weatherProviderLocationError != "") { it.text = Preferences.weatherProviderLocationError - it.isVisible = provider.value == Preferences.weatherProvider + it.isVisible = provider.rawValue == Preferences.weatherProvider } else { it.isVisible = false } @@ -137,7 +137,7 @@ class WeatherProviderActivity : AppCompatActivity() { private fun updateListItem(provider: Int = Preferences.weatherProvider) { (adapter.data).forEachIndexed { index, item -> - if (item is Constants.WeatherProvider && item.value == provider) { + if (item is Constants.WeatherProvider && item.rawValue == provider) { adapter.notifyItemChanged(index) } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt index 0bae616..048acf8 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt @@ -1,9 +1,7 @@ package com.tommasoberlose.anotherwidget.ui.fragments -import android.Manifest import android.animation.ValueAnimator import android.content.Intent -import android.content.SharedPreferences import android.net.Uri import android.os.Build import android.os.Bundle @@ -14,23 +12,14 @@ import android.util.TypedValue import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.FrameLayout import android.widget.RelativeLayout -import androidx.core.animation.addListener -import androidx.core.app.NotificationManagerCompat import androidx.core.content.ContextCompat import androidx.core.view.isVisible import androidx.fragment.app.Fragment -import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope -import androidx.navigation.NavController import androidx.navigation.Navigation -import androidx.navigation.fragment.FragmentNavigatorExtras 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.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog @@ -39,11 +28,10 @@ import com.tommasoberlose.anotherwidget.global.Constants import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.helpers.* 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.adapters.ViewPagerAdapter import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget +import com.tommasoberlose.anotherwidget.ui.widgets.StandardWidget import com.tommasoberlose.anotherwidget.utils.* import kotlinx.coroutines.* import org.greenrobot.eventbus.EventBus @@ -54,7 +42,7 @@ class MainFragment : Fragment() { companion object { fun newInstance() = MainFragment() - private const val PREVIEW_BASE_HEIGHT = 120 + private var PREVIEW_BASE_HEIGHT: Int = if (Preferences.widgetAlign == Constants.WidgetAlign.CENTER.rawValue) 120 else 200 } private lateinit var viewModel: MainViewModel @@ -164,6 +152,10 @@ class MainFragment : Fragment() { binding.toolbar.cardElevation = if (it > 0) 24f else 0f } + viewModel.widgetAlign.observe(viewLifecycleOwner) { + updatePreviewVisibility() + } + viewModel.showPreview.observe(viewLifecycleOwner) { updatePreviewVisibility() } @@ -209,7 +201,7 @@ class MainFragment : Fragment() { WidgetHelper.runWithCustomTypeface(requireContext()) { typeface -> uiJob = lifecycleScope.launch(Dispatchers.IO) { - val generatedView = MainWidget.generateWidgetView(requireContext(), typeface).root + val generatedView = MainWidget.getWidgetView(requireContext(), typeface).root withContext(Dispatchers.Main) { generatedView.measure(0, 0) @@ -252,13 +244,13 @@ class MainFragment : Fragment() { // Clock bottom margin binding.widgetDetail.clockBottomMarginNone.isVisible = - Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.value + Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.rawValue binding.widgetDetail.clockBottomMarginSmall.isVisible = - Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.value + Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.rawValue binding.widgetDetail.clockBottomMarginMedium.isVisible = - Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.value + Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.rawValue binding.widgetDetail.clockBottomMarginLarge.isVisible = - Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.value + Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.rawValue } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/CalendarFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/CalendarFragment.kt index 3b23956..1b0ac73 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/CalendarFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/CalendarFragment.kt @@ -1,19 +1,14 @@ package com.tommasoberlose.anotherwidget.ui.fragments.tabs import android.Manifest -import android.app.Activity -import android.content.Intent import android.os.Bundle import android.provider.CalendarContract import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment -import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope -import com.chibatching.kotpref.bulk import com.google.android.material.transition.MaterialSharedAxis import com.tommasoberlose.anotherwidget.R 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.global.Constants 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.viewmodels.MainViewModel import com.tommasoberlose.anotherwidget.helpers.CalendarHelper -import com.tommasoberlose.anotherwidget.helpers.IntentHelper import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission -import com.tommasoberlose.anotherwidget.utils.isDefaultSet import com.tommasoberlose.anotherwidget.utils.toast import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import kotlin.Comparator class CalendarFragment : Fragment() { @@ -110,9 +100,9 @@ class CalendarFragment : Fragment() { viewModel.widgetUpdateFrequency.observe(viewLifecycleOwner) { maintainScrollPosition { binding.widgetUpdateFrequencyLabel.text = when (it) { - Constants.WidgetUpdateFrequency.HIGH.value -> getString(R.string.settings_widget_update_frequency_high) - Constants.WidgetUpdateFrequency.DEFAULT.value -> getString(R.string.settings_widget_update_frequency_default) - Constants.WidgetUpdateFrequency.LOW.value -> getString(R.string.settings_widget_update_frequency_low) + Constants.WidgetUpdateFrequency.HIGH.rawValue -> getString(R.string.settings_widget_update_frequency_high) + Constants.WidgetUpdateFrequency.DEFAULT.rawValue -> getString(R.string.settings_widget_update_frequency_default) + Constants.WidgetUpdateFrequency.LOW.rawValue -> getString(R.string.settings_widget_update_frequency_low) else -> "" } } @@ -244,9 +234,9 @@ class CalendarFragment : Fragment() { binding.actionWidgetUpdateFrequency.setOnClickListener { if (Preferences.showEvents && Preferences.showDiffTime) { BottomSheetMenu(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_default), Constants.WidgetUpdateFrequency.DEFAULT.value) - .addItem(getString(R.string.settings_widget_update_frequency_low), Constants.WidgetUpdateFrequency.LOW.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.rawValue) + .addItem(getString(R.string.settings_widget_update_frequency_low), Constants.WidgetUpdateFrequency.LOW.rawValue) .addOnSelectItemListener { value -> Preferences.widgetUpdateFrequency = value }.show() diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/LayoutFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/LayoutFragment.kt index c19a10d..8df929f 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/LayoutFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/LayoutFragment.kt @@ -1,17 +1,14 @@ package com.tommasoberlose.anotherwidget.ui.fragments.tabs import android.annotation.SuppressLint -import android.content.Intent import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment -import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope -import com.chibatching.kotpref.blockingBulk import com.google.android.material.transition.MaterialSharedAxis import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.components.BottomSheetColorPicker @@ -22,8 +19,6 @@ import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.helpers.ColorHelper import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toHexValue 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.viewmodels.MainViewModel import com.tommasoberlose.anotherwidget.utils.isDarkTheme @@ -31,7 +26,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import java.util.* class LayoutFragment : Fragment() { @@ -94,20 +88,31 @@ class LayoutFragment : Fragment() { viewModel.secondRowTopMargin.observe(viewLifecycleOwner) { maintainScrollPosition { binding.secondRowTopMarginLabel.text = when (it) { - Constants.SecondRowTopMargin.NONE.value -> getString(R.string.settings_clock_bottom_margin_subtitle_none) - Constants.SecondRowTopMargin.SMALL.value -> getString(R.string.settings_clock_bottom_margin_subtitle_small) - Constants.SecondRowTopMargin.LARGE.value -> getString(R.string.settings_clock_bottom_margin_subtitle_large) + Constants.SecondRowTopMargin.NONE.rawValue -> getString(R.string.settings_clock_bottom_margin_subtitle_none) + Constants.SecondRowTopMargin.SMALL.rawValue -> getString(R.string.settings_clock_bottom_margin_subtitle_small) + Constants.SecondRowTopMargin.LARGE.rawValue -> getString(R.string.settings_clock_bottom_margin_subtitle_large) else -> getString(R.string.settings_clock_bottom_margin_subtitle_medium) } } } + viewModel.widgetAlign.observe(viewLifecycleOwner) { + maintainScrollPosition { + 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) { maintainScrollPosition { binding.clockBottomMarginLabel.text = when (it) { - Constants.ClockBottomMargin.NONE.value -> getString(R.string.settings_clock_bottom_margin_subtitle_none) - Constants.ClockBottomMargin.SMALL.value -> getString(R.string.settings_clock_bottom_margin_subtitle_small) - Constants.ClockBottomMargin.LARGE.value -> getString(R.string.settings_clock_bottom_margin_subtitle_large) + Constants.ClockBottomMargin.NONE.rawValue -> getString(R.string.settings_clock_bottom_margin_subtitle_none) + Constants.ClockBottomMargin.SMALL.rawValue -> getString(R.string.settings_clock_bottom_margin_subtitle_small) + Constants.ClockBottomMargin.LARGE.rawValue -> getString(R.string.settings_clock_bottom_margin_subtitle_large) else -> getString(R.string.settings_clock_bottom_margin_subtitle_medium) } } @@ -115,7 +120,7 @@ class LayoutFragment : Fragment() { viewModel.backgroundCardColor.observe(viewLifecycleOwner) { maintainScrollPosition { - if (Preferences.backgroundCardAlpha == "00") { + if (ColorHelper.getBackgroundAlpha(requireActivity().isDarkTheme()) == 0) { binding.backgroundColorLabel.text = getString(R.string.transparent) } else { binding.backgroundColorLabel.text = @@ -141,19 +146,19 @@ class LayoutFragment : Fragment() { ).setSelectedValue(Preferences.secondRowTopMargin) .addItem( getString(R.string.settings_clock_bottom_margin_subtitle_none), - Constants.SecondRowTopMargin.NONE.value + Constants.SecondRowTopMargin.NONE.rawValue ) .addItem( getString(R.string.settings_clock_bottom_margin_subtitle_small), - Constants.SecondRowTopMargin.SMALL.value + Constants.SecondRowTopMargin.SMALL.rawValue ) .addItem( getString(R.string.settings_clock_bottom_margin_subtitle_medium), - Constants.SecondRowTopMargin.MEDIUM.value + Constants.SecondRowTopMargin.MEDIUM.rawValue ) .addItem( getString(R.string.settings_clock_bottom_margin_subtitle_large), - Constants.SecondRowTopMargin.LARGE.value + Constants.SecondRowTopMargin.LARGE.rawValue ) .addOnSelectItemListener { value -> Preferences.secondRowTopMargin = value @@ -167,25 +172,47 @@ class LayoutFragment : Fragment() { ).setSelectedValue(Preferences.clockBottomMargin) .addItem( getString(R.string.settings_clock_bottom_margin_subtitle_none), - Constants.ClockBottomMargin.NONE.value + Constants.ClockBottomMargin.NONE.rawValue ) .addItem( getString(R.string.settings_clock_bottom_margin_subtitle_small), - Constants.ClockBottomMargin.SMALL.value + Constants.ClockBottomMargin.SMALL.rawValue ) .addItem( getString(R.string.settings_clock_bottom_margin_subtitle_medium), - Constants.ClockBottomMargin.MEDIUM.value + Constants.ClockBottomMargin.MEDIUM.rawValue ) .addItem( getString(R.string.settings_clock_bottom_margin_subtitle_large), - Constants.ClockBottomMargin.LARGE.value + Constants.ClockBottomMargin.LARGE.rawValue ) .addOnSelectItemListener { value -> Preferences.clockBottomMargin = value }.show() } + binding.actionWidgetAlign.setOnClickListener { + BottomSheetMenu( + 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 { BottomSheetColorPicker(requireContext(), colors = colors, diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/viewmodels/MainViewModel.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/viewmodels/MainViewModel.kt index 42dab9d..915f85a 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/viewmodels/MainViewModel.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/viewmodels/MainViewModel.kt @@ -49,6 +49,7 @@ class MainViewModel(context: Application) : AndroidViewModel(context) { val secondRowInformation = Preferences.asLiveData(Preferences::secondRowInformation) val showDividers = Preferences.asLiveData(Preferences::showDividers) val secondRowTopMargin = Preferences.asLiveData(Preferences::secondRowTopMargin) + val widgetAlign = Preferences.asLiveData(Preferences::widgetAlign) // Calendar Settings val showEvents = Preferences.asLiveData(Preferences::showEvents) diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/ClockWidget.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/ClockWidget.kt new file mode 100644 index 0000000..6433989 --- /dev/null +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/ClockWidget.kt @@ -0,0 +1,75 @@ +package com.tommasoberlose.anotherwidget.ui.widgets + +import android.app.PendingIntent +import android.content.Context +import android.util.TypedValue +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) + } 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 + ) + } + } catch (ex: Exception) { + ex.printStackTrace() + CrashlyticsReceiver.sendCrash(context, ex) + } + + return views + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt new file mode 100644 index 0000000..7a28fc2 --- /dev/null +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt @@ -0,0 +1,886 @@ +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.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.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 LeftAlignedWidget(val context: Context) { + fun generateWidget(appWidgetId: Int, w: Int, typeface: Typeface? = null): RemoteViews { + + var views = RemoteViews(context.packageName, R.layout.left_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) + 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 { + val eventRepository = EventRepository(context) + try { + // 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.date_layout, View.VISIBLE) + + val nextEvent = eventRepository.getNextEvent() + 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 && eventRepository.getEventsCount() > 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 - 1000 * 60 * 60)) { + 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) + + // Second row + views.setImageViewBitmap( + R.id.sub_line_rect, + BitmapHelper.getBitmapFromView(bindingView.subLine, draw = false) + ) + views.setViewVisibility(R.id.sub_line_rect, View.VISIBLE) + } else if (GlanceProviderHelper.showGlanceProviders(context) && bindingView.calendarLayout.isVisible) { + 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.calendar_layout_rect, View.GONE) + views.setViewVisibility(R.id.sub_line_rect, View.VISIBLE) + + 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) + } finally { + eventRepository.close() + } + + return views + } + + + // Generates the widget bitmap from the view + fun generateWidgetView(typeface: Typeface? = null): LeftAlignedWidgetBinding { + val eventRepository = EventRepository(context) + 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 nextEvent = eventRepository.getNextEvent() + 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 && eventRepository.getEventsCount() > 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( + bindingView.date, + bindingView.weatherDateLineTemperature, + bindingView.nextEvent, + bindingView.nextEventDifferenceTime, + ).forEach { + it.setTextColor(ColorHelper.getFontColor(context.applicationContext.isDarkTheme())) + } + + if (Preferences.weatherIconPack != Constants.WeatherIconPack.MINIMAL.rawValue) { + listOf(bindingView.actionNext) + } else { + listOf( + 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(bindingView.subLineText, bindingView.weatherSubLineDivider, bindingView.weatherSubLineTemperature).forEach { + it.setTextColor(ColorHelper.getSecondaryFontColor(context.applicationContext.isDarkTheme())) + } + + if (Preferences.weatherIconPack != Constants.WeatherIconPack.MINIMAL.rawValue) { + listOf(bindingView.subLineIcon, bindingView.subLineIconShadow) + } else { + listOf(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>( + 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( + 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( + 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( + 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 + } + } + + eventRepository.close() + + return bindingView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/MainWidget.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/MainWidget.kt index c797dcc..adb1dcc 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/MainWidget.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/MainWidget.kt @@ -7,13 +7,11 @@ import android.appwidget.AppWidgetProvider import android.content.ComponentName import android.content.Context import android.content.Intent -import android.content.IntentSender import android.content.res.Resources import android.graphics.Color import android.graphics.Typeface import android.os.Bundle import android.text.format.DateUtils -import android.util.Log import android.util.TypedValue import android.view.LayoutInflater import android.view.View @@ -23,8 +21,9 @@ import android.widget.RemoteViews import android.widget.TextView import androidx.core.content.ContextCompat import androidx.core.view.isVisible -import com.google.gson.Gson +import androidx.viewbinding.ViewBinding import com.tommasoberlose.anotherwidget.R +import com.tommasoberlose.anotherwidget.databinding.LeftAlignedWidgetBinding import com.tommasoberlose.anotherwidget.databinding.TheWidgetBinding import com.tommasoberlose.anotherwidget.db.EventRepository import com.tommasoberlose.anotherwidget.global.Actions @@ -98,991 +97,21 @@ class MainWidget : AppWidgetProvider() { val dimensions = WidgetHelper.WidgetSizeProvider(context, appWidgetManager).getWidgetsSize(appWidgetId) WidgetHelper.runWithCustomTypeface(context) { - generateWidgetView(context, appWidgetId, appWidgetManager, min(dimensions.first - 8.toPixel(context), min(width, height) - 16.toPixel(context)), it) + val views = when (Preferences.widgetAlign) { + Constants.WidgetAlign.LEFT.rawValue -> LeftAlignedWidget(context).generateWidget(appWidgetId, min(dimensions.first - 8.toPixel(context), min(width, height) - 16.toPixel(context)), it) + Constants.WidgetAlign.RIGHT.rawValue -> LeftAlignedWidget(context).generateWidget(appWidgetId, min(dimensions.first - 8.toPixel(context), min(width, height) - 16.toPixel(context)), it) + else -> StandardWidget(context).generateWidget(appWidgetId, min(dimensions.first - 8.toPixel(context), min(width, height) - 16.toPixel(context)), it) + } + appWidgetManager.updateAppWidget(appWidgetId, views) } } - private fun generateWidgetView(context: Context, appWidgetId: Int, appWidgetManager: AppWidgetManager, w: Int, typeface: Typeface? = null) { - - 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) + fun getWidgetView(context: Context, typeface: Typeface?): ViewBinding { + return when (Preferences.widgetAlign) { + Constants.WidgetAlign.LEFT.rawValue -> LeftAlignedWidget(context).generateWidgetView(typeface) + Constants.WidgetAlign.RIGHT.rawValue -> LeftAlignedWidget(context).generateWidgetView(typeface) + else -> StandardWidget(context).generateWidgetView(typeface) } - - // Clock - views = updateClockView(context, views, appWidgetId) - - // Setup listener - try { - - val generatedBinding = generateWidgetView(context, typeface) - views.setImageViewBitmap( - R.id.bitmap_container, - BitmapHelper.getBitmapFromView(generatedBinding.root, width = w) - ) - views = updateCalendarView(context, generatedBinding, views, appWidgetId) - views = updateWeatherView(context, generatedBinding, views, appWidgetId) - } catch (ex: Exception) { - ex.printStackTrace() - CrashlyticsReceiver.sendCrash(context, ex) - } - - appWidgetManager.updateAppWidget(appWidgetId, views) - } - - private fun updateCalendarView(context: Context, bindingView: TheWidgetBinding, views: RemoteViews, widgetID: Int): RemoteViews { - val eventRepository = EventRepository(context) - try { - views.setImageViewBitmap( - R.id.empty_date_rect, - BitmapHelper.getBitmapFromView(bindingView.emptyDate, draw = false) - ) - - views.setViewVisibility(R.id.empty_layout_rect, View.VISIBLE) - views.setViewVisibility(R.id.calendar_layout_rect, View.GONE) - views.setViewVisibility(R.id.second_row_rect, View.GONE) - views.setViewVisibility(R.id.next_event_difference_time_rect, View.GONE) - - val calPIntent = PendingIntent.getActivity( - context, - widgetID, - IntentHelper.getCalendarIntent(context), - PendingIntent.FLAG_UPDATE_CURRENT - ) - views.setOnClickPendingIntent(R.id.empty_date_rect, calPIntent) - - val nextEvent = eventRepository.getNextEvent() - val nextAlarm = AlarmHelper.getNextAlarm(context) - - if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null && !Preferences.showEventsAsGlanceProvider) { - if (Preferences.showNextEvent && eventRepository.getEventsCount() > 1) { - 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.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 - ) - ) - } else { - views.setViewVisibility(R.id.action_next_rect, View.GONE) - views.setViewVisibility(R.id.action_previous_rect, View.GONE) - } - - val pIntent = PendingIntent.getActivity( - context, - widgetID, - IntentHelper.getEventIntent(context, nextEvent), - PendingIntent.FLAG_UPDATE_CURRENT - ) - views.setOnClickPendingIntent(R.id.next_event_rect, pIntent) - views.setOnClickPendingIntent(R.id.next_event_difference_time_rect, pIntent) - - if (Preferences.showDiffTime && Calendar.getInstance().timeInMillis < (nextEvent.startDate - 1000 * 60 * 60)) { - 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) - } else { - views.setViewVisibility(R.id.next_event_difference_time_rect, View.GONE) - } - - 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.second_row_rect, mapIntent) - } else { - val pIntentDetail = PendingIntent.getActivity( - context, - widgetID, - IntentHelper.getEventIntent( - context, - nextEvent, - forceEventDetails = true - ), - PendingIntent.FLAG_UPDATE_CURRENT - ) - views.setOnClickPendingIntent(R.id.second_row_rect, pIntentDetail) - } - - views.setImageViewBitmap( - R.id.next_event_rect, - BitmapHelper.getBitmapFromView(bindingView.nextEvent, draw = false) - ) - - views.setImageViewBitmap( - R.id.second_row_rect, - BitmapHelper.getBitmapFromView(bindingView.secondRow, draw = false) - ) - views.setViewVisibility(R.id.second_row_rect, View.VISIBLE) - - views.setViewVisibility(R.id.empty_layout_rect, View.GONE) - views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE) - - views.setViewVisibility( - R.id.second_row_top_margin_small_sans, - if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.SMALL.value) View.VISIBLE else View.GONE - ) - views.setViewVisibility( - R.id.second_row_top_margin_medium_sans, - if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.MEDIUM.value) View.VISIBLE else View.GONE - ) - views.setViewVisibility( - R.id.second_row_top_margin_large_sans, - if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.value) View.VISIBLE else View.GONE - ) - } else if (GlanceProviderHelper.showGlanceProviders(context) && bindingView.calendarLayout.isVisible) { - 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.second_row_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.second_row_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.second_row_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.second_row_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.second_row_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.second_row_rect, - pIntentDetail - ) - showSomething = true - break@loop - } - } - } - } - - - if (showSomething) { - views.setImageViewBitmap( - R.id.next_event_rect, - BitmapHelper.getBitmapFromView(bindingView.nextEvent, draw = false) - ) - - views.setImageViewBitmap( - R.id.second_row_rect, - BitmapHelper.getBitmapFromView(bindingView.secondRow, draw = false) - ) - - views.setViewVisibility(R.id.second_row_rect, View.VISIBLE) - views.setViewVisibility(R.id.empty_layout_rect, View.GONE) - views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE) - views.setOnClickPendingIntent(R.id.next_event_rect, calPIntent) - - - views.setViewVisibility( - R.id.second_row_top_margin_small_sans, - if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.SMALL.value) View.VISIBLE else View.GONE - ) - views.setViewVisibility( - R.id.second_row_top_margin_medium_sans, - if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.MEDIUM.value) View.VISIBLE else View.GONE - ) - views.setViewVisibility( - R.id.second_row_top_margin_large_sans, - if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.value) View.VISIBLE else View.GONE - ) - } - } - } catch (ex: Exception) { - ex.printStackTrace() - CrashlyticsReceiver.sendCrash(context, ex) - } finally { - eventRepository.close() - } - - return views - } - - private fun updateWeatherView(context: Context, bindingView: TheWidgetBinding, views: RemoteViews, widgetID: Int): RemoteViews { - try { - if (Preferences.showWeather && Preferences.weatherIcon != "") { - views.setViewVisibility(R.id.weather_rect, View.VISIBLE) - views.setViewVisibility(R.id.calendar_weather_rect, View.VISIBLE) - views.setViewVisibility(R.id.special_weather_rect, View.VISIBLE) - - 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.calendar_weather_rect, weatherPIntent) - views.setOnClickPendingIntent(R.id.special_weather_rect, weatherPIntent) - - views.setImageViewBitmap( - R.id.weather_rect, - BitmapHelper.getBitmapFromView(bindingView.weather, draw = false) - ) - - views.setImageViewBitmap( - R.id.calendar_weather_rect, - BitmapHelper.getBitmapFromView(bindingView.calendarWeather, draw = false) - ) - - views.setImageViewBitmap( - R.id.special_weather_rect, - BitmapHelper.getBitmapFromView(bindingView.calendarWeather, draw = false) - ) - - if (GlanceProviderHelper.showGlanceProviders(context)) { - views.setViewVisibility(R.id.calendar_weather_rect, View.GONE) - } else { - views.setViewVisibility(R.id.special_weather_rect, View.GONE) - } - } else { - views.setViewVisibility(R.id.weather_rect, View.GONE) - views.setViewVisibility(R.id.calendar_weather_rect, View.GONE) - views.setViewVisibility(R.id.special_weather_rect, View.GONE) - } - } catch (ex: Exception) { - ex.printStackTrace() - CrashlyticsReceiver.sendCrash(context, ex) - } - return views - } - - private fun updateClockView(context: Context, 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) - } 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.value) View.VISIBLE else View.GONE - ) - views.setViewVisibility( - R.id.clock_bottom_margin_small, - if (Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.value) View.VISIBLE else View.GONE - ) - views.setViewVisibility( - R.id.clock_bottom_margin_medium, - if (Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.value) View.VISIBLE else View.GONE - ) - views.setViewVisibility( - R.id.clock_bottom_margin_large, - if (Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.value) View.VISIBLE else View.GONE - ) - } - } catch (ex: Exception) { - ex.printStackTrace() - CrashlyticsReceiver.sendCrash(context, ex) - } - - return views - } - - - // Generates the widget bitmap from the view - fun generateWidgetView(context: Context, typeface: Typeface? = null): TheWidgetBinding { - val eventRepository = EventRepository(context) - val bindingView = TheWidgetBinding.inflate(LayoutInflater.from(context)) - - bindingView.loader.isVisible = false - - val now = Calendar.getInstance().apply { - set(Calendar.SECOND, 0) - set(Calendar.MILLISECOND, 0) - } - - bindingView.emptyLayout.visibility = View.VISIBLE - bindingView.calendarLayout.visibility = View.GONE - bindingView.nextEventDifferenceTime.visibility = View.GONE - bindingView.actionNext.isVisible = false - bindingView.actionPrevious.isVisible = false - - bindingView.emptyDate.text = DateHelper.getDateText(context, now) - - val nextEvent = eventRepository.getNextEvent() - 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 && eventRepository.getEventsCount() > 1 - bindingView.actionPrevious.isVisible = - Preferences.showNextEvent && eventRepository.getEventsCount() > 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.visibility = View.VISIBLE - } else { - bindingView.nextEventDifferenceTime.visibility = View.GONE - } - - if (nextEvent.address != "" && Preferences.secondRowInformation == 1) { - bindingView.secondRowIcon.setImageDrawable( - ContextCompat.getDrawable( - context, - R.drawable.round_place_24 - ) - ) - bindingView.nextEventDate.text = nextEvent.address - } else { - bindingView.secondRowIcon.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.nextEventDate.text = - String.format("%s - %s%s", startHour, endHour, multipleDay) - } else { - bindingView.nextEventDate.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.nextEventDate.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.emptyLayout.visibility = View.GONE - bindingView.calendarLayout.visibility = View.VISIBLE - - bindingView.secondRowTopMarginSmall.visibility = - if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.SMALL.value) View.VISIBLE else View.GONE - bindingView.secondRowTopMarginMedium.visibility = - if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.MEDIUM.value) View.VISIBLE else View.GONE - bindingView.secondRowTopMarginLarge.visibility = - if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.value) View.VISIBLE else View.GONE - } else if (GlanceProviderHelper.showGlanceProviders(context)) { - bindingView.secondRowIcon.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.secondRowIcon.setImageDrawable( - ContextCompat.getDrawable( - context, - R.drawable.round_music_note_24 - ) - ) - bindingView.nextEventDate.text = MediaPlayerHelper.getMediaInfo() - showSomething = true - break@loop - } - } - Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> { - if (Preferences.showNextAlarm && nextAlarm != "") { - bindingView.secondRowIcon.setImageDrawable( - ContextCompat.getDrawable( - context, - R.drawable.round_alarm_24 - ) - ) - bindingView.nextEventDate.text = AlarmHelper.getNextAlarm(context) - showSomething = true - break@loop - } - } - Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> { - if (Preferences.showBatteryCharging) { - BatteryHelper.updateBatteryInfo(context) - if (Preferences.isCharging) { - bindingView.secondRowIcon.isVisible = false - val batteryLevel = BatteryHelper.getBatteryLevel(context) - if (batteryLevel != 100) { - bindingView.nextEventDate.text = context.getString(R.string.charging) - } else { - bindingView.nextEventDate.text = - context.getString(R.string.charged) - } - showSomething = true - break@loop - } else if (Preferences.isBatteryLevelLow) { - bindingView.secondRowIcon.isVisible = false - bindingView.nextEventDate.text = - context.getString(R.string.battery_low_warning) - showSomething = true - break@loop - } - } - } - Constants.GlanceProviderId.CUSTOM_INFO -> { - if (Preferences.customNotes.isNotEmpty()) { - bindingView.secondRowIcon.isVisible = false - bindingView.nextEventDate.text = Preferences.customNotes - bindingView.nextEventDate.maxLines = 2 - showSomething = true - break@loop - } - } - Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> { - if (Preferences.showDailySteps && Preferences.googleFitSteps > 0) { - bindingView.secondRowIcon.isVisible = false - bindingView.nextEventDate.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.secondRowIcon.isVisible = true - bindingView.secondRowIcon.setImageDrawable(icon) - } else { - bindingView.secondRowIcon.isVisible = false - } - bindingView.nextEventDate.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.nextEventDate.text = greetingsText - bindingView.nextEventDate.maxLines = 2 - bindingView.secondRowIcon.isVisible = false - showSomething = true - break@loop - } - } - Constants.GlanceProviderId.EVENTS -> { - if (Preferences.showEventsAsGlanceProvider && Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null) { - bindingView.nextEventDate.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.secondRowIcon.isVisible = true - bindingView.secondRowIcon.setImageDrawable( - ContextCompat.getDrawable( - context, - R.drawable.round_today_24 - ) - ) - showSomething = true - break@loop - } - } - } - } - - if (showSomething) { - bindingView.nextEvent.text = DateHelper.getDateText(context, now) - bindingView.emptyLayout.visibility = View.GONE - bindingView.calendarLayout.visibility = View.VISIBLE - - bindingView.secondRowTopMarginSmall.visibility = - if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.SMALL.value) View.VISIBLE else View.GONE - bindingView.secondRowTopMarginMedium.visibility = - if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.MEDIUM.value) View.VISIBLE else View.GONE - bindingView.secondRowTopMarginLarge.visibility = - if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.value) View.VISIBLE else View.GONE - } else { - bindingView.secondRowIcon.isVisible = false - } - } - - - // Color - listOf( - bindingView.emptyDate, - bindingView.divider1, - bindingView.temp, - bindingView.nextEvent, - bindingView.nextEventDifferenceTime, - bindingView.divider3, - bindingView.specialTemp - ).forEach { - it.setTextColor(ColorHelper.getFontColor(context.applicationContext.isDarkTheme())) - } - - if (Preferences.weatherIconPack != Constants.WeatherIconPack.MINIMAL.value) { - listOf(bindingView.actionNext, bindingView.actionPrevious) - } else { - listOf( - bindingView.actionNext, - bindingView.actionPrevious, - bindingView.emptyWeatherIcon, - bindingView.specialWeatherIcon - ) - }.forEach { - it.setColorFilter(ColorHelper.getFontColorRgb(context.applicationContext.isDarkTheme())) - it.alpha = - (if (context.isDarkTheme()) Preferences.textGlobalAlphaDark.toIntValue() - .toFloat() else Preferences.textGlobalAlpha.toIntValue() - .toFloat()) / 100 - } - - listOf(bindingView.nextEventDate, bindingView.divider2, bindingView.calendarTemp).forEach { - it.setTextColor(ColorHelper.getSecondaryFontColor(context.applicationContext.isDarkTheme())) - } - - if (Preferences.weatherIconPack != Constants.WeatherIconPack.MINIMAL.value) { - listOf(bindingView.secondRowIcon, bindingView.secondRowIconShadow) - } else { - listOf(bindingView.secondRowIcon, bindingView.weatherIcon, bindingView.secondRowIconShadow) - }.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>( - bindingView.emptyDate to Preferences.textMainSize, - bindingView.divider1 to (Preferences.textMainSize - 2), - bindingView.temp to Preferences.textMainSize, - bindingView.nextEvent to Preferences.textMainSize, - bindingView.nextEventDifferenceTime to Preferences.textMainSize, - bindingView.nextEventDate to Preferences.textSecondSize, - bindingView.divider2 to (Preferences.textSecondSize - 2), - bindingView.calendarTemp to Preferences.textSecondSize, - bindingView.divider3 to (Preferences.textMainSize - 2), - bindingView.specialTemp to Preferences.textMainSize - ).forEach { - it.first.setTextSize(TypedValue.COMPLEX_UNIT_SP, it.second) - } - - // Icons scale - bindingView.secondRowIcon.scaleX = Preferences.textSecondSize / 18f - bindingView.secondRowIcon.scaleY = Preferences.textSecondSize / 18f - - bindingView.weatherIcon.scaleX = Preferences.textSecondSize / 14f - bindingView.weatherIcon.scaleY = Preferences.textSecondSize / 14f - - bindingView.emptyWeatherIcon.scaleX = Preferences.textMainSize / 18f - bindingView.emptyWeatherIcon.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 - - bindingView.specialWeatherIcon.scaleX = Preferences.textMainSize / 18f - bindingView.specialWeatherIcon.scaleY = Preferences.textMainSize / 18f - - - // 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( - bindingView.emptyDate, - bindingView.divider1, - bindingView.temp, - bindingView.nextEvent, - bindingView.nextEventDifferenceTime, - bindingView.nextEventDate, - bindingView.divider2, - bindingView.calendarTemp, - bindingView.divider3, - bindingView.specialTemp - ).forEach { - it.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor) - } - - // Icons shadow - - listOf( - Pair(bindingView.secondRowIcon, bindingView.secondRowIconShadow), - ).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( - bindingView.emptyDate, - bindingView.divider1, - bindingView.temp, - bindingView.nextEvent, - bindingView.nextEventDifferenceTime, - bindingView.nextEventDate, - bindingView.divider2, - bindingView.calendarTemp, - bindingView.divider3, - bindingView.specialTemp - ).forEach { - it.typeface = googleSans - } - } else if (Preferences.customFont == Constants.CUSTOM_FONT_DOWNLOADED && typeface != null) { - listOf( - bindingView.emptyDate, - bindingView.divider1, - bindingView.temp, - bindingView.nextEvent, - bindingView.nextEventDifferenceTime, - bindingView.nextEventDate, - bindingView.divider2, - bindingView.calendarTemp, - bindingView.divider3, - bindingView.specialTemp - ).forEach { - it.typeface = typeface - } - } - - // Weather - if (Preferences.showWeather && Preferences.weatherIcon != "") { - bindingView.weather.visibility = View.VISIBLE - bindingView.calendarWeather.visibility = View.VISIBLE - bindingView.specialWeather.visibility = View.VISIBLE - val currentTemp = String.format( - Locale.getDefault(), - "%d °%s", - Preferences.weatherTemp.roundToInt(), - Preferences.weatherRealTempUnit - ) - - val icon: String = Preferences.weatherIcon - if (icon == "") { - bindingView.weatherIcon.visibility = View.GONE - bindingView.emptyWeatherIcon.visibility = View.GONE - bindingView.specialWeatherIcon.visibility = View.GONE - } else { - bindingView.weatherIcon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon)) - bindingView.emptyWeatherIcon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon)) - bindingView.specialWeatherIcon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon)) - bindingView.weatherIcon.visibility = View.VISIBLE - bindingView.emptyWeatherIcon.visibility = View.VISIBLE - bindingView.specialWeatherIcon.visibility = View.VISIBLE - } - - bindingView.temp.text = currentTemp - bindingView.calendarTemp.text = currentTemp - bindingView.specialTemp.text = currentTemp - - if (GlanceProviderHelper.showGlanceProviders(context)) { - bindingView.calendarWeather.visibility = View.GONE - } else { - bindingView.specialWeather.visibility = View.GONE - } - } else { - bindingView.weather.visibility = View.GONE - bindingView.calendarWeather.visibility = View.GONE - bindingView.specialWeather.visibility = View.GONE - } - - // Dividers - arrayOf(bindingView.divider1, bindingView.divider2, bindingView.divider3).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 - } - } - - eventRepository.close() - - return bindingView } } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt new file mode 100644 index 0000000..1901107 --- /dev/null +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt @@ -0,0 +1,925 @@ +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.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) + 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 { + val eventRepository = EventRepository(context) + try { + // 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.date_layout, View.VISIBLE) + + val nextEvent = eventRepository.getNextEvent() + 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 && eventRepository.getEventsCount() > 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 - 1000 * 60 * 60)) { + 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) + + // Second row + views.setImageViewBitmap( + R.id.sub_line_rect, + BitmapHelper.getBitmapFromView(bindingView.subLine, draw = false) + ) + views.setViewVisibility(R.id.sub_line_rect, View.VISIBLE) + } else if (GlanceProviderHelper.showGlanceProviders(context) && bindingView.calendarLayout.isVisible) { + 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.calendar_layout_rect, View.GONE) + views.setViewVisibility(R.id.sub_line_rect, View.VISIBLE) + + 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) + } finally { + eventRepository.close() + } + + return views + } + + + // Generates the widget bitmap from the view + fun generateWidgetView(typeface: Typeface? = null): TheWidgetBinding { + val eventRepository = EventRepository(context) + 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 nextEvent = eventRepository.getNextEvent() + 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 && eventRepository.getEventsCount() > 1 + bindingView.actionPrevious.isVisible = + Preferences.showNextEvent && eventRepository.getEventsCount() > 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( + 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(bindingView.actionNext, bindingView.actionPrevious) + } else { + listOf( + 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(bindingView.subLineText, bindingView.weatherSubLineDivider, bindingView.weatherSubLineTemperature).forEach { + it.setTextColor(ColorHelper.getSecondaryFontColor(context.applicationContext.isDarkTheme())) + } + + if (Preferences.weatherIconPack != Constants.WeatherIconPack.MINIMAL.rawValue) { + listOf(bindingView.subLineIcon, bindingView.subLineIconShadow) + } else { + listOf(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>( + 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( + 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( + 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( + 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 + } + } + + eventRepository.close() + + return bindingView + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_tab_layout.xml b/app/src/main/res/layout/fragment_tab_layout.xml index 5761e31..3492aec 100644 --- a/app/src/main/res/layout/fragment_tab_layout.xml +++ b/app/src/main/res/layout/fragment_tab_layout.xml @@ -111,6 +111,43 @@ android:paddingLeft="20dp" android:paddingRight="20dp" android:textAppearance="@style/AnotherWidget.Settings.Header" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/left_aligned_widget_sans.xml b/app/src/main/res/layout/left_aligned_widget_sans.xml new file mode 100644 index 0000000..11fa721 --- /dev/null +++ b/app/src/main/res/layout/left_aligned_widget_sans.xml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/right_aligned_widget.xml b/app/src/main/res/layout/right_aligned_widget.xml new file mode 100644 index 0000000..5519290 --- /dev/null +++ b/app/src/main/res/layout/right_aligned_widget.xml @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/right_aligned_widget_sans.xml b/app/src/main/res/layout/right_aligned_widget_sans.xml new file mode 100644 index 0000000..85ce6f5 --- /dev/null +++ b/app/src/main/res/layout/right_aligned_widget_sans.xml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/the_widget.xml b/app/src/main/res/layout/the_widget.xml index c0b260e..2282237 100644 --- a/app/src/main/res/layout/the_widget.xml +++ b/app/src/main/res/layout/the_widget.xml @@ -4,79 +4,80 @@ android:layout_gravity="center" android:clipChildren="false" android:clipToPadding="false" + android:orientation="vertical" android:id="@+id/main_layout"> - + android:orientation="vertical" + android:layout_centerInParent="true"> + android:layout_gravity="center" + android:orientation="horizontal" + android:layoutDirection="locale" + android:id="@+id/date_layout"> - - + style="@style/AnotherWidget.Widget.Title"/> + + + + + - - - - - - - + android:id="@+id/sub_line_top_margin_small" /> + android:id="@+id/sub_line_top_margin_medium" /> + android:id="@+id/sub_line_top_margin_large" /> + android:layout_marginStart="4dp" + android:id="@+id/weather_sub_line"> + android:layout_width="20dp" + android:layout_height="20dp" + android:id="@+id/weather_sub_line_weather_icon" + android:layout_marginStart="4dp" + android:layout_marginEnd="8dp"/> + android:id="@+id/weather_sub_line_temperature"/> - \ No newline at end of file diff --git a/app/src/main/res/layout/the_widget_sans.xml b/app/src/main/res/layout/the_widget_sans.xml index 697b42a..75e8cda 100644 --- a/app/src/main/res/layout/the_widget_sans.xml +++ b/app/src/main/res/layout/the_widget_sans.xml @@ -74,40 +74,48 @@ + - + - - - + android:gravity="center" + android:alpha="0" + android:visibility="gone" + android:orientation="horizontal" + android:layoutDirection="locale" + android:id="@+id/first_line_rect"> + + + - + android:id="@+id/sub_line_top_margin_small_sans" /> + android:id="@+id/sub_line_top_margin_medium_sans" /> + android:id="@+id/sub_line_top_margin_large_sans" /> + android:id="@+id/sub_line_rect" /> + android:visibility="gone" + android:id="@+id/weather_sub_line_rect" /> - - - \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 24eb9f2..f37c356 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -37,6 +37,10 @@ Grassetto Nero Molto nero + Allineamento widget + Sinistra + Destra + Centro Calendario diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3d2c9b0..218745c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -31,6 +31,10 @@ Rows spacing Custom font… Font family + Widget align + Left + Right + Center Thin Light diff --git a/build.gradle b/build.gradle index abafc28..8238dc1 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.4.21' + ext.kotlin_version = '1.4.32' repositories { google() jcenter() @@ -10,14 +10,14 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.1.2' + classpath 'com.android.tools.build:gradle:4.1.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.google.gms:google-services:4.3.4' + classpath 'com.google.gms:google-services:4.3.5' // Add the Crashlytics Gradle plugin. - classpath 'com.google.firebase:firebase-crashlytics-gradle:2.4.1' + classpath 'com.google.firebase:firebase-crashlytics-gradle:2.5.2' - classpath 'io.realm:realm-gradle-plugin:6.0.2' + classpath 'io.realm:realm-gradle-plugin:10.4.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files From 1f22426dec104f6f45ac5122e71c0d97ca3ba7d5 Mon Sep 17 00:00:00 2001 From: Tommaso Berlose Date: Tue, 4 May 2021 18:32:20 +0200 Subject: [PATCH 4/6] Update align support --- .idea/caches/build_file_checksums.ser | Bin 537 -> 537 bytes .../anotherwidget/global/Constants.kt | 2 +- .../ui/fragments/MainFragment.kt | 15 +++++- .../ui/fragments/tabs/LayoutFragment.kt | 12 +++-- .../ui/viewmodels/MainViewModel.kt | 1 + .../ui/widgets/LeftAlignedWidget.kt | 44 ++++++++++-------- .../anotherwidget/ui/widgets/MainWidget.kt | 2 - .../ui/widgets/StandardWidget.kt | 22 +++++---- .../anotherwidget/utils/Extensions.kt | 4 +- ...round_align_horizontal_center_white_18.png | Bin 0 -> 207 bytes ...round_align_horizontal_center_white_20.png | Bin 0 -> 210 bytes ...round_align_horizontal_center_white_24.png | Bin 0 -> 203 bytes ...round_align_horizontal_center_white_36.png | Bin 0 -> 292 bytes ...round_align_horizontal_center_white_48.png | Bin 0 -> 245 bytes .../round_align_horizontal_left_white_18.png | Bin 0 -> 184 bytes .../round_align_horizontal_left_white_20.png | Bin 0 -> 186 bytes .../round_align_horizontal_left_white_24.png | Bin 0 -> 174 bytes .../round_align_horizontal_left_white_36.png | Bin 0 -> 275 bytes .../round_align_horizontal_left_white_48.png | Bin 0 -> 251 bytes .../round_align_horizontal_right_white_18.png | Bin 0 -> 187 bytes .../round_align_horizontal_right_white_20.png | Bin 0 -> 189 bytes .../round_align_horizontal_right_white_24.png | Bin 0 -> 174 bytes .../round_align_horizontal_right_white_36.png | Bin 0 -> 275 bytes .../round_align_horizontal_right_white_48.png | Bin 0 -> 253 bytes ...round_align_horizontal_center_white_18.png | Bin 0 -> 166 bytes ...round_align_horizontal_center_white_20.png | Bin 0 -> 172 bytes ...round_align_horizontal_center_white_24.png | Bin 0 -> 123 bytes ...round_align_horizontal_center_white_36.png | Bin 0 -> 203 bytes ...round_align_horizontal_center_white_48.png | Bin 0 -> 172 bytes .../round_align_horizontal_left_white_18.png | Bin 0 -> 142 bytes .../round_align_horizontal_left_white_20.png | Bin 0 -> 159 bytes .../round_align_horizontal_left_white_24.png | Bin 0 -> 122 bytes .../round_align_horizontal_left_white_36.png | Bin 0 -> 174 bytes .../round_align_horizontal_left_white_48.png | Bin 0 -> 176 bytes .../round_align_horizontal_right_white_18.png | Bin 0 -> 147 bytes .../round_align_horizontal_right_white_20.png | Bin 0 -> 163 bytes .../round_align_horizontal_right_white_24.png | Bin 0 -> 125 bytes .../round_align_horizontal_right_white_36.png | Bin 0 -> 174 bytes .../round_align_horizontal_right_white_48.png | Bin 0 -> 175 bytes .../round_align_horizontal_center_24.png | Bin 0 -> 213 bytes .../round_align_horizontal_left_24.png | Bin 0 -> 188 bytes .../round_align_horizontal_right_24.png | Bin 0 -> 187 bytes .../round_align_horizontal_center_24.png | Bin 0 -> 124 bytes .../round_align_horizontal_left_24.png | Bin 0 -> 124 bytes .../round_align_horizontal_right_24.png | Bin 0 -> 126 bytes .../round_align_horizontal_center_24.png | Bin 0 -> 176 bytes .../round_align_horizontal_left_24.png | Bin 0 -> 181 bytes .../round_align_horizontal_right_24.png | Bin 0 -> 179 bytes .../round_align_horizontal_center_24.png | Bin 0 -> 285 bytes .../round_align_horizontal_left_24.png | Bin 0 -> 274 bytes .../round_align_horizontal_right_24.png | Bin 0 -> 272 bytes .../round_align_horizontal_center_24.png | Bin 0 -> 329 bytes .../round_align_horizontal_left_24.png | Bin 0 -> 328 bytes .../round_align_horizontal_right_24.png | Bin 0 -> 331 bytes ...round_align_horizontal_center_white_18.png | Bin 0 -> 203 bytes ...round_align_horizontal_center_white_20.png | Bin 0 -> 216 bytes ...round_align_horizontal_center_white_24.png | Bin 0 -> 172 bytes ...round_align_horizontal_center_white_36.png | Bin 0 -> 245 bytes ...round_align_horizontal_center_white_48.png | Bin 0 -> 308 bytes .../round_align_horizontal_left_white_18.png | Bin 0 -> 174 bytes .../round_align_horizontal_left_white_20.png | Bin 0 -> 211 bytes .../round_align_horizontal_left_white_24.png | Bin 0 -> 176 bytes .../round_align_horizontal_left_white_36.png | Bin 0 -> 251 bytes .../round_align_horizontal_left_white_48.png | Bin 0 -> 312 bytes .../round_align_horizontal_right_white_18.png | Bin 0 -> 174 bytes .../round_align_horizontal_right_white_20.png | Bin 0 -> 216 bytes .../round_align_horizontal_right_white_24.png | Bin 0 -> 175 bytes .../round_align_horizontal_right_white_36.png | Bin 0 -> 253 bytes .../round_align_horizontal_right_white_48.png | Bin 0 -> 313 bytes ...round_align_horizontal_center_white_18.png | Bin 0 -> 292 bytes ...round_align_horizontal_center_white_20.png | Bin 0 -> 287 bytes ...round_align_horizontal_center_white_24.png | Bin 0 -> 245 bytes ...round_align_horizontal_center_white_36.png | Bin 0 -> 483 bytes ...round_align_horizontal_center_white_48.png | Bin 0 -> 464 bytes .../round_align_horizontal_left_white_18.png | Bin 0 -> 275 bytes .../round_align_horizontal_left_white_20.png | Bin 0 -> 254 bytes .../round_align_horizontal_left_white_24.png | Bin 0 -> 251 bytes .../round_align_horizontal_left_white_36.png | Bin 0 -> 448 bytes .../round_align_horizontal_left_white_48.png | Bin 0 -> 466 bytes .../round_align_horizontal_right_white_18.png | Bin 0 -> 275 bytes .../round_align_horizontal_right_white_20.png | Bin 0 -> 257 bytes .../round_align_horizontal_right_white_24.png | Bin 0 -> 253 bytes .../round_align_horizontal_right_white_36.png | Bin 0 -> 444 bytes .../round_align_horizontal_right_white_48.png | Bin 0 -> 466 bytes ...round_align_horizontal_center_white_18.png | Bin 0 -> 245 bytes ...round_align_horizontal_center_white_20.png | Bin 0 -> 366 bytes ...round_align_horizontal_center_white_24.png | Bin 0 -> 308 bytes ...round_align_horizontal_center_white_36.png | Bin 0 -> 464 bytes ...round_align_horizontal_center_white_48.png | Bin 0 -> 596 bytes .../round_align_horizontal_left_white_18.png | Bin 0 -> 251 bytes .../round_align_horizontal_left_white_20.png | Bin 0 -> 369 bytes .../round_align_horizontal_left_white_24.png | Bin 0 -> 312 bytes .../round_align_horizontal_left_white_36.png | Bin 0 -> 466 bytes .../round_align_horizontal_left_white_48.png | Bin 0 -> 592 bytes .../round_align_horizontal_right_white_18.png | Bin 0 -> 253 bytes .../round_align_horizontal_right_white_20.png | Bin 0 -> 367 bytes .../round_align_horizontal_right_white_24.png | Bin 0 -> 313 bytes .../round_align_horizontal_right_white_36.png | Bin 0 -> 466 bytes .../round_align_horizontal_right_white_48.png | Bin 0 -> 588 bytes .../round_align_horizontal_center_24.xml | 10 ++++ .../round_align_horizontal_left_24.xml | 11 +++++ .../round_align_horizontal_right_24.xml | 11 +++++ app/src/main/res/layout/fragment_app_main.xml | 2 + .../main/res/layout/fragment_tab_layout.xml | 3 +- .../main/res/layout/left_aligned_widget.xml | 2 +- .../res/layout/left_aligned_widget_sans.xml | 34 +++++++++----- app/src/main/res/layout/the_widget_sans.xml | 21 +++++++-- 107 files changed, 138 insertions(+), 58 deletions(-) create mode 100644 app/src/main/res/drawable-hdpi/round_align_horizontal_center_white_18.png create mode 100644 app/src/main/res/drawable-hdpi/round_align_horizontal_center_white_20.png create mode 100644 app/src/main/res/drawable-hdpi/round_align_horizontal_center_white_24.png create mode 100644 app/src/main/res/drawable-hdpi/round_align_horizontal_center_white_36.png create mode 100644 app/src/main/res/drawable-hdpi/round_align_horizontal_center_white_48.png create mode 100644 app/src/main/res/drawable-hdpi/round_align_horizontal_left_white_18.png create mode 100644 app/src/main/res/drawable-hdpi/round_align_horizontal_left_white_20.png create mode 100644 app/src/main/res/drawable-hdpi/round_align_horizontal_left_white_24.png create mode 100644 app/src/main/res/drawable-hdpi/round_align_horizontal_left_white_36.png create mode 100644 app/src/main/res/drawable-hdpi/round_align_horizontal_left_white_48.png create mode 100644 app/src/main/res/drawable-hdpi/round_align_horizontal_right_white_18.png create mode 100644 app/src/main/res/drawable-hdpi/round_align_horizontal_right_white_20.png create mode 100644 app/src/main/res/drawable-hdpi/round_align_horizontal_right_white_24.png create mode 100644 app/src/main/res/drawable-hdpi/round_align_horizontal_right_white_36.png create mode 100644 app/src/main/res/drawable-hdpi/round_align_horizontal_right_white_48.png create mode 100644 app/src/main/res/drawable-mdpi/round_align_horizontal_center_white_18.png create mode 100644 app/src/main/res/drawable-mdpi/round_align_horizontal_center_white_20.png create mode 100644 app/src/main/res/drawable-mdpi/round_align_horizontal_center_white_24.png create mode 100644 app/src/main/res/drawable-mdpi/round_align_horizontal_center_white_36.png create mode 100644 app/src/main/res/drawable-mdpi/round_align_horizontal_center_white_48.png create mode 100644 app/src/main/res/drawable-mdpi/round_align_horizontal_left_white_18.png create mode 100644 app/src/main/res/drawable-mdpi/round_align_horizontal_left_white_20.png create mode 100644 app/src/main/res/drawable-mdpi/round_align_horizontal_left_white_24.png create mode 100644 app/src/main/res/drawable-mdpi/round_align_horizontal_left_white_36.png create mode 100644 app/src/main/res/drawable-mdpi/round_align_horizontal_left_white_48.png create mode 100644 app/src/main/res/drawable-mdpi/round_align_horizontal_right_white_18.png create mode 100644 app/src/main/res/drawable-mdpi/round_align_horizontal_right_white_20.png create mode 100644 app/src/main/res/drawable-mdpi/round_align_horizontal_right_white_24.png create mode 100644 app/src/main/res/drawable-mdpi/round_align_horizontal_right_white_36.png create mode 100644 app/src/main/res/drawable-mdpi/round_align_horizontal_right_white_48.png create mode 100644 app/src/main/res/drawable-night-hdpi/round_align_horizontal_center_24.png create mode 100644 app/src/main/res/drawable-night-hdpi/round_align_horizontal_left_24.png create mode 100644 app/src/main/res/drawable-night-hdpi/round_align_horizontal_right_24.png create mode 100644 app/src/main/res/drawable-night-mdpi/round_align_horizontal_center_24.png create mode 100644 app/src/main/res/drawable-night-mdpi/round_align_horizontal_left_24.png create mode 100644 app/src/main/res/drawable-night-mdpi/round_align_horizontal_right_24.png create mode 100644 app/src/main/res/drawable-night-xhdpi/round_align_horizontal_center_24.png create mode 100644 app/src/main/res/drawable-night-xhdpi/round_align_horizontal_left_24.png create mode 100644 app/src/main/res/drawable-night-xhdpi/round_align_horizontal_right_24.png create mode 100644 app/src/main/res/drawable-night-xxhdpi/round_align_horizontal_center_24.png create mode 100644 app/src/main/res/drawable-night-xxhdpi/round_align_horizontal_left_24.png create mode 100644 app/src/main/res/drawable-night-xxhdpi/round_align_horizontal_right_24.png create mode 100644 app/src/main/res/drawable-night-xxxhdpi/round_align_horizontal_center_24.png create mode 100644 app/src/main/res/drawable-night-xxxhdpi/round_align_horizontal_left_24.png create mode 100644 app/src/main/res/drawable-night-xxxhdpi/round_align_horizontal_right_24.png create mode 100644 app/src/main/res/drawable-xhdpi/round_align_horizontal_center_white_18.png create mode 100644 app/src/main/res/drawable-xhdpi/round_align_horizontal_center_white_20.png create mode 100644 app/src/main/res/drawable-xhdpi/round_align_horizontal_center_white_24.png create mode 100644 app/src/main/res/drawable-xhdpi/round_align_horizontal_center_white_36.png create mode 100644 app/src/main/res/drawable-xhdpi/round_align_horizontal_center_white_48.png create mode 100644 app/src/main/res/drawable-xhdpi/round_align_horizontal_left_white_18.png create mode 100644 app/src/main/res/drawable-xhdpi/round_align_horizontal_left_white_20.png create mode 100644 app/src/main/res/drawable-xhdpi/round_align_horizontal_left_white_24.png create mode 100644 app/src/main/res/drawable-xhdpi/round_align_horizontal_left_white_36.png create mode 100644 app/src/main/res/drawable-xhdpi/round_align_horizontal_left_white_48.png create mode 100644 app/src/main/res/drawable-xhdpi/round_align_horizontal_right_white_18.png create mode 100644 app/src/main/res/drawable-xhdpi/round_align_horizontal_right_white_20.png create mode 100644 app/src/main/res/drawable-xhdpi/round_align_horizontal_right_white_24.png create mode 100644 app/src/main/res/drawable-xhdpi/round_align_horizontal_right_white_36.png create mode 100644 app/src/main/res/drawable-xhdpi/round_align_horizontal_right_white_48.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_align_horizontal_center_white_18.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_align_horizontal_center_white_20.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_align_horizontal_center_white_24.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_align_horizontal_center_white_36.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_align_horizontal_center_white_48.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_align_horizontal_left_white_18.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_align_horizontal_left_white_20.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_align_horizontal_left_white_24.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_align_horizontal_left_white_36.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_align_horizontal_left_white_48.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_align_horizontal_right_white_18.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_align_horizontal_right_white_20.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_align_horizontal_right_white_24.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_align_horizontal_right_white_36.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_align_horizontal_right_white_48.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_align_horizontal_center_white_18.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_align_horizontal_center_white_20.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_align_horizontal_center_white_24.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_align_horizontal_center_white_36.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_align_horizontal_center_white_48.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_align_horizontal_left_white_18.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_align_horizontal_left_white_20.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_align_horizontal_left_white_24.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_align_horizontal_left_white_36.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_align_horizontal_left_white_48.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_align_horizontal_right_white_18.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_align_horizontal_right_white_20.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_align_horizontal_right_white_24.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_align_horizontal_right_white_36.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_align_horizontal_right_white_48.png create mode 100644 app/src/main/res/drawable/round_align_horizontal_center_24.xml create mode 100644 app/src/main/res/drawable/round_align_horizontal_left_24.xml create mode 100644 app/src/main/res/drawable/round_align_horizontal_right_24.xml diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 64d3a40ba2006e5a13b25073a36fd41c7968e269..d6a67dcd8909d949c7a52a2af6a2933e2c76787e 100644 GIT binary patch delta 15 XcmbQqGLvP(3>LGr69+fWsbvHJFZl*n delta 15 XcmbQqGLvP(3>Hqk$?O~F)G`79C@BR4 diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/global/Constants.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/global/Constants.kt index a4eab88..fa36ce3 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/global/Constants.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/global/Constants.kt @@ -83,7 +83,7 @@ object Constants { enum class WidgetAlign(val rawValue: Int) { LEFT(0), - RIGHT(1), +// RIGHT(1), CENTER(2) } } \ No newline at end of file diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt index 048acf8..c890ea7 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt @@ -9,9 +9,11 @@ import android.provider.Settings import android.util.DisplayMetrics 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.LinearLayout import android.widget.RelativeLayout import androidx.core.content.ContextCompat import androidx.core.view.isVisible @@ -42,7 +44,8 @@ class MainFragment : Fragment() { companion object { fun newInstance() = MainFragment() - private var PREVIEW_BASE_HEIGHT: Int = if (Preferences.widgetAlign == Constants.WidgetAlign.CENTER.rawValue) 120 else 200 + private val PREVIEW_BASE_HEIGHT: Int + get() = if (Preferences.widgetAlign == Constants.WidgetAlign.CENTER.rawValue) 120 else 200 } private lateinit var viewModel: MainViewModel @@ -154,6 +157,10 @@ class MainFragment : Fragment() { viewModel.widgetAlign.observe(viewLifecycleOwner) { updatePreviewVisibility() + lifecycleScope.launch { + delay(350) + updateClock() + } } viewModel.showPreview.observe(viewLifecycleOwner) { @@ -252,6 +259,10 @@ class MainFragment : Fragment() { binding.widgetDetail.clockBottomMarginLarge.isVisible = Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.rawValue + // Align + binding.widgetDetail.timeContainer.layoutParams = (binding.widgetDetail.timeContainer.layoutParams as LinearLayout.LayoutParams).apply { + gravity = if (Preferences.widgetAlign == Constants.WidgetAlign.CENTER.rawValue) Gravity.CENTER_HORIZONTAL else Gravity.NO_GRAVITY + } } private fun updateClockVisibility(showClock: Boolean) { @@ -261,7 +272,7 @@ class MainFragment : Fragment() { updatePreviewVisibility() 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 } binding.widgetDetail.timeContainer.measure(0, 0) diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/LayoutFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/LayoutFragment.kt index 8df929f..2ba7cc2 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/LayoutFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/LayoutFragment.kt @@ -6,6 +6,7 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope @@ -98,9 +99,14 @@ class LayoutFragment : Fragment() { 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.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) } @@ -204,10 +210,6 @@ class LayoutFragment : Fragment() { 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() diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/viewmodels/MainViewModel.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/viewmodels/MainViewModel.kt index 915f85a..9d5562c 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/viewmodels/MainViewModel.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/viewmodels/MainViewModel.kt @@ -132,6 +132,7 @@ class MainViewModel(context: Application) : AndroidViewModel(context) { addSource(Preferences.asLiveData(Preferences::customFontName)) { value = true } addSource(Preferences.asLiveData(Preferences::customFontVariant)) { 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::secondRowTopMargin)) { value = true } addSource(Preferences.asLiveData(Preferences::isDateCapitalize)) { value = true } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt index 7a28fc2..a1255c1 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt @@ -7,6 +7,7 @@ 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 @@ -16,6 +17,7 @@ import android.widget.RemoteViews import android.widget.TextView 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 @@ -127,7 +129,7 @@ class LeftAlignedWidget(val context: Context) { PendingIntent.FLAG_UPDATE_CURRENT ) views.setOnClickPendingIntent(R.id.date_rect, calPIntent) - views.setViewVisibility(R.id.date_layout, View.VISIBLE) + views.setViewVisibility(R.id.first_line_rect, View.VISIBLE) val nextEvent = eventRepository.getNextEvent() val nextAlarm = AlarmHelper.getNextAlarm(context) @@ -184,7 +186,7 @@ class LeftAlignedWidget(val context: Context) { views.setViewVisibility(R.id.next_event_rect, View.VISIBLE) // Event time difference - if (Preferences.showDiffTime && Calendar.getInstance().timeInMillis < (nextEvent.startDate - 1000 * 60 * 60)) { + if (Preferences.showDiffTime && Calendar.getInstance().timeInMillis < nextEvent.startDate) { views.setImageViewBitmap( R.id.next_event_difference_time_rect, BitmapHelper.getBitmapFromView( @@ -192,8 +194,9 @@ class LeftAlignedWidget(val context: Context) { draw = false ) ) - views.setViewVisibility(R.id.next_event_difference_time_rect, View.VISIBLE) + 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) } @@ -227,12 +230,14 @@ class LeftAlignedWidget(val context: Context) { ) views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE) - // Second row - views.setImageViewBitmap( - R.id.sub_line_rect, - BitmapHelper.getBitmapFromView(bindingView.subLine, 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) + + 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) && bindingView.calendarLayout.isVisible) { var showSomething = false loop@ for (provider: Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders(context)) { @@ -354,15 +359,11 @@ class LeftAlignedWidget(val context: Context) { 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.calendar_layout_rect, View.GONE) + 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 @@ -371,6 +372,12 @@ class LeftAlignedWidget(val context: Context) { 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) @@ -542,12 +549,9 @@ class LeftAlignedWidget(val context: Context) { 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 + 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 diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/MainWidget.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/MainWidget.kt index adb1dcc..ef013d5 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/MainWidget.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/MainWidget.kt @@ -99,7 +99,6 @@ class MainWidget : AppWidgetProvider() { WidgetHelper.runWithCustomTypeface(context) { val views = when (Preferences.widgetAlign) { Constants.WidgetAlign.LEFT.rawValue -> LeftAlignedWidget(context).generateWidget(appWidgetId, min(dimensions.first - 8.toPixel(context), min(width, height) - 16.toPixel(context)), it) - Constants.WidgetAlign.RIGHT.rawValue -> LeftAlignedWidget(context).generateWidget(appWidgetId, min(dimensions.first - 8.toPixel(context), min(width, height) - 16.toPixel(context)), it) else -> StandardWidget(context).generateWidget(appWidgetId, min(dimensions.first - 8.toPixel(context), min(width, height) - 16.toPixel(context)), it) } appWidgetManager.updateAppWidget(appWidgetId, views) @@ -109,7 +108,6 @@ class MainWidget : AppWidgetProvider() { fun getWidgetView(context: Context, typeface: Typeface?): ViewBinding { return when (Preferences.widgetAlign) { Constants.WidgetAlign.LEFT.rawValue -> LeftAlignedWidget(context).generateWidgetView(typeface) - Constants.WidgetAlign.RIGHT.rawValue -> LeftAlignedWidget(context).generateWidgetView(typeface) else -> StandardWidget(context).generateWidgetView(typeface) } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt index 1901107..3503207 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt @@ -129,7 +129,13 @@ class StandardWidget(val context: Context) { PendingIntent.FLAG_UPDATE_CURRENT ) views.setOnClickPendingIntent(R.id.date_rect, calPIntent) - views.setViewVisibility(R.id.date_layout, View.VISIBLE) + 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 nextEvent = eventRepository.getNextEvent() val nextAlarm = AlarmHelper.getNextAlarm(context) @@ -207,7 +213,7 @@ class StandardWidget(val context: Context) { views.setViewVisibility(R.id.next_event_rect, View.VISIBLE) // Event time difference - if (Preferences.showDiffTime && Calendar.getInstance().timeInMillis < (nextEvent.startDate - 1000 * 60 * 60)) { + if (Preferences.showDiffTime && Calendar.getInstance().timeInMillis < nextEvent.startDate) { views.setImageViewBitmap( R.id.next_event_difference_time_rect, BitmapHelper.getBitmapFromView( @@ -249,13 +255,11 @@ class StandardWidget(val context: Context) { BitmapHelper.getBitmapFromView(bindingView.nextEvent, draw = false) ) views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE) - - // Second row - views.setImageViewBitmap( - R.id.sub_line_rect, - BitmapHelper.getBitmapFromView(bindingView.subLine, draw = false) - ) 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) && bindingView.calendarLayout.isVisible) { var showSomething = false loop@ for (provider: Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders(context)) { @@ -383,9 +387,9 @@ class StandardWidget(val context: Context) { ) views.setViewVisibility(R.id.first_line_rect, View.VISIBLE) - views.setViewVisibility(R.id.calendar_layout_rect, View.GONE) 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 diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/utils/Extensions.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/utils/Extensions.kt index 707f29b..8d7fc41 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/utils/Extensions.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/utils/Extensions.kt @@ -21,7 +21,9 @@ import android.content.res.Resources import android.graphics.drawable.Drawable import android.util.DisplayMetrics import android.util.TypedValue +import android.view.animation.AlphaAnimation import android.widget.RelativeLayout +import androidx.annotation.UiThread import androidx.browser.customtabs.CustomTabColorSchemeParams import androidx.core.animation.addListener import androidx.core.view.isVisible @@ -262,4 +264,4 @@ fun View.setOnSingleClickListener(l: View.OnClickListener) { fun View.setOnSingleClickListener(l: (View) -> Unit) { setOnClickListener(OnSingleClickListener(l)) -} \ No newline at end of file +} diff --git a/app/src/main/res/drawable-hdpi/round_align_horizontal_center_white_18.png b/app/src/main/res/drawable-hdpi/round_align_horizontal_center_white_18.png new file mode 100644 index 0000000000000000000000000000000000000000..264233dac1d90d055c3c2d2cfbea101e4263df4c GIT binary patch literal 207 zcmV;=05JcFP)I@OwK@h>l*7d9d8NkxQ0i41utZkl+O@fI=6!g39xCi$y#3w|_KpBoH zK!sx(&>zEy$qnm)-txsZRIzZbh04S_uBkJzmh}R((%NZeG=`19X!){#&TS7)s1ItZ zNqkVs?C9Z4>c$FB^9wf?F*%@#$X}g2*h%^Cdwc4a-1}UwXags_UVOr1f|dXP002ov JPDHLkV1hKmStI}e literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_align_horizontal_center_white_20.png b/app/src/main/res/drawable-hdpi/round_align_horizontal_center_white_20.png new file mode 100644 index 0000000000000000000000000000000000000000..a804e134b6e9fad9bb6b941819678cd3ec6835e6 GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^av;pX0wgC|rfCAHnVv3=Ar`0KPT9-ZU?9+%t8Qt&!n{PHJ_cuySsZes+O);`F@cm!%N!;#s&Mh zg(ojwlf{rRC(mz>oBO$}k^-Z38k-XvEqkR}tarFvjy7d5u!!yb)1T5QQZk$SwMO5C zNtxFdbzb7%9@idiuVZ^WiBDE-;jNmUt|$JJ3NHTE_`;mcW~#huO(k2#6`&&-JYD@< J);T3K0RX}OPB#Dm literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_align_horizontal_center_white_24.png b/app/src/main/res/drawable-hdpi/round_align_horizontal_center_white_24.png new file mode 100644 index 0000000000000000000000000000000000000000..3a36a32c71e18378302f7e8970aa5173b3a82319 GIT binary patch literal 203 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8LpBu^K|5Rc<;ukGe-P+)KkjCJ8s zPY^aUoEDa&puCgG)>%M(2Ok4t2$#K$*QDSBk1v=0=T+uAULhaF5b@4gis9~pRRT?t zvOT;Fx<3lI>|Jqf@p0#?^WH?w@A&?VVNtE__5cB{Z$Q^Ec)I$ztaD0e0svSI BMb-cS literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_align_horizontal_center_white_36.png b/app/src/main/res/drawable-hdpi/round_align_horizontal_center_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..6ad39c5e360633678eedc990e0bda6c04aedd34d GIT binary patch literal 292 zcmV+<0o(qGP)+B*R|;{DeZft zQDpgpkg#P-5`v1k0B|9m9?Q8WpB}3QtTN0n!_>>ARKnN~*j}8MK8Kbx_)5c4#?JW6 zS>8b3dAylyyki@weY9SwR%}BQbl#|r;@Nqe<2VZAG%R)!=Q-w9t_(Bm>o8XAUcS^j zR_{;;`cVa{=b)w5BdHs=)?u}({MI_msW7L*7K(P$vCw|Ca%3}YDc?DdGqRU|j7%&X6WBdAhso~xx;jrb%5;12CZ$uoDyptiZ#k&)gxqp4lHjalPoJ zt#AMR|6kAh^42%ztylRKbN{FQ(|*us6S3uQ`rrB=_H`c~*E1|Ld;GuUpqfu^%>R6$ z3t!&XYl-du`}|M--}{XGA+ozZwjIqs_Fs}S0&BCO7fR17CboFyt=akR{00BcpGXMYp literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_align_horizontal_left_white_24.png b/app/src/main/res/drawable-hdpi/round_align_horizontal_left_white_24.png new file mode 100644 index 0000000000000000000000000000000000000000..c7ee41b43f83b854f4cb69437bf1aaac0bb91dc5 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8si%u$h{y4_*EaGVP~dS13`-I= z^Kw0%bFW2-_pZM@=Z1+(T{;%m_nvp)*xi1{_gjP11seqhzAua}kAmizG-yNw{R%L3 z+{)j{Imu3hcZz_&;`S!C$MyWxOr5*xgjcK*Pht}N+NBq-{PN3-@Cmmkzx~>I!;n9T XLFC~%1;y7u2QYZL`njxgN@xNA^~yYW literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_align_horizontal_left_white_36.png b/app/src/main/res/drawable-hdpi/round_align_horizontal_left_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..3fa79acff23f6cfb75a743e71a0bfb7fce38cfdb GIT binary patch literal 275 zcmV+u0qp*XP)Py5XNz6?5(iUmXI)l!4Y%<1|TFbfT6K<0edHM025k6w5Rx6XzxAl{E^n4I0@mlKOI3VL+uDMT0v1Nsak z60F2eN(okZ!YT=tF?ygzGFgE%YHp;Fmwrl3H~H11)@=P<8p`JWw-zU002ovPDHLkV1fc9bbbH; literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_align_horizontal_left_white_48.png b/app/src/main/res/drawable-hdpi/round_align_horizontal_left_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..5bd216f1d8cf67a96efd020b6aadfe7291dcc71e GIT binary patch literal 251 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhaw4tcsbhGg7(duuOmvw?_fBA2m| z9OJb`?mdjm7Xo8fxnxe_m?M7I;y=6Nb@kh(tAlqj1YKIO;+Xi7V~Y}@*n;mumAJlLw%S}?(BcUY{zEY3i|(F zdBMwP^?EsV!GGU3ut)uWF2f?|z?%DC^1t-thui;qckp?N#|IUr&q~k m=}AS2{44t2C$x8Jurcr%rW6zxmaGE0hQZU-&t;ucLK6UNBu~%) literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_align_horizontal_right_white_20.png b/app/src/main/res/drawable-hdpi/round_align_horizontal_right_white_20.png new file mode 100644 index 0000000000000000000000000000000000000000..f19c9394c8afe44b7ad83109f9175bd54298144b GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^av;pX0wgC|rfCAH7Ec$)5R21quh{cB7>FD%oZad? z<1AaI$~k47vO-4jBGrvM8rIL9p0&EI>;7ze=imQa0v#4EP%b;FePLHpgJF%2m+RWK zT_HzObnc`pPA=$=tm4!zW8Ss+iTQM%o?B8H`>&?=&uBUJ^YDzdQKg4wADs~MA;oYW o)A?TU$MTcP{ohYs{9cn?n|c1~xne;Rf$m}OboFyt=akR{034P{z5oCK literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_align_horizontal_right_white_24.png b/app/src/main/res/drawable-hdpi/round_align_horizontal_right_white_24.png new file mode 100644 index 0000000000000000000000000000000000000000..33bcf6e04d23ef94864ac9d37fa15ded767a39f1 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8si%u$h{y4_*EaGVP~dU7xaNpj z&XlfcH}`P5O6{7@%J6gox5&>I@rNagVxJ&U*hNH!B%6 XwL~5sP-JNaI)K5`)z4*}Q$iB}AuK!F literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_align_horizontal_right_white_36.png b/app/src/main/res/drawable-hdpi/round_align_horizontal_right_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..4298f7fe20c7f33f9a86125e6e77665b0e0c829e GIT binary patch literal 275 zcmV+u0qp*XP)ohyL$s&(EsP0`uz_(Bl6hNh z@inuvlkq%@r4#m)Y;>qI08iE$*o#j}4eXoBFvAS%T>HfAMxPkp86%-)T51v}jDUve zX$V}f6q%$hSSEyJE?7h>K($0}1yW4rS_=2l56P)UpPbM-h+&4!1Y^O0qspUZ#ZA0j z{lu=~jkpJU2!AoX*j@PZ?8Q#PW5GZzUPK3;L2$`daFnxlWtd?z#8j6qn(HLhMVaMK Zc>{bU<8q3F%LD)b002ovPDHLkV1g1Oa!~*P literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_align_horizontal_right_white_48.png b/app/src/main/res/drawable-hdpi/round_align_horizontal_right_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..cd08e6e2d8e7acee84abc3d6edfb265bedbc64a5 GIT binary patch literal 253 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhawj(EB_hGg7(dut?>nLnOL+r=Py_<^v3 z%ZHeZH`yDQPX52B5$67X`jK@X`?_3QRP(-=Hm{an^LB{Ts5!mlo! literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_align_horizontal_center_white_36.png b/app/src/main/res/drawable-mdpi/round_align_horizontal_center_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..3a36a32c71e18378302f7e8970aa5173b3a82319 GIT binary patch literal 203 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8LpBu^K|5Rc<;ukGe-P+)KkjCJ8s zPY^aUoEDa&puCgG)>%M(2Ok4t2$#K$*QDSBk1v=0=T+uAULhaF5b@4gis9~pRRT?t zvOT;Fx<3lI>|Jqf@p0#?^WH?w@A&?VVNtE__5cB{Z$Q^Ec)I$ztaD0e0svSI BMb-cS literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_align_horizontal_center_white_48.png b/app/src/main/res/drawable-mdpi/round_align_horizontal_center_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..1fe59df922ab3e4ad1a0427851ef2a41b26e1e59 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0DVow*xkch)?uOH+*pdjFKan72v z=eGE{-u|)k$t%al3Y^BgHaAkmzU`Xh-|DecsMLXR!HWiUHl9C{3KL%J@l+Q)=8)$8 zNg^YVAa#Bxwhy W>Cet6@9YO!&*16m=d#Wzp$Py!HbYwg literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_align_horizontal_left_white_18.png b/app/src/main/res/drawable-mdpi/round_align_horizontal_left_white_18.png new file mode 100644 index 0000000000000000000000000000000000000000..19785fb63294884603d7bc203d1ad162acc2b6d8 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mLOop^Lp07OCn)g!nf_DWDgTe~DWM4fArUx| literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_align_horizontal_left_white_20.png b/app/src/main/res/drawable-mdpi/round_align_horizontal_left_white_20.png new file mode 100644 index 0000000000000000000000000000000000000000..f01c184d242bc056f860dd9d06cf5fc90e80c47e GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc0wmQNuC@WGG*1`D5RLQ62?}z5(*NcEoIg{d z_1*vf|I5|g5;+1AIdnz-J^!)3L6mEuw#`R*>mT3ZWkVm@%5eSvYwjAV@zefSy^UCg zS9Sd2sNAmThqi0t4lMe>a?L?e;(^nbj_gH~B{ymWDax){k`_3NiQ%Ep W)349lKgIwJWAJqKb6Mw<&;$U)PcJ+G literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_align_horizontal_left_white_36.png b/app/src/main/res/drawable-mdpi/round_align_horizontal_left_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..c7ee41b43f83b854f4cb69437bf1aaac0bb91dc5 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8si%u$h{y4_*EaGVP~dS13`-I= z^Kw0%bFW2-_pZM@=Z1+(T{;%m_nvp)*xi1{_gjP11seqhzAua}kAmizG-yNw{R%L3 z+{)j{Imu3hcZz_&;`S!C$MyWxOr5*xgjcK*Pht}N+NBq-{PN3-@Cmmkzx~>I!;n9T XLFC~%1;y7u2QYZL`njxgN@xNA^~yYW literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_align_horizontal_left_white_48.png b/app/src/main/res/drawable-mdpi/round_align_horizontal_left_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..4cdacfa6eacc2fba9f5af6809a03b16fad0b87c1 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0Da!(h>kch)?uOH+*pdjE9=zlFO zJu1Cv+s9(gCqe;J6rIwfDmI+f$>BI>rdU`sspJ6TfrZTPBn%QBFm|L!8E2*>$!n}x z@}+SX%N1URpB-1c%P#UrNNC-vUf9-XR4LTfXjOUT8{-q@ApM)J#vi;L{;{mOAMt#1 ZOoiX{XAd_ey#_jg!PC{xWt~$(69A20L5TnW literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_align_horizontal_right_white_18.png b/app/src/main/res/drawable-mdpi/round_align_horizontal_right_white_18.png new file mode 100644 index 0000000000000000000000000000000000000000..1df81b4c5bdc6dda613fc9cf059e72de4f40bd42 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mqC8z3Lp07OCoGWp!~a*`IpX5` z|E4XXfB(n(?^*O;>;LvY_xl;Q{|R>t3;7^#t>F-Mwo)?zbsI36}4z?5aUxfZ|d~a5@2BXTRL}5|E({TKwB6*UHx3vIVCg!03@?IHvj+t literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_align_horizontal_right_white_20.png b/app/src/main/res/drawable-mdpi/round_align_horizontal_right_white_20.png new file mode 100644 index 0000000000000000000000000000000000000000..41314d0c419cf06c9a19a32916caa520e18703ac GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc0wmQNuC@WGEKe855RLQ62@Ax2od0wGlfAJa z*WLgB|G)R^IV7;)kU)^=Kk;Ad8$^p1X#83K@Bi)kHxF1=IbHt$zd&P8d*0TU|0{G1 ze(hJ;IZx49u}iriy7%GQ>K!7B*spNj3FCgqS#ayutVt&F*)`5!Jjc@HZ_1gczMZkVuqBg;qiSGNpgnxw%}%^MU3uc)I$ztaD0e0szPIF023m literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_align_horizontal_right_white_36.png b/app/src/main/res/drawable-mdpi/round_align_horizontal_right_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..33bcf6e04d23ef94864ac9d37fa15ded767a39f1 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8si%u$h{y4_*EaGVP~dU7xaNpj z&XlfcH}`P5O6{7@%J6gox5&>I@rNagVxJ&U*hNH!B%6 XwL~5sP-JNaI)K5`)z4*}Q$iB}AuK!F literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_align_horizontal_right_white_48.png b/app/src/main/res/drawable-mdpi/round_align_horizontal_right_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..cf318945e79d4836e37e23c753a76c3e6e6fcd53 GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0DGEW!Bkch)?uOH+*pdjE9=zlFO zJ!<))+&?izeSw>gw9MRXb0bx(#P4S;hX~g}z7q^7)(?6Z7~@$!xJVgiy41*ftWo*e zxQpcqFT-cSNc~7xVTA{e9QQY5yY8-Zx?~d|Z&mi5@tN|bxJ_MZ4hQE}E Y!)*Gq8CtjefG%M0boFyt=akR{05wlOPyhe` literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-night-hdpi/round_align_horizontal_center_24.png b/app/src/main/res/drawable-night-hdpi/round_align_horizontal_center_24.png new file mode 100644 index 0000000000000000000000000000000000000000..48c3e74a59e3600760d59fdb8c0167341cbdc31d GIT binary patch literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8Lp98VX=kcwMxuXzhLD2TKsu1#QY z-cg>&Jn2Qmft{Qu5`?ucxadB}XDDz;eb{_>(#-tB51pp{H5b{kMdbTJDaRG>oq3xs zsAy=pc=ktRrz9nny!kREFYRHD7`yB7sU>Dh^c+vM6`8!&OmSWARL8gI&<0t#Uu_Gy zntQf8s`1R)dqIXRQ(xp-Mv=(jhZ2%9-?c?QWd>|fx4x$SXzxu%+hG2)TXRw;1Kr8s M>FVdQ&MBb@0GrrQi~s-t literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-night-hdpi/round_align_horizontal_left_24.png b/app/src/main/res/drawable-night-hdpi/round_align_horizontal_left_24.png new file mode 100644 index 0000000000000000000000000000000000000000..47745139ed33012c407bb77c510796acc4e8ee6c GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8v!{z=NX4zU*UoYtP~c$;*gZ*m zN5f|k5%q#?Igi-tmVVL5RAON<+*w&M{m;ug?;0DV4>Eaac!&j5es|k0wldT1B8K8lc$SgNX4zU*A8+XP~c$=*gZ*m zN5f|k5%q#?Igi->1yz}Dn<%s7$#ac8-JVx0Pit^k2%0QtX zGv_ho{eS!4|3CfwfBxKWTlMgBz0(8ZR5PCTgrkp3YwjHt+%bP;`r!hOFs@A+qKphN X2XB;0pWsLU8pq)2>gTe~DWM4ffMzU= literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-night-mdpi/round_align_horizontal_left_24.png b/app/src/main/res/drawable-night-mdpi/round_align_horizontal_left_24.png new file mode 100644 index 0000000000000000000000000000000000000000..ff42ba088c35bed5231bd150b640dd136e264246 GIT binary patch literal 124 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1XHOT$kcwN$2@AM?$p5vUWx~t* zU%IWk?SJn7`hUk+>;B~*zVhLxz1@eIMbd4l8bP0l+XkKkSZ;8 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-night-mdpi/round_align_horizontal_right_24.png b/app/src/main/res/drawable-night-mdpi/round_align_horizontal_right_24.png new file mode 100644 index 0000000000000000000000000000000000000000..16d5034d51d542cbb708c066d98eddcdcf0a35e2 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1S5FtmkcwN$2@)m`>c9NYxMX7T zCtu=>)W7Y2|NoR1|M7D_Z}8#g|9>1vKb0%Ncd$#TQI4U-rdPGYKKOduLxD9Rrx&F# ZGjxSqYP==euL3lX!PC{xWt~$(697z2FAD$w literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-night-xhdpi/round_align_horizontal_center_24.png b/app/src/main/res/drawable-night-xhdpi/round_align_horizontal_center_24.png new file mode 100644 index 0000000000000000000000000000000000000000..aa4e2b45787d5145620643f5312a9fdc7836768c GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0Da!(h>kcwMxuW#f%puof8pkb^@O4>-Y-3b=>d{yU4<^;up)N{TsPd Z&CjPK`7m2a?E*T1!PC{xWt~$(69CA{K!yMS literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-night-xhdpi/round_align_horizontal_left_24.png b/app/src/main/res/drawable-night-xhdpi/round_align_horizontal_left_24.png new file mode 100644 index 0000000000000000000000000000000000000000..8a8570f696c5f938c7091069b2109b77f1aef01a GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0D8c!F;kcwMxuW#f$V8FxT5Pt6n zcNWw1Pm7`+2QTpu-Y~H;>BN3^iwPBt-hq9bQao+Pn0aJnk1_xH%fcb>fnh}fixH>A zD;bF!o#z{GFg;>8a8o%+KhjlLAz@|4`_?Enw@)fM%oA<0o->@26RbX|HLD?>>5IR@ eZ|T)F)3~R+_o}%N=5QY94hBzGKbLh*2~7YffImq9 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-night-xhdpi/round_align_horizontal_right_24.png b/app/src/main/res/drawable-night-xhdpi/round_align_horizontal_right_24.png new file mode 100644 index 0000000000000000000000000000000000000000..b070723e4076a764a93669cf5c13e1e84494fe44 GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0DDo+>3kcwMxuW#gSFyLW15OPz6 zyQ*nQTHyMRB41dN;#j`Sx3W4pO?Rir({jh=gBL0q7A`(q;b1?Hfia#X;33Bul?N-5 z6P(rT*pyh0Fg0xUK9aYI&9|XpGXG=7GrYHs>c0N$V6)}TJ?1&FN@bHxGniP`RIqG1 dAMv!T?4y-e&FYq8(}1pE@O1TaS?83{1OTS(LTdm3 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-night-xxhdpi/round_align_horizontal_center_24.png b/app/src/main/res/drawable-night-xxhdpi/round_align_horizontal_center_24.png new file mode 100644 index 0000000000000000000000000000000000000000..94806cdb6bdef10bc37fdd1c118c0c28e21eb175 GIT binary patch literal 285 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~dVo)eE0F$A1XyS5WeHTuTN30K z%)sJOQry5?e&*-@1D}0<`KACRW_Y?dhE&{odn22RS&@e&Ve*?f zjY*8XJSGL|hwcmhyV|Als>9d2;{xA>J4_vMYi*5fi-gbBHz}DW7Dp!>@MGD%`2W7B wiR(*`#3{REB%fGT{N_ueLe{dN8S2kiT^f`tV}v?ffNo^)boFyt=akR{0ELl(N&o-= literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-night-xxhdpi/round_align_horizontal_left_24.png b/app/src/main/res/drawable-night-xxhdpi/round_align_horizontal_left_24.png new file mode 100644 index 0000000000000000000000000000000000000000..0ed8123a2635ac0b483d37ac4168abd81bb6ef8d GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xZ3?!EyURMI7)B}7%T!Hj|BEULZFH4|O-jX1{ zU?u^9P09MZsyeH;^mdS z)a53+G4xDSD`VI;^#vNI;#x&>oC8BzV=oqoxW?WPUF#57!nJ#m>5*A3H++};?h|yk z;9b4MXqKSBM=s`yNvF)-bgjB@Ns8xz=RWNRn<|VBNfr4XDiLPgm+Zp3{NZFSH_@4G kZ2>DkDx|DAVbH|Lkfknt>vE|~9nfJ6p00i_>zopr038^3oB#j- literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-night-xxhdpi/round_align_horizontal_right_24.png b/app/src/main/res/drawable-night-xxhdpi/round_align_horizontal_right_24.png new file mode 100644 index 0000000000000000000000000000000000000000..6c9e01288ec228a7e2c17e876172757916c8cdb6 GIT binary patch literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xZ3?!EyURMI7)B}7%T!Hj|BEULZFH4|O-jX1{ zU?u^9P09MZsyeH;^mb+ z)8!_*G4xDSD`VI;^#vNI;#x&>oC8BzV=oqoxW?WPUF#57!nJ#m>5*A3H++};?h|yk z;GMn1XcfmqWe)cOvv*6H7(#al%QBTb^xMZ#z-6jDAzNtK>=PelmE3#Q^cbu4*2kCEaH-czgEjmlwSA59kpFPgg&ebxsLQ0I(35RR910 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-night-xxxhdpi/round_align_horizontal_left_24.png b/app/src/main/res/drawable-night-xxxhdpi/round_align_horizontal_left_24.png new file mode 100644 index 0000000000000000000000000000000000000000..337f90bc8a17956ac5d46e66fe608259f010e2e4 GIT binary patch literal 328 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeE3?v1%WpM*3-2k5uS0MeLXt2;@^=zO9{*oZS zU0q|D^6|x3&1+?O*+{+t}a-&z+Cnik{6<8?rrbpVMBv iX(Gen2~3L_81B4_pC)^F|8$@?7(8A5T-G@yGywp92#s0* literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-night-xxxhdpi/round_align_horizontal_right_24.png b/app/src/main/res/drawable-night-xxxhdpi/round_align_horizontal_right_24.png new file mode 100644 index 0000000000000000000000000000000000000000..55402353b94cedbbb33473432e976a0b3eefb46d GIT binary patch literal 331 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeE3?v1%WpM*3-2k5uS0MeLXt2;@^=zO9{*oZS zUgN+K>NqF#t|Fa8)chit2b`f zygqsFIvwe2r>`}yY5pZp&ENKQ&EF3<#95C1zh1u~_dQ?Sx9F97ZcX9PIkSyJ=1dmL zwKQv%H&Yu9#5XMS&$pJf)mSD{vfKK?vJLIbu{`Jacno(~7#w@h#aOTM@6w;mpX87C zx3OioF){g`XInAjkl@#?AB8@Yew_7@_oLG1UgI!T=06jEcz-^Bs$RxkYL*2fW7Wso o${S2p+gDefT^%~J*7p_Xo1^j5=3Hed2l|A;)78&qol`;+04vg|k0wldT1B8LpBu^K|5Rc<;ukGe-P+)KkjCJ8s zPY^aUoEDa&puCgG)>%M(2Ok4t2$#K$*QDSBk1v=0=T+uAULhaF5b@4gis9~pRRT?t zvOT;Fx<3lI>|Jqf@p0#?^WH?w@A&?VVNtE__5cB{Z$Q^Ec)I$ztaD0e0svSI BMb-cS literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_align_horizontal_center_white_20.png b/app/src/main/res/drawable-xhdpi/round_align_horizontal_center_white_20.png new file mode 100644 index 0000000000000000000000000000000000000000..53577be53eb7473c049200d448e1f1538c6df46f GIT binary patch literal 216 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU0wmSG7d!(}^F3W0Lp+YZy|$3I)j*^*u_>Lg z?U2C%W1irvq91w=ahU1^^!}A>xcnsO7thY+n@%qG^S@OpC(6duxKLJtf#dA~-iEUW z^&5K5{5f)y@y64;XCfY{`DGOuWf}y|UUD#oH;wmLmO<8r^u(#p86Ifd(fbmY!~UK% zXlrGVSn|=uvS;+=?sU)eD7#>kvh<>n@7vmh)0mdKI;Vst0OVv?mH+?% literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_align_horizontal_center_white_24.png b/app/src/main/res/drawable-xhdpi/round_align_horizontal_center_white_24.png new file mode 100644 index 0000000000000000000000000000000000000000..1fe59df922ab3e4ad1a0427851ef2a41b26e1e59 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0DVow*xkch)?uOH+*pdjFKan72v z=eGE{-u|)k$t%al3Y^BgHaAkmzU`Xh-|DecsMLXR!HWiUHl9C{3KL%J@l+Q)=8)$8 zNg^YVAa#Bxwhy W>Cet6@9YO!&*16m=d#Wzp$Py!HbYwg literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_align_horizontal_center_white_36.png b/app/src/main/res/drawable-xhdpi/round_align_horizontal_center_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..6261b302605b26eecc4353e628c83445715bb195 GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhaw_ISEDhGg7(duuOmvw?_fBA0|@ zKSTD;?Gnsv1@5K6s$QazU7t&m=NcbWe==YFVWyJO?=2aZmwL|@j7%&X6WBdAhso~xx;jrb%5;12CZ$uoDyptiZ#k&)gxqp4*KFFU=XL&u6i_@9S&vS{rGkUCFSKbLh*2~7a@(sbbf literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_align_horizontal_left_white_18.png b/app/src/main/res/drawable-xhdpi/round_align_horizontal_left_white_18.png new file mode 100644 index 0000000000000000000000000000000000000000..c7ee41b43f83b854f4cb69437bf1aaac0bb91dc5 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8si%u$h{y4_*EaGVP~dS13`-I= z^Kw0%bFW2-_pZM@=Z1+(T{;%m_nvp)*xi1{_gjP11seqhzAua}kAmizG-yNw{R%L3 z+{)j{Imu3hcZz_&;`S!C$MyWxOr5*xgjcK*Pht}N+NBq-{PN3-@Cmmkzx~>I!;n9T XLFC~%1;y7u2QYZL`njxgN@xNA^~yYW literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_align_horizontal_left_white_20.png b/app/src/main/res/drawable-xhdpi/round_align_horizontal_left_white_20.png new file mode 100644 index 0000000000000000000000000000000000000000..e6b495235630129cf8ffd69ed10c0a35e6780b05 GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU0wmSG7d!(}vpiiKLp+YZy{66AU?9K}&~zw4 zFosn}>@cIjoYs(s976Y{4@zFJFsf1UHQODqeePF(U-e$4wT@iHv9I_|b|n94{KlBe zVA^=%;)2xp))tn);;PsIG&N!&@gaok1S9=6_E2)AyRs~5>J7^ z)ESIH literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_align_horizontal_left_white_24.png b/app/src/main/res/drawable-xhdpi/round_align_horizontal_left_white_24.png new file mode 100644 index 0000000000000000000000000000000000000000..4cdacfa6eacc2fba9f5af6809a03b16fad0b87c1 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0Da!(h>kch)?uOH+*pdjE9=zlFO zJu1Cv+s9(gCqe;J6rIwfDmI+f$>BI>rdU`sspJ6TfrZTPBn%QBFm|L!8E2*>$!n}x z@}+SX%N1URpB-1c%P#UrNNC-vUf9-XR4LTfXjOUT8{-q@ApM)J#vi;L{;{mOAMt#1 ZOoiX{XAd_ey#_jg!PC{xWt~$(69A20L5TnW literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_align_horizontal_left_white_36.png b/app/src/main/res/drawable-xhdpi/round_align_horizontal_left_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..5bd216f1d8cf67a96efd020b6aadfe7291dcc71e GIT binary patch literal 251 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhaw4tcsbhGg7(duuOmvw?_fBA2m| z9OJb`?mdjm7Xo8fxnxe_m?M7I;y=6Nb@kh(tAlqj1YKIO;+Xi7GpEDiy8=%7}oU4&A9N#*zqL)3A3d>%m4I- zlmyN9+ria3J#^QnhCSTT$(0WGmL3&7@HY>)A=6oJ@^tlcS?83{1ONsicKHAR literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_align_horizontal_right_white_18.png b/app/src/main/res/drawable-xhdpi/round_align_horizontal_right_white_18.png new file mode 100644 index 0000000000000000000000000000000000000000..33bcf6e04d23ef94864ac9d37fa15ded767a39f1 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8si%u$h{y4_*EaGVP~dU7xaNpj z&XlfcH}`P5O6{7@%J6gox5&>I@rNagVxJ&U*hNH!B%6 XwL~5sP-JNaI)K5`)z4*}Q$iB}AuK!F literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_align_horizontal_right_white_20.png b/app/src/main/res/drawable-xhdpi/round_align_horizontal_right_white_20.png new file mode 100644 index 0000000000000000000000000000000000000000..452925e7edcb6a892f633a576a67a06eede45e57 GIT binary patch literal 216 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU0wmSG7d!(}^F3W0Lp+YZy{66AU?9K}&~zw4 zFosn}>@cIjoYs(s9;*Ayn~WC}ru=xZX~P8pkFslK=S!?tKKK0L$g$P$1z*UGMRyw0 z*n1o9vkNLXS5|TzQR(2Yt(Z9>IDxm0jq8f}fr(7QXL2?y)K_)w?lTmviOgZlbzd3! zX#Lrjo6KVZ>?^9mHq-_1g-uvzvTGmTiN}|0wIhIP?*BWt^IyR~U2g3=2j+iUZw~SU NgQu&X%Q~loCIF2tQ$qj% literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_align_horizontal_right_white_24.png b/app/src/main/res/drawable-xhdpi/round_align_horizontal_right_white_24.png new file mode 100644 index 0000000000000000000000000000000000000000..cf318945e79d4836e37e23c753a76c3e6e6fcd53 GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0DGEW!Bkch)?uOH+*pdjE9=zlFO zJ!<))+&?izeSw>gw9MRXb0bx(#P4S;hX~g}z7q^7)(?6Z7~@$!xJVgiy41*ftWo*e zxQpcqFT-cSNc~7xVTA{e9QQY5yY8-Zx?~d|Z&mi5@tN|bxJ_MZ4hQE}E Y!)*Gq8CtjefG%M0boFyt=akR{05wlOPyhe` literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_align_horizontal_right_white_36.png b/app/src/main/res/drawable-xhdpi/round_align_horizontal_right_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..cd08e6e2d8e7acee84abc3d6edfb265bedbc64a5 GIT binary patch literal 253 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhawj(EB_hGg7(dut+S8`yv+s@u8CUu z2YWV5O>dl}x?oWgV_ug=kkHbNIR?|`YG4!GO6>;^|v-V&cb z-K;7F(! nIQLIu(eK27-;Z~=xRhk@tG@T}wvy?c3zGMA^>bP0l+XkKE30+B*R|;{DeZft zQDpgpkg#P-5`v1k0B|9m9?Q8WpB}3QtTN0n!_>>ARKnN~*j}8MK8Kbx_)5c4#?JW6 zS>8b3dAylyyki@weY9SwR%}BQbl#|r;@Nqe<2VZAG%R)!=Q-w9t_(Bm>o8XAUcS^j zR_{;;`cVa{=b)w5BdHs=)?u}({MI_msW7L*7K(P$vCw|Ca%3}YDc?DdGqRU|ST5QX71YygAMLd^__9grf*RET-lzzt)-1T+*VB@KUyD5S%|#*irY+*6;8I|L1s3>yXh2G-Sj7%&X6WBdAhso~xx;jrb%5;12CZ$uoDyptiZ#k&)gxqp4eJ%V z@UUBlU4IliF1wqM`ZMk(@3qfz*NU5Y_q6lgNzi?tsB0b(XTCnt{Auj^Zuz*wc6Z(< zTlVY!sD3)>&LZwx6(?`4nDAwx*5YkpRu#@x8B4brXYuMcnk zhen?bsS#bh{&evDyqGKXyr&oK`>V8P#sR%!+(E&cujd9w-#Ev!ZFB3~GYRU^H!kv& zZE4j#o8TQCah&Jc#@5uHWd_opKQ?o*ZQfk_C~=~&?((0)?K{oS3io~!dh{tP>&plG z&fY5}^Yl08GQxrZ5+46W#ojoo9+cA+ewFBOQ0~5n>p{64t}ZSv^{<5&Oe$HdYA(AF P7Py5XNz6?5(iUmXI)l!4Y%<1|TFbfT6K<0edHM025k6w5Rx6XzxAl{E^n4I0@mlKOI3VL+uDMT0v1Nsak z60F2eN(okZ!YT=tF?ygzGFgE%YHp;Fmwrl3H~H11)@=P<8p`JWw-zU002ovPDHLkV1fc9bbbH; literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/round_align_horizontal_left_white_20.png b/app/src/main/res/drawable-xxhdpi/round_align_horizontal_left_white_20.png new file mode 100644 index 0000000000000000000000000000000000000000..48d08f1a8161f0134cb4e1715b6e374deb302584 GIT binary patch literal 254 zcmVVU5ClLH%Ag3xR7C|Yhz?E^;w~)o367TFU!Q?&vlt2Ox`2s%x4N!Vl>37L3qDvd zw1y4eSZjFu!CPziAHjkJ3nsxBF~MJa6UHJKJ!Y^nqtAyunDO~=pu!;^j#N12!$yTI zA9hGIHo+BqCpZ|^%jgO_U^Te}3l{tyID2HC4aIV}a7m;pnz9y+1xL!NuYd!k+*H7x zQs*k*vU+<|U~et-XO&%(OR!+UuREeXb~b+MP_8K4>|3z0z(zBTzyJUM07*qoM6N<$ Ef=`8JE&u=k literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/round_align_horizontal_left_white_24.png b/app/src/main/res/drawable-xxhdpi/round_align_horizontal_left_white_24.png new file mode 100644 index 0000000000000000000000000000000000000000..5bd216f1d8cf67a96efd020b6aadfe7291dcc71e GIT binary patch literal 251 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhaw4tcsbhGg7(duuOmvw?_fBA2m| z9OJb`?mdjm7Xo8fxnxe_m?M7I;y=6Nb@kh(tAlqj1YKIO;+Xi7yU#;d!gfc zg@~w1wcj$1%QoEzK60=52zN%J=8_LgFSm8LJlX$rQ{LnQ)xXo)-+yMY=Sea8JmY3h zM@Pp$_gUG?yX{IZ`hA`hpN24UEieJQ4;F z#+&|xsLa)S?U?GSbGH^XX0BWu*Y#%U;%UbW)|Q6z-Q8-|lDTko(aTk>vTK6;Ld!O& zX-6cpzuweTTDHMXJ0hPwdvnv)vJF<+5xMNQGfuRbW+eY?^1FFp($`5^sUOz!3j4i3 zrr)&nqNBO3vxooP5{aJzpKdb2ZHF)_5Av^M1BkmAfc0uKjhW$(eMSq&Er8ueop4HKhL0 z==wbARMC@+TOTI;e|0a#Bj?u+@%g%_e%4`+*eE_#q+M ZUwUXMtoYpTJ1}M#JYD@<);T3K0RYpc#&iGx literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/round_align_horizontal_left_white_48.png b/app/src/main/res/drawable-xxhdpi/round_align_horizontal_left_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..e2b2f4a13e6c7f7928c1313f9f437b4343de153d GIT binary patch literal 466 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=oC178T!Hj|$^b|Fr8b}`VkJR- z!3=CU$397&`+qk3xXbKYpVbc7y*oJTMy1N`6b1%HO-~ockP61PcUadQb`W5>ct9;V z?f(B2^8?=mMrFB%s#m1lu@w{)v<-iLdh3+ePv1P+dH3<+-)B?)hI|Zty0P!okCodP zO!qH1#uQTLc$7(`o{5D+K*6Dbff2$;Td?hQdqsxx{jHf7ELxXjo@soh>Y`iBW}>H< zEh)Ufv}Nsa$6SwW{^o5Hw#l-+Rm`>L(NbLdqxp~d%&&gA1vh@rm-srJ?{fF*|8Lv> z^Ukt!XkdYw46@?L>_7M054aq1f0=m&Xz))Z#fhIv&lq(%WUEA*E-<^aRp^4)OEb=l z{*v7+Axg0y*?#65{hxd5|Az1OhOhKx*~G*D-{$`>ZSrmohyL$s&(EsP0`uz_(Bl6hNh z@inuvlkq%@r4#m)Y;>qI08iE$*o#j}4eXoBFvAS%T>HfAMxPkp86%-)T51v}jDUve zX$V}f6q%$hSSEyJE?7h>K($0}1yW4rS_=2l56P)UpPbM-h+&4!1Y^O0qspUZ#ZA0j z{lu=~jkpJU2!AoX*j@PZ?8Q#PW5GZzUPK3;L2$`daFnxlWtd?z#8j6qn(HLhMVaMK Zc>{bU<8q3F%LD)b002ovPDHLkV1g1Oa!~*P literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/round_align_horizontal_right_white_20.png b/app/src/main/res/drawable-xxhdpi/round_align_horizontal_right_white_20.png new file mode 100644 index 0000000000000000000000000000000000000000..be140dd3246a12060a073bfcedf6c8ff9c7600d6 GIT binary patch literal 257 zcmV+c0sj7pP)ST5Cu>g#$X87OvMBqhz(8*;w>zc2CAPTQIsmWFHR;2|9gN}`R?nwPEme27_i`m z1w(7t@QAgBwtS?-y|bEJf&~k{AnYEfu_KdQA>5Mq2(wGmqF}Zr)F_xOMkNYn zt6+|Tx$?`@TL`&00000NkvXX Hu0mjfEaqsx literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/round_align_horizontal_right_white_24.png b/app/src/main/res/drawable-xxhdpi/round_align_horizontal_right_white_24.png new file mode 100644 index 0000000000000000000000000000000000000000..cd08e6e2d8e7acee84abc3d6edfb265bedbc64a5 GIT binary patch literal 253 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhawj(EB_hGg7(dutfSu zE-opPpWS-3rhM+!t2XM_0_V$aUbyno^;Izm%f)YKir@IlT6UiGn{L8^21aH!9ti_5 z;~RTIROaHj_k?Q7Ze=`Wx*WuAJ9X1?z9^}~Tdw&E?#j&Nxa=hE`f^dL?3$1zUe*!9 zT-RnRTTzBYz*6aNtp$+-DKi=NS zzBE5U^w#TD?n0NG!{63daa86q!fl5zoDTP}ab0v{KBlZNKk=MK*q@KLSF{%tNFEej znHbmn(aQA9YmLReyq~RVUIicC)5pF0iots3dul*ok9|J8pCcD-h-sJb-5g)NF*aeQ z!{(TfPZ5^0S~f@MevTG;ypdkX)g!ivPfe-b>a%S+w633WKMspUXO@geCy(%eub+ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/round_align_horizontal_right_white_48.png b/app/src/main/res/drawable-xxhdpi/round_align_horizontal_right_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..35d53dae3e09447c64841f8caf4e1235472610ae GIT binary patch literal 466 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=oC178T!Hj|$^b|Fr8b}`VkJR- z!3=CU$397&`+qk3xXbKYpVbc7y*oJTMy1N`6b1%HO-~ockP61PcU&j27z(f)WIP*U z{Qdv@T|U<*<<5Gl_=xph&!yHZWhJFu_uehNlOHaA{;{OIt-RXn<(=!L`b)1I^Iyxl zqI?|yEHC^U7#NvYI0O_NK#VK=k4669GU2N=&4_clWOTjpnyyQ3HgCo~ zr)y^64c`Q|J$J12czt<+@)Ft13zC=4nXG8plEl90cFH^Jt^X6>*C$u!z0#x1|DJC1`Mj)Nc5>GB{TsZlzK(zS)ar}AZSmY+ z*AMOV3JL$?_;2=^`sLT;zx`8p`|sWU|7d9a?}zoxX;7!a+?@2GEUCg;n1N%N#{?gx hgC^20E-p=RjLo-7dbOpdT>%CwgQu&X%Q~loCIB3mj7%&X6WBdAhso~xx;jrb%5;12CZ$uoDyptiZ#k&)gxqp4qHApVdGt?A;;{^Cx&cHe9Nw^3XK%;S_vJOLjMVqFWW~Uu?Hst@+8=l(C z3=>5R!!YmQfHTfGgvvW%1OSXUg~*FvyeBaZ518RIS$M#51uO|9kU#pB8@w6G67ERz}W;iy8{Ok;NT9dO@Ote z0q?!@dQroV1T7YCxCO2Fsg5F~C~$E;*VQMlf|~_W77GLtNFad(61WrKmjc4ASlF^K zP%6QGE3G^ivHb>rqm9gOQwU)TTDn zbRA$;n>^Dj76>GeKmrLQkidU|!7rDEzMdESg5#^X4|zqDVHlG<0DMDoM`hQb%K!iX M07*qoM6N<$f&=i8xBvhE literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/round_align_horizontal_center_white_24.png b/app/src/main/res/drawable-xxxhdpi/round_align_horizontal_center_white_24.png new file mode 100644 index 0000000000000000000000000000000000000000..07e95ef36794e993f4c6a29b98d7b9322dbe2f5b GIT binary patch literal 308 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%xcgetWt&hE&{odwVZ$vw?_fqSmwo zw;QK6JG@j~u&9Yq&s9XzQ@HVqOnlKfmYPTB`5!J*R8r#doI6QO*XxxHfBn_XS0^l3 za($9~LLKv&x`uwBiE!|MHDI;l;*KFFU=XL&u6i_@9S&vS{rGkUCFSKbLh*2~7a@(sbbf literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/round_align_horizontal_center_white_36.png b/app/src/main/res/drawable-xxxhdpi/round_align_horizontal_center_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..108f15c317e18c50163754375ebb2f04aa5fc629 GIT binary patch literal 464 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=oC178T!Hj|$^b|Fr8b}`VkJR- z!3=CU$397&`+qk3xXbKYpVbc7y*oJTMy1N`6b1%Hbx#+^kP61PcaCm7;=sciICJLP zKhA#*_FTDO9d)I5!I|7F;{yx~p0l1-PE!+e2@F$DO;l7VEe%u`a}2&~BIX!UB}K7#JAmd%8G=R4~51%i4F?fyW_G zeQudd+K&IO(<5ixY|{N(-@N?-pQqR^R~HbN@^ra?U!|Izb^M}zqWbBDH+EiF&(+@) zR3Fl{d(#U0u9+3u*W;f)TI*FG+PS^ypH|2AFaAJ>6bJ(eEZ~ao?XSNU{92cr_0#{b z#MgsI3nx5T7RP(Vf6|RTD>|n|PMRfVddbMs$vMEdRguwP)j~JR7}=`<8>cN^o3$#m zZ`;b1W|p_sExUF3zSRwl9qd2;3xE3W|K@-4mH*;1|1WL%e{|0Or(6E>_Wsvh`rmi& z|720WXINYT6?!QyU#D->W;kny*QU~+*Zqr@KRbG%G|TC7(sQTVx2i80oOmnkYx`=$ zw|OSlie85$^Uq#m>w5diwYSIQzDHK~Nis&Kea8{3*saedlkNdy@?s9%p=PTa(+;>iabbGq` KxvXy=6Nb@kh(tAlqj1YKIO;+Xi7vJ=xgI4d|o;6)g50RHs{HFPuwLUrWC*5srU2$Z>IZ~zS%F| z9+D*S?0gf$-P4>kPfI5}nk6DDUpdwKz1x}}>^vW5T(D30!qUT`GQoj~6GYfEE$ZS- z+Pc}{Fh_@7*@d%$#fAcQNJf0cW%zUW_j!16MWIiYJ@!F+! zl>?_3^{XxW#rLqUj(D`>)a?biKUO;PGWUd@Kh$)=2g~>$zPW3K_%U6%Dp4uk5;N_=`RsZFttiRuN zEh|1QK}=sQQVi~3Ylrvx(|^|4p8w6=_nqGpEDiy8=%7}oU4&A9N#*zqL)3A3d>%m4I- zlmyN9+ria3J#^QnhCSTT$(0WGmL3&7@HY>)A=6oJ@^tlcS?83{1ONsicKHAR literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/round_align_horizontal_left_white_36.png b/app/src/main/res/drawable-xxxhdpi/round_align_horizontal_left_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..e2b2f4a13e6c7f7928c1313f9f437b4343de153d GIT binary patch literal 466 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=oC178T!Hj|$^b|Fr8b}`VkJR- z!3=CU$397&`+qk3xXbKYpVbc7y*oJTMy1N`6b1%HO-~ockP61PcUadQb`W5>ct9;V z?f(B2^8?=mMrFB%s#m1lu@w{)v<-iLdh3+ePv1P+dH3<+-)B?)hI|Zty0P!okCodP zO!qH1#uQTLc$7(`o{5D+K*6Dbff2$;Td?hQdqsxx{jHf7ELxXjo@soh>Y`iBW}>H< zEh)Ufv}Nsa$6SwW{^o5Hw#l-+Rm`>L(NbLdqxp~d%&&gA1vh@rm-srJ?{fF*|8Lv> z^Ukt!XkdYw46@?L>_7M054aq1f0=m&Xz))Z#fhIv&lq(%WUEA*E-<^aRp^4)OEb=l z{*v7+Axg0y*?#65{hxd5|Az1OhOhKx*~G*D-{$`>ZSrmUB}K7#J95d%8G=R4~51%ewBcfq?5p zv%=S$#&7Bu&zE$Oe0uWIUhNl}M^%1)GF1YBMcLEZC!}BZo^|)##kj8T(UaEi-_YMB z!n(9}rO$`o@^8IA&XQ5soS%A^cW%i2t-f!$ zB#vdMiyuG8Z}3%Z#r!=CpOYp{yUA{#tCls>hQZk&GO>W6M=i&OZ^dHH?yrdlvMyaa z+;DbDZad>{&)fXWO`hBgSK<}xj=b6*D3@}QU-e0|W!vRnoV>waHM6Ve))^3;)%V{*E(!IarxhCj`+Zy^Uzec{=h-$0tbag79kHHv5Rd{mt@jr zV<%76BO>ZI(z^R3It-ms`nxzfY|1z$N3i86hnN{9=u3RiV7}JGDEv}2l8wo4$pMab zhCN5Co9Dfg%}Ge@vQGZ@Gi3R{R{`$w&XX^@&OFKlHU1xOKtM=~w%C!>NU^8a#BE{| zS8GP>XUU3g?$k7Bex|jN_0{dmi**C;KgiE%{3Ym_!xh3mbIIYwAuc~>_!-xEyH4S? z+RA)p{;zIMl?e_^K;nQr;*uRHkB@5^4LQwBX2;^ndvm<>K%J`4;<22WQ% Jmvv4FO#oLPj+S8`yv+s@u8CUu z2YWV5O>dl}x?oWgV_ug=kkHbNIR?|`YG4!GO6>;^|v-V&cb z-K;7F(! nIQLIu(eK27-;Z~=xRhk@tG@T}wvy?c3zGMA^>bP0l+XkKE30?|yEHC^U7#NvYI0O_NK#VK=k4669GU2N=&4_clWOTjpnyyQ3HgCo~ zr)y^64c`Q|J$J12czt<+@)Ft13zC=4nXG8plEl90cFH^Jt^X6>*C$u!z0#x1|DJC1`Mj)Nc5>GB{TsZlzK(zS)ar}AZSmY+ z*AMOV3JL$?_;2=^`sLT;zx`8p`|sWU|7d9a?}zoxX;7!a+?@2GEUCg;n1N%N#{?gx hgC^20E-p=RjLo-7dbOpdT>%CwgQu&X%Q~loCIB3mUB}K7#J9*d%8G=R4~518{WrcDBv2n zfOp+F%Qy9lCx6bbtcciE&MFgR?P(_n2DU}dy#<{LE$4rFQ`P+~Y)|awn!ihHL!W7^ zc;g=0cK?5deb@6h4C249s#-hb?q9W;ndNur3BH7SCZJ=mf`7UUzPGa@2B* znad_`+s)YSX?>?5;Sv+W*YFPcjlc4zu+OZ~IGEsPHz&<$^8YD8_AApPTc=uLbpc4Q zA>Uc0nYXX7>yWNm{pSUDo_yZE=2UK2{pVG8UVJlWdl|@FKl$H=_SI^y`fu;J^@V+2 z&D&qf>HGNpF0_w7I7y7*$v4qQ?rZ)@KXp`-_cE9 + + diff --git a/app/src/main/res/drawable/round_align_horizontal_left_24.xml b/app/src/main/res/drawable/round_align_horizontal_left_24.xml new file mode 100644 index 0000000..5034ea2 --- /dev/null +++ b/app/src/main/res/drawable/round_align_horizontal_left_24.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/round_align_horizontal_right_24.xml b/app/src/main/res/drawable/round_align_horizontal_right_24.xml new file mode 100644 index 0000000..9092905 --- /dev/null +++ b/app/src/main/res/drawable/round_align_horizontal_right_24.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/layout/fragment_app_main.xml b/app/src/main/res/layout/fragment_app_main.xml index 3be5427..d02520c 100644 --- a/app/src/main/res/layout/fragment_app_main.xml +++ b/app/src/main/res/layout/fragment_app_main.xml @@ -96,6 +96,8 @@ android:orientation="vertical" android:id="@+id/widget" android:alpha="0" + android:paddingStart="8dp" + android:paddingEnd="8dp" android:animateLayoutChanges="true" android:gravity="center"> diff --git a/app/src/main/res/layout/fragment_tab_layout.xml b/app/src/main/res/layout/fragment_tab_layout.xml index 3492aec..2fd1cf5 100644 --- a/app/src/main/res/layout/fragment_tab_layout.xml +++ b/app/src/main/res/layout/fragment_tab_layout.xml @@ -128,7 +128,8 @@ android:layout_width="48dp" android:layout_height="48dp" android:padding="12dp" - android:src="@drawable/round_dashboard_24" + android:id="@+id/widget_align_icon" + android:src="@drawable/round_align_horizontal_center_24" app:tint="@color/colorPrimaryText"/> diff --git a/app/src/main/res/layout/left_aligned_widget_sans.xml b/app/src/main/res/layout/left_aligned_widget_sans.xml index 11fa721..e2f2311 100644 --- a/app/src/main/res/layout/left_aligned_widget_sans.xml +++ b/app/src/main/res/layout/left_aligned_widget_sans.xml @@ -73,28 +73,41 @@ + + + @@ -109,16 +122,18 @@ android:layout_height="wrap_content" android:layout_width="0dp" android:layout_weight="1" + android:background="@color/colorAccent" android:id="@+id/next_event_rect" /> @@ -143,6 +158,7 @@ @@ -155,6 +171,7 @@ - \ No newline at end of file diff --git a/app/src/main/res/layout/the_widget_sans.xml b/app/src/main/res/layout/the_widget_sans.xml index 75e8cda..34af404 100644 --- a/app/src/main/res/layout/the_widget_sans.xml +++ b/app/src/main/res/layout/the_widget_sans.xml @@ -74,26 +74,34 @@ - + android:paddingTop="4dp"> + + From 854cfac28ce9510f6d339fbe5256d71c0763cd0b Mon Sep 17 00:00:00 2001 From: Tommaso Berlose Date: Wed, 5 May 2021 10:54:09 +0200 Subject: [PATCH 5/6] Bugfixes --- .../anotherwidget/ui/activities/tabs/CustomLocationActivity.kt | 1 + .../anotherwidget/ui/widgets/LeftAlignedWidget.kt | 2 +- .../tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt | 2 +- app/src/main/res/layout/custom_location_item.xml | 2 -- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/CustomLocationActivity.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/CustomLocationActivity.kt index 8be37f3..9f46e34 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/CustomLocationActivity.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/activities/tabs/CustomLocationActivity.kt @@ -5,6 +5,7 @@ import android.app.Activity import android.location.Address import android.location.Geocoder import android.os.Bundle +import android.util.Log import com.tommasoberlose.anotherwidget.R import android.view.View import androidx.appcompat.app.AppCompatActivity diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt index a1255c1..5040072 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt @@ -401,7 +401,7 @@ class LeftAlignedWidget(val context: Context) { bindingView.weatherDateLine.isVisible = true val currentTemp = String.format( Locale.getDefault(), - "%d °%s", + "%d°%s", Preferences.weatherTemp.roundToInt(), Preferences.weatherRealTempUnit ) diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt index 3503207..f9d3b7d 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt @@ -421,7 +421,7 @@ class StandardWidget(val context: Context) { bindingView.weatherDateLine.isVisible = true val currentTemp = String.format( Locale.getDefault(), - "%d °%s", + "%d°%s", Preferences.weatherTemp.roundToInt(), Preferences.weatherRealTempUnit ) diff --git a/app/src/main/res/layout/custom_location_item.xml b/app/src/main/res/layout/custom_location_item.xml index 8be6b34..db10c90 100644 --- a/app/src/main/res/layout/custom_location_item.xml +++ b/app/src/main/res/layout/custom_location_item.xml @@ -26,8 +26,6 @@ android:paddingBottom="8dp" android:paddingEnd="16dp" android:paddingStart="16dp" - android:focusable="true" - android:clickable="true" android:textAlignment="viewStart" android:background="?attr/selectableItemBackground" android:textColor="@color/colorPrimaryText" From 67abd14bb10a8425dfc0a596cb2ced7e9396df2d Mon Sep 17 00:00:00 2001 From: Tommaso Berlose Date: Wed, 5 May 2021 12:11:51 +0200 Subject: [PATCH 6/6] Bugfixes --- .../anotherwidget/helpers/ImageHelper.kt | 2 +- .../helpers/MediaPlayerHelper.kt | 2 + .../receivers/NotificationListener.kt | 1 + .../ui/fragments/MainFragment.kt | 2 +- .../ui/widgets/LeftAlignedWidget.kt | 2 +- .../ui/widgets/StandardWidget.kt | 3 +- .../res/layout/activity_media_info_format.xml | 5 +- .../main/res/layout/left_aligned_widget.xml | 11 +- .../res/layout/left_aligned_widget_sans.xml | 6 +- .../main/res/layout/right_aligned_widget.xml | 280 ------------------ .../res/layout/right_aligned_widget_sans.xml | 173 ----------- 11 files changed, 14 insertions(+), 473 deletions(-) delete mode 100644 app/src/main/res/layout/right_aligned_widget.xml delete mode 100644 app/src/main/res/layout/right_aligned_widget_sans.xml diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/ImageHelper.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/ImageHelper.kt index 257115d..d852137 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/ImageHelper.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/ImageHelper.kt @@ -20,7 +20,7 @@ object ImageHelper { else -> 0f * factor }, 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 comb = Bitmap.createBitmap(btm) val shadowBitmap = generateShadowBitmap(context, cElevation, btm, factor) diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/MediaPlayerHelper.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/MediaPlayerHelper.kt index cd51492..5d20eac 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/MediaPlayerHelper.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/MediaPlayerHelper.kt @@ -33,12 +33,14 @@ object MediaPlayerHelper { DEFAULT_MEDIA_INFO_FORMAT.replace(MEDIA_INFO_TITLE, title) .replace(MEDIA_INFO_ARTIST, artist) .replace(MEDIA_INFO_ALBUM, album) + .replace("\\n", System.getProperty("line.separator") ?: " ") } } else -> { format.replace(MEDIA_INFO_TITLE, title) .replace(MEDIA_INFO_ARTIST, artist) .replace(MEDIA_INFO_ALBUM, album) + .replace("\\n", System.getProperty("line.separator") ?: " ") } } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/NotificationListener.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/NotificationListener.kt index e86d2ba..6a6bcf1 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/NotificationListener.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/NotificationListener.kt @@ -9,6 +9,7 @@ import android.service.notification.NotificationListenerService import android.service.notification.StatusBarNotification import android.util.Log import android.widget.Toast +import com.google.gson.Gson import com.tommasoberlose.anotherwidget.global.Actions import com.tommasoberlose.anotherwidget.global.Constants import com.tommasoberlose.anotherwidget.global.Preferences diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt index c890ea7..5406549 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt @@ -45,7 +45,7 @@ class MainFragment : Fragment() { companion object { fun newInstance() = MainFragment() private val PREVIEW_BASE_HEIGHT: Int - get() = if (Preferences.widgetAlign == Constants.WidgetAlign.CENTER.rawValue) 120 else 200 + get() = if (Preferences.widgetAlign == Constants.WidgetAlign.CENTER.rawValue) 120 else 180 } private lateinit var viewModel: MainViewModel diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt index 5040072..6d89ea0 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/LeftAlignedWidget.kt @@ -238,7 +238,7 @@ class LeftAlignedWidget(val context: Context) { 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) && bindingView.calendarLayout.isVisible) { + } else if (GlanceProviderHelper.showGlanceProviders(context)) { var showSomething = false loop@ for (provider: Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders(context)) { when (provider) { diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt index f9d3b7d..f4b2b79 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/StandardWidget.kt @@ -8,6 +8,7 @@ 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 @@ -260,7 +261,7 @@ class StandardWidget(val context: Context) { views.setViewVisibility(R.id.first_line_rect, View.GONE) - } else if (GlanceProviderHelper.showGlanceProviders(context) && bindingView.calendarLayout.isVisible) { + } else if (GlanceProviderHelper.showGlanceProviders(context)) { var showSomething = false loop@ for (provider: Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders(context)) { when (provider) { diff --git a/app/src/main/res/layout/activity_media_info_format.xml b/app/src/main/res/layout/activity_media_info_format.xml index 5138a46..25c9526 100644 --- a/app/src/main/res/layout/activity_media_info_format.xml +++ b/app/src/main/res/layout/activity_media_info_format.xml @@ -110,10 +110,7 @@ app:textAllCaps="false" android:gravity="center_vertical|start" android:textAlignment="viewStart" - android:maxLines="1" - android:lines="1" - android:singleLine="true" - android:ellipsize="end" + android:maxLines="2" android:layout_marginLeft="32dp" android:layout_marginRight="32dp" /> diff --git a/app/src/main/res/layout/left_aligned_widget.xml b/app/src/main/res/layout/left_aligned_widget.xml index 276fb0d..89ee934 100644 --- a/app/src/main/res/layout/left_aligned_widget.xml +++ b/app/src/main/res/layout/left_aligned_widget.xml @@ -1,7 +1,6 @@ + android:orientation="vertical"> @@ -150,6 +147,7 @@ android:layout_height="wrap_content" android:cropToPadding="false" android:clipChildren="false" + android:layout_marginTop="2dp" android:layout_marginEnd="4dp"> diff --git a/app/src/main/res/layout/left_aligned_widget_sans.xml b/app/src/main/res/layout/left_aligned_widget_sans.xml index e2f2311..131c28e 100644 --- a/app/src/main/res/layout/left_aligned_widget_sans.xml +++ b/app/src/main/res/layout/left_aligned_widget_sans.xml @@ -12,7 +12,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:gravity="center_vertical" android:paddingLeft="8dp" android:paddingRight="8dp" android:id="@+id/main_layout" @@ -75,9 +74,7 @@ android:layout_height="wrap_content"> + android:layout_height="wrap_content"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/right_aligned_widget_sans.xml b/app/src/main/res/layout/right_aligned_widget_sans.xml deleted file mode 100644 index 85ce6f5..0000000 --- a/app/src/main/res/layout/right_aligned_widget_sans.xml +++ /dev/null @@ -1,173 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file