diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index fb824573..2c24b426 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -12,7 +12,7 @@
-
+
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/config/ProfileConfigUI.kt b/app/src/main/java/pl/szczodrzynski/edziennik/config/ProfileConfigUI.kt
index 187cb6bd..a3fb184e 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/config/ProfileConfigUI.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/config/ProfileConfigUI.kt
@@ -69,4 +69,24 @@ class ProfileConfigUI(private val config: ProfileConfig) {
var messagesGreetingText: String?
get() { mMessagesGreetingText = mMessagesGreetingText ?: config.values["messagesGreetingText"]; return mMessagesGreetingText }
set(value) { config.set("messagesGreetingText", value); mMessagesGreetingText = value }
+
+ private var mTimetableShowAttendance: Boolean? = null
+ var timetableShowAttendance: Boolean
+ get() { mTimetableShowAttendance = mTimetableShowAttendance ?: config.values.get("timetableShowAttendance", true); return mTimetableShowAttendance ?: true }
+ set(value) { config.set("timetableShowAttendance", value); mTimetableShowAttendance = value }
+
+ private var mTimetableShowEvents: Boolean? = null
+ var timetableShowEvents: Boolean
+ get() { mTimetableShowEvents = mTimetableShowEvents ?: config.values.get("timetableShowEvents", true); return mTimetableShowEvents ?: true }
+ set(value) { config.set("timetableShowEvents", value); mTimetableShowEvents = value }
+
+ private var mTimetableTrimHourRange: Boolean? = null
+ var timetableTrimHourRange: Boolean
+ get() { mTimetableTrimHourRange = mTimetableTrimHourRange ?: config.values.get("timetableTrimHourRange", false); return mTimetableTrimHourRange ?: false }
+ set(value) { config.set("timetableTrimHourRange", value); mTimetableTrimHourRange = value }
+
+ private var mTimetableColorSubjectName: Boolean? = null
+ var timetableColorSubjectName: Boolean
+ get() { mTimetableColorSubjectName = mTimetableColorSubjectName ?: config.values.get("timetableColorSubjectName", false); return mTimetableColorSubjectName ?: false }
+ set(value) { config.set("timetableColorSubjectName", value); mTimetableColorSubjectName = value }
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/settings/TimetableConfigDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/settings/TimetableConfigDialog.kt
new file mode 100644
index 00000000..b784165b
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/settings/TimetableConfigDialog.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2022-10-7.
+ */
+
+package pl.szczodrzynski.edziennik.ui.dialogs.settings
+
+import android.view.LayoutInflater
+import androidx.appcompat.app.AppCompatActivity
+import pl.szczodrzynski.edziennik.MainActivity
+import pl.szczodrzynski.edziennik.R
+import pl.szczodrzynski.edziennik.databinding.TimetableConfigDialogBinding
+import pl.szczodrzynski.edziennik.ext.Intent
+import pl.szczodrzynski.edziennik.ext.onClick
+import pl.szczodrzynski.edziennik.ui.dialogs.base.ConfigDialog
+import pl.szczodrzynski.edziennik.ui.timetable.TimetableFragment
+
+class TimetableConfigDialog(
+ activity: AppCompatActivity,
+ reloadOnDismiss: Boolean = true,
+ onShowListener: ((tag: String) -> Unit)? = null,
+ onDismissListener: ((tag: String) -> Unit)? = null,
+) : ConfigDialog(
+ activity,
+ reloadOnDismiss,
+ onShowListener,
+ onDismissListener,
+) {
+
+ override val TAG = "TimetableConfigDialog"
+
+ override fun getTitleRes() = R.string.menu_timetable_config
+ override fun inflate(layoutInflater: LayoutInflater) =
+ TimetableConfigDialogBinding.inflate(layoutInflater)
+
+ private val profileConfig by lazy { app.config.getFor(app.profileId).ui }
+
+ override suspend fun loadConfig() {
+ b.config = profileConfig
+ }
+
+ override suspend fun saveConfig() {
+ activity.sendBroadcast(Intent(TimetableFragment.ACTION_RELOAD_PAGES))
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/HomeFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/HomeFragment.kt
index 54f94433..635c7b56 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/HomeFragment.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/HomeFragment.kt
@@ -81,7 +81,8 @@ class HomeFragment : Fragment(), CoroutineScope {
private val job: Job = Job()
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
-
+ private val manager
+ get() = app.permissionManager
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
activity = (getActivity() as MainActivity?) ?: return null
context ?: return null
@@ -96,6 +97,10 @@ class HomeFragment : Fragment(), CoroutineScope {
if (!isAdded)
return
+ if (!manager.isNotificationPermissionGranted) {
+ manager.requestNotificationsPermission(activity, 0, false){}
+ }
+
activity.bottomSheet.prependItems(
BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_add_remove_cards)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginChooserFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginChooserFragment.kt
index 1bfe0abd..a4367dee 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginChooserFragment.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginChooserFragment.kt
@@ -23,8 +23,8 @@ import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.*
-import pl.szczodrzynski.edziennik.*
-import pl.szczodrzynski.edziennik.data.api.*
+import pl.szczodrzynski.edziennik.App
+import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.databinding.LoginChooserFragmentBinding
import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.ui.dialogs.sync.RegisterUnavailableDialog
@@ -51,7 +51,8 @@ class LoginChooserFragment : Fragment(), CoroutineScope {
private val job: Job = Job()
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
-
+ private val manager
+ get() = app.permissionManager
// local/private variables go here
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@@ -67,6 +68,9 @@ class LoginChooserFragment : Fragment(), CoroutineScope {
if (!isAdded) return
val adapter = LoginChooserAdapter(activity, this::onLoginModeClicked)
+ if (!manager.isNotificationPermissionGranted) {
+ manager.requestNotificationsPermission(activity, 0, false){}
+ }
b.versionText.setText(
R.string.login_chooser_version_format,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/timetable/TimetableDayFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/timetable/TimetableDayFragment.kt
index 754bd4f5..37e82a27 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/timetable/TimetableDayFragment.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/timetable/TimetableDayFragment.kt
@@ -4,6 +4,7 @@
package pl.szczodrzynski.edziennik.ui.timetable
+import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -12,6 +13,7 @@ import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.TextView
import androidx.asynclayoutinflater.view.AsyncLayoutInflater
+import androidx.core.graphics.ColorUtils
import androidx.core.view.*
import com.linkedin.android.tachyon.DayView
import com.linkedin.android.tachyon.DayViewConfig
@@ -33,9 +35,11 @@ import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.ui.base.lazypager.LazyFragment
import pl.szczodrzynski.edziennik.ui.timetable.TimetableFragment.Companion.DEFAULT_END_HOUR
import pl.szczodrzynski.edziennik.ui.timetable.TimetableFragment.Companion.DEFAULT_START_HOUR
+import pl.szczodrzynski.edziennik.utils.Colors
import pl.szczodrzynski.edziennik.utils.managers.NoteManager
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
+import pl.szczodrzynski.edziennik.utils.mutableLazy
import java.util.*
import kotlin.coroutines.CoroutineContext
import kotlin.math.min
@@ -71,8 +75,9 @@ class TimetableDayFragment : LazyFragment(), CoroutineScope {
// find SwipeRefreshLayout in the hierarchy
private val refreshLayout by lazy { view?.findParentById(R.id.refreshLayout) }
+ private val profileConfig by lazy { app.config.forProfile().ui }
- private val dayView by lazy {
+ private val dayViewDelegate = mutableLazy {
val dayView = DayView(activity, DayViewConfig(
startHour = startHour,
endHour = endHour,
@@ -85,8 +90,9 @@ class TimetableDayFragment : LazyFragment(), CoroutineScope {
eventMargin = 2.dp
), true)
dayView.setPadding(10.dp)
- return@lazy dayView
+ return@mutableLazy dayView
}
+ private val dayView by dayViewDelegate
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
activity = (getActivity() as MainActivity?) ?: return null
@@ -173,8 +179,19 @@ class TimetableDayFragment : LazyFragment(), CoroutineScope {
return
}
+ if (dayViewDelegate.isInitialized())
+ b.dayFrame.removeView(dayView)
+
+ val lessonsActual = lessons.filter { it.type != Lesson.TYPE_NO_LESSONS }
+
+ if (profileConfig.timetableTrimHourRange) {
+ dayViewDelegate.deinitialize()
+ // end/start defaults are swapped on purpose
+ startHour = lessonsActual.minOf { it.displayStartTime?.hour ?: DEFAULT_END_HOUR }
+ endHour = lessonsActual.maxOf { it.displayEndTime?.hour?.plus(1) ?: DEFAULT_START_HOUR }
+ }
+
b.scrollView.isVisible = true
- b.dayFrame.removeView(dayView)
b.dayFrame.addView(dayView, 0)
// Inflate a label view for each hour the day view will display
@@ -195,7 +212,7 @@ class TimetableDayFragment : LazyFragment(), CoroutineScope {
lessons.forEach { it.showAsUnseen = !it.seen }
- buildLessonViews(lessons.filter { it.type != Lesson.TYPE_NO_LESSONS }, events, attendanceList)
+ buildLessonViews(lessonsActual, events, attendanceList)
}
private fun buildLessonViews(lessons: List, events: List, attendanceList: List) {
@@ -215,7 +232,10 @@ class TimetableDayFragment : LazyFragment(), CoroutineScope {
val colorSecondary = android.R.attr.textColorSecondary.resolveAttr(activity)
for (lesson in lessons) {
- val attendance = attendanceList.find { it.startTime == lesson.startTime }
+ val attendance = if (profileConfig.timetableShowAttendance)
+ attendanceList.find { it.startTime == lesson.startTime }
+ else
+ null
val startTime = lesson.displayStartTime ?: continue
val endTime = lesson.displayEndTime ?: continue
@@ -245,23 +265,20 @@ class TimetableDayFragment : LazyFragment(), CoroutineScope {
}
}
- val eventList = events.filter { it.time != null && it.time == lesson.displayStartTime }.take(3)
- eventList.getOrNull(0).let {
- lb.event1.visibility = if (it == null) View.GONE else View.VISIBLE
- lb.event1.background = it?.let {
- R.drawable.bg_circle.resolveDrawable(activity).setTintColor(it.eventColor)
+ val eventIcons = listOf(lb.event1, lb.event2, lb.event3)
+ if (profileConfig.timetableShowEvents) {
+ val eventList = events.filter { it.time != null && it.time == lesson.displayStartTime }.take(3)
+ for ((i, eventIcon) in eventIcons.withIndex()) {
+ eventList.getOrNull(i).let {
+ eventIcon.isVisible = it != null
+ eventIcon.background = it?.let {
+ R.drawable.bg_circle.resolveDrawable(activity).setTintColor(it.eventColor)
+ }
+ }
}
- }
- eventList.getOrNull(1).let {
- lb.event2.visibility = if (it == null) View.GONE else View.VISIBLE
- lb.event2.background = it?.let {
- R.drawable.bg_circle.resolveDrawable(activity).setTintColor(it.eventColor)
- }
- }
- eventList.getOrNull(2).let {
- lb.event3.visibility = if (it == null) View.GONE else View.VISIBLE
- lb.event3.background = it?.let {
- R.drawable.bg_circle.resolveDrawable(activity).setTintColor(it.eventColor)
+ } else {
+ for (eventIcon in eventIcons) {
+ eventIcon.visibility = View.GONE
}
}
@@ -295,13 +312,36 @@ class TimetableDayFragment : LazyFragment(), CoroutineScope {
lesson.classroom?.let { add(it) }
}.concat(arrowRight)
+ lb.annotationVisible = manager.getAnnotation(activity, lesson, lb.annotation)
- lb.lessonNumber = lesson.displayLessonNumber
val lessonText =
lesson.getNoteSubstituteText(showNotes = true) ?: lesson.displaySubjectName
+
+ val (subjectTextPrimary, subjectTextSecondary) = if (profileConfig.timetableColorSubjectName) {
+ val subjectColor = Colors.stringToMaterialColorCRC(lessonText?.toString() ?: "")
+ if (lb.annotationVisible) {
+ lb.subjectContainer.background = ColorDrawable(subjectColor)
+ } else {
+ lb.subjectContainer.setBackgroundResource(R.drawable.timetable_subject_color_rounded)
+ lb.subjectContainer.background.setTintColor(subjectColor)
+ }
+ when (ColorUtils.calculateLuminance(subjectColor) > 0.5) {
+ true -> /* light */ 0xFF000000 to 0xFF666666
+ false -> /* dark */ 0xFFFFFFFF to 0xFFAAAAAA
+ }
+ } else {
+ lb.subjectContainer.background = null
+ null to colorSecondary
+ }
+
+ lb.lessonNumber = lesson.displayLessonNumber
+ if (subjectTextPrimary != null)
+ lb.lessonNumberText.setTextColor(subjectTextPrimary.toInt())
lb.subjectName.text = lessonText?.let {
if (lesson.type == Lesson.TYPE_CANCELLED || lesson.type == Lesson.TYPE_SHIFTED_SOURCE)
- it.asStrikethroughSpannable().asColoredSpannable(colorSecondary)
+ it.asStrikethroughSpannable().asColoredSpannable(subjectTextSecondary.toInt())
+ else if (subjectTextPrimary != null)
+ it.asColoredSpannable(subjectTextPrimary.toInt())
else
it
}
@@ -328,7 +368,6 @@ class TimetableDayFragment : LazyFragment(), CoroutineScope {
}
//lb.subjectName.typeface = Typeface.create("sans-serif-light", Typeface.BOLD)
- lb.annotationVisible = manager.getAnnotation(activity, lesson, lb.annotation)
val lessonNumberMargin =
if (lb.annotationVisible) (-8).dp
else 0
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/timetable/TimetableFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/timetable/TimetableFragment.kt
index b046ff68..fc2221bc 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/timetable/TimetableFragment.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/timetable/TimetableFragment.kt
@@ -26,6 +26,7 @@ import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.databinding.FragmentTimetableV2Binding
import pl.szczodrzynski.edziennik.ext.getSchoolYearConstrains
+import pl.szczodrzynski.edziennik.ui.dialogs.settings.TimetableConfigDialog
import pl.szczodrzynski.edziennik.ui.event.EventManualDialog
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
@@ -52,6 +53,7 @@ class TimetableFragment : Fragment(), CoroutineScope {
private var fabShown = false
private val items = mutableListOf()
+ private val profileConfig by lazy { app.config.forProfile().ui }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
activity = (getActivity() as MainActivity?) ?: return null
@@ -128,8 +130,8 @@ class TimetableFragment : Fragment(), CoroutineScope {
}
val lessonRanges = app.db.lessonRangeDao().getAllNow(App.profileId)
- startHour = lessonRanges.map { it.startTime.hour }.minOrNull() ?: DEFAULT_START_HOUR
- endHour = lessonRanges.map { it.endTime.hour }.maxOrNull()?.plus(1) ?: DEFAULT_END_HOUR
+ startHour = lessonRanges.minOfOrNull { it.startTime.hour } ?: DEFAULT_START_HOUR
+ endHour = lessonRanges.maxOfOrNull { it.endTime.hour }?.plus(1) ?: DEFAULT_END_HOUR
}
deferred.await()
if (!isAdded)
@@ -208,6 +210,13 @@ class TimetableFragment : Fragment(), CoroutineScope {
activity.bottomSheet.close()
GenerateBlockTimetableDialog(activity)
}),
+ BottomSheetPrimaryItem(true)
+ .withTitle(R.string.menu_timetable_config)
+ .withIcon(CommunityMaterial.Icon.cmd_cog_outline)
+ .withOnClickListener {
+ activity.bottomSheet.close()
+ TimetableConfigDialog(activity, false, null, null).show()
+ },
BottomSheetSeparatorItem(true),
BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_mark_as_read)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/utils/Colors.java b/app/src/main/java/pl/szczodrzynski/edziennik/utils/Colors.java
index 1f6c7ad3..39371516 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/utils/Colors.java
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/utils/Colors.java
@@ -15,6 +15,7 @@ import androidx.core.graphics.ColorUtils;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Random;
+import java.util.zip.CRC32;
import pl.szczodrzynski.edziennik.data.db.entity.Grade;
@@ -84,6 +85,28 @@ public class Colors {
0xFF6D4C41
};
+ public static final int[] materialColorsBasic = {
+ 0xFFE53935, 0xFFD81B60, 0xFF8E24AA, 0xFF5E35B1,
+ 0xFF3949AB, 0xFF1E88E5, 0xFF039BE5, 0xFF00ACC1,
+ 0xFF00897B, 0xFF43A047, 0xFF7CB342, 0xFFC0CA33,
+ 0xFFFDD835, 0xFFFFB300, 0xFFFB8C00, 0xFFF4511E,
+ 0xFF6D4C41, 0xFF757575, 0xFF546E7A, 0xFF00E676,
+
+ 0xFFEF9A9A, 0xFFF48FB1, 0xFFCE93D8, 0xFFB39DDB,
+ 0xFF9FA8DA, 0xFF90CAF9, 0xFF81D4FA, 0xFF80DEEA,
+ 0xFF80CBC4, 0xFFA5D6A7, 0xFFC5E1A5, 0xFFE6EE9C,
+ 0xFFFFF59D, 0xFFFFE082, 0xFFFFCC80, 0xFFFFAB91,
+ 0xFFBCAAA4, 0xFFEEEEEE, 0xFFB0BEC5, 0xFFCCFF90,
+ };
+
+ public static final int[] metroColors = {
+ 0xFF76FF03, 0xFF60A917, 0xFF00C853, 0xFF00ABA9,
+ 0xFF1BA1E2, 0xFF0050EF, 0xFF6A00FF, 0xFFAA00FF,
+ 0xFFF472D0, 0xFFD80073, 0xFFA20025, 0xFFE51400,
+ 0xFFFA6800, 0xFFF0A30A, 0xFFE3C800, 0xFF795548,
+ 0xFF6D8764, 0xFF647687, 0xFF76608A, 0xFFA0522D,
+ };
+
/**
* Used for teacher's images (e.g. in messages or announcements).
* @param s teacher's fullName
@@ -115,6 +138,18 @@ public class Colors {
return materialColors[getRandomNumberInRange(0, materialColors.length-1, seed)];
}
+ public static int stringToMaterialColorCRC(String s) {
+ long seed;
+ try {
+ CRC32 crc = new CRC32();
+ crc.update(s.getBytes());
+ seed = crc.getValue();
+ } catch (Exception e) {
+ seed = 1234;
+ }
+ return metroColors[(int) (seed % metroColors.length)];
+ }
+
public static int gradeToColor(Grade grade)
{
if (grade.getType() == Grade.TYPE_POINT_SUM) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/utils/MutableLazy.kt b/app/src/main/java/pl/szczodrzynski/edziennik/utils/MutableLazy.kt
index cf000e1f..f742c185 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/utils/MutableLazy.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/utils/MutableLazy.kt
@@ -19,7 +19,6 @@ class MutableLazyImpl(initializer: () -> T, lock: Any? = null) {
return synchronized(lock) {
val typedValue = initializer!!()
_value = typedValue
- initializer = null
typedValue
}
}
@@ -29,7 +28,11 @@ class MutableLazyImpl(initializer: () -> T, lock: Any? = null) {
fun isInitialized() = _value !== UNINITIALIZED_VALUE
+ fun deinitialize() {
+ _value = UNINITIALIZED_VALUE
+ }
+
override fun toString() = if (isInitialized()) _value.toString() else "ChangeableLazy value not initialized yet."
}
-fun mutableLazy(initializer: () -> T): MutableLazyImpl = MutableLazyImpl(initializer)
\ No newline at end of file
+fun mutableLazy(initializer: () -> T): MutableLazyImpl = MutableLazyImpl(initializer)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/utils/managers/PermissionManager.kt b/app/src/main/java/pl/szczodrzynski/edziennik/utils/managers/PermissionManager.kt
index 65430f60..e99f9e3e 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/utils/managers/PermissionManager.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/utils/managers/PermissionManager.kt
@@ -36,7 +36,13 @@ class PermissionManager(val app: App) : CoroutineScope {
app.checkSelfPermission(name) == PackageManager.PERMISSION_GRANTED
else
true
-
+ val isNotificationPermissionGranted by lazy {
+ if (Build.VERSION.SDK_INT >= 33) {
+ app.checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED
+ } else {
+ true
+ }
+ }
private fun openPermissionSettings(activity: AppCompatActivity) {
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val uri = Uri.fromParts("package", app.packageName, null)
@@ -80,6 +86,10 @@ class PermissionManager(val app: App) : CoroutineScope {
.show()
}
result.hasPermanentDenied() -> {
+ if (!isRequired) {
+ onSuccess()
+ return@launch
+ }
MaterialAlertDialogBuilder(activity)
.setTitle(R.string.permissions_required)
.setMessage(R.string.permissions_denied)
@@ -92,6 +102,18 @@ class PermissionManager(val app: App) : CoroutineScope {
}
}
}
+ fun requestNotificationsPermission(
+ activity: AppCompatActivity,
+ @StringRes permissionMessage: Int,
+ isRequired: Boolean = false,
+ onSuccess: suspend CoroutineScope.() -> Unit
+ ) = requestPermission(
+ activity,
+ permissionMessage,
+ isRequired,
+ Manifest.permission.POST_NOTIFICATIONS,
+ onSuccess
+ )
fun requestStoragePermission(
activity: AppCompatActivity,
diff --git a/app/src/main/res/layout/dialog_config_agenda.xml b/app/src/main/res/layout/dialog_config_agenda.xml
index f17b5989..b51464e2 100644
--- a/app/src/main/res/layout/dialog_config_agenda.xml
+++ b/app/src/main/res/layout/dialog_config_agenda.xml
@@ -31,7 +31,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/timetable_lesson.xml b/app/src/main/res/layout/timetable_lesson.xml
index 491788b5..d8d9609c 100644
--- a/app/src/main/res/layout/timetable_lesson.xml
+++ b/app/src/main/res/layout/timetable_lesson.xml
@@ -45,14 +45,15 @@
tools:visibility="gone" />
-
+ android:paddingVertical="4dp"
+ tools:background="@drawable/timetable_subject_color_rounded">
Grade
read the Privacy Policy and accept its provisions.
The authors of the application are not responsible for the use of the Szkolny.eu application.]]>
Szkolny.eu v%s\n%s
- Appearance
+ Appearance
Online learning
online lesson
Messages settings
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7aae860c..3cc2451d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1424,7 +1424,7 @@
przeczytanie Polityki prywatności i akceptujesz jej postanowienia.
Autorzy aplikacji nie biorą odpowiedzialności za korzystanie z aplikacji Szkolny.eu.]]>
Szkolny.eu v%s\n%s
Ustawienia terminarza
- Wygląd
+ Wygląd
Pokazuj zmiany planu lekcji
Pokazuj nieobecności nauczycieli
Tryb kompaktowy
@@ -1537,6 +1537,11 @@
(rodzic)
- nieznany przedmiot -
{cmd-information-outline} Oceny, których przedmiot nie został podany w dzienniku. Może to być na przykład taki, który nie jest prowadzony w tym roku szkolnym.
+ Ustawienia planu lekcji
+ Pokazuj wydarzenia przy lekcjach
+ Pokazuj rodzaj obecności na lekcji
+ Koloruj nazwę przedmiotu
+ Nie pokazuj godzin bez lekcji
Logowanie do USOS API...
USOS
Logowanie z użyciem przeglądarki