From 7232938c12e2e393c443c32d6813cfef86587ee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Borcz?= Date: Thu, 12 Sep 2019 16:36:32 +0200 Subject: [PATCH 01/34] Update API 28 to API 29 (#506) --- .travis.yml | 4 ++-- app/build.gradle | 6 +++--- .../github/wulkanowy/ui/base/ErrorDialog.kt | 19 ++++++++++--------- gradle/wrapper/gradle-wrapper.properties | 2 +- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index d3f5049c..8c94ef86 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,8 @@ jdk: oraclejdk8 env: global: - - ANDROID_API_LEVEL=28 - - ANDROID_BUILD_TOOLS_VERSION=28.0.3 + - ANDROID_API_LEVEL=29 + - ANDROID_BUILD_TOOLS_VERSION=29.0.2 cache: directories: diff --git a/app/build.gradle b/app/build.gradle index 68a673e0..f6d5d0b3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,14 +9,14 @@ apply from: 'sonarqube.gradle' apply from: 'hooks.gradle' android { - compileSdkVersion 28 - buildToolsVersion '28.0.3' + compileSdkVersion 29 + buildToolsVersion '29.0.2' defaultConfig { applicationId "io.github.wulkanowy" testApplicationId "io.github.tests.wulkanowy" minSdkVersion 16 - targetSdkVersion 28 + targetSdkVersion 29 versionCode 45 versionName "0.10.2" multiDexEnabled true diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt index b74af6c5..3255ea68 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt @@ -43,16 +43,17 @@ class ErrorDialog : DialogFragment() { override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - StringWriter().let { writer -> - error.printStackTrace(PrintWriter(writer)) - errorDialogContent.text = writer.toString() - errorDialogCopy.setOnClickListener { - ClipData.newPlainText("wulkanowyError", writer.toString()).let { clip -> - activity?.getSystemService()?.primaryClip = clip - } - Toast.makeText(context, R.string.all_copied, LENGTH_LONG).show() - } + val stringWriter = StringWriter().apply { + error.printStackTrace(PrintWriter(this)) + } + + errorDialogContent.text = stringWriter.toString() + errorDialogCopy.setOnClickListener { + val clip = ClipData.newPlainText("wulkanowy", stringWriter.toString()) + activity?.getSystemService()?.setPrimaryClip(clip) + + Toast.makeText(context, R.string.all_copied, LENGTH_LONG).show() } errorDialogCancel.setOnClickListener { dismiss() } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index dbe85eef..ca9d6281 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From e332fd9cf9b432a5756ba447595e18bc915d3758 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2019 08:29:32 +0000 Subject: [PATCH 02/34] Bump logging-interceptor from 3.12.4 to 3.12.5 (#510) --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index f6d5d0b3..55447a2c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -173,7 +173,7 @@ dependencies { implementation "com.jakewharton.threetenabp:threetenabp:1.2.1" implementation "com.jakewharton.timber:timber:4.7.1" implementation "at.favre.lib:slf4j-timber:1.0.1" - implementation "com.squareup.okhttp3:logging-interceptor:3.12.4" + implementation "com.squareup.okhttp3:logging-interceptor:3.12.5" implementation "com.mikepenz:aboutlibraries:7.0.3" playImplementation "com.google.firebase:firebase-core:17.2.0" From 53a5d0205170a22237e4e726c201cf9f0483be1f Mon Sep 17 00:00:00 2001 From: Dominik Korsa Date: Mon, 16 Sep 2019 23:06:37 +0200 Subject: [PATCH 03/34] Fix attendance_excused_lateness pl typo (#511) --- app/src/main/res/values-pl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index a43493e7..62803deb 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -111,7 +111,7 @@ Nieobecność usprawiedliwiona Nieobecność nieusprawiedliwiona Zwolniony - Spóźnienie usprawiedliowione + Spóźnienie usprawiedliwione Spóźnienie nieusprawiedliwione Obecny Numer lekcji From 3ee98e2bd0c6db13e34a71ecee8a4de3886a7552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Borcz?= Date: Mon, 16 Sep 2019 23:13:46 +0200 Subject: [PATCH 04/34] Fix privacy link position on small screens (#508) --- .../main/res/layout/fragment_login_form.xml | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/app/src/main/res/layout/fragment_login_form.xml b/app/src/main/res/layout/fragment_login_form.xml index 5f6d2b5c..7627e71b 100644 --- a/app/src/main/res/layout/fragment_login_form.xml +++ b/app/src/main/res/layout/fragment_login_form.xml @@ -136,45 +136,41 @@ android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginTop="48dp" - android:layout_marginEnd="24dp" - android:layout_marginRight="24dp" - android:layout_marginBottom="16dp" + android:layout_marginBottom="32dp" android:text="@string/login_sign_in" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintEnd_toEndOf="@id/loginFormHostLayout" app:layout_constraintTop_toBottomOf="@+id/loginFormHostLayout" /> From 6089df9462c34560ddc8e04e74e832fef4e7da92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Borcz?= Date: Mon, 16 Sep 2019 23:27:58 +0200 Subject: [PATCH 05/34] Fix wrong index in form host value (#507) --- .../ui/modules/login/form/LoginFormFragment.kt | 11 +++-------- .../ui/modules/login/form/LoginFormPresenter.kt | 6 ++++-- .../wulkanowy/ui/modules/login/form/LoginFormView.kt | 4 ++-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt index c847d005..4849b213 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt @@ -38,7 +38,7 @@ class LoginFormFragment : BaseFragment(), LoginFormView { override val formPassValue get() = loginFormPass.text.toString() - override val formHostValue get() = hostValues[(hostKeys.indexOf(loginFormHost.text.toString()))] + override val formHostValue get() = hostValues.getOrNull(hostKeys.indexOf(loginFormHost.text.toString())) private lateinit var hostKeys: Array @@ -146,13 +146,8 @@ class LoginFormFragment : BaseFragment(), LoginFormView { loginFormPrivacyLink.visibility = VISIBLE } - override fun notifyParentAccountLogged(students: List) { - (activity as? LoginActivity)?.onFormFragmentAccountLogged(students, - Triple( - loginFormName.text.toString(), - loginFormPass.text.toString(), - formHostValue - )) + override fun notifyParentAccountLogged(students: List, loginData: Triple) { + (activity as? LoginActivity)?.onFormFragmentAccountLogged(students, loginData) } override fun openPrivacyPolicyPage() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt index 6310f36a..d5b81b5b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt @@ -40,7 +40,9 @@ class LoginFormPresenter @Inject constructor( view?.apply { clearPassError() clearNameError() - if (formHostValue.contains("fakelog")) setCredentials("jan@fakelog.cf", "jan123") + if (formHostValue?.contains("fakelog") == true) { + setCredentials("jan@fakelog.cf", "jan123") + } } } @@ -79,7 +81,7 @@ class LoginFormPresenter @Inject constructor( .subscribe({ Timber.i("Login result: Success") analytics.logEvent("registration_form", "success" to true, "students" to it.size, "endpoint" to endpoint, "error" to "No error") - view?.notifyParentAccountLogged(it) + view?.notifyParentAccountLogged(it, Triple(email, password, endpoint)) }, { Timber.i("Login result: An exception occurred") analytics.logEvent("registration_form", "success" to false, "students" to -1, "endpoint" to endpoint, "error" to it.message.ifNullOrBlank { "No message" }) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt index 3c21e25d..097b6f62 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt @@ -11,7 +11,7 @@ interface LoginFormView : BaseView { val formPassValue: String - val formHostValue: String + val formHostValue: String? fun setCredentials(name: String, pass: String) @@ -39,7 +39,7 @@ interface LoginFormView : BaseView { fun showPrivacyPolicy() - fun notifyParentAccountLogged(students: List) + fun notifyParentAccountLogged(students: List, loginData: Triple) fun openPrivacyPolicyPage() } From 5d33cefe1d97669029dc4925e342a340bedf4f90 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 22 Sep 2019 10:49:39 +0000 Subject: [PATCH 06/34] Bump mockito-core from 3.0.7 to 3.0.8 (#515) --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 55447a2c..377f7026 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -114,7 +114,7 @@ ext { dagger = "2.24" chucker = "2.0.4" mockk = "1.9.2" - mockito_core = "3.0.7" + mockito_core = "3.0.8" } configurations.all { From 23b49e4b8c8873a69ca10a461cbd1ffac017fdb6 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 22 Sep 2019 10:50:21 +0000 Subject: [PATCH 07/34] Bump mockito-inline from 3.0.7 to 3.0.8 (#516) --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 377f7026..ec094520 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -188,7 +188,7 @@ dependencies { testImplementation "io.mockk:mockk:$mockk" testImplementation "org.threeten:threetenbp:1.4.0" testImplementation "org.mockito:mockito-core:$mockito_core" - testImplementation("org.mockito:mockito-inline:3.0.7") { + testImplementation("org.mockito:mockito-inline:3.0.8") { exclude group: "org.mockito", module: "mockito-core" } From 2f44f3c4ba1eb49aa2795ff7aa1bc19512438eb4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 22 Sep 2019 10:55:34 +0000 Subject: [PATCH 08/34] Bump gradle from 1.31.0 to 1.31.1 (#517) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c7ca235a..ae630184 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ buildscript { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'com.android.tools.build:gradle:3.5.0' classpath 'com.google.gms:google-services:4.3.2' - classpath "io.fabric.tools:gradle:1.31.0" + classpath "io.fabric.tools:gradle:1.31.1" classpath "com.github.triplet.gradle:play-publisher:2.4.1" classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1" classpath "gradle.plugin.com.star-zero.gradle:githook:1.1.0" From d6ece78eff5c368fb56581a96c2ea88dff568402 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 22 Sep 2019 11:03:41 +0000 Subject: [PATCH 09/34] Bump mockito-android from 3.0.7 to 3.0.8 (#518) --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index ec094520..cf1b0f3b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -199,7 +199,7 @@ dependencies { androidTestImplementation "androidx.room:room-testing:$room" androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version" androidTestImplementation "org.mockito:mockito-core:$mockito_core" - androidTestImplementation("org.mockito:mockito-android:3.0.7") { + androidTestImplementation("org.mockito:mockito-android:3.0.8") { exclude group: 'org.mockito', module: 'mockito-core' } } From d4b73fb73eaf7b7c0191009a29e8c1c3cce1ac86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Borcz?= Date: Wed, 25 Sep 2019 22:44:55 +0200 Subject: [PATCH 10/34] Add dark theme for app widgets (#509) --- .../LuckyNumberWidgetConfigureActivity.kt | 28 +++- .../LuckyNumberWidgetConfigurePresenter.kt | 31 +++- .../LuckyNumberWidgetConfigureView.kt | 3 +- .../LuckyNumberWidgetProvider.kt | 74 +++++---- .../TimetableWidgetConfigureActivity.kt | 28 +++- .../TimetableWidgetConfigurePresenter.kt | 38 ++++- .../TimetableWidgetConfigureView.kt | 2 + .../timetablewidget/TimetableWidgetFactory.kt | 65 ++++---- .../TimetableWidgetProvider.kt | 116 +++++++------ ....xml => background_luckynumber_widget.xml} | 2 +- .../background_luckynumber_widget_dark.xml | 6 + .../main/res/layout/item_widget_timetable.xml | 156 ++++++++++-------- .../res/layout/item_widget_timetable_dark.xml | 95 +++++++++++ .../main/res/layout/widget_luckynumber.xml | 2 +- .../res/layout/widget_luckynumber_dark.xml | 65 ++++++++ .../main/res/layout/widget_timetable_dark.xml | 99 +++++++++++ app/src/main/res/values-pl/strings.xml | 3 + app/src/main/res/values/colors.xml | 11 +- app/src/main/res/values/strings.xml | 3 + app/src/main/res/values/styles.xml | 1 + 20 files changed, 614 insertions(+), 214 deletions(-) rename app/src/main/res/drawable/{backgorund_luckynumber_widget.xml => background_luckynumber_widget.xml} (78%) create mode 100644 app/src/main/res/drawable/background_luckynumber_widget_dark.xml create mode 100644 app/src/main/res/layout/item_widget_timetable_dark.xml create mode 100644 app/src/main/res/layout/widget_luckynumber_dark.xml create mode 100644 app/src/main/res/layout/widget_timetable_dark.xml diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureActivity.kt index 3dd0e5df..e8ce3bcf 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureActivity.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureActivity.kt @@ -6,6 +6,7 @@ import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS import android.content.Intent import android.os.Bundle import android.widget.Toast +import androidx.appcompat.app.AlertDialog import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager import eu.davidea.flexibleadapter.items.AbstractFlexibleItem @@ -25,6 +26,8 @@ class LuckyNumberWidgetConfigureActivity : BaseActivity + presenter.onThemeSelect(which) + } + .show() } override fun updateData(data: List) { @@ -70,4 +89,9 @@ class LuckyNumberWidgetConfigureActivity : BaseActivity) { if (item is LuckyNumberWidgetConfigureItem) { - registerStudent(item.student) + selectedStudent = item.student + view?.showThemeDialog() } } + fun onThemeSelect(index: Int) { + appWidgetId?.let { + sharedPref.putLong(getThemeWidgetKey(it), index.toLong()) + } + registerStudent(selectedStudent) + } + + fun onDismissThemeView(){ + view?.finishView() + } + private fun loadData() { disposable.add(studentRepository.getSavedStudents(false) .map { it to appWidgetId?.let { id -> sharedPref.getLong(getStudentWidgetKey(id), 0) } } @@ -49,12 +64,14 @@ class LuckyNumberWidgetConfigurePresenter @Inject constructor( }, { errorHandler.dispatch(it) })) } - private fun registerStudent(student: Student) { - appWidgetId?.also { - sharedPref.putLong(getStudentWidgetKey(it), student.id) - view?.apply { - updateLuckyNumberWidget(it) - setSuccessResult(it) + private fun registerStudent(student: Student?) { + requireNotNull(student) + + appWidgetId?.let { id -> + sharedPref.putLong(getStudentWidgetKey(id), student.id) + view?.run { + updateLuckyNumberWidget(id) + setSuccessResult(id) } } view?.finishView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureView.kt index 49c3f1dc..fa4c0cc6 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureView.kt @@ -1,12 +1,13 @@ package io.github.wulkanowy.ui.modules.luckynumberwidget import io.github.wulkanowy.ui.base.BaseView -import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetConfigureItem interface LuckyNumberWidgetConfigureView : BaseView { fun initView() + fun showThemeDialog() + fun updateData(data: List) fun updateLuckyNumberWidget(widgetId: Int) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetProvider.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetProvider.kt index 895fe571..12753b35 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetProvider.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetProvider.kt @@ -55,7 +55,10 @@ class LuckyNumberWidgetProvider : BroadcastReceiver() { lateinit var sharedPref: SharedPrefProvider companion object { + fun getStudentWidgetKey(appWidgetId: Int) = "lucky_number_widget_student_$appWidgetId" + + fun getThemeWidgetKey(appWidgetId: Int) = "lucky_number_widget_theme_$appWidgetId" } @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @@ -70,24 +73,26 @@ class LuckyNumberWidgetProvider : BroadcastReceiver() { private fun onUpdate(context: Context, intent: Intent) { intent.getIntArrayExtra(EXTRA_APPWIDGET_IDS)?.forEach { appWidgetId -> - RemoteViews(context.packageName, R.layout.widget_luckynumber).apply { - setTextViewText(R.id.luckyNumberWidgetNumber, - getLuckyNumber(sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0), appWidgetId)?.luckyNumber?.toString() ?: "#" - ) - setOnClickPendingIntent(R.id.luckyNumberWidgetContainer, - PendingIntent.getActivity(context, MainView.Section.LUCKY_NUMBER.id, - MainActivity.getStartIntent(context, MainView.Section.LUCKY_NUMBER, true), FLAG_UPDATE_CURRENT)) - }.also { - setStyles(it, intent) - appWidgetManager.updateAppWidget(appWidgetId, it) + val savedTheme = sharedPref.getLong(getThemeWidgetKey(appWidgetId), 0) + val layoutId = if (savedTheme == 0L) R.layout.widget_luckynumber else R.layout.widget_luckynumber_dark + + val luckyNumber = getLuckyNumber(sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0), appWidgetId) + val appIntent = PendingIntent.getActivity(context, MainView.Section.LUCKY_NUMBER.id, + MainActivity.getStartIntent(context, MainView.Section.LUCKY_NUMBER, true), FLAG_UPDATE_CURRENT) + + val remoteView = RemoteViews(context.packageName, layoutId).apply { + setTextViewText(R.id.luckyNumberWidgetNumber, luckyNumber?.luckyNumber?.toString() ?: "#") + setOnClickPendingIntent(R.id.luckyNumberWidgetContainer, appIntent) } + + setStyles(remoteView, intent) + appWidgetManager.updateAppWidget(appWidgetId, remoteView) } } private fun onDelete(intent: Intent) { - intent.getIntExtra(EXTRA_APPWIDGET_ID, 0).let { - if (it != 0) sharedPref.delete(getStudentWidgetKey(it)) - } + val appWidgetId = intent.getIntExtra(EXTRA_APPWIDGET_ID, 0) + if (appWidgetId != 0) sharedPref.delete(getStudentWidgetKey(appWidgetId)) } private fun getLuckyNumber(studentId: Long, appWidgetId: Int): LuckyNumber? { @@ -96,19 +101,17 @@ class LuckyNumberWidgetProvider : BroadcastReceiver() { .filter { true } .flatMap { studentRepository.getSavedStudents().toMaybe() } .flatMap { students -> - students.singleOrNull { student -> student.id == studentId } - .let { student -> - when { - student != null -> Maybe.just(student) - studentId != 0L -> { - studentRepository.isCurrentStudentSet() - .filter { true } - .flatMap { studentRepository.getCurrentStudent(false).toMaybe() } - .doOnSuccess { sharedPref.putLong(getStudentWidgetKey(appWidgetId), it.id) } - } - else -> Maybe.empty() - } + val student = students.singleOrNull { student -> student.id == studentId } + when { + student != null -> Maybe.just(student) + studentId != 0L -> { + studentRepository.isCurrentStudentSet() + .filter { true } + .flatMap { studentRepository.getCurrentStudent(false).toMaybe() } + .doOnSuccess { sharedPref.putLong(getStudentWidgetKey(appWidgetId), it.id) } } + else -> Maybe.empty() + } } .flatMap { semesterRepository.getCurrentSemester(it).toMaybe() } .flatMap { luckyNumberRepository.getLuckyNumber(it) } @@ -123,11 +126,14 @@ class LuckyNumberWidgetProvider : BroadcastReceiver() { } private fun onOptionsChange(context: Context, intent: Intent) { - intent.extras?.let { extras -> - RemoteViews(context.packageName, R.layout.widget_luckynumber).apply { - setStyles(this, intent) - appWidgetManager.updateAppWidget(extras.getInt(EXTRA_APPWIDGET_ID), this) - } + intent.extras?.getInt(EXTRA_APPWIDGET_ID)?.let { appWidgetId -> + val savedTheme = sharedPref.getLong(getThemeWidgetKey(appWidgetId), 0) + val layoutId = if (savedTheme == 0L) R.layout.widget_luckynumber else R.layout.widget_luckynumber_dark + + val remoteView = RemoteViews(context.packageName, layoutId) + + setStyles(remoteView, intent) + appWidgetManager.updateAppWidget(appWidgetId, remoteView) } } @@ -144,7 +150,7 @@ class LuckyNumberWidgetProvider : BroadcastReceiver() { // 1x1 maxWidth < 150 && maxHeight < 110 -> { Timber.d("Lucky number widget size: 1x1") - views.run { + with(views) { setViewVisibility(R.id.luckyNumberWidgetImageTop, GONE) setViewVisibility(R.id.luckyNumberWidgetImageLeft, GONE) setViewVisibility(R.id.luckyNumberWidgetTitle, GONE) @@ -154,7 +160,7 @@ class LuckyNumberWidgetProvider : BroadcastReceiver() { // 1x2 maxWidth < 150 && maxHeight > 110 -> { Timber.d("Lucky number widget size: 1x2") - views.run { + with(views) { setViewVisibility(R.id.luckyNumberWidgetImageTop, VISIBLE) setViewVisibility(R.id.luckyNumberWidgetImageLeft, GONE) setViewVisibility(R.id.luckyNumberWidgetTitle, GONE) @@ -164,7 +170,7 @@ class LuckyNumberWidgetProvider : BroadcastReceiver() { // 2x1 maxWidth >= 150 && maxHeight <= 110 -> { Timber.d("Lucky number widget size: 2x1") - views.run { + with(views) { setViewVisibility(R.id.luckyNumberWidgetImageTop, GONE) setViewVisibility(R.id.luckyNumberWidgetImageLeft, VISIBLE) setViewVisibility(R.id.luckyNumberWidgetTitle, GONE) @@ -174,7 +180,7 @@ class LuckyNumberWidgetProvider : BroadcastReceiver() { // 2x2 and bigger else -> { Timber.d("Lucky number widget size: 2x2 and bigger") - views.run { + with(views) { setViewVisibility(R.id.luckyNumberWidgetImageTop, GONE) setViewVisibility(R.id.luckyNumberWidgetImageLeft, GONE) setViewVisibility(R.id.luckyNumberWidgetTitle, VISIBLE) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureActivity.kt index 79dd59bf..7636637f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureActivity.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureActivity.kt @@ -7,6 +7,7 @@ import android.content.Intent import android.os.Bundle import android.widget.Toast import android.widget.Toast.LENGTH_LONG +import androidx.appcompat.app.AlertDialog import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager import eu.davidea.flexibleadapter.items.AbstractFlexibleItem @@ -27,6 +28,8 @@ class TimetableWidgetConfigureActivity : BaseActivity + presenter.onThemeSelect(which) + } + .show() } override fun updateData(data: List) { @@ -72,4 +91,9 @@ class TimetableWidgetConfigureActivity : BaseActivity) { if (item is TimetableWidgetConfigureItem) { - registerStudent(item.student) + selectedStudent = item.student + + if (isFromProvider) registerStudent(selectedStudent) + else view?.showThemeDialog() } } + fun onThemeSelect(index: Int) { + appWidgetId?.let { + sharedPref.putLong(getThemeWidgetKey(it), index.toLong()) + } + registerStudent(selectedStudent) + } + + fun onDismissThemeView(){ + view?.finishView() + } + private fun loadData() { disposable.add(studentRepository.getSavedStudents(false) .map { it to appWidgetId?.let { id -> sharedPref.getLong(getStudentWidgetKey(id), 0) } } @@ -46,18 +63,23 @@ class TimetableWidgetConfigurePresenter @Inject constructor( .subscribe({ when { it.isEmpty() -> view?.openLoginView() - it.size == 1 && !isFromProvider -> registerStudent(it.single().student) + it.size == 1 && !isFromProvider -> { + selectedStudent = it.single().student + view?.showThemeDialog() + } else -> view?.updateData(it) } }, { errorHandler.dispatch(it) })) } - private fun registerStudent(student: Student) { - appWidgetId?.also { - sharedPref.putLong(getStudentWidgetKey(it), student.id) - view?.apply { - updateTimetableWidget(it) - setSuccessResult(it) + private fun registerStudent(student: Student?) { + requireNotNull(student) + + appWidgetId?.let { id -> + sharedPref.putLong(getStudentWidgetKey(id), student.id) + view?.run { + updateTimetableWidget(id) + setSuccessResult(id) } } view?.finishView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureView.kt index 98c800d4..7cac892d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureView.kt @@ -10,6 +10,8 @@ interface TimetableWidgetConfigureView : BaseView { fun updateTimetableWidget(widgetId: Int) + fun showThemeDialog() + fun setSuccessResult(widgetId: Int) fun finishView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt index a0a519e2..a2591ac8 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt @@ -1,5 +1,6 @@ package io.github.wulkanowy.ui.modules.timetablewidget +import android.annotation.SuppressLint import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID import android.content.Context import android.content.Intent @@ -18,6 +19,7 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.data.repositories.timetable.TimetableRepository import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getDateWidgetKey import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getStudentWidgetKey +import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getThemeWidgetKey import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.toFormattedString import io.reactivex.Maybe @@ -36,6 +38,8 @@ class TimetableWidgetFactory( private var lessons = emptyList() + private var layoutId: Int? = null + override fun getLoadingView() = null override fun hasStableIds() = true @@ -55,16 +59,18 @@ class TimetableWidgetFactory( val date = LocalDate.ofEpochDay(sharedPref.getLong(getDateWidgetKey(appWidgetId), 0)) val studentId = sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0) + val savedTheme = sharedPref.getLong(getThemeWidgetKey(appWidgetId), 0) + layoutId = if (savedTheme == 0L) R.layout.item_widget_timetable else R.layout.item_widget_timetable_dark + lessons = try { studentRepository.isStudentSaved() .filter { true } .flatMap { studentRepository.getSavedStudents().toMaybe() } .flatMap { - it.singleOrNull { student -> student.id == studentId } - .let { student -> - if (student != null) Maybe.just(student) - else Maybe.empty() - } + val student = it.singleOrNull { student -> student.id == studentId } + + if (student != null) Maybe.just(student) + else Maybe.empty() } .flatMap { semesterRepository.getCurrentSemester(it).toMaybe() } .flatMap { timetableRepository.getTimetable(it, date, date).toMaybe() } @@ -78,39 +84,42 @@ class TimetableWidgetFactory( } } + @SuppressLint("DefaultLocale") override fun getViewAt(position: Int): RemoteViews? { if (position == INVALID_POSITION || lessons.getOrNull(position) == null) return null - return RemoteViews(context.packageName, R.layout.item_widget_timetable).apply { - lessons[position].let { - setTextViewText(R.id.timetableWidgetItemSubject, it.subject) - setTextViewText(R.id.timetableWidgetItemNumber, it.number.toString()) - setTextViewText(R.id.timetableWidgetItemTime, it.start.toFormattedString("HH:mm") + - " - ${it.end.toFormattedString("HH:mm")}") + return RemoteViews(context.packageName, layoutId!!).apply { + val lesson = lessons[position] - if (it.room.isNotBlank()) { - setTextViewText(R.id.timetableWidgetItemRoom, "${context.getString(R.string.timetable_room)} ${it.room}") - } else setTextViewText(R.id.timetableWidgetItemRoom, "") + setTextViewText(R.id.timetableWidgetItemSubject, lesson.subject) + setTextViewText(R.id.timetableWidgetItemNumber, lesson.number.toString()) + setTextViewText(R.id.timetableWidgetItemTime, lesson.start.toFormattedString("HH:mm") + + " - ${lesson.end.toFormattedString("HH:mm")}") - if (it.info.isNotBlank()) { - setViewVisibility(R.id.timetableWidgetItemDescription, VISIBLE) - setTextViewText(R.id.timetableWidgetItemDescription, it.run { + if (lesson.room.isNotBlank()) { + setTextViewText(R.id.timetableWidgetItemRoom, "${context.getString(R.string.timetable_room)} ${lesson.room}") + } else setTextViewText(R.id.timetableWidgetItemRoom, "") + + if (lesson.info.isNotBlank()) { + setViewVisibility(R.id.timetableWidgetItemDescription, VISIBLE) + setTextViewText(R.id.timetableWidgetItemDescription, + with(lesson) { when (true) { - canceled && !changes -> "Lekcja odwołana: $info" - changes && teacher.isNotBlank() -> "Zastępstwo: $teacher" - changes && teacher.isBlank() -> "Zastępstwo, ${info.decapitalize()}" - else -> it.info.capitalize() + canceled && !changes -> "Lekcja odwołana: ${lesson.info}" + changes && teacher.isNotBlank() -> "Zastępstwo: ${lesson.teacher}" + changes && teacher.isBlank() -> "Zastępstwo, ${lesson.info.decapitalize()}" + else -> info.capitalize() } }) - } else setViewVisibility(R.id.timetableWidgetItemDescription, GONE) + } else setViewVisibility(R.id.timetableWidgetItemDescription, GONE) - if (it.canceled) { - setInt(R.id.timetableWidgetItemSubject, "setPaintFlags", - STRIKE_THRU_TEXT_FLAG or ANTI_ALIAS_FLAG) - } else { - setInt(R.id.timetableWidgetItemSubject, "setPaintFlags", ANTI_ALIAS_FLAG) - } + if (lesson.canceled) { + setInt(R.id.timetableWidgetItemSubject, "setPaintFlags", + STRIKE_THRU_TEXT_FLAG or ANTI_ALIAS_FLAG) + } else { + setInt(R.id.timetableWidgetItemSubject, "setPaintFlags", ANTI_ALIAS_FLAG) } + setOnClickFillInIntent(R.id.timetableWidgetItemContainer, Intent()) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetProvider.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetProvider.kt index dadbe050..416696a5 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetProvider.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetProvider.kt @@ -54,21 +54,24 @@ class TimetableWidgetProvider : BroadcastReceiver() { lateinit var analytics: FirebaseAnalyticsHelper companion object { + + private const val EXTRA_TOGGLED_WIDGET_ID = "extraToggledWidget" + + private const val EXTRA_BUTTON_TYPE = "extraButtonType" + + private const val BUTTON_NEXT = "buttonNext" + + private const val BUTTON_PREV = "buttonPrev" + + private const val BUTTON_RESET = "buttonReset" + const val EXTRA_FROM_PROVIDER = "extraFromProvider" - const val EXTRA_TOGGLED_WIDGET_ID = "extraToggledWidget" - - const val EXTRA_BUTTON_TYPE = "extraButtonType" - - const val BUTTON_NEXT = "buttonNext" - - const val BUTTON_PREV = "buttonPrev" - - const val BUTTON_RESET = "buttonReset" - fun getDateWidgetKey(appWidgetId: Int) = "timetable_widget_date_$appWidgetId" fun getStudentWidgetKey(appWidgetId: Int) = "timetable_widget_student_$appWidgetId" + + fun getThemeWidgetKey(appWidgetId: Int) = "timetable_widget_theme_$appWidgetId" } override fun onReceive(context: Context, intent: Intent) { @@ -102,45 +105,56 @@ class TimetableWidgetProvider : BroadcastReceiver() { } private fun onDelete(intent: Intent) { - intent.getIntExtra(EXTRA_APPWIDGET_ID, 0).let { - if (it != 0) { - sharedPref.apply { - delete(getStudentWidgetKey(it)) - delete(getDateWidgetKey(it)) - } + val appWidgetId = intent.getIntExtra(EXTRA_APPWIDGET_ID, 0) + + if (appWidgetId != 0) { + with(sharedPref) { + delete(getStudentWidgetKey(appWidgetId)) + delete(getDateWidgetKey(appWidgetId)) } } } @SuppressLint("DefaultLocale") private fun updateWidget(context: Context, appWidgetId: Int, date: LocalDate, student: Student?) { - RemoteViews(context.packageName, R.layout.widget_timetable).apply { + val savedTheme = sharedPref.getLong(getThemeWidgetKey(appWidgetId), 0) + val layoutId = if (savedTheme == 0L) R.layout.widget_timetable else R.layout.widget_timetable_dark + + val nextNavIntent = createNavIntent(context, appWidgetId, appWidgetId, BUTTON_NEXT) + val prevNavIntent = createNavIntent(context, -appWidgetId, appWidgetId, BUTTON_PREV) + val resetNavIntent = createNavIntent(context, Int.MAX_VALUE - appWidgetId, appWidgetId, BUTTON_RESET) + val adapterIntent = Intent(context, TimetableWidgetService::class.java) + .apply { + putExtra(EXTRA_APPWIDGET_ID, appWidgetId) + //make Intent unique + action = appWidgetId.toString() + } + val accountIntent = PendingIntent.getActivity(context, -Int.MAX_VALUE + appWidgetId, + Intent(context, TimetableWidgetConfigureActivity::class.java).apply { + addFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK) + putExtra(EXTRA_APPWIDGET_ID, appWidgetId) + putExtra(EXTRA_FROM_PROVIDER, true) + }, FLAG_UPDATE_CURRENT) + val appIntent = PendingIntent.getActivity(context, MainView.Section.TIMETABLE.id, + MainActivity.getStartIntent(context, MainView.Section.TIMETABLE, true), FLAG_UPDATE_CURRENT) + + val remoteView = RemoteViews(context.packageName, layoutId).apply { setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty) setTextViewText(R.id.timetableWidgetDate, "${date.shortcutWeekDayName.capitalize()} ${date.toFormattedString()}") setTextViewText(R.id.timetableWidgetName, student?.studentName ?: context.getString(R.string.all_no_data)) - setRemoteAdapter(R.id.timetableWidgetList, Intent(context, TimetableWidgetService::class.java) - .apply { putExtra(EXTRA_APPWIDGET_ID, appWidgetId) }) - setOnClickPendingIntent(R.id.timetableWidgetNext, createNavIntent(context, appWidgetId, appWidgetId, BUTTON_NEXT)) - setOnClickPendingIntent(R.id.timetableWidgetPrev, createNavIntent(context, -appWidgetId, appWidgetId, BUTTON_PREV)) - createNavIntent(context, Int.MAX_VALUE - appWidgetId, appWidgetId, BUTTON_RESET).let { - setOnClickPendingIntent(R.id.timetableWidgetDate, it) - setOnClickPendingIntent(R.id.timetableWidgetName, it) - } - setOnClickPendingIntent(R.id.timetableWidgetAccount, PendingIntent.getActivity(context, -Int.MAX_VALUE + appWidgetId, - Intent(context, TimetableWidgetConfigureActivity::class.java).apply { - addFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK) - putExtra(EXTRA_APPWIDGET_ID, appWidgetId) - putExtra(EXTRA_FROM_PROVIDER, true) - }, FLAG_UPDATE_CURRENT)) - setPendingIntentTemplate(R.id.timetableWidgetList, - PendingIntent.getActivity(context, MainView.Section.TIMETABLE.id, - MainActivity.getStartIntent(context, MainView.Section.TIMETABLE, true), FLAG_UPDATE_CURRENT)) - }.also { - sharedPref.putLong(getDateWidgetKey(appWidgetId), date.toEpochDay(), true) - appWidgetManager.apply { - notifyAppWidgetViewDataChanged(appWidgetId, R.id.timetableWidgetList) - updateAppWidget(appWidgetId, it) - } + setRemoteAdapter(R.id.timetableWidgetList, adapterIntent) + setOnClickPendingIntent(R.id.timetableWidgetNext, nextNavIntent) + setOnClickPendingIntent(R.id.timetableWidgetPrev, prevNavIntent) + setOnClickPendingIntent(R.id.timetableWidgetDate, resetNavIntent) + setOnClickPendingIntent(R.id.timetableWidgetName, resetNavIntent) + setOnClickPendingIntent(R.id.timetableWidgetAccount, accountIntent) + setPendingIntentTemplate(R.id.timetableWidgetList, appIntent) + } + + sharedPref.putLong(getDateWidgetKey(appWidgetId), date.toEpochDay(), true) + with(appWidgetManager) { + notifyAppWidgetViewDataChanged(appWidgetId, R.id.timetableWidgetList) + updateAppWidget(appWidgetId, remoteView) } } @@ -159,19 +173,17 @@ class TimetableWidgetProvider : BroadcastReceiver() { .filter { true } .flatMap { studentRepository.getSavedStudents(false).toMaybe() } .flatMap { students -> - students.singleOrNull { student -> student.id == studentId } - .let { student -> - when { - student != null -> Maybe.just(student) - studentId != 0L -> { - studentRepository.isCurrentStudentSet() - .filter { true } - .flatMap { studentRepository.getCurrentStudent(false).toMaybe() } - .doOnSuccess { sharedPref.putLong(getStudentWidgetKey(appWidgetId), it.id) } - } - else -> Maybe.empty() - } + val student = students.singleOrNull { student -> student.id == studentId } + when { + student != null -> Maybe.just(student) + studentId != 0L -> { + studentRepository.isCurrentStudentSet() + .filter { true } + .flatMap { studentRepository.getCurrentStudent(false).toMaybe() } + .doOnSuccess { sharedPref.putLong(getStudentWidgetKey(appWidgetId), it.id) } } + else -> Maybe.empty() + } } .subscribeOn(schedulers.backgroundThread) .blockingGet() diff --git a/app/src/main/res/drawable/backgorund_luckynumber_widget.xml b/app/src/main/res/drawable/background_luckynumber_widget.xml similarity index 78% rename from app/src/main/res/drawable/backgorund_luckynumber_widget.xml rename to app/src/main/res/drawable/background_luckynumber_widget.xml index 38cbde9b..f29744d0 100644 --- a/app/src/main/res/drawable/backgorund_luckynumber_widget.xml +++ b/app/src/main/res/drawable/background_luckynumber_widget.xml @@ -1,6 +1,6 @@ - + diff --git a/app/src/main/res/drawable/background_luckynumber_widget_dark.xml b/app/src/main/res/drawable/background_luckynumber_widget_dark.xml new file mode 100644 index 00000000..fa15fd85 --- /dev/null +++ b/app/src/main/res/drawable/background_luckynumber_widget_dark.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/layout/item_widget_timetable.xml b/app/src/main/res/layout/item_widget_timetable.xml index bffc0bd5..a700fcc0 100644 --- a/app/src/main/res/layout/item_widget_timetable.xml +++ b/app/src/main/res/layout/item_widget_timetable.xml @@ -1,85 +1,95 @@ - - - - + android:background="@android:color/white"> - + - + - - + + + + + + + + + diff --git a/app/src/main/res/layout/item_widget_timetable_dark.xml b/app/src/main/res/layout/item_widget_timetable_dark.xml new file mode 100644 index 00000000..011cde6e --- /dev/null +++ b/app/src/main/res/layout/item_widget_timetable_dark.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/widget_luckynumber.xml b/app/src/main/res/layout/widget_luckynumber.xml index ec12e421..360a1970 100644 --- a/app/src/main/res/layout/widget_luckynumber.xml +++ b/app/src/main/res/layout/widget_luckynumber.xml @@ -4,7 +4,7 @@ android:id="@+id/luckyNumberWidgetContainer" android:layout_width="fill_parent" android:layout_height="fill_parent" - android:background="@drawable/backgorund_luckynumber_widget" + android:background="@drawable/background_luckynumber_widget" android:gravity="center" android:padding="10dp" tools:context=".ui.modules.luckynumberwidget.LuckyNumberWidgetProvider"> diff --git a/app/src/main/res/layout/widget_luckynumber_dark.xml b/app/src/main/res/layout/widget_luckynumber_dark.xml new file mode 100644 index 00000000..77174730 --- /dev/null +++ b/app/src/main/res/layout/widget_luckynumber_dark.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/widget_timetable_dark.xml b/app/src/main/res/layout/widget_timetable_dark.xml new file mode 100644 index 00000000..3a301eb9 --- /dev/null +++ b/app/src/main/res/layout/widget_timetable_dark.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 62803deb..e4db5b87 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -260,6 +260,9 @@ Brak lekcji + Wybierz motyw + Jasny + Ciemny diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f7accebf..a2bf9e00 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -31,9 +31,10 @@ #d65757 #3d5f9c - #595959 - #fefefe - #fefefe - #393939 - #fefefe + + + + #121212 + #272727 + #383838 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8ebb4b84..c4e5ed9b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -244,6 +244,9 @@ No lessons + Choose theme + Light + Dark diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index c8b41a1a..8c693f73 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -23,6 +23,7 @@