[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 {
companion object {
const val DATA_VERSION = 10
const val DATA_VERSION = 11
}
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.getIntList
import pl.szczodrzynski.edziennik.config.utils.set
import pl.szczodrzynski.edziennik.utils.models.Time
class ConfigSync(private val config: Config) {
private var mDontShowAppManagerDialog: Boolean? = null
@ -40,14 +41,19 @@ class ConfigSync(private val config: Config) {
| | | | | | | |/ _ \ __| | '_ \ / _ \| | | | '__/ __|
| |__| | |_| | | __/ |_ | | | | (_) | |_| | | \__ \
\___\_\\__,_|_|\___|\__| |_| |_|\___/ \__,_|_| |__*/
private var mQuietHoursStart: Long? = null
var quietHoursStart: Long
get() { mQuietHoursStart = mQuietHoursStart ?: config.values.get("quietHoursStart", 0L); return mQuietHoursStart ?: 0L }
private var mQuietHoursEnabled: Boolean? = null
var quietHoursEnabled: Boolean
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 }
private var mQuietHoursEnd: Long? = null
var quietHoursEnd: Long
get() { mQuietHoursEnd = mQuietHoursEnd ?: config.values.get("quietHoursEnd", 0L); return mQuietHoursEnd ?: 0L }
private var mQuietHoursEnd: Time? = null
var quietHoursEnd: Time?
get() { mQuietHoursEnd = mQuietHoursEnd ?: config.values.get("quietHoursEnd", null as Time?); return mQuietHoursEnd }
set(value) { config.set("quietHoursEnd", value); mQuietHoursEnd = value }
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_VULCAN
import pl.szczodrzynski.edziennik.utils.models.Time
import kotlin.math.abs
class AppConfigMigrationV3(p: SharedPreferences, config: Config) {
init { config.apply {
@ -42,9 +43,7 @@ class AppConfigMigrationV3(p: SharedPreferences, config: Config) {
devModePassword = p.getString("$s.devModePassword", null).fix()
sync.tokenApp = p.getString("$s.fcmToken", null).fix()
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
sync.quietHoursEnd = p.getString("$s.quietHoursEnd", null)?.toLongOrNull() ?: 0
timetable.countInSeconds = p.getString("$s.countInSeconds", null)?.toBoolean() ?: false
ui.headerBackground = p.getString("$s.headerBackground", 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
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.tokenVulcanList = listOf()
sync.tokenLibrusList = listOf()

View File

@ -11,6 +11,8 @@ import pl.szczodrzynski.edziennik.HOUR
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.config.Config
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) {
init { config.apply {
@ -43,8 +45,9 @@ class ConfigMigration(app: App, config: Config) {
sync.interval = 1*HOUR.toInt()
sync.notifyAboutUpdates = true
sync.onlyWifi = false
sync.quietHoursStart = 0
sync.quietHoursEnd = 0
sync.quietHoursEnabled = false
sync.quietHoursStart = null
sync.quietHoursEnd = null
sync.quietDuringLessons = false
sync.tokenApp = null
sync.tokenMobidziennik = null
@ -69,5 +72,25 @@ class ConfigMigration(app: App, config: Config) {
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 pl.szczodrzynski.edziennik.*
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
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"
}
/*public boolean shouldBeQuiet() {
long now = Time.getNow().getInMillis();
long start = app.config.getSync().getQuietHoursStart();
long end = app.config.getSync().getQuietHoursEnd();
private val quiet by lazy { shouldBeQuiet() }
fun shouldBeQuiet(): Boolean {
if (!app.config.sync.quietHoursEnabled)
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) {
end += 1000 * 60 * 60 * 24;
//Log.d(TAG, "Night passing");
// the range spans between two days
end += 240000
}
if (start > now) {
now += 1000 * 60 * 60 * 24;
//Log.d(TAG, "Now is smaller");
}
//Log.d(TAG, "Start is "+start+", now is "+now+", end is "+end);
return start > 0 && now >= start && now <= end;
}*/
fun shouldBeQuiet() = false
return now in start..end || now+240000 in start..end
}
private fun NotificationCompat.Builder.addDefaults(): NotificationCompat.Builder {
return this.setColor(0xff2196f3.toInt())
.setLights(0xff2196f3.toInt(), 2000, 2000)
.setPriority(if (quiet) NotificationCompat.PRIORITY_LOW else NotificationCompat.PRIORITY_MAX)
.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 {
val summaryTexts = mutableListOf<String>()
@ -108,11 +121,7 @@ class PostNotifications(val app: App, nList: List<AppNotification>) {
it.addLine(line)
}
})
.setColor(0xff2196f3.toInt())
.setLights(0xff2196f3.toInt(), 2000, 2000)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setGroup(app.notificationChannelsManager.data.key)
.addDefaults()
.setContentIntent(summaryIntent)
.setAutoCancel(true)
.build()
@ -131,11 +140,7 @@ class PostNotifications(val app: App, nList: List<AppNotification>) {
.setStyle(NotificationCompat.BigTextStyle()
.bigText(it.text))
.setWhen(it.addedDate)
.setColor(0xff2196f3.toInt())
.setLights(0xff2196f3.toInt(), 2000, 2000)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setGroup(app.notificationChannelsManager.data.key)
.addDefaults()
.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY)
.setContentIntent(it.getPendingIntent(app))
.setAutoCancel(true)
@ -155,11 +160,7 @@ class PostNotifications(val app: App, nList: List<AppNotification>) {
.setContentText(buildSummaryText(summaryCounts))
.setTicker(newNotificationsText)
.setSmallIcon(R.drawable.ic_notification)
.setColor(0xff2196f3.toInt())
.setLights(0xff2196f3.toInt(), 2000, 2000)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setGroup(app.notificationChannelsManager.data.key)
.addDefaults()
.setGroupSummary(true)
.setContentIntent(summaryIntent)
.setAutoCancel(true)

View File

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

View File

@ -1237,4 +1237,16 @@
<string name="dropdown_subject_custom">Własny przedmiot</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="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>