mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-01-31 05:48:19 +01:00
[Notifications] Add filtering notifications to show during sync.
This commit is contained in:
parent
af8bda9e92
commit
a4493ec964
@ -29,8 +29,8 @@ class ProfileConfig(val db: AppDb, val profileId: Int, rawEntries: List<ConfigEn
|
|||||||
|
|
||||||
val grades by lazy { ProfileConfigGrades(this) }
|
val grades by lazy { ProfileConfigGrades(this) }
|
||||||
val ui by lazy { ProfileConfigUI(this) }
|
val ui by lazy { ProfileConfigUI(this) }
|
||||||
|
val sync by lazy { ProfileConfigSync(this) }
|
||||||
/*
|
/*
|
||||||
val sync by lazy { ConfigSync(this) }
|
|
||||||
val timetable by lazy { ConfigTimetable(this) }
|
val timetable by lazy { ConfigTimetable(this) }
|
||||||
val grades by lazy { ConfigGrades(this) }*/
|
val grades by lazy { ConfigGrades(this) }*/
|
||||||
|
|
||||||
@ -56,4 +56,4 @@ class ProfileConfig(val db: AppDb, val profileId: Int, rawEntries: List<ConfigEn
|
|||||||
db.configDao().add(ConfigEntry(profileId, key, value))
|
db.configDao().add(ConfigEntry(profileId, key, value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-2-21.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.config
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
|
|
||||||
|
class ProfileConfigSync(private val config: ProfileConfig) {
|
||||||
|
private var mNotificationFilter: List<Int>? = null
|
||||||
|
var notificationFilter: List<Int>
|
||||||
|
get() { mNotificationFilter = mNotificationFilter ?: config.values.get("notificationFilter", listOf()); return mNotificationFilter ?: listOf() }
|
||||||
|
set(value) { config.set("notificationFilter", value); mNotificationFilter = value }
|
||||||
|
}
|
@ -44,6 +44,17 @@ class SzkolnyTask(val app: App, val syncingProfiles: List<Profile>) : IApiTask(-
|
|||||||
}
|
}
|
||||||
d(TAG, "Created ${notificationList.count()} notifications.")
|
d(TAG, "Created ${notificationList.count()} notifications.")
|
||||||
|
|
||||||
|
// filter notifications
|
||||||
|
notificationList
|
||||||
|
.mapNotNull { it.profileId }
|
||||||
|
.distinct()
|
||||||
|
.map { app.config.getFor(it).sync.notificationFilter }
|
||||||
|
.forEach { filter ->
|
||||||
|
filter.forEach { type ->
|
||||||
|
notificationList.removeAll { it.type == type }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// update the database
|
// update the database
|
||||||
app.db.metadataDao().setAllNotified(true)
|
app.db.metadataDao().setAllNotified(true)
|
||||||
if (notificationList.isNotEmpty())
|
if (notificationList.isNotEmpty())
|
||||||
|
@ -145,25 +145,31 @@ class SzkolnyAppFirebase(val app: App, val profiles: List<Profile>, val message:
|
|||||||
event.topic
|
event.topic
|
||||||
)*/
|
)*/
|
||||||
val type = if (event.type == Event.TYPE_HOMEWORK) Notification.TYPE_NEW_SHARED_HOMEWORK else Notification.TYPE_NEW_SHARED_EVENT
|
val type = if (event.type == Event.TYPE_HOMEWORK) Notification.TYPE_NEW_SHARED_HOMEWORK else Notification.TYPE_NEW_SHARED_EVENT
|
||||||
val notification = Notification(
|
val notificationFilter = app.config.getFor(event.profileId).sync.notificationFilter
|
||||||
id = Notification.buildId(event.profileId, type, event.id),
|
|
||||||
title = app.getNotificationTitle(type),
|
if (!notificationFilter.contains(type)) {
|
||||||
text = message,
|
val notification = Notification(
|
||||||
type = type,
|
id = Notification.buildId(event.profileId, type, event.id),
|
||||||
profileId = profile?.id,
|
title = app.getNotificationTitle(type),
|
||||||
profileName = profile?.name,
|
text = message,
|
||||||
viewId = if (event.type == Event.TYPE_HOMEWORK) MainActivity.DRAWER_ITEM_HOMEWORK else MainActivity.DRAWER_ITEM_AGENDA,
|
type = type,
|
||||||
addedDate = metadata.addedDate
|
profileId = profile?.id,
|
||||||
).addExtra("eventId", event.id).addExtra("eventDate", event.eventDate.value.toLong())
|
profileName = profile?.name,
|
||||||
|
viewId = if (event.type == Event.TYPE_HOMEWORK) MainActivity.DRAWER_ITEM_HOMEWORK else MainActivity.DRAWER_ITEM_AGENDA,
|
||||||
|
addedDate = metadata.addedDate
|
||||||
|
).addExtra("eventId", event.id).addExtra("eventDate", event.eventDate.value.toLong())
|
||||||
|
notificationList += notification
|
||||||
|
}
|
||||||
|
|
||||||
events += event
|
events += event
|
||||||
metadataList += metadata
|
metadataList += metadata
|
||||||
notificationList += notification
|
|
||||||
}
|
}
|
||||||
app.db.eventDao().addAll(events)
|
app.db.eventDao().addAll(events)
|
||||||
app.db.metadataDao().addAllReplace(metadataList)
|
app.db.metadataDao().addAllReplace(metadataList)
|
||||||
app.db.notificationDao().addAll(notificationList)
|
if (notificationList.isNotEmpty()) {
|
||||||
PostNotifications(app, notificationList)
|
app.db.notificationDao().addAll(notificationList)
|
||||||
|
PostNotifications(app, notificationList)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unsharedEvent(teamCode: String, eventId: Long, message: String) {
|
private fun unsharedEvent(teamCode: String, eventId: Long, message: String) {
|
||||||
@ -172,19 +178,26 @@ class SzkolnyAppFirebase(val app: App, val profiles: List<Profile>, val message:
|
|||||||
|
|
||||||
teams.filter { it.code == teamCode }.distinctBy { it.profileId }.forEach { team ->
|
teams.filter { it.code == teamCode }.distinctBy { it.profileId }.forEach { team ->
|
||||||
val profile = profiles.firstOrNull { it.id == team.profileId }
|
val profile = profiles.firstOrNull { it.id == team.profileId }
|
||||||
val notification = Notification(
|
val notificationFilter = app.config.getFor(team.profileId).sync.notificationFilter
|
||||||
id = Notification.buildId(profile?.id ?: 0, Notification.TYPE_REMOVED_SHARED_EVENT, eventId),
|
|
||||||
title = app.getNotificationTitle(Notification.TYPE_REMOVED_SHARED_EVENT),
|
if (!notificationFilter.contains(Notification.TYPE_REMOVED_SHARED_EVENT)) {
|
||||||
text = message,
|
val notification = Notification(
|
||||||
type = Notification.TYPE_REMOVED_SHARED_EVENT,
|
id = Notification.buildId(profile?.id
|
||||||
profileId = profile?.id,
|
?: 0, Notification.TYPE_REMOVED_SHARED_EVENT, eventId),
|
||||||
profileName = profile?.name,
|
title = app.getNotificationTitle(Notification.TYPE_REMOVED_SHARED_EVENT),
|
||||||
viewId = MainActivity.DRAWER_ITEM_AGENDA
|
text = message,
|
||||||
)
|
type = Notification.TYPE_REMOVED_SHARED_EVENT,
|
||||||
notificationList += notification
|
profileId = profile?.id,
|
||||||
|
profileName = profile?.name,
|
||||||
|
viewId = MainActivity.DRAWER_ITEM_AGENDA
|
||||||
|
)
|
||||||
|
notificationList += notification
|
||||||
|
}
|
||||||
app.db.eventDao().remove(team.profileId, eventId)
|
app.db.eventDao().remove(team.profileId, eventId)
|
||||||
}
|
}
|
||||||
app.db.notificationDao().addAll(notificationList)
|
if (notificationList.isNotEmpty()) {
|
||||||
PostNotifications(app, notificationList)
|
app.db.notificationDao().addAll(notificationList)
|
||||||
|
PostNotifications(app, notificationList)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-2-21.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.dialogs.sync
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
||||||
|
import pl.szczodrzynski.edziennik.onClick
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
// TODO refactor dialog to allow configuring other profiles
|
||||||
|
// than the selected one in UI
|
||||||
|
class NotificationFilterDialog(
|
||||||
|
val activity: AppCompatActivity,
|
||||||
|
val onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
|
val onDismissListener: ((tag: String) -> Unit)? = null
|
||||||
|
) : CoroutineScope {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "NotificationFilterDialog"
|
||||||
|
private val notificationTypes = listOf(
|
||||||
|
Notification.TYPE_TIMETABLE_LESSON_CHANGE to R.string.notification_type_timetable_lesson_change,
|
||||||
|
Notification.TYPE_NEW_GRADE to R.string.notification_type_new_grade,
|
||||||
|
Notification.TYPE_NEW_EVENT to R.string.notification_type_new_event,
|
||||||
|
Notification.TYPE_NEW_HOMEWORK to R.string.notification_type_new_homework,
|
||||||
|
Notification.TYPE_NEW_MESSAGE to R.string.notification_type_new_message,
|
||||||
|
Notification.TYPE_LUCKY_NUMBER to R.string.notification_type_lucky_number,
|
||||||
|
Notification.TYPE_NEW_NOTICE to R.string.notification_type_notice,
|
||||||
|
Notification.TYPE_NEW_ATTENDANCE to R.string.notification_type_attendance,
|
||||||
|
Notification.TYPE_NEW_ANNOUNCEMENT to R.string.notification_type_new_announcement,
|
||||||
|
Notification.TYPE_NEW_SHARED_EVENT to R.string.notification_type_new_shared_event,
|
||||||
|
Notification.TYPE_NEW_SHARED_HOMEWORK to R.string.notification_type_new_shared_homework,
|
||||||
|
Notification.TYPE_REMOVED_SHARED_EVENT to R.string.notification_type_removed_shared_event
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var app: App
|
||||||
|
private lateinit var dialog: AlertDialog
|
||||||
|
|
||||||
|
private val job = Job()
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = job + Dispatchers.Main
|
||||||
|
|
||||||
|
private val notificationFilter = mutableListOf<Int>()
|
||||||
|
|
||||||
|
init { run {
|
||||||
|
if (activity.isFinishing)
|
||||||
|
return@run
|
||||||
|
onShowListener?.invoke(TAG)
|
||||||
|
app = activity.applicationContext as App
|
||||||
|
|
||||||
|
notificationFilter.clear()
|
||||||
|
notificationFilter += app.config.forProfile().sync.notificationFilter
|
||||||
|
val items = notificationTypes.map { app.getString(it.second) }.toTypedArray()
|
||||||
|
val checkedItems = notificationTypes.map { !notificationFilter.contains(it.first) }.toBooleanArray()
|
||||||
|
|
||||||
|
dialog = MaterialAlertDialogBuilder(activity)
|
||||||
|
.setTitle(R.string.dialog_notification_filter_title)
|
||||||
|
//.setMessage(R.string.dialog_notification_filter_text)
|
||||||
|
.setMultiChoiceItems(items, checkedItems) { _, which, isChecked ->
|
||||||
|
val type = notificationTypes[which].first
|
||||||
|
notificationFilter.remove(type)
|
||||||
|
if (!isChecked)
|
||||||
|
notificationFilter += type
|
||||||
|
}
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.setOnDismissListener {
|
||||||
|
onDismissListener?.invoke(TAG)
|
||||||
|
}
|
||||||
|
.show()
|
||||||
|
|
||||||
|
dialog.getButton(AlertDialog.BUTTON_POSITIVE)?.onClick {
|
||||||
|
if (notificationFilter.isEmpty()) {
|
||||||
|
app.config.forProfile().sync.notificationFilter = notificationFilter
|
||||||
|
dialog.dismiss()
|
||||||
|
return@onClick
|
||||||
|
}
|
||||||
|
// warn user when he tries to disable some notifications
|
||||||
|
MaterialAlertDialogBuilder(activity)
|
||||||
|
.setTitle(R.string.are_you_sure)
|
||||||
|
.setMessage(R.string.notification_filter_warning)
|
||||||
|
.setPositiveButton(R.string.ok) { _, _ ->
|
||||||
|
app.config.forProfile().sync.notificationFilter = notificationFilter
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}
|
@ -54,6 +54,7 @@ import pl.szczodrzynski.edziennik.sync.UpdateWorker;
|
|||||||
import pl.szczodrzynski.edziennik.ui.dialogs.changelog.ChangelogDialog;
|
import pl.szczodrzynski.edziennik.ui.dialogs.changelog.ChangelogDialog;
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.GradesConfigDialog;
|
import pl.szczodrzynski.edziennik.ui.dialogs.settings.GradesConfigDialog;
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.ProfileRemoveDialog;
|
import pl.szczodrzynski.edziennik.ui.dialogs.settings.ProfileRemoveDialog;
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.sync.NotificationFilterDialog;
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes;
|
import pl.szczodrzynski.edziennik.utils.Themes;
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils;
|
import pl.szczodrzynski.edziennik.utils.Utils;
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date;
|
import pl.szczodrzynski.edziennik.utils.models.Date;
|
||||||
@ -217,6 +218,24 @@ public class SettingsNewFragment extends MaterialAboutFragment {
|
|||||||
})
|
})
|
||||||
);*/
|
);*/
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
new MaterialAboutActionItem(
|
||||||
|
getString(R.string.settings_profile_notifications_text),
|
||||||
|
getString(R.string.settings_profile_notifications_subtext),
|
||||||
|
new IconicsDrawable(activity)
|
||||||
|
.icon(CommunityMaterial.Icon.cmd_filter_outline)
|
||||||
|
.size(IconicsSize.dp(iconSizeDp))
|
||||||
|
.color(IconicsColor.colorInt(iconColor))
|
||||||
|
)
|
||||||
|
.setOnClickAction(() -> {
|
||||||
|
new NotificationFilterDialog(activity, null, null);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
items.add(getMoreItem(() -> addCardItems(CARD_PROFILE, getProfileCard(true))));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
items.add(
|
items.add(
|
||||||
new MaterialAboutSwitchItem(
|
new MaterialAboutSwitchItem(
|
||||||
getString(R.string.settings_profile_sync_text),
|
getString(R.string.settings_profile_sync_text),
|
||||||
@ -226,35 +245,14 @@ public class SettingsNewFragment extends MaterialAboutFragment {
|
|||||||
.size(IconicsSize.dp(iconSizeDp))
|
.size(IconicsSize.dp(iconSizeDp))
|
||||||
.color(IconicsColor.colorInt(iconColor))
|
.color(IconicsColor.colorInt(iconColor))
|
||||||
)
|
)
|
||||||
.setChecked(app.getProfile().getSyncEnabled())
|
.setChecked(app.getProfile().getSyncEnabled())
|
||||||
.setOnChangeAction(((isChecked, tag) -> {
|
.setOnChangeAction(((isChecked, tag) -> {
|
||||||
app.getProfile().setSyncEnabled(isChecked);
|
app.getProfile().setSyncEnabled(isChecked);
|
||||||
app.profileSave();
|
app.profileSave();
|
||||||
return true;
|
return true;
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
items.add(getMoreItem(() -> addCardItems(CARD_PROFILE, getProfileCard(true))));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
/*items.add(
|
|
||||||
new MaterialAboutSwitchItem(
|
|
||||||
getString(R.string.settings_profile_notify_text),
|
|
||||||
getString(R.string.settings_profile_notify_subtext),
|
|
||||||
new IconicsDrawable(activity)
|
|
||||||
.icon(CommunityMaterial.Icon.cmd_bell_ring)
|
|
||||||
.size(IconicsSize.dp(iconSizeDp))
|
|
||||||
.color(IconicsColor.colorInt(iconColor))
|
|
||||||
)
|
|
||||||
.setChecked(app.getProfile().getSyncNotifications())
|
|
||||||
.setOnChangeAction(((isChecked, tag) -> {
|
|
||||||
app.getProfile().setSyncNotifications(isChecked);
|
|
||||||
app.profileSave();
|
|
||||||
return true;
|
|
||||||
}))
|
|
||||||
);*/
|
|
||||||
|
|
||||||
items.add(
|
items.add(
|
||||||
new MaterialAboutActionItem(
|
new MaterialAboutActionItem(
|
||||||
getString(R.string.settings_profile_remove_text),
|
getString(R.string.settings_profile_remove_text),
|
||||||
|
@ -567,7 +567,7 @@
|
|||||||
<string name="notification_type_new_homework">Nowe zadanie domowe</string>
|
<string name="notification_type_new_homework">Nowe zadanie domowe</string>
|
||||||
<string name="notification_type_new_message">Nowa wiadomość</string>
|
<string name="notification_type_new_message">Nowa wiadomość</string>
|
||||||
<string name="notification_type_new_shared_event">Udostępniono wydarzenie</string>
|
<string name="notification_type_new_shared_event">Udostępniono wydarzenie</string>
|
||||||
<string name="notification_type_notice">Ocena ucznia</string>
|
<string name="notification_type_notice">Wpis zachowania</string>
|
||||||
<string name="notification_type_server_message">Wiadomość z serwera</string>
|
<string name="notification_type_server_message">Wiadomość z serwera</string>
|
||||||
<string name="notification_type_timetable_change">Zmiana planu zajęć</string>
|
<string name="notification_type_timetable_change">Zmiana planu zajęć</string>
|
||||||
<string name="notification_type_timetable_lesson_change">Zmiana lekcji</string>
|
<string name="notification_type_timetable_lesson_change">Zmiana lekcji</string>
|
||||||
@ -1181,5 +1181,10 @@
|
|||||||
<string name="notification_user_action_required_title">Wymagane działanie w aplikacji</string>
|
<string name="notification_user_action_required_title">Wymagane działanie w aplikacji</string>
|
||||||
<string name="notification_user_action_required_text">Problem, który uniemożliwia synchronizację musi być rozwiązany przez użytkownika. Kliknij, aby uzyskać więcej informacji.</string>
|
<string name="notification_user_action_required_text">Problem, który uniemożliwia synchronizację musi być rozwiązany przez użytkownika. Kliknij, aby uzyskać więcej informacji.</string>
|
||||||
<string name="notification_user_action_required_captcha_librus">Librus: wymagane rozwiązanie zadania Captcha. Kliknij, aby kontynuować logowanie do dziennika.</string>
|
<string name="notification_user_action_required_captcha_librus">Librus: wymagane rozwiązanie zadania Captcha. Kliknij, aby kontynuować logowanie do dziennika.</string>
|
||||||
|
<string name="settings_profile_notifications_text">Filtruj powiadomienia</string>
|
||||||
|
<string name="settings_profile_notifications_subtext">Wyłącz określone rodzaje powiadomień</string>
|
||||||
|
<string name="dialog_notification_filter_title">Pokazuj wybrane powiadomienia</string>
|
||||||
|
<string name="dialog_notification_filter_text"><![CDATA[Zaznacz, które powiadomienia mają być pokazywane w systemie oraz w aplikacji.]]></string>
|
||||||
|
<string name="notification_filter_warning">Czy na pewno chcesz zastosować te ustawienia?\n\nNie będziesz widział informacji o niektórych danych, przez co możesz przeoczyć ważne komunikaty, wiadomości lub oceny.\n\nUstawienia zostaną zastosowane dla aktualnie otwartego profilu.</string>
|
||||||
<string name="dialog_day_lessons_info">%s - %s (%s lekcji - %s godzin %s minut)</string>
|
<string name="dialog_day_lessons_info">%s - %s (%s lekcji - %s godzin %s minut)</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user