[Notifications] Implement Quiet hours. Add missing timetable manual strings.

This commit is contained in:
Kuba Szczodrzyński 2020-03-08 17:22:14 +01:00
parent 88a1de50ca
commit 630361849c
7 changed files with 119 additions and 64 deletions

View File

@ -22,7 +22,7 @@ import kotlin.coroutines.CoroutineContext
class Config(val db: AppDb) : CoroutineScope, AbstractConfig { class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
companion object { companion object {
const val DATA_VERSION = 10 const val DATA_VERSION = 11
} }
private val job = Job() private val job = Job()

View File

@ -7,6 +7,7 @@ package pl.szczodrzynski.edziennik.config
import pl.szczodrzynski.edziennik.config.utils.get import pl.szczodrzynski.edziennik.config.utils.get
import pl.szczodrzynski.edziennik.config.utils.getIntList import pl.szczodrzynski.edziennik.config.utils.getIntList
import pl.szczodrzynski.edziennik.config.utils.set import pl.szczodrzynski.edziennik.config.utils.set
import pl.szczodrzynski.edziennik.utils.models.Time
class ConfigSync(private val config: Config) { class ConfigSync(private val config: Config) {
private var mDontShowAppManagerDialog: Boolean? = null private var mDontShowAppManagerDialog: Boolean? = null
@ -40,14 +41,19 @@ class ConfigSync(private val config: Config) {
| | | | | | | |/ _ \ __| | '_ \ / _ \| | | | '__/ __| | | | | | | | |/ _ \ __| | '_ \ / _ \| | | | '__/ __|
| |__| | |_| | | __/ |_ | | | | (_) | |_| | | \__ \ | |__| | |_| | | __/ |_ | | | | (_) | |_| | | \__ \
\___\_\\__,_|_|\___|\__| |_| |_|\___/ \__,_|_| |__*/ \___\_\\__,_|_|\___|\__| |_| |_|\___/ \__,_|_| |__*/
private var mQuietHoursStart: Long? = null private var mQuietHoursEnabled: Boolean? = null
var quietHoursStart: Long var quietHoursEnabled: Boolean
get() { mQuietHoursStart = mQuietHoursStart ?: config.values.get("quietHoursStart", 0L); return mQuietHoursStart ?: 0L } get() { mQuietHoursEnabled = mQuietHoursEnabled ?: config.values.get("quietHoursEnabled", false); return mQuietHoursEnabled ?: false }
set(value) { config.set("quietHoursEnabled", value); mQuietHoursEnabled = value }
private var mQuietHoursStart: Time? = null
var quietHoursStart: Time?
get() { mQuietHoursStart = mQuietHoursStart ?: config.values.get("quietHoursStart", null as Time?); return mQuietHoursStart }
set(value) { config.set("quietHoursStart", value); mQuietHoursStart = value } set(value) { config.set("quietHoursStart", value); mQuietHoursStart = value }
private var mQuietHoursEnd: Long? = null private var mQuietHoursEnd: Time? = null
var quietHoursEnd: Long var quietHoursEnd: Time?
get() { mQuietHoursEnd = mQuietHoursEnd ?: config.values.get("quietHoursEnd", 0L); return mQuietHoursEnd ?: 0L } get() { mQuietHoursEnd = mQuietHoursEnd ?: config.values.get("quietHoursEnd", null as Time?); return mQuietHoursEnd }
set(value) { config.set("quietHoursEnd", value); mQuietHoursEnd = value } set(value) { config.set("quietHoursEnd", value); mQuietHoursEnd = value }
private var mQuietDuringLessons: Boolean? = null private var mQuietDuringLessons: Boolean? = null

View File

@ -14,6 +14,7 @@ import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_LIBRUS
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_MOBIDZIENNIK import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_MOBIDZIENNIK
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_VULCAN import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_VULCAN
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
import kotlin.math.abs
class AppConfigMigrationV3(p: SharedPreferences, config: Config) { class AppConfigMigrationV3(p: SharedPreferences, config: Config) {
init { config.apply { init { config.apply {
@ -42,9 +43,7 @@ class AppConfigMigrationV3(p: SharedPreferences, config: Config) {
devModePassword = p.getString("$s.devModePassword", null).fix() devModePassword = p.getString("$s.devModePassword", null).fix()
sync.tokenApp = p.getString("$s.fcmToken", null).fix() sync.tokenApp = p.getString("$s.fcmToken", null).fix()
timetable.bellSyncMultiplier = p.getString("$s.bellSyncMultiplier", null)?.toIntOrNull() ?: 0 timetable.bellSyncMultiplier = p.getString("$s.bellSyncMultiplier", null)?.toIntOrNull() ?: 0
sync.quietHoursStart = p.getString("$s.quietHoursStart", null)?.toLongOrNull() ?: 0
appRateSnackbarTime = p.getString("$s.appRateSnackbarTime", null)?.toLongOrNull() ?: 0 appRateSnackbarTime = p.getString("$s.appRateSnackbarTime", null)?.toLongOrNull() ?: 0
sync.quietHoursEnd = p.getString("$s.quietHoursEnd", null)?.toLongOrNull() ?: 0
timetable.countInSeconds = p.getString("$s.countInSeconds", null)?.toBoolean() ?: false timetable.countInSeconds = p.getString("$s.countInSeconds", null)?.toBoolean() ?: false
ui.headerBackground = p.getString("$s.headerBackground", null).fix() ui.headerBackground = p.getString("$s.headerBackground", null).fix()
ui.appBackground = p.getString("$s.appBackground", null).fix() ui.appBackground = p.getString("$s.appBackground", null).fix()
@ -59,6 +58,22 @@ class AppConfigMigrationV3(p: SharedPreferences, config: Config) {
sync.notifyAboutUpdates = p.getString("$s.notifyAboutUpdates", null)?.toBoolean() ?: true sync.notifyAboutUpdates = p.getString("$s.notifyAboutUpdates", null)?.toBoolean() ?: true
timetable.bellSyncDiff = p.getString("$s.bellSyncDiff", null)?.let { Gson().fromJson(it, Time::class.java) } timetable.bellSyncDiff = p.getString("$s.bellSyncDiff", null)?.let { Gson().fromJson(it, Time::class.java) }
val startMillis = p.getString("$s.quietHoursStart", null)?.toLongOrNull() ?: 0
val endMillis = p.getString("$s.quietHoursEnd", null)?.toLongOrNull() ?: 0
if (startMillis > 0) {
try {
sync.quietHoursStart = Time.fromMillis(abs(startMillis))
sync.quietHoursEnd = Time.fromMillis(abs(endMillis))
sync.quietHoursEnabled = true
}
catch (_: Exception) {}
}
else {
sync.quietHoursEnabled = false
sync.quietHoursStart = null
sync.quietHoursEnd = null
}
sync.tokenMobidziennikList = listOf() sync.tokenMobidziennikList = listOf()
sync.tokenVulcanList = listOf() sync.tokenVulcanList = listOf()
sync.tokenLibrusList = listOf() sync.tokenLibrusList = listOf()

View File

@ -11,6 +11,8 @@ import pl.szczodrzynski.edziennik.HOUR
import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.config.Config import pl.szczodrzynski.edziennik.config.Config
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.ORDER_BY_DATE_DESC import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.ORDER_BY_DATE_DESC
import pl.szczodrzynski.edziennik.utils.models.Time
import kotlin.math.abs
class ConfigMigration(app: App, config: Config) { class ConfigMigration(app: App, config: Config) {
init { config.apply { init { config.apply {
@ -43,8 +45,9 @@ class ConfigMigration(app: App, config: Config) {
sync.interval = 1*HOUR.toInt() sync.interval = 1*HOUR.toInt()
sync.notifyAboutUpdates = true sync.notifyAboutUpdates = true
sync.onlyWifi = false sync.onlyWifi = false
sync.quietHoursStart = 0 sync.quietHoursEnabled = false
sync.quietHoursEnd = 0 sync.quietHoursStart = null
sync.quietHoursEnd = null
sync.quietDuringLessons = false sync.quietDuringLessons = false
sync.tokenApp = null sync.tokenApp = null
sync.tokenMobidziennik = null sync.tokenMobidziennik = null
@ -69,5 +72,25 @@ class ConfigMigration(app: App, config: Config) {
dataVersion = 10 dataVersion = 10
} }
if (dataVersion < 11) {
val startMillis = config.values.get("quietHoursStart", 0L)
val endMillis = config.values.get("quietHoursEnd", 0L)
if (startMillis > 0) {
try {
sync.quietHoursStart = Time.fromMillis(abs(startMillis))
sync.quietHoursEnd = Time.fromMillis(abs(endMillis))
sync.quietHoursEnabled = true
}
catch (_: Exception) {}
}
else {
sync.quietHoursEnabled = false
sync.quietHoursStart = null
sync.quietHoursEnd = null
}
dataVersion = 11
}
}} }}
} }

View File

@ -10,6 +10,7 @@ import androidx.core.util.forEach
import androidx.core.util.set import androidx.core.util.set
import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_SERVER_MESSAGE import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_SERVER_MESSAGE
import pl.szczodrzynski.edziennik.utils.models.Time
import pl.szczodrzynski.edziennik.data.db.entity.Notification as AppNotification import pl.szczodrzynski.edziennik.data.db.entity.Notification as AppNotification
class PostNotifications(val app: App, nList: List<AppNotification>) { class PostNotifications(val app: App, nList: List<AppNotification>) {
@ -17,22 +18,34 @@ class PostNotifications(val app: App, nList: List<AppNotification>) {
private const val TAG = "PostNotifications" private const val TAG = "PostNotifications"
} }
/*public boolean shouldBeQuiet() { private val quiet by lazy { shouldBeQuiet() }
long now = Time.getNow().getInMillis(); fun shouldBeQuiet(): Boolean {
long start = app.config.getSync().getQuietHoursStart(); if (!app.config.sync.quietHoursEnabled)
long end = app.config.getSync().getQuietHoursEnd(); return false
val now = Time.getNow().value
val start = app.config.sync.quietHoursStart?.value ?: return false
var end = app.config.sync.quietHoursEnd?.value ?: return false
if (start > end) { if (start > end) {
end += 1000 * 60 * 60 * 24; // the range spans between two days
//Log.d(TAG, "Night passing"); end += 240000
} }
if (start > now) { return now in start..end || now+240000 in start..end
now += 1000 * 60 * 60 * 24; }
//Log.d(TAG, "Now is smaller");
} private fun NotificationCompat.Builder.addDefaults(): NotificationCompat.Builder {
//Log.d(TAG, "Start is "+start+", now is "+now+", end is "+end); return this.setColor(0xff2196f3.toInt())
return start > 0 && now >= start && now <= end; .setLights(0xff2196f3.toInt(), 2000, 2000)
}*/ .setPriority(if (quiet) NotificationCompat.PRIORITY_LOW else NotificationCompat.PRIORITY_MAX)
fun shouldBeQuiet() = false .also {
if (quiet) {
it.setSound(null)
it.setVibrate(longArrayOf())
}
else
it.setDefaults(NotificationCompat.DEFAULT_ALL)
}
.setGroup(if (quiet) app.notificationChannelsManager.dataQuiet.key else app.notificationChannelsManager.data.key)
}
private fun buildSummaryText(summaryCounts: SparseIntArray): CharSequence { private fun buildSummaryText(summaryCounts: SparseIntArray): CharSequence {
val summaryTexts = mutableListOf<String>() val summaryTexts = mutableListOf<String>()
@ -108,11 +121,7 @@ class PostNotifications(val app: App, nList: List<AppNotification>) {
it.addLine(line) it.addLine(line)
} }
}) })
.setColor(0xff2196f3.toInt()) .addDefaults()
.setLights(0xff2196f3.toInt(), 2000, 2000)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setGroup(app.notificationChannelsManager.data.key)
.setContentIntent(summaryIntent) .setContentIntent(summaryIntent)
.setAutoCancel(true) .setAutoCancel(true)
.build() .build()
@ -131,11 +140,7 @@ class PostNotifications(val app: App, nList: List<AppNotification>) {
.setStyle(NotificationCompat.BigTextStyle() .setStyle(NotificationCompat.BigTextStyle()
.bigText(it.text)) .bigText(it.text))
.setWhen(it.addedDate) .setWhen(it.addedDate)
.setColor(0xff2196f3.toInt()) .addDefaults()
.setLights(0xff2196f3.toInt(), 2000, 2000)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setGroup(app.notificationChannelsManager.data.key)
.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY) .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY)
.setContentIntent(it.getPendingIntent(app)) .setContentIntent(it.getPendingIntent(app))
.setAutoCancel(true) .setAutoCancel(true)
@ -155,11 +160,7 @@ class PostNotifications(val app: App, nList: List<AppNotification>) {
.setContentText(buildSummaryText(summaryCounts)) .setContentText(buildSummaryText(summaryCounts))
.setTicker(newNotificationsText) .setTicker(newNotificationsText)
.setSmallIcon(R.drawable.ic_notification) .setSmallIcon(R.drawable.ic_notification)
.setColor(0xff2196f3.toInt()) .addDefaults()
.setLights(0xff2196f3.toInt(), 2000, 2000)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setGroup(app.notificationChannelsManager.data.key)
.setGroupSummary(true) .setGroupSummary(true)
.setContentIntent(summaryIntent) .setContentIntent(summaryIntent)
.setAutoCancel(true) .setAutoCancel(true)

View File

@ -523,10 +523,12 @@ public class SettingsNewFragment extends MaterialAboutFragment {
); );
} }
private String getSyncCardQuietHoursSubText() { private String getSyncCardQuietHoursSubText() {
if (app.getConfig().getSync().getQuietHoursStart() == null || app.getConfig().getSync().getQuietHoursEnd() == null)
return "";
return getString( return getString(
app.getConfig().getSync().getQuietHoursStart() >= app.getConfig().getSync().getQuietHoursEnd() ? R.string.settings_sync_quiet_hours_subtext_next_day_format : R.string.settings_sync_quiet_hours_subtext_format, app.getConfig().getSync().getQuietHoursStart().getValue() >= app.getConfig().getSync().getQuietHoursEnd().getValue() ? R.string.settings_sync_quiet_hours_subtext_next_day_format : R.string.settings_sync_quiet_hours_subtext_format,
Time.fromMillis(Math.abs(app.getConfig().getSync().getQuietHoursStart())).getStringHM(), app.getConfig().getSync().getQuietHoursStart().getStringHM(),
Time.fromMillis(app.getConfig().getSync().getQuietHoursEnd()).getStringHM() app.getConfig().getSync().getQuietHoursEnd().getStringHM()
); );
} }
private MaterialAboutItem getSyncCardWifiItem() { private MaterialAboutItem getSyncCardWifiItem() {
@ -650,7 +652,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
.size(IconicsSize.dp(iconSizeDp)) .size(IconicsSize.dp(iconSizeDp))
.color(IconicsColor.colorInt(iconColor)) .color(IconicsColor.colorInt(iconColor))
); );
syncCardQuietHoursItem.setChecked(app.getConfig().getSync().getQuietHoursStart() > 0); syncCardQuietHoursItem.setChecked(app.getConfig().getSync().getQuietHoursEnabled());
syncCardQuietHoursItem.setSubTextChecked(getSyncCardQuietHoursSubText()); syncCardQuietHoursItem.setSubTextChecked(getSyncCardQuietHoursSubText());
syncCardQuietHoursItem.setOnClickAction(() -> { syncCardQuietHoursItem.setOnClickAction(() -> {
new MaterialDialog.Builder(activity) new MaterialDialog.Builder(activity)
@ -662,10 +664,12 @@ public class SettingsNewFragment extends MaterialAboutFragment {
.itemsCallback((dialog, itemView, position, text) -> { .itemsCallback((dialog, itemView, position, text) -> {
if (position == 0) { if (position == 0) {
// set beginning // set beginning
Time time = Time.fromMillis(Math.abs(app.getConfig().getSync().getQuietHoursStart())); Time time = app.getConfig().getSync().getQuietHoursStart();
if (time == null)
time = new Time(22, 30, 0);
TimePickerDialog.newInstance((v2, hourOfDay, minute, second) -> { TimePickerDialog.newInstance((v2, hourOfDay, minute, second) -> {
// if it's disabled, it'll be enabled automatically app.getConfig().getSync().setQuietHoursEnabled(true);
app.getConfig().getSync().setQuietHoursStart(new Time(hourOfDay, minute, second).getInMillis()); app.getConfig().getSync().setQuietHoursStart(new Time(hourOfDay, minute, second));
syncCardQuietHoursItem.setChecked(true); syncCardQuietHoursItem.setChecked(true);
syncCardQuietHoursItem.setSubTextChecked(getSyncCardQuietHoursSubText()); syncCardQuietHoursItem.setSubTextChecked(getSyncCardQuietHoursSubText());
refreshMaterialAboutList(); refreshMaterialAboutList();
@ -673,13 +677,12 @@ public class SettingsNewFragment extends MaterialAboutFragment {
} }
else { else {
// set end // set end
Time time = Time.fromMillis(app.getConfig().getSync().getQuietHoursEnd()); Time time = app.getConfig().getSync().getQuietHoursEnd();
if (time == null)
time = new Time(5, 30, 0);
TimePickerDialog.newInstance((v2, hourOfDay, minute, second) -> { TimePickerDialog.newInstance((v2, hourOfDay, minute, second) -> {
if (app.getConfig().getSync().getQuietHoursStart() < 0) { app.getConfig().getSync().setQuietHoursEnabled(true);
// if it's disabled, enable app.getConfig().getSync().setQuietHoursEnd(new Time(hourOfDay, minute, second));
app.getConfig().getSync().setQuietHoursStart(-1 * app.getConfig().getSync().getQuietHoursStart());
}
app.getConfig().getSync().setQuietHoursEnd(new Time(hourOfDay, minute, second).getInMillis());
syncCardQuietHoursItem.setChecked(true); syncCardQuietHoursItem.setChecked(true);
syncCardQuietHoursItem.setSubTextChecked(getSyncCardQuietHoursSubText()); syncCardQuietHoursItem.setSubTextChecked(getSyncCardQuietHoursSubText());
refreshMaterialAboutList(); refreshMaterialAboutList();
@ -689,15 +692,10 @@ public class SettingsNewFragment extends MaterialAboutFragment {
.show(); .show();
}); });
syncCardQuietHoursItem.setOnChangeAction((isChecked, tag) -> { syncCardQuietHoursItem.setOnChangeAction((isChecked, tag) -> {
if (isChecked && app.getConfig().getSync().getQuietHoursStart() < 0) { app.getConfig().getSync().setQuietHoursEnabled(isChecked);
app.getConfig().getSync().setQuietHoursStart(app.getConfig().getSync().getQuietHoursStart() * -1); if (isChecked && app.getConfig().getSync().getQuietHoursStart() == null) {
} app.getConfig().getSync().setQuietHoursStart(new Time(22, 30, 0));
else if (!isChecked && app.getConfig().getSync().getQuietHoursStart() > 0) { app.getConfig().getSync().setQuietHoursEnd(new Time(5, 30, 0));
app.getConfig().getSync().setQuietHoursStart(app.getConfig().getSync().getQuietHoursStart() * -1);
}
else if (isChecked && app.getConfig().getSync().getQuietHoursStart() == 0) {
app.getConfig().getSync().setQuietHoursStart(new Time(22, 30, 0).getInMillis());
app.getConfig().getSync().setQuietHoursEnd(new Time(5, 30, 0).getInMillis());
syncCardQuietHoursItem.setSubTextChecked(getSyncCardQuietHoursSubText()); syncCardQuietHoursItem.setSubTextChecked(getSyncCardQuietHoursSubText());
refreshMaterialAboutList(); refreshMaterialAboutList();
} }

View File

@ -1237,4 +1237,16 @@
<string name="dropdown_subject_custom">Własny przedmiot</string> <string name="dropdown_subject_custom">Własny przedmiot</string>
<string name="dialog_event_manual_date_choose">Wybierz datę</string> <string name="dialog_event_manual_date_choose">Wybierz datę</string>
<string name="dropdown_date_no_more_lessons">Nie ma więcej lekcji tego przedmiotu. Pobierz plan lekcji i spróbuj ponownie.</string> <string name="dropdown_date_no_more_lessons">Nie ma więcej lekcji tego przedmiotu. Pobierz plan lekcji i spróbuj ponownie.</string>
<string name="timetable_manual_dialog_date">Data</string>
<string name="timetable_manual_dialog_date_choose">Wybierz datę</string>
<string name="timetable_manual_dialog_subject_choose">Wybierz przedmiot</string>
<string name="timetable_manual_dialog_time">Godzina</string>
<string name="timetable_manual_dialog_time_choose">Wybierz godzinę</string>
<string name="timetable_manual_dialog_time_format" formatted="false">%s (lekcja %d)</string>
<string name="timetable_manual_item_empty">Nie dodano własnych lekcji na ten dzień.</string>
<string name="timetable_manual_repeat_by_subject_notice">Na każdej lekcji przedmiotu %s</string>
<string name="timetable_manual_repeating_notice">Obejmuje plan lekcji na każdy tydzień</string>
<string name="timetable_manual_type_by_subject">Wg. przedmiotu</string>
<string name="timetable_manual_type_one_time">Jednorazowo</string>
<string name="timetable_manual_type_repeating">Cyklicznie</string>
</resources> </resources>