diff --git a/app/build.gradle b/app/build.gradle
index de3b49134..cf7223bae 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -16,13 +16,13 @@ apply from: 'hooks.gradle'
android {
namespace 'io.github.wulkanowy'
- compileSdkVersion 32
+ compileSdkVersion 33
defaultConfig {
applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 21
- targetSdkVersion 32
+ targetSdkVersion 33
versionCode 116
versionName "1.8.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -193,9 +193,9 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines"
- implementation "androidx.core:core-ktx:1.8.0"
+ implementation "androidx.core:core-ktx:1.9.0"
implementation 'androidx.core:core-splashscreen:1.0.0'
- implementation "androidx.activity:activity-ktx:1.5.1"
+ implementation "androidx.activity:activity-ktx:1.6.1"
implementation "androidx.appcompat:appcompat:1.5.1"
implementation "androidx.fragment:fragment-ktx:1.5.4"
implementation "androidx.annotation:annotation:1.5.0"
@@ -271,9 +271,9 @@ dependencies {
testImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
kaptTest "com.google.dagger:hilt-android-compiler:$hilt_version"
- androidTestImplementation "androidx.test:core:1.4.0"
- androidTestImplementation "androidx.test:runner:1.4.0"
- androidTestImplementation "androidx.test.ext:junit:1.1.3"
+ androidTestImplementation "androidx.test:core:1.5.0"
+ androidTestImplementation "androidx.test:runner:1.5.1"
+ androidTestImplementation "androidx.test.ext:junit:1.1.4"
androidTestImplementation "io.mockk:mockk-android:$mockk"
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
}
diff --git a/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml
index 7dbec2cb9..b7b756b9e 100644
--- a/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -2,4 +2,5 @@
-
\ No newline at end of file
+
+
diff --git a/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml
deleted file mode 100644
index 7dbec2cb9..000000000
--- a/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/debug/res/mipmap-hdpi/ic_launcher_round.png b/app/src/debug/res/mipmap-hdpi/ic_launcher_round.png
deleted file mode 100644
index 81e723ecc..000000000
Binary files a/app/src/debug/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/debug/res/mipmap-mdpi/ic_launcher_round.png b/app/src/debug/res/mipmap-mdpi/ic_launcher_round.png
deleted file mode 100644
index 394b57076..000000000
Binary files a/app/src/debug/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.png
deleted file mode 100644
index 365b4d663..000000000
Binary files a/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png
deleted file mode 100644
index 463c089b3..000000000
Binary files a/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png
deleted file mode 100644
index 53d6f5bbd..000000000
Binary files a/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7835db902..3773093b2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -8,7 +8,8 @@
-
+
+
@@ -36,13 +37,14 @@
+ tools:ignore="DataExtractionRules,UnusedAttribute">
(ARGUMENT_KEY)
val binding = DialogErrorBinding.inflate(layoutInflater)
binding.bindErrorDetails(error)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt b/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt
index 2d83bbbf9..e1c234575 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt
@@ -1,6 +1,9 @@
package io.github.wulkanowy.ui.base
+import android.content.pm.PackageInfo
+import android.content.pm.PackageManager
import android.content.pm.PackageManager.GET_ACTIVITIES
+import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
@@ -41,9 +44,8 @@ class ThemeManager @Inject constructor(private val preferencesRepository: Prefer
)
}
- private fun isThemeApplicable(activity: AppCompatActivity) =
- activity.packageManager
- .getPackageInfo(activity.packageName, GET_ACTIVITIES)
+ private fun isThemeApplicable(activity: AppCompatActivity): Boolean =
+ getPackageInfo(activity)
.activities
.singleOrNull { it.name == activity::class.java.canonicalName }
?.theme
@@ -52,4 +54,14 @@ class ThemeManager @Inject constructor(private val preferencesRepository: Prefer
|| it == R.style.WulkanowyTheme_Login || it == R.style.WulkanowyTheme_Login_Black
|| it == R.style.WulkanowyTheme_MessageSend || it == R.style.WulkanowyTheme_MessageSend_Black
}
+
+ @Suppress("DEPRECATION")
+ private fun getPackageInfo(activity: AppCompatActivity): PackageInfo {
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ activity.packageManager.getPackageInfo(
+ activity.packageName,
+ PackageManager.PackageInfoFlags.of(GET_ACTIVITIES.toLong())
+ )
+ } else activity.packageManager.getPackageInfo(activity.packageName, GET_ACTIVITIES)
+ }
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsFragment.kt
index c6fe8a69b..41b97b075 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsFragment.kt
@@ -6,6 +6,7 @@ import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AlertDialog
+import androidx.core.os.bundleOf
import androidx.core.view.get
import androidx.core.view.isVisible
import dagger.hilt.android.AndroidEntryPoint
@@ -21,6 +22,7 @@ import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoFragment
import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoView
import io.github.wulkanowy.utils.createNameInitialsDrawable
import io.github.wulkanowy.utils.nickOrName
+import io.github.wulkanowy.utils.serializable
import javax.inject.Inject
@AndroidEntryPoint
@@ -37,10 +39,9 @@ class AccountDetailsFragment :
private const val ARGUMENT_KEY = "Data"
- fun newInstance(student: Student) =
- AccountDetailsFragment().apply {
- arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, student) }
- }
+ fun newInstance(student: Student) = AccountDetailsFragment().apply {
+ arguments = bundleOf(ARGUMENT_KEY to student)
+ }
}
@Suppress("DEPRECATION")
@@ -52,7 +53,7 @@ class AccountDetailsFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentAccountDetailsBinding.bind(view)
- presenter.onAttachView(this, requireArguments()[ARGUMENT_KEY] as Student)
+ presenter.onAttachView(this, requireArguments().serializable(ARGUMENT_KEY))
}
override fun initView() {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditDialog.kt
index 21a7a492d..6e2bc8c44 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditDialog.kt
@@ -4,11 +4,13 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.core.os.bundleOf
import androidx.recyclerview.widget.GridLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.databinding.DialogAccountEditBinding
import io.github.wulkanowy.ui.base.BaseDialogFragment
+import io.github.wulkanowy.utils.serializable
import javax.inject.Inject
@AndroidEntryPoint
@@ -24,12 +26,9 @@ class AccountEditDialog : BaseDialogFragment(), Accoun
private const val ARGUMENT_KEY = "student_with_semesters"
- fun newInstance(student: Student) =
- AccountEditDialog().apply {
- arguments = Bundle().apply {
- putSerializable(ARGUMENT_KEY, student)
- }
- }
+ fun newInstance(student: Student) = AccountEditDialog().apply {
+ arguments = bundleOf(ARGUMENT_KEY to student)
+ }
}
override fun onCreate(savedInstanceState: Bundle?) {
@@ -45,7 +44,7 @@ class AccountEditDialog : BaseDialogFragment(), Accoun
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- presenter.onAttachView(this, requireArguments()[ARGUMENT_KEY] as Student)
+ presenter.onAttachView(this, requireArguments().serializable(ARGUMENT_KEY))
}
override fun initView() {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickDialog.kt
index 4279102e1..d23978f5f 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickDialog.kt
@@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.core.os.bundleOf
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
@@ -13,6 +14,7 @@ import io.github.wulkanowy.ui.modules.account.AccountAdapter
import io.github.wulkanowy.ui.modules.account.AccountFragment
import io.github.wulkanowy.ui.modules.account.AccountItem
import io.github.wulkanowy.ui.modules.main.MainActivity
+import io.github.wulkanowy.utils.serializable
import javax.inject.Inject
@AndroidEntryPoint
@@ -30,9 +32,7 @@ class AccountQuickDialog : BaseDialogFragment(), Acco
fun newInstance(studentsWithSemesters: List) =
AccountQuickDialog().apply {
- arguments = Bundle().apply {
- putSerializable(STUDENTS_ARGUMENT_KEY, studentsWithSemesters.toTypedArray())
- }
+ arguments = bundleOf(STUDENTS_ARGUMENT_KEY to studentsWithSemesters.toTypedArray())
}
}
@@ -49,8 +49,8 @@ class AccountQuickDialog : BaseDialogFragment(), Acco
@Suppress("UNCHECKED_CAST")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- val studentsWithSemesters =
- (requireArguments()[STUDENTS_ARGUMENT_KEY] as Array).toList()
+ val studentsWithSemesters = requireArguments()
+ .serializable>(STUDENTS_ARGUMENT_KEY).toList()
presenter.onAttachView(this, studentsWithSemesters)
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceDialog.kt
index 9b5c63e4c..eab24f91d 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceDialog.kt
@@ -4,11 +4,13 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.databinding.DialogAttendanceBinding
import io.github.wulkanowy.utils.descriptionRes
import io.github.wulkanowy.utils.lifecycleAwareVariable
+import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.toFormattedString
class AttendanceDialog : DialogFragment() {
@@ -22,16 +24,14 @@ class AttendanceDialog : DialogFragment() {
private const val ARGUMENT_KEY = "Item"
fun newInstance(exam: Attendance) = AttendanceDialog().apply {
- arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) }
+ arguments = bundleOf(ARGUMENT_KEY to exam)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- arguments?.run {
- attendance = getSerializable(ARGUMENT_KEY) as Attendance
- }
+ attendance = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceDialog.kt
index 477b762b9..7834b6e8b 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceDialog.kt
@@ -4,11 +4,13 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.data.db.entities.Conference
import io.github.wulkanowy.databinding.DialogConferenceBinding
import io.github.wulkanowy.utils.lifecycleAwareVariable
+import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.toFormattedString
class ConferenceDialog : DialogFragment() {
@@ -22,16 +24,14 @@ class ConferenceDialog : DialogFragment() {
private const val ARGUMENT_KEY = "item"
fun newInstance(conference: Conference) = ConferenceDialog().apply {
- arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, conference) }
+ arguments = bundleOf(ARGUMENT_KEY to conference)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- arguments?.let {
- conference = it.getSerializable(ARGUMENT_KEY) as Conference
- }
+ conference = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
@@ -57,4 +57,4 @@ class ConferenceDialog : DialogFragment() {
conferenceDialogAgendaTitle.isVisible = conference.agenda.isNotBlank()
}
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamDialog.kt
index 41adc008a..876b563f9 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamDialog.kt
@@ -4,12 +4,14 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.databinding.DialogExamBinding
import io.github.wulkanowy.utils.lifecycleAwareVariable
import io.github.wulkanowy.utils.openCalendarEventAdd
+import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.toFormattedString
import java.time.LocalTime
@@ -24,16 +26,14 @@ class ExamDialog : DialogFragment() {
private const val ARGUMENT_KEY = "Item"
fun newInstance(exam: Exam) = ExamDialog().apply {
- arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) }
+ arguments = bundleOf(ARGUMENT_KEY to exam)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- arguments?.run {
- exam = getSerializable(ARGUMENT_KEY) as Exam
- }
+ exam = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt
index 34594111f..a1ef2ec5a 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt
@@ -5,6 +5,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.ViewGroup
+import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Grade
@@ -27,22 +28,19 @@ class GradeDetailsDialog : DialogFragment() {
private const val COLOR_THEME_KEY = "Theme"
- fun newInstance(grade: Grade, colorTheme: GradeColorTheme) =
- GradeDetailsDialog().apply {
- arguments = Bundle().apply {
- putSerializable(ARGUMENT_KEY, grade)
- putSerializable(COLOR_THEME_KEY, colorTheme)
- }
- }
+ fun newInstance(grade: Grade, colorTheme: GradeColorTheme) = GradeDetailsDialog().apply {
+ arguments = bundleOf(
+ ARGUMENT_KEY to grade,
+ COLOR_THEME_KEY to colorTheme
+ )
+ }
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- arguments?.run {
- grade = getSerializable(ARGUMENT_KEY) as Grade
- gradeColorTheme = getSerializable(COLOR_THEME_KEY) as GradeColorTheme
- }
+ grade = requireArguments().serializable(ARGUMENT_KEY)
+ gradeColorTheme = requireArguments().serializable(COLOR_THEME_KEY)
}
override fun onCreateView(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt
index 2af59c011..edc384c5e 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt
@@ -15,6 +15,7 @@ import io.github.wulkanowy.ui.modules.grade.GradeFragment
import io.github.wulkanowy.ui.modules.grade.GradeView
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.getThemeAttrColor
+import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.setOnItemSelectedListener
import javax.inject.Inject
@@ -48,8 +49,8 @@ class GradeStatisticsFragment :
messageContainer = binding.gradeStatisticsRecycler
presenter.onAttachView(
view = this,
- type = savedInstanceState?.getSerializable(SAVED_CHART_TYPE) as? GradeStatisticsItem.DataType,
- subjectName = savedInstanceState?.getSerializable(SAVED_SUBJECT_NAME) as? String,
+ type = savedInstanceState?.serializable(SAVED_CHART_TYPE),
+ subjectName = savedInstanceState?.serializable(SAVED_SUBJECT_NAME),
)
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsDialog.kt
index f9d463510..5e2cc65dc 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsDialog.kt
@@ -7,6 +7,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import androidx.core.os.bundleOf
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
@@ -14,6 +15,7 @@ import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.databinding.DialogHomeworkBinding
import io.github.wulkanowy.ui.base.BaseDialogFragment
import io.github.wulkanowy.utils.openInternetBrowser
+import io.github.wulkanowy.utils.serializable
import javax.inject.Inject
@AndroidEntryPoint
@@ -35,16 +37,14 @@ class HomeworkDetailsDialog : BaseDialogFragment(), Homew
private const val ARGUMENT_KEY = "Item"
fun newInstance(homework: Homework) = HomeworkDetailsDialog().apply {
- arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, homework) }
+ arguments = bundleOf(ARGUMENT_KEY to homework)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- arguments?.run {
- homework = getSerializable(ARGUMENT_KEY) as Homework
- }
+ homework = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt
index aac60b56d..8f237e537 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt
@@ -2,8 +2,11 @@ package io.github.wulkanowy.ui.modules.login
import android.content.Context
import android.content.Intent
+import android.content.pm.PackageManager
+import android.os.Build.VERSION_CODES.TIRAMISU
import android.os.Bundle
import android.view.MenuItem
+import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.commit
import dagger.hilt.android.AndroidEntryPoint
@@ -16,6 +19,9 @@ import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
import io.github.wulkanowy.ui.modules.login.recover.LoginRecoverFragment
import io.github.wulkanowy.ui.modules.login.studentselect.LoginStudentSelectFragment
import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment
+import io.github.wulkanowy.ui.modules.main.MainActivity
+import io.github.wulkanowy.ui.modules.notifications.NotificationsFragment
+import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.UpdateHelper
import javax.inject.Inject
@@ -28,6 +34,9 @@ class LoginActivity : BaseActivity(), Logi
@Inject
lateinit var updateHelper: UpdateHelper
+ @Inject
+ lateinit var appInfo: AppInfo
+
companion object {
fun getStartIntent(context: Context) = Intent(context, LoginActivity::class.java)
}
@@ -55,7 +64,7 @@ class LoginActivity : BaseActivity(), Logi
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
- if (item.itemId == android.R.id.home) onBackPressed()
+ if (item.itemId == android.R.id.home) onBackPressedDispatcher.onBackPressed()
return true
}
@@ -71,6 +80,22 @@ class LoginActivity : BaseActivity(), Logi
openFragment(LoginStudentSelectFragment.newInstance(studentsWithSemesters))
}
+ fun navigateToNotifications() {
+ val isNotificationsPermissionRequired = appInfo.systemVersion >= TIRAMISU
+ val isPermissionGranted = ContextCompat.checkSelfPermission(
+ this, "android.permission.POST_NOTIFICATIONS"
+ ) == PackageManager.PERMISSION_GRANTED
+
+ if (isNotificationsPermissionRequired && !isPermissionGranted) {
+ openFragment(NotificationsFragment.newInstance(), clearBackStack = true)
+ } else navigateToFinish()
+ }
+
+ fun navigateToFinish() {
+ startActivity(MainActivity.getStartIntent(this))
+ finish()
+ }
+
fun onAdvancedLoginClick() {
openFragment(LoginAdvancedFragment.newInstance())
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverFragment.kt
index 786bbfce8..b9afba986 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverFragment.kt
@@ -98,7 +98,7 @@ class LoginRecoverFragment :
loginRecoverButton.setOnClickListener { presenter.onRecoverClick() }
loginRecoverErrorRetry.setOnClickListener { presenter.onRecoverClick() }
loginRecoverErrorDetails.setOnClickListener { presenter.onDetailsClick() }
- loginRecoverLogin.setOnClickListener { (activity as LoginActivity).onBackPressed() }
+ loginRecoverLogin.setOnClickListener { (activity as LoginActivity).onBackPressedDispatcher.onBackPressed() }
}
with(bindingLocal.loginRecoverHost) {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt
index c42a4e9d1..03aced14e 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt
@@ -13,10 +13,10 @@ import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.databinding.FragmentLoginStudentSelectBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.login.LoginActivity
-import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.openEmailClient
import io.github.wulkanowy.utils.openInternetBrowser
+import io.github.wulkanowy.utils.serializable
import javax.inject.Inject
@AndroidEntryPoint
@@ -51,7 +51,7 @@ class LoginStudentSelectFragment :
binding = FragmentLoginStudentSelectBinding.bind(view)
presenter.onAttachView(
view = this,
- students = requireArguments().getSerializable(ARG_STUDENTS) as List,
+ students = requireArguments().serializable(ARG_STUDENTS),
)
}
@@ -79,9 +79,8 @@ class LoginStudentSelectFragment :
}
}
- override fun openMainView() {
- startActivity(MainActivity.getStartIntent(requireContext()))
- requireActivity().finish()
+ override fun navigateToNext() {
+ (requireActivity() as LoginActivity).navigateToNotifications()
}
override fun showProgress(show: Boolean) {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt
index 3455b3cf1..5a40a6bc3 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt
@@ -100,7 +100,7 @@ class LoginStudentSelectPresenter @Inject constructor(
}
is Resource.Success -> {
syncManager.startOneTimeSyncWorker(quiet = true)
- view?.openMainView()
+ view?.navigateToNext()
logRegisterEvent(studentsWithSemesters)
}
is Resource.Error -> {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt
index f2acd76c5..8d403271b 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt
@@ -9,7 +9,7 @@ interface LoginStudentSelectView : BaseView {
fun updateData(data: List>)
- fun openMainView()
+ fun navigateToNext()
fun showProgress(show: Boolean)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt
index 36c40d156..ab27ecf3f 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt
@@ -18,11 +18,7 @@ import io.github.wulkanowy.databinding.FragmentLoginSymbolBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.ui.modules.login.LoginData
-import io.github.wulkanowy.utils.AppInfo
-import io.github.wulkanowy.utils.hideSoftInput
-import io.github.wulkanowy.utils.openEmailClient
-import io.github.wulkanowy.utils.openInternetBrowser
-import io.github.wulkanowy.utils.showSoftInput
+import io.github.wulkanowy.utils.*
import javax.inject.Inject
@AndroidEntryPoint
@@ -54,7 +50,7 @@ class LoginSymbolFragment :
binding = FragmentLoginSymbolBinding.bind(view)
presenter.onAttachView(
view = this,
- loginData = requireArguments().getSerializable(SAVED_LOGIN_DATA) as LoginData,
+ loginData = requireArguments().serializable(SAVED_LOGIN_DATA),
)
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt
index 5cd6fa103..d332ee350 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt
@@ -6,6 +6,8 @@ import android.os.Build.VERSION_CODES.P
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
+import androidx.activity.OnBackPressedCallback
+import androidx.activity.addCallback
import androidx.core.view.ViewCompat
import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment
@@ -50,6 +52,8 @@ class MainActivity : BaseActivity(), MainVie
@Inject
lateinit var appInfo: AppInfo
+ private var onBackCallback: OnBackPressedCallback? = null
+
private var accountMenu: MenuItem? = null
private val overlayProvider by lazy { ElevationOverlayProvider(this) }
@@ -88,6 +92,9 @@ class MainActivity : BaseActivity(), MainVie
this.savedInstanceState = savedInstanceState
messageContainer = binding.mainMessageContainer
updateHelper.messageContainer = binding.mainFragmentContainer
+ onBackCallback = onBackPressedDispatcher.addCallback(this, enabled = false) {
+ presenter.onBackPressed()
+ }
val destination = intent.getStringExtra(EXTRA_START_DESTINATION)
?.takeIf { savedInstanceState == null }
@@ -266,6 +273,7 @@ class MainActivity : BaseActivity(), MainVie
analytics.popCurrentScreen(navController.currentFrag!!::class.simpleName)
navController.pushFragment(fragment)
+ onBackCallback?.isEnabled = !isRootView
}
override fun popView(depth: Int) {
@@ -273,10 +281,7 @@ class MainActivity : BaseActivity(), MainVie
analytics.popCurrentScreen(navController.currentFrag!!::class.simpleName)
navController.safelyPopFragments(depth)
- }
-
- override fun onBackPressed() {
- presenter.onBackPressed { super.onBackPressed() }
+ onBackCallback?.isEnabled = !isRootView
}
override fun showStudentAvatar(student: Student) {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt
index 9c32d8583..458e966d4 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt
@@ -139,12 +139,9 @@ class MainPresenter @Inject constructor(
return true
}
- fun onBackPressed(default: () -> Unit) {
+ fun onBackPressed() {
Timber.i("Back pressed in main view")
- view?.run {
- if (isRootView) default()
- else popView()
- }
+ view?.popView()
}
fun onTabSelected(index: Int, wasSelected: Boolean): Boolean {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserDialog.kt
index 222412ef1..37f9a19b5 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserDialog.kt
@@ -10,6 +10,7 @@ import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.data.db.entities.Mailbox
import io.github.wulkanowy.databinding.DialogMailboxChooserBinding
import io.github.wulkanowy.ui.base.BaseDialogFragment
+import io.github.wulkanowy.utils.parcelableArray
import javax.inject.Inject
@AndroidEntryPoint
@@ -52,8 +53,7 @@ class MailboxChooserDialog : BaseDialogFragment(),
presenter.onAttachView(
view = this,
requireMailbox = requireArguments().getBoolean(REQUIRED_KEY, false),
- mailboxes = requireArguments().getParcelableArray(MAILBOX_KEY).orEmpty()
- .toList() as List,
+ mailboxes = requireArguments().parcelableArray(MAILBOX_KEY).orEmpty().toList(),
)
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt
index 8c6b0402b..6c54d9fcb 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt
@@ -13,6 +13,7 @@ import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.core.content.getSystemService
+import androidx.core.os.bundleOf
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
@@ -23,6 +24,7 @@ import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
+import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.shareText
import javax.inject.Inject
@@ -66,10 +68,8 @@ class MessagePreviewFragment :
companion object {
const val MESSAGE_ID_KEY = "message_id"
- fun newInstance(message: Message): MessagePreviewFragment {
- return MessagePreviewFragment().apply {
- arguments = Bundle().apply { putSerializable(MESSAGE_ID_KEY, message) }
- }
+ fun newInstance(message: Message) = MessagePreviewFragment().apply {
+ arguments = bundleOf(MESSAGE_ID_KEY to message)
}
}
@@ -84,8 +84,8 @@ class MessagePreviewFragment :
binding = FragmentMessagePreviewBinding.bind(view)
messageContainer = binding.messagePreviewContainer
presenter.onAttachView(
- this,
- (savedInstanceState ?: arguments)?.getSerializable(MESSAGE_ID_KEY) as? Message
+ view = this,
+ message = (savedInstanceState ?: arguments)?.serializable(MESSAGE_ID_KEY),
)
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt
index b5f687bd4..14f3d718d 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt
@@ -28,6 +28,7 @@ import io.github.wulkanowy.ui.modules.message.mailboxchooser.MailboxChooserDialo
import io.github.wulkanowy.ui.modules.message.mailboxchooser.MailboxChooserDialog.Companion.LISTENER_KEY
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.hideSoftInput
+import io.github.wulkanowy.utils.nullableSerializable
import io.github.wulkanowy.utils.showSoftInput
import javax.inject.Inject
@@ -108,12 +109,12 @@ class SendMessageActivity : BaseActivity
- presenter.onMailboxSelected(bundle.getSerializable(MAILBOX_KEY) as? Mailbox)
+ presenter.onMailboxSelected(bundle.nullableSerializable(MAILBOX_KEY))
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt
index eddb43243..c78ccc6ec 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt
@@ -9,6 +9,7 @@ import android.view.View.*
import android.widget.CompoundButton
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.SearchView
+import androidx.core.os.bundleOf
import androidx.core.view.updatePadding
import androidx.fragment.app.setFragmentResultListener
import androidx.recyclerview.widget.LinearLayoutManager
@@ -27,6 +28,7 @@ import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.hideSoftInput
+import io.github.wulkanowy.utils.nullableSerializable
import javax.inject.Inject
@AndroidEntryPoint
@@ -43,12 +45,8 @@ class MessageTabFragment : BaseFragment(R.layout.frag
const val MESSAGE_TAB_FOLDER_ID = "message_tab_folder_id"
- fun newInstance(folder: MessageFolder): MessageTabFragment {
- return MessageTabFragment().apply {
- arguments = Bundle().apply {
- putString(MESSAGE_TAB_FOLDER_ID, folder.name)
- }
- }
+ fun newInstance(folder: MessageFolder) = MessageTabFragment().apply {
+ arguments = bundleOf(MESSAGE_TAB_FOLDER_ID to folder.name)
}
}
@@ -131,7 +129,7 @@ class MessageTabFragment : BaseFragment(R.layout.frag
setFragmentResultListener(requireArguments().getString(MESSAGE_TAB_FOLDER_ID)!!) { _, bundle ->
presenter.onMailboxSelected(
- mailbox = bundle.getSerializable(MailboxChooserDialog.MAILBOX_KEY) as? Mailbox,
+ mailbox = bundle.nullableSerializable(MailboxChooserDialog.MAILBOX_KEY),
)
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteDialog.kt
index 5811456b6..e46ab42cc 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteDialog.kt
@@ -6,6 +6,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
+import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Note
@@ -13,6 +14,7 @@ import io.github.wulkanowy.databinding.DialogNoteBinding
import io.github.wulkanowy.sdk.scrapper.notes.NoteCategory
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.lifecycleAwareVariable
+import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.toFormattedString
class NoteDialog : DialogFragment() {
@@ -25,17 +27,15 @@ class NoteDialog : DialogFragment() {
private const val ARGUMENT_KEY = "Item"
- fun newInstance(exam: Note) = NoteDialog().apply {
- arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) }
+ fun newInstance(note: Note) = NoteDialog().apply {
+ arguments = bundleOf(ARGUMENT_KEY to note)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- arguments?.run {
- note = getSerializable(ARGUMENT_KEY) as Note
- }
+ note = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/notifications/NotificationsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/notifications/NotificationsFragment.kt
new file mode 100644
index 000000000..163ba8cdf
--- /dev/null
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/notifications/NotificationsFragment.kt
@@ -0,0 +1,64 @@
+package io.github.wulkanowy.ui.modules.notifications
+
+import android.os.Bundle
+import android.view.View
+import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
+import androidx.appcompat.app.AlertDialog
+import dagger.hilt.android.AndroidEntryPoint
+import io.github.wulkanowy.R
+import io.github.wulkanowy.databinding.FragmentNotificationsBinding
+import io.github.wulkanowy.ui.base.BaseFragment
+import io.github.wulkanowy.ui.modules.login.LoginActivity
+import io.github.wulkanowy.utils.openNotificationSettings
+
+@AndroidEntryPoint
+class NotificationsFragment :
+ BaseFragment(R.layout.fragment_notifications) {
+
+ private val permission = "android.permission.POST_NOTIFICATIONS"
+
+ private val requestPermissionLauncher = registerForActivityResult(RequestPermission()) {
+ if (it) {
+ navigateToFinish()
+ } else showSettingsDialog()
+ }
+
+ companion object {
+ fun newInstance() = NotificationsFragment()
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ binding = FragmentNotificationsBinding.bind(view)
+ initView()
+ }
+
+ private fun initView() {
+ with(binding) {
+ notificationsSkip.setOnClickListener { navigateToFinish() }
+ notificationsEnable.setOnClickListener { requestPermission() }
+ }
+ }
+
+ private fun showSettingsDialog() {
+ AlertDialog.Builder(requireContext())
+ .setTitle(R.string.notifications_header_title)
+ .setMessage(R.string.notifications_header_description)
+ .setNegativeButton(R.string.notifications_skip) { dialog, _ ->
+ dialog.dismiss()
+ navigateToFinish()
+ }
+ .setPositiveButton(R.string.pref_notification_go_to_settings) { _, _ ->
+ requireActivity().openNotificationSettings()
+ }
+ .show()
+ }
+
+ private fun requestPermission() {
+ requestPermissionLauncher.launch(permission)
+ }
+
+ private fun navigateToFinish() {
+ (requireActivity() as LoginActivity).navigateToFinish()
+ }
+}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementDialog.kt
index 7dcd51cea..0a71afef1 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementDialog.kt
@@ -4,11 +4,13 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.core.os.bundleOf
import androidx.core.text.parseAsHtml
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
import io.github.wulkanowy.databinding.DialogSchoolAnnouncementBinding
import io.github.wulkanowy.utils.lifecycleAwareVariable
+import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.toFormattedString
class SchoolAnnouncementDialog : DialogFragment() {
@@ -21,17 +23,15 @@ class SchoolAnnouncementDialog : DialogFragment() {
private const val ARGUMENT_KEY = "item"
- fun newInstance(exam: SchoolAnnouncement) = SchoolAnnouncementDialog().apply {
- arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) }
+ fun newInstance(announcement: SchoolAnnouncement) = SchoolAnnouncementDialog().apply {
+ arguments = bundleOf(ARGUMENT_KEY to announcement)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- arguments?.run {
- announcement = getSerializable(ARGUMENT_KEY) as SchoolAnnouncement
- }
+ announcement = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsFragment.kt
index 364ad2137..77a3c6cf4 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsFragment.kt
@@ -1,18 +1,16 @@
package io.github.wulkanowy.ui.modules.settings.notifications
-import android.annotation.SuppressLint
import android.content.Intent
import android.content.SharedPreferences
-import android.net.Uri
-import android.os.Build
+import android.content.pm.PackageManager
import android.os.Bundle
-import android.provider.Settings
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.core.app.NotificationManagerCompat
+import androidx.core.content.ContextCompat
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreferenceCompat
@@ -26,7 +24,7 @@ import io.github.wulkanowy.ui.base.ErrorDialog
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.openInternetBrowser
-import timber.log.Timber
+import io.github.wulkanowy.utils.openNotificationSettings
import javax.inject.Inject
@AndroidEntryPoint
@@ -42,7 +40,14 @@ class NotificationsFragment : PreferenceFragmentCompat(),
override val titleStringId get() = R.string.pref_settings_notifications_title
+ private val notificationsPermission = "android.permission.POST_NOTIFICATIONS"
+
override val isNotificationPermissionGranted: Boolean
+ get() = ContextCompat.checkSelfPermission(
+ requireContext(), notificationsPermission
+ ) == PackageManager.PERMISSION_GRANTED
+
+ override val isNotificationPiggybackPermissionGranted: Boolean
get() {
val packageNameList =
NotificationManagerCompat.getEnabledListenerPackages(requireContext())
@@ -51,6 +56,13 @@ class NotificationsFragment : PreferenceFragmentCompat(),
return appPackageName in packageNameList
}
+ private val requestPermissionLauncher =
+ registerForActivityResult(ActivityResultContracts.RequestPermission()) {
+ if (it) {
+ presenter.onNotificationsPermissionResult()
+ } else openNotificationsPermissionDialog()
+ }
+
private val notificationSettingsPiggybackContract =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
presenter.onNotificationPiggybackPermissionResult()
@@ -156,25 +168,29 @@ class NotificationsFragment : PreferenceFragmentCompat(),
.show()
}
- @SuppressLint("InlinedApi")
override fun openSystemSettings() {
- val intent = if (appInfo.systemVersion >= Build.VERSION_CODES.O) {
- Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
- putExtra("android.provider.extra.APP_PACKAGE", requireActivity().packageName)
- }
- } else {
- Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
- data = Uri.fromParts("package", requireActivity().packageName, null)
- }
- }
- try {
- requireActivity().startActivity(intent)
- } catch (e: Exception) {
- Timber.e(e)
- }
+ requireActivity().openNotificationSettings()
}
- override fun openNotificationPermissionDialog() {
+ override fun requestNotificationPermissions() {
+ requestPermissionLauncher.launch(notificationsPermission)
+ }
+
+ override fun openNotificationsPermissionDialog() {
+ AlertDialog.Builder(requireContext())
+ .setTitle(R.string.notifications_header_title)
+ .setMessage(R.string.notifications_header_description)
+ .setPositiveButton(R.string.pref_notification_go_to_settings) { _, _ ->
+ requireActivity().openNotificationSettings()
+ }
+ .setNegativeButton(android.R.string.cancel) { _, _ ->
+ setNotificationPreferencesChecked(false)
+ }
+ .setOnDismissListener { setNotificationPreferencesChecked(false) }
+ .show()
+ }
+
+ override fun openNotificationPiggyBackPermissionDialog() {
AlertDialog.Builder(requireContext())
.setTitle(getString(R.string.pref_notification_piggyback_popup_title))
.setMessage(getString(R.string.pref_notification_piggyback_popup_description))
@@ -202,6 +218,11 @@ class NotificationsFragment : PreferenceFragmentCompat(),
.show()
}
+ override fun setNotificationPreferencesChecked(isChecked: Boolean) {
+ findPreference(getString(R.string.pref_key_notifications_enable))?.isChecked =
+ isChecked
+ }
+
override fun setNotificationPiggybackPreferenceChecked(isChecked: Boolean) {
findPreference(getString(R.string.pref_key_notifications_piggyback))?.isChecked =
isChecked
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsPresenter.kt
index 4cbdac945..232b03480 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsPresenter.kt
@@ -26,12 +26,13 @@ class NotificationsPresenter @Inject constructor(
with(view) {
enableNotification(
- preferencesRepository.notificationsEnableKey,
- preferencesRepository.isServiceEnabled
+ notificationKey = preferencesRepository.notificationsEnableKey,
+ enable = preferencesRepository.isServiceEnabled
)
initView(appInfo.isDebug)
}
+ checkNotificationsPermissionState()
checkNotificationPiggybackState()
Timber.i("Settings notifications view was initialized")
@@ -49,12 +50,17 @@ class NotificationsPresenter @Inject constructor(
view?.openNotificationExactAlarmSettings()
}
}
+ notificationsEnableKey -> {
+ if (isNotificationsEnable && view?.isNotificationPermissionGranted == false) {
+ view?.requestNotificationPermissions()
+ }
+ }
isDebugNotificationEnableKey -> {
chuckerCollector.showNotification = isDebugNotificationEnable
}
isNotificationPiggybackEnabledKey -> {
- if (isNotificationPiggybackEnabled && view?.isNotificationPermissionGranted == false) {
- view?.openNotificationPermissionDialog()
+ if (isNotificationPiggybackEnabled && view?.isNotificationPiggybackPermissionGranted == false) {
+ view?.openNotificationPiggyBackPermissionDialog()
}
}
}
@@ -70,9 +76,15 @@ class NotificationsPresenter @Inject constructor(
view?.openSystemSettings()
}
+ fun onNotificationsPermissionResult() {
+ view?.run {
+ setNotificationPreferencesChecked(isNotificationPermissionGranted)
+ }
+ }
+
fun onNotificationPiggybackPermissionResult() {
view?.run {
- setNotificationPiggybackPreferenceChecked(isNotificationPermissionGranted)
+ setNotificationPiggybackPreferenceChecked(isNotificationPiggybackPermissionGranted)
}
}
@@ -80,10 +92,18 @@ class NotificationsPresenter @Inject constructor(
view?.setUpcomingLessonsNotificationPreferenceChecked(timetableNotificationHelper.canScheduleExactAlarms())
}
+ private fun checkNotificationsPermissionState() {
+ if (preferencesRepository.isNotificationsEnable) {
+ view?.run {
+ setNotificationPreferencesChecked(isNotificationPermissionGranted)
+ }
+ }
+ }
+
private fun checkNotificationPiggybackState() {
if (preferencesRepository.isNotificationPiggybackEnabled) {
view?.run {
- setNotificationPiggybackPreferenceChecked(isNotificationPermissionGranted)
+ setNotificationPiggybackPreferenceChecked(isNotificationPiggybackPermissionGranted)
}
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsView.kt
index 2bf8e31f4..a391681cb 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsView.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsView.kt
@@ -6,6 +6,8 @@ interface NotificationsView : BaseView {
val isNotificationPermissionGranted: Boolean
+ val isNotificationPiggybackPermissionGranted: Boolean
+
fun initView(showDebugNotificationSwitch: Boolean)
fun showFixSyncDialog()
@@ -14,10 +16,16 @@ interface NotificationsView : BaseView {
fun enableNotification(notificationKey: String, enable: Boolean)
- fun openNotificationPermissionDialog()
+ fun requestNotificationPermissions()
+
+ fun openNotificationsPermissionDialog()
+
+ fun openNotificationPiggyBackPermissionDialog()
fun openNotificationExactAlarmSettings()
+ fun setNotificationPreferencesChecked(isChecked: Boolean)
+
fun setNotificationPiggybackPreferenceChecked(isChecked: Boolean)
fun setUpcomingLessonsNotificationPreferenceChecked(isChecked: Boolean)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoFragment.kt
index 6ff7a39b7..598046a2d 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoFragment.kt
@@ -8,6 +8,7 @@ import android.view.MenuInflater
import android.view.View
import android.widget.Toast
import androidx.core.content.getSystemService
+import androidx.core.os.bundleOf
import androidx.core.view.get
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
@@ -24,6 +25,8 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.capitalise
import io.github.wulkanowy.utils.getThemeAttrColor
+import io.github.wulkanowy.utils.nullableSerializable
+import io.github.wulkanowy.utils.serializable
import javax.inject.Inject
@AndroidEntryPoint
@@ -38,7 +41,9 @@ class StudentInfoFragment :
lateinit var studentInfoAdapter: StudentInfoAdapter
override val titleStringId: Int
- get() = when (requireArguments().getSerializable(INFO_TYPE_ARGUMENT_KEY) as? StudentInfoView.Type) {
+ get() = when (
+ requireArguments().nullableSerializable(INFO_TYPE_ARGUMENT_KEY)
+ ) {
StudentInfoView.Type.PERSONAL -> R.string.account_personal_data
StudentInfoView.Type.CONTACT -> R.string.account_contact
StudentInfoView.Type.ADDRESS -> R.string.account_address
@@ -58,10 +63,10 @@ class StudentInfoFragment :
fun newInstance(type: StudentInfoView.Type, studentWithSemesters: StudentWithSemesters) =
StudentInfoFragment().apply {
- arguments = Bundle().apply {
- putSerializable(INFO_TYPE_ARGUMENT_KEY, type)
- putSerializable(STUDENT_ARGUMENT_KEY, studentWithSemesters)
- }
+ arguments = bundleOf(
+ INFO_TYPE_ARGUMENT_KEY to type,
+ STUDENT_ARGUMENT_KEY to studentWithSemesters
+ )
}
}
@@ -75,9 +80,9 @@ class StudentInfoFragment :
super.onViewCreated(view, savedInstanceState)
binding = FragmentStudentInfoBinding.bind(view)
presenter.onAttachView(
- this,
- requireArguments().getSerializable(INFO_TYPE_ARGUMENT_KEY) as StudentInfoView.Type,
- requireArguments().getSerializable(STUDENT_ARGUMENT_KEY) as StudentWithSemesters
+ view = this,
+ type = requireArguments().serializable(INFO_TYPE_ARGUMENT_KEY),
+ studentWithSemesters = requireArguments().serializable(STUDENT_ARGUMENT_KEY),
)
}
@@ -154,7 +159,6 @@ class StudentInfoFragment :
)
}
- @OptIn(ExperimentalStdlibApi::class)
override fun showFamilyTypeData(studentInfo: StudentInfo) {
val items = buildList {
add(studentInfo.firstGuardian?.let {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt
index c9243b12e..4f5547d20 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt
@@ -8,14 +8,12 @@ import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
+import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.databinding.DialogTimetableBinding
-import io.github.wulkanowy.utils.capitalise
-import io.github.wulkanowy.utils.getThemeAttrColor
-import io.github.wulkanowy.utils.lifecycleAwareVariable
-import io.github.wulkanowy.utils.toFormattedString
+import io.github.wulkanowy.utils.*
import java.time.Instant
class TimetableDialog : DialogFragment() {
@@ -28,17 +26,15 @@ class TimetableDialog : DialogFragment() {
private const val ARGUMENT_KEY = "Item"
- fun newInstance(exam: Timetable) = TimetableDialog().apply {
- arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) }
+ fun newInstance(lesson: Timetable) = TimetableDialog().apply {
+ arguments = bundleOf(ARGUMENT_KEY to lesson)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- arguments?.run {
- lesson = getSerializable(ARGUMENT_KEY) as Timetable
- }
+ lesson = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt
index 6fd126326..e95d6f827 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt
@@ -7,6 +7,7 @@ import android.view.MenuItem
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
+import androidx.core.os.bundleOf
import androidx.core.text.parseAsHtml
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
@@ -39,9 +40,7 @@ class TimetableFragment : BaseFragment(R.layout.fragme
private const val ARGUMENT_DATE_KEY = "ARGUMENT_DATE"
fun newInstance(date: LocalDate? = null) = TimetableFragment().apply {
- arguments = Bundle().apply {
- date?.let { putLong(ARGUMENT_DATE_KEY, it.toEpochDay()) }
- }
+ arguments = date?.let { bundleOf(ARGUMENT_DATE_KEY to it.toEpochDay()) }
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonDialog.kt
index 7d32278f0..ddd7488e4 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonDialog.kt
@@ -4,10 +4,12 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.databinding.DialogLessonCompletedBinding
import io.github.wulkanowy.utils.lifecycleAwareVariable
+import io.github.wulkanowy.utils.serializable
class CompletedLessonDialog : DialogFragment() {
@@ -19,17 +21,15 @@ class CompletedLessonDialog : DialogFragment() {
private const val ARGUMENT_KEY = "Item"
- fun newInstance(exam: CompletedLesson) = CompletedLessonDialog().apply {
- arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) }
+ fun newInstance(lesson: CompletedLesson) = CompletedLessonDialog().apply {
+ arguments = bundleOf(ARGUMENT_KEY to lesson)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- arguments?.run {
- completedLesson = getSerializable(ARGUMENT_KEY) as CompletedLesson
- }
+ completedLesson = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
diff --git a/app/src/main/java/io/github/wulkanowy/utils/BundleExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/BundleExtension.kt
new file mode 100644
index 000000000..d0d47025e
--- /dev/null
+++ b/app/src/main/java/io/github/wulkanowy/utils/BundleExtension.kt
@@ -0,0 +1,32 @@
+package io.github.wulkanowy.utils
+
+import android.content.Intent
+import android.os.Build
+import android.os.Bundle
+import java.io.Serializable
+
+inline fun Bundle.serializable(key: String): T = when {
+ Build.VERSION.SDK_INT >= 33 -> getSerializable(key, T::class.java)!!
+ else -> @Suppress("DEPRECATION") getSerializable(key) as T
+}
+
+inline fun Bundle.nullableSerializable(key: String): T? = when {
+ Build.VERSION.SDK_INT >= 33 -> getSerializable(key, T::class.java)
+ else -> @Suppress("DEPRECATION") getSerializable(key) as T?
+}
+
+@Suppress("DEPRECATION", "UNCHECKED_CAST")
+inline fun Bundle.parcelableArray(key: String): Array? = when {
+ Build.VERSION.SDK_INT >= 33 -> getParcelableArray(key, T::class.java)
+ else -> getParcelableArray(key) as Array?
+}
+
+inline fun Intent.serializable(key: String): T = when {
+ Build.VERSION.SDK_INT >= 33 -> getSerializableExtra(key, T::class.java)!!
+ else -> @Suppress("DEPRECATION") getSerializableExtra(key) as T
+}
+
+inline fun Intent.nullableSerializable(key: String): T? = when {
+ Build.VERSION.SDK_INT >= 33 -> getSerializableExtra(key, T::class.java)
+ else -> @Suppress("DEPRECATION") getSerializableExtra(key) as T?
+}
diff --git a/app/src/main/java/io/github/wulkanowy/utils/IntentUtils.kt b/app/src/main/java/io/github/wulkanowy/utils/IntentUtils.kt
index 1ef03f2e6..62b85af4d 100644
--- a/app/src/main/java/io/github/wulkanowy/utils/IntentUtils.kt
+++ b/app/src/main/java/io/github/wulkanowy/utils/IntentUtils.kt
@@ -1,11 +1,15 @@
package io.github.wulkanowy.utils
+import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.net.Uri
+import android.os.Build
import android.provider.CalendarContract
+import android.provider.Settings
import io.github.wulkanowy.BuildConfig
+import timber.log.Timber
import java.time.LocalDateTime
import java.time.ZoneId
@@ -86,6 +90,23 @@ fun Context.openDialer(phone: String) {
}
}
+fun Activity.openNotificationSettings() {
+ val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
+ putExtra("android.provider.extra.APP_PACKAGE", packageName)
+ }
+ } else {
+ Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
+ data = Uri.fromParts("package", packageName, null)
+ }
+ }
+ try {
+ startActivity(intent)
+ } catch (e: Exception) {
+ Timber.e(e)
+ }
+}
+
fun Context.shareText(text: String, subject: String?) {
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
diff --git a/app/src/main/res/drawable/ic_launcher_foreground_dev_mono.xml b/app/src/main/res/drawable/ic_launcher_foreground_dev_mono.xml
new file mode 100644
index 000000000..b1b01a0b6
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_foreground_dev_mono.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_launcher_foreground_mono.xml b/app/src/main/res/drawable/ic_launcher_foreground_mono.xml
new file mode 100644
index 000000000..e2e747316
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_foreground_mono.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_notifications.xml b/app/src/main/res/layout/fragment_notifications.xml
new file mode 100644
index 000000000..8e506e1e7
--- /dev/null
+++ b/app/src/main/res/layout/fragment_notifications.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index d59ec8e17..da1bca126 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -2,4 +2,5 @@
-
\ No newline at end of file
+
+
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
deleted file mode 100644
index d59ec8e17..000000000
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
deleted file mode 100644
index 85f6a2c87..000000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
deleted file mode 100644
index dc6ac682d..000000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
deleted file mode 100644
index dd67b8771..000000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
deleted file mode 100644
index b7d82f5d5..000000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
deleted file mode 100644
index 7ad000eec..000000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 71d1767ed..874b121f6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -74,6 +74,11 @@
Recover
Student is already signed in
Standard
+
+ Enable notifications
+ Enable notifications so you don\'t miss message from teacher or new grade
+ Skip
+ Enable
Account manager
Log in
diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 000000000..418b6d4c4
--- /dev/null
+++ b/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt
index e52ec3ae2..a31ef5177 100644
--- a/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt
+++ b/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt
@@ -90,14 +90,14 @@ class LoginStudentSelectPresenterTest {
studentRepository.saveStudents(listOf(StudentWithSemesters(testStudent, emptyList())))
} just Runs
- every { loginStudentSelectView.openMainView() } just Runs
+ every { loginStudentSelectView.navigateToNext() } just Runs
presenter.onItemSelected(StudentWithSemesters(testStudent, emptyList()), false)
presenter.onSignIn()
verify { loginStudentSelectView.showContent(false) }
verify { loginStudentSelectView.showProgress(true) }
- verify { loginStudentSelectView.openMainView() }
+ verify { loginStudentSelectView.navigateToNext() }
}
@Test