mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-03-22 01:17:16 +01:00
[Structure] Refactor App class to Kotlin. Rewrite SzkolnyTask and posting notifications. Remove dependency on AppConfig. Update libraries and gradle.
This commit is contained in:
parent
55c6e40d6d
commit
b7fc6fcc38
@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
|
|||||||
//apply plugin: 'me.tatarka.retrolambda'
|
//apply plugin: 'me.tatarka.retrolambda'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
compileSdkVersion setup.compileSdk
|
||||||
|
|
||||||
android {
|
android {
|
||||||
lintOptions {
|
lintOptions {
|
||||||
@ -12,7 +12,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 14
|
minSdkVersion 14
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion setup.targetSdk
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
}
|
}
|
||||||
@ -43,9 +43,9 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
// Google libraries
|
// Google libraries
|
||||||
implementation "androidx.appcompat:appcompat:${androidXAppCompat}"
|
implementation "androidx.appcompat:appcompat:${versions.appcompat}"
|
||||||
implementation "androidx.recyclerview:recyclerview:${androidXRecyclerView}"
|
implementation "androidx.recyclerview:recyclerview:${versions.recyclerView}"
|
||||||
implementation "com.google.android.material:material:${googleMaterial}"
|
implementation "com.google.android.material:material:${versions.material}"
|
||||||
|
|
||||||
// other libraries
|
// other libraries
|
||||||
//implementation 'se.emilsjolander:stickylistheaders:2.7.0'
|
//implementation 'se.emilsjolander:stickylistheaders:2.7.0'
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'kotlin-android-extensions'
|
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
apply plugin: 'kotlin-kapt'
|
||||||
|
apply plugin: 'kotlin-android-extensions'
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
apply plugin: 'io.fabric'
|
apply plugin: 'io.fabric'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
}
|
}
|
||||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
compileSdkVersion setup.compileSdk
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId 'pl.szczodrzynski.edziennik'
|
applicationId 'pl.szczodrzynski.edziennik'
|
||||||
minSdkVersion setup.minSdk
|
minSdkVersion setup.minSdk
|
||||||
@ -103,7 +104,7 @@ tasks.whenTaskAdded { task ->
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
|
|
||||||
annotationProcessor "androidx.room:room-compiler:${versions.room}"
|
kapt "androidx.room:room-compiler:${versions.room}"
|
||||||
debugImplementation "com.amitshekhar.android:debug-db:1.0.5"
|
debugImplementation "com.amitshekhar.android:debug-db:1.0.5"
|
||||||
|
|
||||||
implementation "android.arch.navigation:navigation-fragment-ktx:${versions.navigationFragment}"
|
implementation "android.arch.navigation:navigation-fragment-ktx:${versions.navigationFragment}"
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
-keepclassmembers class pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig { public *; }
|
-keepclassmembers class pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig { public *; }
|
||||||
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.timetable.WidgetTimetableProvider
|
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.timetable.WidgetTimetableProvider
|
||||||
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.notifications.WidgetNotificationsProvider
|
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.notifications.WidgetNotificationsProvider
|
||||||
-keepnames class pl.szczodrzynski.edziennik.widgets.luckynumber.WidgetLuckyNumber
|
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.luckynumber.WidgetLuckyNumberProvider
|
||||||
|
|
||||||
-keep class .R
|
-keep class .R
|
||||||
-keep class **.R$* {
|
-keep class **.R$* {
|
||||||
|
@ -80,6 +80,7 @@
|
|||||||
<service android:name=".ui.widgets.timetable.WidgetTimetableService"
|
<service android:name=".ui.widgets.timetable.WidgetTimetableService"
|
||||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||||
<activity android:name=".ui.widgets.LessonDialogActivity"
|
<activity android:name=".ui.widgets.LessonDialogActivity"
|
||||||
|
android:label=""
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
android:excludeFromRecents="true"
|
android:excludeFromRecents="true"
|
||||||
android:noHistory="true"
|
android:noHistory="true"
|
||||||
@ -141,12 +142,8 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/AppTheme" />
|
android:theme="@style/AppTheme" />
|
||||||
<activity android:name=".ui.modules.settings.SettingsLicenseActivity"
|
<activity android:name=".ui.modules.settings.SettingsLicenseActivity"
|
||||||
|
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
android:theme="@style/AppTheme" />
|
android:theme="@style/AppTheme" />
|
||||||
<activity android:name=".ui.modules.webpush.WebPushConfigActivity"
|
|
||||||
android:configChanges="orientation|keyboardHidden"
|
|
||||||
android:theme="@style/AppTheme.Dark" />
|
|
||||||
<activity android:name=".ui.modules.webpush.QrScannerActivity" />
|
<activity android:name=".ui.modules.webpush.QrScannerActivity" />
|
||||||
<activity android:name="com.theartofdev.edmodo.cropper.CropImageActivity"
|
<activity android:name="com.theartofdev.edmodo.cropper.CropImageActivity"
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
@ -165,20 +162,11 @@
|
|||||||
<action android:name="android.intent.action.USER_PRESENT" />
|
<action android:name="android.intent.action.USER_PRESENT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
<receiver android:name=".receivers.BootReceiver">
|
<receiver android:name=".sync.UpdateDownloaderService$DownloadProgressReceiver">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
|
||||||
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
|
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
|
||||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
<!--<receiver android:name=".sync.FirebaseBroadcastReceiver"
|
|
||||||
android:exported="true"
|
|
||||||
android:permission="com.google.android.c2dm.permission.SEND">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
|
|
||||||
</intent-filter>
|
|
||||||
</receiver>-->
|
|
||||||
<receiver android:name=".receivers.SzkolnyReceiver"
|
<receiver android:name=".receivers.SzkolnyReceiver"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@ -200,8 +188,6 @@
|
|||||||
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>-->
|
</service>-->
|
||||||
<service android:name=".receivers.BootReceiver$NotificationActionService" />
|
|
||||||
<service android:name=".Notifier$GetDataRetryService" />
|
|
||||||
<service android:name=".data.api.ApiService" />
|
<service android:name=".data.api.ApiService" />
|
||||||
<service android:name=".data.firebase.MyFirebaseService"
|
<service android:name=".data.firebase.MyFirebaseService"
|
||||||
android:exported="false">
|
android:exported="false">
|
||||||
@ -210,6 +196,7 @@
|
|||||||
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
|
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>
|
||||||
|
<service android:name=".sync.UpdateDownloaderService" />
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
_____ _ _
|
_____ _ _
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<h3>Wersja 4.0-beta.3, 2020-01-10</h3>
|
<h3>Wersja 4.0-beta.4, 2020-01-19</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Przebudowaliśmy cały moduł synchronizacji</b>, co oznacza większą stabilność aplikacji, szybkosć oraz poprawność pobieranych danych.</li>
|
<li><b>Przebudowaliśmy cały moduł synchronizacji</b>, co oznacza większą stabilność aplikacji, szybkosć oraz poprawność pobieranych danych.</li>
|
||||||
<li><b><u>Wysyłanie wiadomości</u></b> - funkcja, na którą czekał każdy. Od teraz w Szkolnym można wysyłać oraz odpowiadać na wiadomości do nauczycieli 👏</li>
|
<li><b><u>Wysyłanie wiadomości</u></b> - funkcja, na którą czekał każdy. Od teraz w Szkolnym można wysyłać oraz odpowiadać na wiadomości do nauczycieli 👏</li>
|
||||||
@ -6,6 +6,7 @@
|
|||||||
<li>Nowa <b>Strona główna</b> - ładniejszy wygląd oraz możliwość przestawiania kart na każdym profilu</li>
|
<li>Nowa <b>Strona główna</b> - ładniejszy wygląd oraz możliwość przestawiania kart na każdym profilu</li>
|
||||||
<li>Nowy <b>Plan lekcji</b> - z doskonałą obsługą lekcji przesuniętych oraz dwóch lekcji o tej samej godzinie</li>
|
<li>Nowy <b>Plan lekcji</b> - z doskonałą obsługą lekcji przesuniętych oraz dwóch lekcji o tej samej godzinie</li>
|
||||||
<li>Nowe okienka informacji o wydarzeniach oraz lekcjach</li>
|
<li>Nowe okienka informacji o wydarzeniach oraz lekcjach</li>
|
||||||
|
<li>Nowe, przyjemniejsze powiadomienia</li>
|
||||||
<li>Łatwiejsze dodawanie własnych wydarzeń</li>
|
<li>Łatwiejsze dodawanie własnych wydarzeń</li>
|
||||||
<li>Dużo poprawek w widoku <b>Wiadomości</b> oraz <b>Ogłoszeń</b></li>
|
<li>Dużo poprawek w widoku <b>Wiadomości</b> oraz <b>Ogłoszeń</b></li>
|
||||||
<li>Częściowa <b>Obsługa dziennika EduDziennik</b></li>
|
<li>Częściowa <b>Obsługa dziennika EduDziennik</b></li>
|
||||||
@ -14,7 +15,9 @@
|
|||||||
<li>Librus: obsługa Zadań domowych bez posiadania Mobilnych dodatków (przez system Synergia)</li>
|
<li>Librus: obsługa Zadań domowych bez posiadania Mobilnych dodatków (przez system Synergia)</li>
|
||||||
<li>Lepsze <b>przekazywanie powiadomień na komputer</b> oraz łatwiejsze parowanie</li>
|
<li>Lepsze <b>przekazywanie powiadomień na komputer</b> oraz łatwiejsze parowanie</li>
|
||||||
<li>Poprawiliśmy synchronizację w tle na niektórych telefonach</li>
|
<li>Poprawiliśmy synchronizację w tle na niektórych telefonach</li>
|
||||||
|
<li>Usunąłem denerwujący brak zaznaczenia w lewym menu</li>
|
||||||
<li>Znaczna ilość błędów z poprzednich wersji już nie występuje</li>
|
<li>Znaczna ilość błędów z poprzednich wersji już nie występuje</li>
|
||||||
|
<li><strike>Występują natomiast nowe błędy, dlatego proszę o ich zgłaszanie :)</strike></li>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
|
@ -4,20 +4,93 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik
|
package pl.szczodrzynski.edziennik
|
||||||
|
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.content.pm.ShortcutInfo
|
||||||
|
import android.content.pm.ShortcutManager
|
||||||
|
import android.graphics.drawable.Icon
|
||||||
|
import android.os.Build
|
||||||
|
import android.provider.Settings
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
|
import androidx.multidex.MultiDexApplication
|
||||||
import androidx.work.Configuration
|
import androidx.work.Configuration
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import cat.ereza.customactivityoncrash.config.CaocConfig
|
||||||
import kotlinx.coroutines.Dispatchers
|
import com.chuckerteam.chucker.api.ChuckerCollector
|
||||||
import kotlinx.coroutines.Job
|
import com.chuckerteam.chucker.api.ChuckerInterceptor
|
||||||
|
import com.chuckerteam.chucker.api.RetentionManager
|
||||||
|
import com.google.firebase.FirebaseApp
|
||||||
|
import com.google.firebase.FirebaseOptions
|
||||||
|
import com.google.firebase.iid.FirebaseInstanceId
|
||||||
|
import com.google.firebase.messaging.FirebaseMessaging
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.hypertrack.hyperlog.HyperLog
|
||||||
|
import com.mikepenz.iconics.Iconics
|
||||||
|
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont
|
||||||
|
import im.wangchao.mhttp.MHttp
|
||||||
|
import im.wangchao.mhttp.internal.cookie.PersistentCookieJar
|
||||||
|
import im.wangchao.mhttp.internal.cookie.cache.SetCookieCache
|
||||||
|
import im.wangchao.mhttp.internal.cookie.persistence.SharedPrefsCookiePersistor
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import me.leolin.shortcutbadger.ShortcutBadger
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import pl.szczodrzynski.edziennik.config.Config
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.ProfileListEmptyEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
|
import pl.szczodrzynski.edziennik.network.NetworkUtils
|
||||||
|
import pl.szczodrzynski.edziennik.sync.SyncWorker
|
||||||
|
import pl.szczodrzynski.edziennik.sync.UpdateWorker
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.base.CrashActivity
|
||||||
|
import pl.szczodrzynski.edziennik.utils.*
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScope {
|
class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||||
companion object {
|
companion object {
|
||||||
|
@Volatile
|
||||||
|
lateinit var db: AppDb
|
||||||
|
val config: Config by lazy { Config(db) }
|
||||||
|
var profile: Profile by mutableLazy { Profile(0, 0, 0, "") }
|
||||||
|
val profileId
|
||||||
|
get() = profile.id
|
||||||
|
|
||||||
var devMode = false
|
var devMode = false
|
||||||
}
|
}
|
||||||
|
|
||||||
//lateinit var db: AppDb
|
val notifications by lazy { Notifications() }
|
||||||
//val config by lazy { Config(db); // TODO migrate }
|
inner class Notifications {
|
||||||
|
val syncId = 1
|
||||||
|
val syncKey = "pl.szczodrzynski.edziennik.SYNC"
|
||||||
|
val syncChannelName: String by lazy { getString(R.string.notification_channel_get_data_name) }
|
||||||
|
val syncChannelDesc: String by lazy { getString(R.string.notification_channel_get_data_desc) }
|
||||||
|
val dataId = 50
|
||||||
|
val dataKey = "pl.szczodrzynski.edziennik.DATA"
|
||||||
|
val dataChannelName: String by lazy { getString(R.string.notification_channel_notifications_name) }
|
||||||
|
val dataChannelDesc: String by lazy { getString(R.string.notification_channel_notifications_desc) }
|
||||||
|
val dataQuietId = 60
|
||||||
|
val dataQuietKey = "pl.szczodrzynski.edziennik.DATA_QUIET"
|
||||||
|
val dataQuietChannelName: String by lazy { getString(R.string.notification_channel_notifications_quiet_name) }
|
||||||
|
val dataQuietChannelDesc: String by lazy { getString(R.string.notification_channel_notifications_quiet_desc) }
|
||||||
|
val updatesId = 100
|
||||||
|
val updatesKey = "pl.szczodrzynski.edziennik.UPDATES"
|
||||||
|
val updatesChannelName: String by lazy { getString(R.string.notification_channel_updates_name) }
|
||||||
|
val updatesChannelDesc: String by lazy { getString(R.string.notification_channel_updates_desc) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val db
|
||||||
|
get() = App.db
|
||||||
|
val config
|
||||||
|
get() = App.config
|
||||||
|
val profile
|
||||||
|
get() = App.profile
|
||||||
|
val profileId
|
||||||
|
get() = App.profileId
|
||||||
|
|
||||||
private val job = Job()
|
private val job = Job()
|
||||||
override val coroutineContext: CoroutineContext
|
override val coroutineContext: CoroutineContext
|
||||||
@ -26,11 +99,10 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
.setMinimumLoggingLevel(Log.VERBOSE)
|
.setMinimumLoggingLevel(Log.VERBOSE)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
/*val preferences by lazy { getSharedPreferences(getString(R.string.preference_file), Context.MODE_PRIVATE) }
|
val preferences by lazy { getSharedPreferences(getString(R.string.preference_file), Context.MODE_PRIVATE) }
|
||||||
val notifier by lazy { Notifier(this) }
|
|
||||||
val permissionChecker by lazy { PermissionChecker(this) }
|
val permissionChecker by lazy { PermissionChecker(this) }
|
||||||
|
val networkUtils by lazy { NetworkUtils(this) }
|
||||||
lateinit var profile: ProfileFull
|
val gson by lazy { Gson() }
|
||||||
|
|
||||||
/* _ _ _______ _______ _____
|
/* _ _ _______ _______ _____
|
||||||
| | | |__ __|__ __| __ \
|
| | | |__ __|__ __| __ \
|
||||||
@ -48,13 +120,13 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
.connectTimeout(20, TimeUnit.SECONDS)
|
.connectTimeout(20, TimeUnit.SECONDS)
|
||||||
.writeTimeout(5, TimeUnit.SECONDS)
|
.writeTimeout(5, TimeUnit.SECONDS)
|
||||||
.readTimeout(10, TimeUnit.SECONDS)
|
.readTimeout(10, TimeUnit.SECONDS)
|
||||||
builder.installHttpsSupport()
|
builder.installHttpsSupport(this)
|
||||||
|
|
||||||
if (devMode || BuildConfig.DEBUG) {
|
if (devMode || BuildConfig.DEBUG) {
|
||||||
HyperLog.initialize(this)
|
HyperLog.initialize(this)
|
||||||
HyperLog.setLogLevel(Log.VERBOSE)
|
HyperLog.setLogLevel(Log.VERBOSE)
|
||||||
HyperLog.setLogFormat(DebugLogFormat(this))
|
HyperLog.setLogFormat(DebugLogFormat(this))
|
||||||
val chuckerCollector = ChuckerCollector(this, true, Period.ONE_HOUR)
|
val chuckerCollector = ChuckerCollector(this, true, RetentionManager.Period.ONE_HOUR)
|
||||||
val chuckerInterceptor = ChuckerInterceptor(this, chuckerCollector)
|
val chuckerInterceptor = ChuckerInterceptor(this, chuckerCollector)
|
||||||
builder.addInterceptor(chuckerInterceptor)
|
builder.addInterceptor(chuckerInterceptor)
|
||||||
}
|
}
|
||||||
@ -77,22 +149,7 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
|_____/|_|\__, |_| |_|\__,_|\__|\__,_|_| \___|
|
|_____/|_|\__, |_| |_|\__,_|\__|\__,_|_| \___|
|
||||||
__/ |
|
__/ |
|
||||||
|__*/
|
|__*/
|
||||||
private val deviceId: String by lazy { Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID) ?: "" }
|
val deviceId: String by lazy { Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID) ?: "" }
|
||||||
private val signature: String by lazy {
|
|
||||||
var str = ""
|
|
||||||
try {
|
|
||||||
val packageInfo: PackageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES)
|
|
||||||
for (signature in packageInfo.signatures) {
|
|
||||||
val signatureBytes = signature.toByteArray()
|
|
||||||
val md = MessageDigest.getInstance("SHA")
|
|
||||||
md.update(signatureBytes)
|
|
||||||
str = Base64.encodeToString(md.digest(), Base64.DEFAULT)
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
str
|
|
||||||
}
|
|
||||||
private var unreadBadgesAvailable = true
|
private var unreadBadgesAvailable = true
|
||||||
|
|
||||||
/* _____ _
|
/* _____ _
|
||||||
@ -118,27 +175,34 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
.apply()
|
.apply()
|
||||||
Iconics.init(applicationContext)
|
Iconics.init(applicationContext)
|
||||||
Iconics.registerFont(SzkolnyFont)
|
Iconics.registerFont(SzkolnyFont)
|
||||||
db = AppDb.getDatabase(this)
|
App.db = AppDb(this)
|
||||||
Themes.themeInt = config.ui.theme
|
Themes.themeInt = config.ui.theme
|
||||||
MHttp.instance().customOkHttpClient(http)
|
MHttp.instance().customOkHttpClient(http)
|
||||||
|
|
||||||
|
if (!profileLoadById(config.lastProfileId)) {
|
||||||
|
db.profileDao().firstId?.let { profileLoadById(it) }
|
||||||
|
}
|
||||||
|
|
||||||
devMode = "f054761fbdb6a238" == deviceId || BuildConfig.DEBUG
|
devMode = "f054761fbdb6a238" == deviceId || BuildConfig.DEBUG
|
||||||
if (config.devModePassword != null)
|
|
||||||
checkDevModePassword()
|
|
||||||
|
|
||||||
Signing.getCert(this)
|
Signing.getCert(this)
|
||||||
|
|
||||||
launch { async(Dispatchers.Default) {
|
launch {
|
||||||
if (config.sync.enabled) {
|
withContext(Dispatchers.Default) {
|
||||||
scheduleNext(this@App, false)
|
config.migrate(this@App)
|
||||||
} else {
|
|
||||||
cancelNext(this@App)
|
|
||||||
}
|
|
||||||
|
|
||||||
db.metadataDao().countUnseen().observeForever { count: Int ->
|
if (config.devModePassword != null)
|
||||||
if (unreadBadgesAvailable)
|
checkDevModePassword()
|
||||||
unreadBadgesAvailable = ShortcutBadger.applyCount(this@App, count)
|
|
||||||
}
|
if (config.sync.enabled)
|
||||||
|
SyncWorker.scheduleNext(this@App, false)
|
||||||
|
else
|
||||||
|
SyncWorker.cancelNext(this@App)
|
||||||
|
|
||||||
|
if (config.sync.notifyAboutUpdates)
|
||||||
|
UpdateWorker.scheduleNext(this@App, false)
|
||||||
|
else
|
||||||
|
UpdateWorker.cancelNext(this@App)
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||||
val shortcutManager = getSystemService(ShortcutManager::class.java)
|
val shortcutManager = getSystemService(ShortcutManager::class.java)
|
||||||
@ -187,11 +251,36 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
)
|
)
|
||||||
} // shortcuts - end
|
} // shortcuts - end
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
||||||
|
notificationManager.createNotificationChannel(
|
||||||
|
NotificationChannel(notifications.syncKey, notifications.syncChannelName, NotificationManager.IMPORTANCE_MIN).apply {
|
||||||
|
description = notifications.syncChannelDesc
|
||||||
|
})
|
||||||
|
notificationManager.createNotificationChannel(
|
||||||
|
NotificationChannel(notifications.dataKey, notifications.dataChannelName, NotificationManager.IMPORTANCE_HIGH).apply {
|
||||||
|
description = notifications.dataChannelDesc
|
||||||
|
enableLights(true)
|
||||||
|
lightColor = 0xff2196f3.toInt()
|
||||||
|
})
|
||||||
|
notificationManager.createNotificationChannel(
|
||||||
|
NotificationChannel(notifications.dataQuietKey, notifications.dataQuietChannelName, NotificationManager.IMPORTANCE_LOW).apply {
|
||||||
|
description = notifications.dataQuietChannelDesc
|
||||||
|
setSound(null, null)
|
||||||
|
enableVibration(false)
|
||||||
|
})
|
||||||
|
notificationManager.createNotificationChannel(
|
||||||
|
NotificationChannel(notifications.updatesKey, notifications.updatesChannelName, NotificationManager.IMPORTANCE_DEFAULT).apply {
|
||||||
|
description = notifications.updatesChannelDesc
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (config.appInstalledTime == 0L)
|
if (config.appInstalledTime == 0L)
|
||||||
try {
|
try {
|
||||||
config.appInstalledTime = packageManager.getPackageInfo(packageName, 0).firstInstallTime
|
config.appInstalledTime = packageManager.getPackageInfo(packageName, 0).firstInstallTime
|
||||||
config.appRateSnackbarTime = config.appInstalledTime + 7 * DAY * MS
|
config.appRateSnackbarTime = config.appInstalledTime + 7 * DAY * MS
|
||||||
} catch (e: NameNotFoundException) {
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,61 +341,50 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
} catch (e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun profileLoad(profileId: Int) {
|
db.metadataDao().countUnseen().observeForever { count: Int ->
|
||||||
db.profileDao().getFullByIdNow(profileId)?.also {
|
if (unreadBadgesAvailable)
|
||||||
profile = it
|
unreadBadgesAvailable = ShortcutBadger.applyCount(this@App, count)
|
||||||
} ?: run {
|
|
||||||
if (!::profile.isInitialized) {
|
|
||||||
profile = ProfileFull(-1, "", "", -1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun profileLoad(profileId: Int, onSuccess: (profile: ProfileFull) -> Unit) {
|
|
||||||
|
private fun profileLoadById(profileId: Int): Boolean {
|
||||||
|
db.profileDao().getByIdNow(profileId)?.also {
|
||||||
|
App.profile = it
|
||||||
|
App.config.lastProfileId = it.id
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
fun profileLoad(profileId: Int, onSuccess: (profile: Profile) -> Unit) {
|
||||||
launch {
|
launch {
|
||||||
val deferred = async(Dispatchers.Default) {
|
val success = withContext(Dispatchers.Default) {
|
||||||
profileLoad(profileId)
|
profileLoadById(profileId)
|
||||||
}
|
}
|
||||||
deferred.await()
|
if (success)
|
||||||
onSuccess(profile)
|
onSuccess(profile)
|
||||||
|
else
|
||||||
|
profileLoadLast(onSuccess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun profileLoadLast(onSuccess: (profile: Profile) -> Unit) {
|
||||||
private fun OkHttpClient.Builder.installHttpsSupport() {
|
launch {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
|
val success = withContext(Dispatchers.Default) {
|
||||||
try {
|
profileLoadById(db.profileDao().lastId ?: return@withContext false)
|
||||||
try {
|
|
||||||
ProviderInstaller.installIfNeeded(this@App)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e("OkHttpTLSCompat", "Play Services not found or outdated")
|
|
||||||
|
|
||||||
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
|
||||||
trustManagerFactory.init(null as KeyStore?)
|
|
||||||
|
|
||||||
val x509TrustManager = trustManagerFactory.trustManagers.singleOrNull { it is X509TrustManager } as X509TrustManager?
|
|
||||||
?: return
|
|
||||||
|
|
||||||
val sc = SSLContext.getInstance("TLSv1.2")
|
|
||||||
sc.init(null, null, null)
|
|
||||||
sslSocketFactory(TLSSocketFactory(sc.socketFactory), x509TrustManager)
|
|
||||||
val cs: ConnectionSpec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
|
||||||
.tlsVersions(TlsVersion.TLS_1_0)
|
|
||||||
.tlsVersions(TlsVersion.TLS_1_1)
|
|
||||||
.tlsVersions(TlsVersion.TLS_1_2)
|
|
||||||
.build()
|
|
||||||
val specs: MutableList<ConnectionSpec> = ArrayList()
|
|
||||||
specs.add(cs)
|
|
||||||
specs.add(ConnectionSpec.COMPATIBLE_TLS)
|
|
||||||
specs.add(ConnectionSpec.CLEARTEXT)
|
|
||||||
connectionSpecs(specs)
|
|
||||||
}
|
}
|
||||||
} catch (exc: Exception) {
|
if (!success) {
|
||||||
Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc)
|
EventBus.getDefault().post(ProfileListEmptyEvent())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun profileSave() = profileSave(profile)
|
||||||
|
fun profileSave(profile: Profile) {
|
||||||
|
launch(Dispatchers.Default) {
|
||||||
|
App.db.profileDao().add(profile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun checkDevModePassword() {
|
fun checkDevModePassword() {
|
||||||
devMode = try {
|
devMode = try {
|
||||||
@ -315,5 +393,5 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
}
|
}
|
@ -1,91 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-19.
|
||||||
|
*/
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik;
|
package pl.szczodrzynski.edziennik;
|
||||||
|
|
||||||
import android.content.Context;
|
/*public class AppOld extends androidx.multidex.MultiDexApplication implements Configuration.Provider {
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.content.pm.PackageInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.content.pm.ShortcutInfo;
|
|
||||||
import android.content.pm.ShortcutManager;
|
|
||||||
import android.content.pm.Signature;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.Icon;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.provider.Settings;
|
|
||||||
import android.util.Base64;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.RequiresApi;
|
|
||||||
import androidx.appcompat.app.AppCompatDelegate;
|
|
||||||
import androidx.work.Configuration;
|
|
||||||
|
|
||||||
import com.chuckerteam.chucker.api.ChuckerCollector;
|
|
||||||
import com.chuckerteam.chucker.api.ChuckerInterceptor;
|
|
||||||
import com.chuckerteam.chucker.api.RetentionManager;
|
|
||||||
import com.google.android.gms.security.ProviderInstaller;
|
|
||||||
import com.google.firebase.FirebaseApp;
|
|
||||||
import com.google.firebase.FirebaseOptions;
|
|
||||||
import com.google.firebase.iid.FirebaseInstanceId;
|
|
||||||
import com.google.firebase.messaging.FirebaseMessaging;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonSyntaxException;
|
|
||||||
import com.hypertrack.hyperlog.HyperLog;
|
|
||||||
import com.mikepenz.iconics.Iconics;
|
|
||||||
import com.mikepenz.iconics.IconicsColor;
|
|
||||||
import com.mikepenz.iconics.IconicsDrawable;
|
|
||||||
import com.mikepenz.iconics.IconicsSize;
|
|
||||||
import com.mikepenz.iconics.typeface.IIcon;
|
|
||||||
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.security.KeyStore;
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.ConcurrentModificationException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
|
||||||
import javax.net.ssl.TrustManager;
|
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
|
||||||
import javax.net.ssl.X509TrustManager;
|
|
||||||
|
|
||||||
import cat.ereza.customactivityoncrash.config.CaocConfig;
|
|
||||||
import im.wangchao.mhttp.MHttp;
|
|
||||||
import im.wangchao.mhttp.internal.cookie.PersistentCookieJar;
|
|
||||||
import im.wangchao.mhttp.internal.cookie.cache.SetCookieCache;
|
|
||||||
import im.wangchao.mhttp.internal.cookie.persistence.SharedPrefsCookiePersistor;
|
|
||||||
import me.leolin.shortcutbadger.ShortcutBadger;
|
|
||||||
import okhttp3.ConnectionSpec;
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import okhttp3.TlsVersion;
|
|
||||||
import pl.szczodrzynski.edziennik.config.Config;
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing;
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.AppDb;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.DebugLog;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile;
|
|
||||||
import pl.szczodrzynski.edziennik.network.NetworkUtils;
|
|
||||||
import pl.szczodrzynski.edziennik.network.TLSSocketFactory;
|
|
||||||
import pl.szczodrzynski.edziennik.sync.SyncWorker;
|
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.base.CrashActivity;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.DebugLogFormat;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.PermissionChecker;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.AppConfig;
|
|
||||||
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.LoginStore.LOGIN_TYPE_MOBIDZIENNIK;
|
|
||||||
|
|
||||||
public class App extends androidx.multidex.MultiDexApplication implements Configuration.Provider {
|
|
||||||
private static final String TAG = "App";
|
private static final String TAG = "App";
|
||||||
public static int profileId = -1;
|
public static int profileId = -1;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
@ -379,36 +298,7 @@ public class App extends androidx.multidex.MultiDexApplication implements Config
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Task<CapabilityInfo> capabilityInfoTask =
|
|
||||||
Wearable.getCapabilityClient(this)
|
|
||||||
.getCapability("edziennik_wear_app", CapabilityClient.FILTER_REACHABLE);
|
|
||||||
capabilityInfoTask.addOnCompleteListener((task) -> {
|
|
||||||
if (task.isSuccessful()) {
|
|
||||||
CapabilityInfo capabilityInfo = task.getResult();
|
|
||||||
assert capabilityInfo != null;
|
|
||||||
Set<Node> nodes;
|
|
||||||
nodes = capabilityInfo.getNodes();
|
|
||||||
Log.d(TAG, "Nodes "+nodes);
|
|
||||||
|
|
||||||
if (nodes.size() > 0) {
|
|
||||||
Wearable.getMessageClient(this).sendMessage(
|
|
||||||
nodes.toArray(new Node[]{})[0].getId(), "/ping", "Hello world".getBytes());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Capability request failed to return any results.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Wearable.getDataClient(this).addListener(dataEventBuffer -> {
|
|
||||||
Log.d(TAG, "onDataChanged(): " + dataEventBuffer);
|
|
||||||
|
|
||||||
for (DataEvent event : dataEventBuffer) {
|
|
||||||
if (event.getType() == DataEvent.TYPE_CHANGED) {
|
|
||||||
String path = event.getDataItem().getUri().getPath();
|
|
||||||
Log.d(TAG, "Data "+path+ " :: "+Arrays.toString(event.getDataItem().getData()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
FirebaseApp pushMobidziennikApp = FirebaseApp.initializeApp(
|
FirebaseApp pushMobidziennikApp = FirebaseApp.initializeApp(
|
||||||
this,
|
this,
|
||||||
@ -498,14 +388,7 @@ public class App extends androidx.multidex.MultiDexApplication implements Config
|
|||||||
|
|
||||||
if (appSharedPrefs.contains("profiles")) {
|
if (appSharedPrefs.contains("profiles")) {
|
||||||
SharedPreferences.Editor appSharedPrefsEditor = appSharedPrefs.edit();
|
SharedPreferences.Editor appSharedPrefsEditor = appSharedPrefs.edit();
|
||||||
/*List<Integer> appProfileIds = gson.fromJson(appSharedPrefs.getString("profiles", ""), new TypeToken<List<Integer>>(){}.getType());
|
|
||||||
for (int id: appProfileIds) {
|
|
||||||
AppProfile appProfile = gson.fromJson(appSharedPrefs.getString("profile"+id, ""), AppProfile.class);
|
|
||||||
if (appProfile != null) {
|
|
||||||
appConfig.profiles.add(appProfile);
|
|
||||||
}
|
|
||||||
appSharedPrefsEditor.remove("profile"+id);
|
|
||||||
}*/
|
|
||||||
appSharedPrefsEditor.remove("profiles");
|
appSharedPrefsEditor.remove("profiles");
|
||||||
appSharedPrefsEditor.apply();
|
appSharedPrefsEditor.apply();
|
||||||
//profilesSave();
|
//profilesSave();
|
||||||
@ -539,16 +422,6 @@ public class App extends androidx.multidex.MultiDexApplication implements Config
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (appConfig.lastAppVersion > BuildConfig.VERSION_CODE) {
|
|
||||||
BootReceiver br = new BootReceiver();
|
|
||||||
Intent i = new Intent();
|
|
||||||
//i.putExtra("UserChecked", true);
|
|
||||||
br.onReceive(getContext(), i);
|
|
||||||
Toast.makeText(mContext, R.string.warning_older_version_running, Toast.LENGTH_LONG).show();
|
|
||||||
//Toast.makeText(mContext, "Zaktualizuj aplikację.", Toast.LENGTH_LONG).show();
|
|
||||||
//System.exit(0);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (appConfig == null) {
|
if (appConfig == null) {
|
||||||
appConfig = new AppConfig(this);
|
appConfig = new AppConfig(this);
|
||||||
}
|
}
|
||||||
@ -564,15 +437,7 @@ public class App extends androidx.multidex.MultiDexApplication implements Config
|
|||||||
for (Map.Entry<String, JsonElement> entry : appConfigJson.entrySet()) {
|
for (Map.Entry<String, JsonElement> entry : appConfigJson.entrySet()) {
|
||||||
String jsonObj;
|
String jsonObj;
|
||||||
jsonObj = entry.getValue().toString();
|
jsonObj = entry.getValue().toString();
|
||||||
/*if (entry.getValue().isJsonObject()) {
|
|
||||||
jsonObj = entry.getValue().getAsJsonObject().toString();
|
|
||||||
}
|
|
||||||
else if (entry.getValue().isJsonArray()) {
|
|
||||||
jsonObj = entry.getValue().getAsJsonArray().toString();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
jsonObj = entry.getValue().toString();
|
|
||||||
}*/
|
|
||||||
appSharedPrefsEditor.putString("app.appConfig." + entry.getKey(), jsonObj);
|
appSharedPrefsEditor.putString("app.appConfig." + entry.getKey(), jsonObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,18 +493,10 @@ public class App extends androidx.multidex.MultiDexApplication implements Config
|
|||||||
}
|
}
|
||||||
public void profileLoadById(int id, boolean loadedLast) {
|
public void profileLoadById(int id, boolean loadedLast) {
|
||||||
//Log.d(TAG, "Loading ID "+id);
|
//Log.d(TAG, "Loading ID "+id);
|
||||||
/*if (profile == null) {
|
|
||||||
profile = profileNew();
|
|
||||||
AppDb.profileId = profile.id;
|
|
||||||
appSharedPrefs.edit().putInt("current_profile_id", profile.id).apply();
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
if (profile == null || profile.getId() != id) {
|
if (profile == null || profile.getId() != id) {
|
||||||
profile = db.profileDao().getByIdNow(id);
|
profile = db.profileDao().getByIdNow(id);
|
||||||
/*if (profile == null) {
|
|
||||||
profileLoadById(id);
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
MainActivity.Companion.setUseOldMessages(profile.getLoginStoreType() == LOGIN_TYPE_MOBIDZIENNIK && appConfig.mobidziennikOldMessages == 1);
|
MainActivity.Companion.setUseOldMessages(profile.getLoginStoreType() == LOGIN_TYPE_MOBIDZIENNIK && appConfig.mobidziennikOldMessages == 1);
|
||||||
profileId = profile.getId();
|
profileId = profile.getId();
|
||||||
@ -655,44 +512,6 @@ public class App extends androidx.multidex.MultiDexApplication implements Config
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public void profileRemove(int id)
|
|
||||||
{
|
|
||||||
Profile profile = db.profileDao().getFullByIdNow(id);
|
|
||||||
|
|
||||||
if (profile.id == profile.loginStoreId) {
|
|
||||||
// this profile is the owner of the login store
|
|
||||||
// we need to check if any other profile is using it
|
|
||||||
List<Integer> transferProfileIds = db.profileDao().getIdsByLoginStoreIdNow(profile.loginStoreId);
|
|
||||||
if (transferProfileIds.size() == 1) {
|
|
||||||
// this login store is free of users, remove it along with the profile
|
|
||||||
db.loginStoreDao().remove(profile.loginStoreId);
|
|
||||||
// the current store is removed, we are ready to remove the profile
|
|
||||||
}
|
|
||||||
else if (transferProfileIds.size() > 1) {
|
|
||||||
transferProfileIds.remove(transferProfileIds.indexOf(profile.id));
|
|
||||||
// someone is using the store
|
|
||||||
// we need to transfer it to the firstProfileId
|
|
||||||
db.loginStoreDao().changeId(profile.loginStoreId, transferProfileIds.get(0));
|
|
||||||
db.profileDao().changeStoreId(profile.loginStoreId, transferProfileIds.get(0));
|
|
||||||
// the current store is removed, we are ready to remove the profile
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// else, the profile uses a store that it doesn't own
|
|
||||||
// leave the store and go on with removing
|
|
||||||
|
|
||||||
Log.d(TAG, "Before removal: "+db.profileDao().getAllNow().toString());
|
|
||||||
db.profileDao().remove(profile.id);
|
|
||||||
Log.d(TAG, "After removal: "+db.profileDao().getAllNow().toString());
|
|
||||||
|
|
||||||
*//*int newId = 1;
|
|
||||||
if (appConfig.profiles.size() > 0) {
|
|
||||||
newId = appConfig.profiles.get(appConfig.profiles.size() - 1).id;
|
|
||||||
}
|
|
||||||
Log.d(TAG, "New ID: "+newId);
|
|
||||||
//Toast.makeText(mContext, "selected new id "+newId, Toast.LENGTH_SHORT).show();
|
|
||||||
profileLoadById(newId);*//*
|
|
||||||
}*/
|
|
||||||
|
|
||||||
public int profileFirstId() {
|
public int profileFirstId() {
|
||||||
Integer id = db.profileDao().getFirstId();
|
Integer id = db.profileDao().getFirstId();
|
||||||
return id == null ? 1 : id;
|
return id == null ? 1 : id;
|
||||||
@ -719,4 +538,4 @@ public class App extends androidx.multidex.MultiDexApplication implements Config
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}*/
|
@ -35,6 +35,7 @@ import androidx.core.util.forEach
|
|||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
|
import com.google.android.gms.security.ProviderInstaller
|
||||||
import com.google.gson.JsonArray
|
import com.google.gson.JsonArray
|
||||||
import com.google.gson.JsonElement
|
import com.google.gson.JsonElement
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
@ -42,23 +43,31 @@ import im.wangchao.mhttp.Response
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import okhttp3.ConnectionSpec
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody
|
||||||
|
import okhttp3.TlsVersion
|
||||||
import okio.Buffer
|
import okio.Buffer
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Team
|
import pl.szczodrzynski.edziennik.data.db.entity.Team
|
||||||
|
import pl.szczodrzynski.edziennik.network.TLSSocketFactory
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
|
import java.security.KeyStore
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.zip.CRC32
|
import java.util.zip.CRC32
|
||||||
import javax.crypto.Mac
|
import javax.crypto.Mac
|
||||||
import javax.crypto.spec.SecretKeySpec
|
import javax.crypto.spec.SecretKeySpec
|
||||||
|
import javax.net.ssl.SSLContext
|
||||||
|
import javax.net.ssl.TrustManagerFactory
|
||||||
|
import javax.net.ssl.X509TrustManager
|
||||||
import kotlin.Pair
|
import kotlin.Pair
|
||||||
|
|
||||||
|
|
||||||
@ -643,6 +652,12 @@ fun Bundle(vararg properties: Pair<String, Any?>): Bundle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun Intent(action: String? = null, vararg properties: Pair<String, Any?>): Intent {
|
||||||
|
return Intent(action).putExtras(Bundle(*properties))
|
||||||
|
}
|
||||||
|
fun Intent(packageContext: Context, cls: Class<*>, vararg properties: Pair<String, Any?>): Intent {
|
||||||
|
return Intent(packageContext, cls).putExtras(Bundle(*properties))
|
||||||
|
}
|
||||||
|
|
||||||
fun Bundle.toJsonObject(): JsonObject {
|
fun Bundle.toJsonObject(): JsonObject {
|
||||||
val json = JsonObject()
|
val json = JsonObject()
|
||||||
@ -957,6 +972,8 @@ fun Context.getNotificationTitle(type: Int): String {
|
|||||||
Notification.TYPE_NEW_EVENT -> R.string.notification_type_new_event
|
Notification.TYPE_NEW_EVENT -> R.string.notification_type_new_event
|
||||||
Notification.TYPE_NEW_HOMEWORK -> R.string.notification_type_new_homework
|
Notification.TYPE_NEW_HOMEWORK -> R.string.notification_type_new_homework
|
||||||
Notification.TYPE_NEW_SHARED_EVENT -> R.string.notification_type_new_shared_event
|
Notification.TYPE_NEW_SHARED_EVENT -> R.string.notification_type_new_shared_event
|
||||||
|
Notification.TYPE_NEW_SHARED_HOMEWORK -> R.string.notification_type_new_shared_homework
|
||||||
|
Notification.TYPE_REMOVED_SHARED_EVENT -> R.string.notification_type_removed_shared_event
|
||||||
Notification.TYPE_NEW_MESSAGE -> R.string.notification_type_new_message
|
Notification.TYPE_NEW_MESSAGE -> R.string.notification_type_new_message
|
||||||
Notification.TYPE_NEW_NOTICE -> R.string.notification_type_notice
|
Notification.TYPE_NEW_NOTICE -> R.string.notification_type_notice
|
||||||
Notification.TYPE_NEW_ATTENDANCE -> R.string.notification_type_attendance
|
Notification.TYPE_NEW_ATTENDANCE -> R.string.notification_type_attendance
|
||||||
@ -973,3 +990,37 @@ fun Context.getNotificationTitle(type: Int): String {
|
|||||||
fun Cursor?.getString(columnName: String) = this?.getStringOrNull(getColumnIndex(columnName))
|
fun Cursor?.getString(columnName: String) = this?.getStringOrNull(getColumnIndex(columnName))
|
||||||
fun Cursor?.getInt(columnName: String) = this?.getIntOrNull(getColumnIndex(columnName))
|
fun Cursor?.getInt(columnName: String) = this?.getIntOrNull(getColumnIndex(columnName))
|
||||||
fun Cursor?.getLong(columnName: String) = this?.getLongOrNull(getColumnIndex(columnName))
|
fun Cursor?.getLong(columnName: String) = this?.getLongOrNull(getColumnIndex(columnName))
|
||||||
|
|
||||||
|
fun OkHttpClient.Builder.installHttpsSupport(context: Context) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
ProviderInstaller.installIfNeeded(context)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("OkHttpTLSCompat", "Play Services not found or outdated")
|
||||||
|
|
||||||
|
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
||||||
|
trustManagerFactory.init(null as KeyStore?)
|
||||||
|
|
||||||
|
val x509TrustManager = trustManagerFactory.trustManagers.singleOrNull { it is X509TrustManager } as X509TrustManager?
|
||||||
|
?: return
|
||||||
|
|
||||||
|
val sc = SSLContext.getInstance("TLSv1.2")
|
||||||
|
sc.init(null, null, null)
|
||||||
|
sslSocketFactory(TLSSocketFactory(sc.socketFactory), x509TrustManager)
|
||||||
|
val cs: ConnectionSpec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
||||||
|
.tlsVersions(TlsVersion.TLS_1_0)
|
||||||
|
.tlsVersions(TlsVersion.TLS_1_1)
|
||||||
|
.tlsVersions(TlsVersion.TLS_1_2)
|
||||||
|
.build()
|
||||||
|
val specs: MutableList<ConnectionSpec> = ArrayList()
|
||||||
|
specs.add(cs)
|
||||||
|
specs.add(ConnectionSpec.COMPATIBLE_TLS)
|
||||||
|
specs.add(ConnectionSpec.CLEARTEXT)
|
||||||
|
connectionSpecs(specs)
|
||||||
|
}
|
||||||
|
} catch (exc: Exception) {
|
||||||
|
Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package pl.szczodrzynski.edziennik
|
package pl.szczodrzynski.edziennik
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.app.ActivityManager
|
import android.app.ActivityManager
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@ -9,7 +8,6 @@ import android.content.IntentFilter
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.drawable.BitmapDrawable
|
||||||
import android.os.AsyncTask
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
@ -41,15 +39,16 @@ import org.greenrobot.eventbus.EventBus
|
|||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import pl.droidsonroids.gif.GifDrawable
|
import pl.droidsonroids.gif.GifDrawable
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.*
|
import pl.szczodrzynski.edziennik.data.api.events.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing
|
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata.*
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata.*
|
||||||
import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding
|
import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding
|
||||||
import pl.szczodrzynski.edziennik.sync.AppManagerDetectedEvent
|
import pl.szczodrzynski.edziennik.sync.AppManagerDetectedEvent
|
||||||
import pl.szczodrzynski.edziennik.sync.SyncWorker
|
import pl.szczodrzynski.edziennik.sync.SyncWorker
|
||||||
|
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.ProfileRemoveDialog
|
import pl.szczodrzynski.edziennik.ui.dialogs.settings.ProfileRemoveDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.sync.SyncViewListDialog
|
import pl.szczodrzynski.edziennik.ui.dialogs.sync.SyncViewListDialog
|
||||||
@ -269,12 +268,21 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
d(TAG, "Activity created")
|
||||||
|
|
||||||
setTheme(Themes.appTheme)
|
setTheme(Themes.appTheme)
|
||||||
|
|
||||||
app.config.ui.language?.let {
|
app.config.ui.language?.let {
|
||||||
setLanguage(it)
|
setLanguage(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (App.profileId == 0) {
|
||||||
|
onProfileListEmptyEvent(ProfileListEmptyEvent())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d(TAG, "Profile is valid, inflating views")
|
||||||
|
|
||||||
setContentView(b.root)
|
setContentView(b.root)
|
||||||
|
|
||||||
Log.d(TAG, Signing.appPassword)
|
Log.d(TAG, Signing.appPassword)
|
||||||
@ -344,8 +352,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
setAccountHeaderBackground(app.config.ui.headerBackground)
|
setAccountHeaderBackground(app.config.ui.headerBackground)
|
||||||
|
|
||||||
drawerProfileListEmptyListener = {
|
drawerProfileListEmptyListener = {
|
||||||
app.config.loginFinished = false
|
onProfileListEmptyEvent(ProfileListEmptyEvent())
|
||||||
profileListEmptyListener()
|
|
||||||
}
|
}
|
||||||
drawerItemSelectedListener = { id, position, drawerItem ->
|
drawerItemSelectedListener = { id, position, drawerItem ->
|
||||||
loadTarget(id)
|
loadTarget(id)
|
||||||
@ -374,31 +381,20 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
|
|
||||||
navTarget = navTargetList[0]
|
navTarget = navTargetList[0]
|
||||||
|
|
||||||
var profileListEmpty = drawer.profileListEmpty
|
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
intent?.putExtras(savedInstanceState)
|
intent?.putExtras(savedInstanceState)
|
||||||
savedInstanceState.clear()
|
savedInstanceState.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!profileListEmpty) {
|
|
||||||
handleIntent(intent?.extras)
|
|
||||||
}
|
|
||||||
app.db.profileDao().all.observe(this, Observer { profiles ->
|
app.db.profileDao().all.observe(this, Observer { profiles ->
|
||||||
drawer.setProfileList(profiles.filter { it.id >= 0 }.toMutableList())
|
drawer.setProfileList(profiles.filter { it.id >= 0 }.toMutableList())
|
||||||
if (profileListEmpty) {
|
drawer.currentProfile = App.profileId
|
||||||
profileListEmpty = false
|
|
||||||
handleIntent(intent?.extras)
|
|
||||||
}
|
|
||||||
else if (app.profile != null) {
|
|
||||||
drawer.currentProfile = app.profile.id
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// if null, getAllFull will load a profile and update drawerItems
|
|
||||||
if (app.profile != null)
|
|
||||||
setDrawerItems()
|
setDrawerItems()
|
||||||
|
|
||||||
|
handleIntent(intent?.extras)
|
||||||
|
|
||||||
app.db.metadataDao().unreadCounts.observe(this, Observer { unreadCounters ->
|
app.db.metadataDao().unreadCounts.observe(this, Observer { unreadCounters ->
|
||||||
unreadCounters.map {
|
unreadCounters.map {
|
||||||
it.type = it.thingType
|
it.type = it.thingType
|
||||||
@ -417,6 +413,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
isStoragePermissionGranted()
|
isStoragePermissionGranted()
|
||||||
|
|
||||||
SyncWorker.scheduleNext(app)
|
SyncWorker.scheduleNext(app)
|
||||||
|
UpdateWorker.scheduleNext(app)
|
||||||
|
|
||||||
// APP BACKGROUND
|
// APP BACKGROUND
|
||||||
if (app.config.ui.appBackground != null) {
|
if (app.config.ui.appBackground != null) {
|
||||||
@ -521,13 +518,10 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var profileListEmptyListener = {
|
|
||||||
startActivityForResult(Intent(this, LoginActivity::class.java), REQUEST_LOGIN_ACTIVITY)
|
|
||||||
}
|
|
||||||
private var profileSettingClickListener = { id: Int, view: View? ->
|
private var profileSettingClickListener = { id: Int, view: View? ->
|
||||||
when (id) {
|
when (id) {
|
||||||
DRAWER_PROFILE_ADD_NEW -> {
|
DRAWER_PROFILE_ADD_NEW -> {
|
||||||
profileListEmptyListener()
|
startActivityForResult(Intent(this, LoginActivity::class.java), REQUEST_LOGIN_ACTIVITY)
|
||||||
}
|
}
|
||||||
DRAWER_PROFILE_SYNC_ALL -> {
|
DRAWER_PROFILE_SYNC_ALL -> {
|
||||||
EdziennikTask.sync().enqueue(this)
|
EdziennikTask.sync().enqueue(this)
|
||||||
@ -587,6 +581,13 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
fun onProfileListEmptyEvent(event: ProfileListEmptyEvent) {
|
||||||
|
d(TAG, "Profile list is empty. Launch LoginActivity.")
|
||||||
|
app.config.loginFinished = false
|
||||||
|
startActivity(Intent(this, LoginActivity::class.java))
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
fun onApiTaskProgressEvent(event: ApiTaskProgressEvent) {
|
fun onApiTaskProgressEvent(event: ApiTaskProgressEvent) {
|
||||||
if (event.profileId == App.profileId) {
|
if (event.profileId == App.profileId) {
|
||||||
navView.toolbar.apply {
|
navView.toolbar.apply {
|
||||||
@ -630,7 +631,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
fun onAppManagerDetectedEvent(event: AppManagerDetectedEvent) {
|
fun onAppManagerDetectedEvent(event: AppManagerDetectedEvent) {
|
||||||
EventBus.getDefault().removeStickyEvent(event)
|
EventBus.getDefault().removeStickyEvent(event)
|
||||||
if (app.appConfig.dontShowAppManagerDialog)
|
if (app.config.sync.dontShowAppManagerDialog)
|
||||||
return
|
return
|
||||||
MaterialAlertDialogBuilder(this)
|
MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.app_manager_dialog_title)
|
.setTitle(R.string.app_manager_dialog_title)
|
||||||
@ -652,8 +653,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.setNeutralButton(R.string.dont_ask_again) { dialog, which ->
|
.setNeutralButton(R.string.dont_ask_again) { dialog, which ->
|
||||||
app.appConfig.dontShowAppManagerDialog = true
|
app.config.sync.dontShowAppManagerDialog = true
|
||||||
app.saveConfig("dontShowAppManagerDialog")
|
|
||||||
}
|
}
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
.show()
|
.show()
|
||||||
@ -698,7 +698,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
if (extras?.containsKey("reloadProfileId") == true) {
|
if (extras?.containsKey("reloadProfileId") == true) {
|
||||||
val reloadProfileId = extras.getInt("reloadProfileId", -1)
|
val reloadProfileId = extras.getInt("reloadProfileId", -1)
|
||||||
extras.remove("reloadProfileId")
|
extras.remove("reloadProfileId")
|
||||||
if (reloadProfileId == -1 || (app.profile != null && app.profile.id == reloadProfileId)) {
|
if (reloadProfileId == -1 || app.profile.id == reloadProfileId) {
|
||||||
reloadTarget()
|
reloadTarget()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -728,9 +728,9 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
when {
|
when {
|
||||||
app.profile == null || app.profile.id == -1 -> {
|
app.profile.id == 0 -> {
|
||||||
if (intentProfileId == -1)
|
if (intentProfileId == -1)
|
||||||
intentProfileId = app.appSharedPrefs.getInt("current_profile_id", 1)
|
intentProfileId = app.config.lastProfileId
|
||||||
loadProfile(intentProfileId, intentTargetId, extras)
|
loadProfile(intentProfileId, intentTargetId, extras)
|
||||||
}
|
}
|
||||||
intentProfileId != -1 -> {
|
intentProfileId != -1 -> {
|
||||||
@ -769,7 +769,16 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
d(TAG, "Activity started")
|
||||||
|
super.onStart()
|
||||||
|
}
|
||||||
|
override fun onStop() {
|
||||||
|
d(TAG, "Activity stopped")
|
||||||
|
super.onStop()
|
||||||
|
}
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
|
d(TAG, "Activity resumed")
|
||||||
val filter = IntentFilter()
|
val filter = IntentFilter()
|
||||||
filter.addAction(Intent.ACTION_MAIN)
|
filter.addAction(Intent.ACTION_MAIN)
|
||||||
registerReceiver(intentReceiver, filter)
|
registerReceiver(intentReceiver, filter)
|
||||||
@ -777,10 +786,15 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
super.onResume()
|
super.onResume()
|
||||||
}
|
}
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
|
d(TAG, "Activity paused")
|
||||||
unregisterReceiver(intentReceiver)
|
unregisterReceiver(intentReceiver)
|
||||||
EventBus.getDefault().unregister(this)
|
EventBus.getDefault().unregister(this)
|
||||||
super.onPause()
|
super.onPause()
|
||||||
}
|
}
|
||||||
|
override fun onDestroy() {
|
||||||
|
d(TAG, "Activity destroyed")
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
@ -794,10 +808,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
if (requestCode == REQUEST_LOGIN_ACTIVITY) {
|
if (requestCode == REQUEST_LOGIN_ACTIVITY) {
|
||||||
if (resultCode == Activity.RESULT_CANCELED && false) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!app.config.loginFinished)
|
if (!app.config.loginFinished)
|
||||||
finish()
|
finish()
|
||||||
else {
|
else {
|
||||||
@ -805,7 +815,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* _ _ _ _ _
|
/* _ _ _ _ _
|
||||||
| | | | | | | | | |
|
| | | | | | | | | |
|
||||||
@ -823,36 +832,25 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
fun loadProfile(id: Int) = loadProfile(id, navTargetId)
|
fun loadProfile(id: Int) = loadProfile(id, navTargetId)
|
||||||
fun loadProfile(id: Int, arguments: Bundle?) = loadProfile(id, navTargetId, arguments)
|
fun loadProfile(id: Int, arguments: Bundle?) = loadProfile(id, navTargetId, arguments)
|
||||||
fun loadProfile(id: Int, drawerSelection: Int, arguments: Bundle? = null) {
|
fun loadProfile(id: Int, drawerSelection: Int, arguments: Bundle? = null) {
|
||||||
//d("NavDebug", "loadProfile(id = $id, drawerSelection = $drawerSelection)")
|
if (App.profileId == id) {
|
||||||
if (app.profile != null && App.profileId == id) {
|
|
||||||
drawer.currentProfile = app.profile.id
|
drawer.currentProfile = app.profile.id
|
||||||
loadTarget(drawerSelection, arguments)
|
loadTarget(drawerSelection, arguments)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
AsyncTask.execute {
|
app.profileLoad(id) {
|
||||||
app.profileLoadById(id)
|
|
||||||
MessagesFragment.pageSelection = -1
|
MessagesFragment.pageSelection = -1
|
||||||
MessagesListFragment.tapPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
MessagesListFragment.tapPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
||||||
MessagesListFragment.topPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
MessagesListFragment.topPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
||||||
MessagesListFragment.bottomPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
MessagesListFragment.bottomPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
||||||
|
|
||||||
this.runOnUiThread {
|
|
||||||
if (app.profile == null) {
|
|
||||||
if (app.config.loginFinished) {
|
|
||||||
// this shouldn't run
|
|
||||||
profileListEmptyListener()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setDrawerItems()
|
setDrawerItems()
|
||||||
// the drawer profile is updated automatically when the drawer item is clicked
|
// the drawer profile is updated automatically when the drawer item is clicked
|
||||||
// update it manually when switching profiles from other source
|
// update it manually when switching profiles from other source
|
||||||
//if (drawer.currentProfile != app.profile.id)
|
//if (drawer.currentProfile != app.profile.id)
|
||||||
drawer.currentProfile = app.profile.id
|
drawer.currentProfile = app.profileId
|
||||||
loadTarget(drawerSelection, arguments)
|
loadTarget(drawerSelection, arguments)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
fun loadTarget(id: Int, arguments: Bundle? = null) {
|
fun loadTarget(id: Int, arguments: Bundle? = null) {
|
||||||
var loadId = id
|
var loadId = id
|
||||||
if (loadId == -1) {
|
if (loadId == -1) {
|
||||||
@ -995,7 +993,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
* that something has changed in the bottom sheet.
|
* that something has changed in the bottom sheet.
|
||||||
*/
|
*/
|
||||||
fun gainAttention() {
|
fun gainAttention() {
|
||||||
if (app.config.ui.bottomSheetOpened || true)
|
if (app.config.ui.bottomSheetOpened)
|
||||||
return
|
return
|
||||||
b.navView.postDelayed({
|
b.navView.postDelayed({
|
||||||
navView.gainAttentionOnBottomBar()
|
navView.gainAttentionOnBottomBar()
|
||||||
@ -1044,12 +1042,11 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setDrawerItems() {
|
fun setDrawerItems() {
|
||||||
d("NavDebug", "setDrawerItems() app.profile = ${app.profile ?: "null"}")
|
d("NavDebug", "setDrawerItems() app.profile = ${app.profile}")
|
||||||
val drawerItems = arrayListOf<IDrawerItem<*>>()
|
val drawerItems = arrayListOf<IDrawerItem<*>>()
|
||||||
val drawerProfiles = arrayListOf<ProfileSettingDrawerItem>()
|
val drawerProfiles = arrayListOf<ProfileSettingDrawerItem>()
|
||||||
|
|
||||||
val supportedFragments = if (app.profile == null) arrayListOf<Int>()
|
val supportedFragments = app.profile.supportedFragments
|
||||||
else app.profile.supportedFragments
|
|
||||||
|
|
||||||
targetPopToHomeList.clear()
|
targetPopToHomeList.clear()
|
||||||
|
|
||||||
@ -1113,7 +1110,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
private var targetHomeId: Int = -1
|
private var targetHomeId: Int = -1
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
if (!b.navView.onBackPressed()) {
|
if (!b.navView.onBackPressed()) {
|
||||||
if (App.getConfig().ui.openDrawerOnBackPressed) {
|
if (App.config.ui.openDrawerOnBackPressed) {
|
||||||
b.navView.drawer.toggle()
|
b.navView.drawer.toggle()
|
||||||
} else {
|
} else {
|
||||||
navigateUp()
|
navigateUp()
|
||||||
|
@ -1,350 +0,0 @@
|
|||||||
package pl.szczodrzynski.edziennik;
|
|
||||||
|
|
||||||
import android.app.IntentService;
|
|
||||||
import android.app.Notification;
|
|
||||||
import android.app.NotificationChannel;
|
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.core.app.NotificationCompat;
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.receivers.BootReceiver;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time;
|
|
||||||
|
|
||||||
import static androidx.core.app.NotificationCompat.PRIORITY_DEFAULT;
|
|
||||||
import static androidx.core.app.NotificationCompat.PRIORITY_MAX;
|
|
||||||
|
|
||||||
public class Notifier {
|
|
||||||
|
|
||||||
private static final String TAG = "Notifier";
|
|
||||||
public static final int ID_GET_DATA = 1337000;
|
|
||||||
public static final int ID_GET_DATA_ERROR = 1337001;
|
|
||||||
private static String CHANNEL_GET_DATA_NAME;
|
|
||||||
private static String CHANNEL_GET_DATA_DESC;
|
|
||||||
private static final String GROUP_KEY_GET_DATA = "pl.szczodrzynski.edziennik.GET_DATA";
|
|
||||||
|
|
||||||
public static final int ID_NOTIFICATIONS = 1337002;
|
|
||||||
public static String CHANNEL_NOTIFICATIONS_NAME;
|
|
||||||
public static String CHANNEL_NOTIFICATIONS_DESC;
|
|
||||||
public static final String GROUP_KEY_NOTIFICATIONS = "pl.szczodrzynski.edziennik.NOTIFICATIONS";
|
|
||||||
|
|
||||||
public static final int ID_NOTIFICATIONS_QUIET = 1337002;
|
|
||||||
public static String CHANNEL_NOTIFICATIONS_QUIET_NAME;
|
|
||||||
public static String CHANNEL_NOTIFICATIONS_QUIET_DESC;
|
|
||||||
public static final String GROUP_KEY_NOTIFICATIONS_QUIET = "pl.szczodrzynski.edziennik.NOTIFICATIONS_QUIET";
|
|
||||||
|
|
||||||
private static final int ID_UPDATES = 1337003;
|
|
||||||
private static String CHANNEL_UPDATES_NAME;
|
|
||||||
private static String CHANNEL_UPDATES_DESC;
|
|
||||||
private static final String GROUP_KEY_UPDATES = "pl.szczodrzynski.edziennik.UPDATES";
|
|
||||||
|
|
||||||
private App app;
|
|
||||||
public NotificationManager notificationManager;
|
|
||||||
private NotificationCompat.Builder getDataNotificationBuilder;
|
|
||||||
public int notificationColor;
|
|
||||||
|
|
||||||
Notifier(App _app) {
|
|
||||||
this.app = _app;
|
|
||||||
|
|
||||||
CHANNEL_GET_DATA_NAME = app.getString(R.string.notification_channel_get_data_name);
|
|
||||||
CHANNEL_GET_DATA_DESC = app.getString(R.string.notification_channel_get_data_desc);
|
|
||||||
CHANNEL_NOTIFICATIONS_NAME = app.getString(R.string.notification_channel_notifications_name);
|
|
||||||
CHANNEL_NOTIFICATIONS_DESC = app.getString(R.string.notification_channel_notifications_desc);
|
|
||||||
CHANNEL_NOTIFICATIONS_QUIET_NAME = app.getString(R.string.notification_channel_notifications_quiet_name);
|
|
||||||
CHANNEL_NOTIFICATIONS_QUIET_DESC = app.getString(R.string.notification_channel_notifications_quiet_desc);
|
|
||||||
CHANNEL_UPDATES_NAME = app.getString(R.string.notification_channel_updates_name);
|
|
||||||
CHANNEL_UPDATES_DESC = app.getString(R.string.notification_channel_updates_desc);
|
|
||||||
|
|
||||||
notificationColor = ContextCompat.getColor(app.getContext(), R.color.colorPrimary);
|
|
||||||
notificationManager = (NotificationManager) app.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
NotificationChannel channelGetData = new NotificationChannel(GROUP_KEY_GET_DATA, CHANNEL_GET_DATA_NAME, NotificationManager.IMPORTANCE_MIN);
|
|
||||||
channelGetData.setDescription(CHANNEL_GET_DATA_DESC);
|
|
||||||
notificationManager.createNotificationChannel(channelGetData);
|
|
||||||
|
|
||||||
NotificationChannel channelNotifications = new NotificationChannel(GROUP_KEY_NOTIFICATIONS, CHANNEL_NOTIFICATIONS_NAME, NotificationManager.IMPORTANCE_HIGH);
|
|
||||||
channelNotifications.setDescription(CHANNEL_NOTIFICATIONS_DESC);
|
|
||||||
channelNotifications.enableLights(true);
|
|
||||||
channelNotifications.setLightColor(notificationColor);
|
|
||||||
notificationManager.createNotificationChannel(channelNotifications);
|
|
||||||
|
|
||||||
NotificationChannel channelNotificationsQuiet = new NotificationChannel(GROUP_KEY_NOTIFICATIONS_QUIET, CHANNEL_NOTIFICATIONS_QUIET_NAME, NotificationManager.IMPORTANCE_DEFAULT);
|
|
||||||
channelNotificationsQuiet.setDescription(CHANNEL_NOTIFICATIONS_QUIET_DESC);
|
|
||||||
channelNotificationsQuiet.setSound(null, null);
|
|
||||||
channelNotificationsQuiet.enableVibration(false);
|
|
||||||
notificationManager.createNotificationChannel(channelNotificationsQuiet);
|
|
||||||
|
|
||||||
NotificationChannel channelUpdates = new NotificationChannel(GROUP_KEY_UPDATES, CHANNEL_UPDATES_NAME, NotificationManager.IMPORTANCE_HIGH);
|
|
||||||
channelUpdates.setDescription(CHANNEL_UPDATES_DESC);
|
|
||||||
notificationManager.createNotificationChannel(channelUpdates);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldBeQuiet() {
|
|
||||||
long now = Time.getNow().getInMillis();
|
|
||||||
long start = app.config.getSync().getQuietHoursStart();
|
|
||||||
long end = app.config.getSync().getQuietHoursEnd();
|
|
||||||
if (start > end) {
|
|
||||||
end += 1000 * 60 * 60 * 24;
|
|
||||||
//Log.d(TAG, "Night passing");
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNotificationDefaults() {
|
|
||||||
return (shouldBeQuiet() ? 0 : Notification.DEFAULT_ALL);
|
|
||||||
}
|
|
||||||
public String getNotificationGroup() {
|
|
||||||
return shouldBeQuiet() ? GROUP_KEY_NOTIFICATIONS_QUIET : GROUP_KEY_NOTIFICATIONS;
|
|
||||||
}
|
|
||||||
public int getNotificationPriority() {
|
|
||||||
return shouldBeQuiet() ? PRIORITY_DEFAULT : PRIORITY_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _____ _ _____ _
|
|
||||||
| __ \ | | / ____| | |
|
|
||||||
| | | | __ _| |_ __ _ | | __ ___| |_
|
|
||||||
| | | |/ _` | __/ _` | | | |_ |/ _ \ __|
|
|
||||||
| |__| | (_| | || (_| | | |__| | __/ |_
|
|
||||||
|_____/ \__,_|\__\__,_| \_____|\___|\_*/
|
|
||||||
public Notification notificationGetDataShow(int maxProgress) {
|
|
||||||
/*Intent notificationIntent = new Intent(app.getContext(), SyncService.class);
|
|
||||||
notificationIntent.setAction(ACTION_CANCEL);
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getService(app.getContext(), 0,
|
|
||||||
notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);*/
|
|
||||||
|
|
||||||
getDataNotificationBuilder = new NotificationCompat.Builder(app, GROUP_KEY_GET_DATA)
|
|
||||||
.setSmallIcon(android.R.drawable.stat_sys_download)
|
|
||||||
.setColor(notificationColor)
|
|
||||||
.setContentTitle(app.getString(R.string.notification_get_data_title))
|
|
||||||
.setContentText(app.getString(R.string.notification_get_data_text))
|
|
||||||
//.addAction(R.drawable.ic_notification, app.getString(R.string.notification_get_data_cancel), pendingIntent)
|
|
||||||
//.setGroup(GROUP_KEY_GET_DATA)
|
|
||||||
.setOngoing(true)
|
|
||||||
.setProgress(maxProgress, 0, false)
|
|
||||||
.setTicker(app.getString(R.string.notification_get_data_summary))
|
|
||||||
.setPriority(NotificationCompat.PRIORITY_LOW);
|
|
||||||
return getDataNotificationBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Notification notificationGetDataProgress(int progress, int maxProgress) {
|
|
||||||
getDataNotificationBuilder.setProgress(maxProgress, progress, false);
|
|
||||||
return getDataNotificationBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Notification notificationGetDataAction(int stringResId) {
|
|
||||||
getDataNotificationBuilder.setContentTitle(app.getString(R.string.sync_action_format, app.getString(stringResId)));
|
|
||||||
return getDataNotificationBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Notification notificationGetDataProfile(String profileName) {
|
|
||||||
getDataNotificationBuilder.setContentText(profileName);
|
|
||||||
return getDataNotificationBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Notification notificationGetDataError(String profileName, String error, int failedProfileId) {
|
|
||||||
Intent notificationIntent = new Intent(app.getContext(), Notifier.GetDataRetryService.class);
|
|
||||||
notificationIntent.putExtra("failedProfileId", failedProfileId);
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getService(app.getContext(), 0,
|
|
||||||
notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
|
||||||
|
|
||||||
getDataNotificationBuilder.mActions.clear();
|
|
||||||
/*try {
|
|
||||||
//Use reflection clean up old actions
|
|
||||||
Field f = getDataNotificationBuilder.getClass().getDeclaredField("mActions");
|
|
||||||
f.setAccessible(true);
|
|
||||||
f.set(getDataNotificationBuilder, new ArrayList<NotificationCompat.Action>());
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
getDataNotificationBuilder.setProgress(0, 0, false)
|
|
||||||
.setTicker(app.getString(R.string.notification_get_data_error_summary))
|
|
||||||
.setSmallIcon(android.R.drawable.stat_sys_warning)
|
|
||||||
.addAction(R.drawable.ic_notification, app.getString(R.string.notification_get_data_once_again), pendingIntent)
|
|
||||||
.setContentTitle(app.getString(R.string.notification_get_data_error_title, profileName))
|
|
||||||
.setContentText(error)
|
|
||||||
.setStyle(new NotificationCompat.BigTextStyle().bigText(error))
|
|
||||||
.setOngoing(false);
|
|
||||||
return getDataNotificationBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notificationPost(int id, Notification notification) {
|
|
||||||
notificationManager.notify(id, notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notificationCancel(int id) {
|
|
||||||
notificationManager.cancel(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//public void notificationGetDataHide() {
|
|
||||||
// notificationManager.cancel(ID_GET_DATA);
|
|
||||||
// }
|
|
||||||
|
|
||||||
public static class GetDataRetryService extends IntentService {
|
|
||||||
private static final String TAG = "Notifier/GetDataRetry";
|
|
||||||
|
|
||||||
public GetDataRetryService() {
|
|
||||||
super(Notifier.GetDataRetryService.class.getSimpleName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onHandleIntent(Intent intent) {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _ _ _ _ __ _ _ _
|
|
||||||
| \ | | | | (_)/ _(_) | | (_)
|
|
||||||
| \| | ___ | |_ _| |_ _ ___ __ _| |_ _ ___ _ __
|
|
||||||
| . ` |/ _ \| __| | _| |/ __/ _` | __| |/ _ \| '_ \
|
|
||||||
| |\ | (_) | |_| | | | | (_| (_| | |_| | (_) | | | |
|
|
||||||
|_| \_|\___/ \__|_|_| |_|\___\__,_|\__|_|\___/|_| |*/
|
|
||||||
public void add(pl.szczodrzynski.edziennik.utils.models.Notification notification) {
|
|
||||||
app.appConfig.notifications.add(notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void postAll() {
|
|
||||||
Collections.sort(app.appConfig.notifications, (o1, o2) -> (o2.addedDate - o1.addedDate > 0) ? 1 : (o2.addedDate - o1.addedDate < 0) ? -1 : 0);
|
|
||||||
|
|
||||||
if (app.appConfig.notifications.size() > 40) {
|
|
||||||
app.appConfig.notifications.subList(40, app.appConfig.notifications.size() - 1).clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
int unreadCount = 0;
|
|
||||||
List<pl.szczodrzynski.edziennik.utils.models.Notification> notificationList = new ArrayList<>();
|
|
||||||
for (pl.szczodrzynski.edziennik.utils.models.Notification notification: app.appConfig.notifications) {
|
|
||||||
if (!notification.notified) {
|
|
||||||
notification.seen = false;
|
|
||||||
notification.notified = true;
|
|
||||||
unreadCount++;
|
|
||||||
if (notificationList.size() < 10) {
|
|
||||||
notificationList.add(notification);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
notification.seen = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (pl.szczodrzynski.edziennik.utils.models.Notification notification: notificationList) {
|
|
||||||
Intent intent = new Intent(app, MainActivity.class);
|
|
||||||
notification.fillIntent(intent);
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getActivity(app, notification.id, intent, 0);
|
|
||||||
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(app, getNotificationGroup())
|
|
||||||
// title, text, type, date
|
|
||||||
.setContentTitle(notification.title)
|
|
||||||
.setContentText(notification.text)
|
|
||||||
.setSubText(pl.szczodrzynski.edziennik.utils.models.Notification.stringType(app, notification.type))
|
|
||||||
.setWhen(notification.addedDate)
|
|
||||||
.setTicker(app.getString(R.string.notification_ticker_format, pl.szczodrzynski.edziennik.utils.models.Notification.stringType(app, notification.type)))
|
|
||||||
// icon, color, lights, priority
|
|
||||||
.setSmallIcon(R.drawable.ic_notification)
|
|
||||||
.setColor(notificationColor)
|
|
||||||
.setLights(0xFF00FFFF, 2000, 2000)
|
|
||||||
.setPriority(getNotificationPriority())
|
|
||||||
// channel, group, style
|
|
||||||
.setChannelId(getNotificationGroup())
|
|
||||||
.setGroup(getNotificationGroup())
|
|
||||||
.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY)
|
|
||||||
.setStyle(new NotificationCompat.BigTextStyle().bigText(notification.text))
|
|
||||||
// intent, auto cancel
|
|
||||||
.setContentIntent(pendingIntent)
|
|
||||||
.setAutoCancel(true);
|
|
||||||
if (!shouldBeQuiet()) {
|
|
||||||
notificationBuilder.setDefaults(getNotificationDefaults());
|
|
||||||
}
|
|
||||||
notificationManager.notify(notification.id, notificationBuilder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notificationList.size() > 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
||||||
Intent intent = new Intent(app, MainActivity.class);
|
|
||||||
intent.setAction("android.intent.action.MAIN");
|
|
||||||
intent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_NOTIFICATIONS);
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getActivity(app, ID_NOTIFICATIONS,
|
|
||||||
intent, 0);
|
|
||||||
|
|
||||||
NotificationCompat.Builder groupBuilder =
|
|
||||||
new NotificationCompat.Builder(app, getNotificationGroup())
|
|
||||||
.setSmallIcon(R.drawable.ic_notification)
|
|
||||||
.setColor(notificationColor)
|
|
||||||
.setContentTitle(app.getString(R.string.notification_new_notification_title_format, unreadCount))
|
|
||||||
.setGroupSummary(true)
|
|
||||||
.setAutoCancel(true)
|
|
||||||
.setChannelId(getNotificationGroup())
|
|
||||||
.setGroup(getNotificationGroup())
|
|
||||||
.setLights(0xFF00FFFF, 2000, 2000)
|
|
||||||
.setPriority(getNotificationPriority())
|
|
||||||
.setContentIntent(pendingIntent)
|
|
||||||
.setStyle(new NotificationCompat.BigTextStyle());
|
|
||||||
if (!shouldBeQuiet()) {
|
|
||||||
groupBuilder.setDefaults(getNotificationDefaults());
|
|
||||||
}
|
|
||||||
notificationManager.notify(ID_NOTIFICATIONS, groupBuilder.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _ _ _ _
|
|
||||||
| | | | | | | |
|
|
||||||
| | | |_ __ __| | __ _| |_ ___ ___
|
|
||||||
| | | | '_ \ / _` |/ _` | __/ _ \/ __|
|
|
||||||
| |__| | |_) | (_| | (_| | || __/\__ \
|
|
||||||
\____/| .__/ \__,_|\__,_|\__\___||___/
|
|
||||||
| |
|
|
||||||
|*/
|
|
||||||
public void notificationUpdatesShow(String updateVersion, String updateUrl, String updateFilename, boolean updateDirect) {
|
|
||||||
if (!app.config.getSync().getNotifyAboutUpdates())
|
|
||||||
return;
|
|
||||||
Intent notificationIntent = new Intent(app.getContext(), BootReceiver.NotificationActionService.class)
|
|
||||||
.putExtra("update_version", updateVersion)
|
|
||||||
.putExtra("update_url", updateUrl)
|
|
||||||
.putExtra("update_filename", updateFilename)
|
|
||||||
.putExtra("update_direct", updateDirect);
|
|
||||||
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getService(app.getContext(), 0,
|
|
||||||
notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
|
||||||
|
|
||||||
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(app, GROUP_KEY_UPDATES)
|
|
||||||
.setSmallIcon(android.R.drawable.stat_sys_download_done)
|
|
||||||
.setColor(notificationColor)
|
|
||||||
.setContentTitle(app.getString(R.string.notification_updates_title))
|
|
||||||
.setContentText(app.getString(R.string.notification_updates_text, updateVersion))
|
|
||||||
.setLights(0xFF00FFFF, 2000, 2000)
|
|
||||||
.setContentIntent(pendingIntent)
|
|
||||||
.setTicker(app.getString(R.string.notification_updates_summary))
|
|
||||||
.setPriority(PRIORITY_MAX)
|
|
||||||
.setAutoCancel(true);
|
|
||||||
if (!shouldBeQuiet()) {
|
|
||||||
notificationBuilder.setDefaults(getNotificationDefaults());
|
|
||||||
}
|
|
||||||
notificationManager.notify(ID_UPDATES, notificationBuilder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notificationUpdatesHide() {
|
|
||||||
if (!app.config.getSync().getNotifyAboutUpdates())
|
|
||||||
return;
|
|
||||||
notificationManager.cancel(ID_UPDATES);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dump() {
|
|
||||||
for (pl.szczodrzynski.edziennik.utils.models.Notification notification: app.appConfig.notifications) {
|
|
||||||
Log.d(TAG, "Profile"+notification.profileId+" Notification from "+ Date.fromMillis(notification.addedDate).getFormattedString()+" "+ Time.fromMillis(notification.addedDate).getStringHMS()+" - "+notification.text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,12 +16,13 @@ import pl.szczodrzynski.edziennik.config.utils.ConfigMigration
|
|||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
import pl.szczodrzynski.edziennik.config.utils.toHashMap
|
import pl.szczodrzynski.edziennik.config.utils.toHashMap
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
||||||
import pl.szczodrzynski.edziennik.data.db.AppDb
|
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||||
import kotlin.coroutines.CoroutineContext
|
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 = 2
|
const val DATA_VERSION = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
private val job = Job()
|
private val job = Job()
|
||||||
@ -45,6 +46,20 @@ class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
|||||||
get() { mHash = mHash ?: values.get("hash", ""); return mHash ?: "" }
|
get() { mHash = mHash ?: values.get("hash", ""); return mHash ?: "" }
|
||||||
set(value) { set("hash", value); mHash = value }
|
set(value) { set("hash", value); mHash = value }
|
||||||
|
|
||||||
|
private var mLastProfileId: Int? = null
|
||||||
|
var lastProfileId: Int
|
||||||
|
get() { mLastProfileId = mLastProfileId ?: values.get("lastProfileId", 0); return mLastProfileId ?: 0 }
|
||||||
|
set(value) { set("lastProfileId", value); mLastProfileId = value }
|
||||||
|
|
||||||
|
private var mUpdatesChannel: String? = null
|
||||||
|
var updatesChannel: String
|
||||||
|
get() { mUpdatesChannel = mUpdatesChannel ?: values.get("updatesChannel", "release"); return mUpdatesChannel ?: "release" }
|
||||||
|
set(value) { set("updatesChannel", value); mUpdatesChannel = value }
|
||||||
|
private var mUpdate: Update? = null
|
||||||
|
var update: Update?
|
||||||
|
get() { mUpdate = mUpdate ?: values.get("update", null as Update?); return mUpdate ?: null as Update? }
|
||||||
|
set(value) { set("update", value); mUpdate = value }
|
||||||
|
|
||||||
private var mAppVersion: Int? = null
|
private var mAppVersion: Int? = null
|
||||||
var appVersion: Int
|
var appVersion: Int
|
||||||
get() { mAppVersion = mAppVersion ?: values.get("appVersion", BuildConfig.VERSION_CODE); return mAppVersion ?: BuildConfig.VERSION_CODE }
|
get() { mAppVersion = mAppVersion ?: values.get("appVersion", BuildConfig.VERSION_CODE); return mAppVersion ?: BuildConfig.VERSION_CODE }
|
||||||
|
@ -17,6 +17,6 @@ class ConfigGrades(private val config: Config) {
|
|||||||
|
|
||||||
private var mOrderBy: Int? = null
|
private var mOrderBy: Int? = null
|
||||||
var orderBy: Int
|
var orderBy: Int
|
||||||
get() { mOrderBy = mOrderBy ?: config.values.get("gradesOrderBy", 0); return mOrderBy ?: 0 }
|
get() { mOrderBy = mOrderBy ?: config.values.get("gradesOrderBy", 0); return mOrderBy ?: ORDER_BY_DATE_DESC }
|
||||||
set(value) { config.set("gradesOrderBy", value); mOrderBy = value }
|
set(value) { config.set("gradesOrderBy", value); mOrderBy = value }
|
||||||
}
|
}
|
@ -9,6 +9,11 @@ import pl.szczodrzynski.edziennik.config.utils.getIntList
|
|||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
|
|
||||||
class ConfigSync(private val config: Config) {
|
class ConfigSync(private val config: Config) {
|
||||||
|
private var mDontShowAppManagerDialog: Boolean? = null
|
||||||
|
var dontShowAppManagerDialog: Boolean
|
||||||
|
get() { mDontShowAppManagerDialog = mDontShowAppManagerDialog ?: config.values.get("dontShowAppManagerDialog", false); return mDontShowAppManagerDialog ?: false }
|
||||||
|
set(value) { config.set("dontShowAppManagerDialog", value); mDontShowAppManagerDialog = value }
|
||||||
|
|
||||||
private var mSyncEnabled: Boolean? = null
|
private var mSyncEnabled: Boolean? = null
|
||||||
var enabled: Boolean
|
var enabled: Boolean
|
||||||
get() { mSyncEnabled = mSyncEnabled ?: config.values.get("syncEnabled", true); return mSyncEnabled ?: true }
|
get() { mSyncEnabled = mSyncEnabled ?: config.values.get("syncEnabled", true); return mSyncEnabled ?: true }
|
||||||
|
@ -45,11 +45,6 @@ class ConfigUI(private val config: Config) {
|
|||||||
get() { mOpenDrawerOnBackPressed = mOpenDrawerOnBackPressed ?: config.values.get("openDrawerOnBackPressed", false); return mOpenDrawerOnBackPressed ?: false }
|
get() { mOpenDrawerOnBackPressed = mOpenDrawerOnBackPressed ?: config.values.get("openDrawerOnBackPressed", false); return mOpenDrawerOnBackPressed ?: false }
|
||||||
set(value) { config.set("openDrawerOnBackPressed", value); mOpenDrawerOnBackPressed = value }
|
set(value) { config.set("openDrawerOnBackPressed", value); mOpenDrawerOnBackPressed = value }
|
||||||
|
|
||||||
private var mAgendaViewType: Int? = null
|
|
||||||
var agendaViewType: Int
|
|
||||||
get() { mAgendaViewType = mAgendaViewType ?: config.values.get("agendaViewType", 0); return mAgendaViewType ?: 0 }
|
|
||||||
set(value) { config.set("agendaViewType", value); mAgendaViewType = value }
|
|
||||||
|
|
||||||
private var mHomeCards: List<HomeCardModel>? = null
|
private var mHomeCards: List<HomeCardModel>? = null
|
||||||
var homeCards: List<HomeCardModel>
|
var homeCards: List<HomeCardModel>
|
||||||
get() { mHomeCards = mHomeCards ?: config.values.get("homeCards", listOf(), HomeCardModel::class.java); return mHomeCards ?: listOf() }
|
get() { mHomeCards = mHomeCards ?: config.values.get("homeCards", listOf(), HomeCardModel::class.java); return mHomeCards ?: listOf() }
|
||||||
|
@ -9,6 +9,7 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import pl.szczodrzynski.edziennik.config.db.ConfigEntry
|
import pl.szczodrzynski.edziennik.config.db.ConfigEntry
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.ProfileConfigMigration
|
||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
import pl.szczodrzynski.edziennik.config.utils.toHashMap
|
import pl.szczodrzynski.edziennik.config.utils.toHashMap
|
||||||
@ -27,6 +28,7 @@ class ProfileConfig(val db: AppDb, val profileId: Int, rawEntries: List<ConfigEn
|
|||||||
val values: HashMap<String, String?> = hashMapOf()
|
val values: HashMap<String, String?> = hashMapOf()
|
||||||
|
|
||||||
val grades by lazy { ProfileConfigGrades(this) }
|
val grades by lazy { ProfileConfigGrades(this) }
|
||||||
|
val ui by lazy { ProfileConfigUI(this) }
|
||||||
/*
|
/*
|
||||||
val sync by lazy { ConfigSync(this) }
|
val sync by lazy { ConfigSync(this) }
|
||||||
val timetable by lazy { ConfigTimetable(this) }
|
val timetable by lazy { ConfigTimetable(this) }
|
||||||
@ -44,8 +46,8 @@ class ProfileConfig(val db: AppDb, val profileId: Int, rawEntries: List<ConfigEn
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
rawEntries.toHashMap(profileId, values)
|
rawEntries.toHashMap(profileId, values)
|
||||||
/*if (dataVersion < DATA_VERSION)
|
if (dataVersion < DATA_VERSION)
|
||||||
ProfileConfigMigration(this)*/
|
ProfileConfigMigration(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun set(key: String, value: String?) {
|
override fun set(key: String, value: String?) {
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-19.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.config
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.AGENDA_DEFAULT
|
||||||
|
|
||||||
|
class ProfileConfigUI(private val config: ProfileConfig) {
|
||||||
|
private var mAgendaViewType: Int? = null
|
||||||
|
var agendaViewType: Int
|
||||||
|
get() { mAgendaViewType = mAgendaViewType ?: config.values.get("agendaViewType", 0); return mAgendaViewType ?: AGENDA_DEFAULT }
|
||||||
|
set(value) { config.set("agendaViewType", value); mAgendaViewType = value }
|
||||||
|
}
|
@ -22,4 +22,7 @@ interface ConfigDao {
|
|||||||
|
|
||||||
@Query("SELECT * FROM config WHERE profileId = :profileId")
|
@Query("SELECT * FROM config WHERE profileId = :profileId")
|
||||||
fun getAllNow(profileId: Int): List<ConfigEntry>
|
fun getAllNow(profileId: Int): List<ConfigEntry>
|
||||||
|
|
||||||
|
@Query("DELETE FROM config WHERE profileId = :profileId")
|
||||||
|
fun clear(profileId: Int)
|
||||||
}
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-19.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.config.utils
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.google.gson.reflect.TypeToken
|
||||||
|
import pl.szczodrzynski.edziennik.BuildConfig
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
|
import pl.szczodrzynski.edziennik.config.Config
|
||||||
|
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
|
||||||
|
|
||||||
|
class AppConfigMigrationV3(p: SharedPreferences, config: Config) {
|
||||||
|
init { config.apply {
|
||||||
|
val s = "app.appConfig"
|
||||||
|
if (dataVersion < 1) {
|
||||||
|
ui.theme = p.getString("$s.appTheme", null)?.toIntOrNull() ?: 1
|
||||||
|
sync.enabled = p.getString("$s.registerSyncEnabled", null)?.toBoolean() ?: true
|
||||||
|
sync.interval = p.getString("$s.registerSyncInterval", null)?.toIntOrNull() ?: 3600
|
||||||
|
val oldButtons = p.getString("$s.miniDrawerButtonIds", null)?.let { str ->
|
||||||
|
str.replace("[\\[\\]]*".toRegex(), "")
|
||||||
|
.split(",\\s?".toRegex())
|
||||||
|
.mapNotNull { it.toIntOrNull() }
|
||||||
|
}
|
||||||
|
ui.miniMenuButtons = oldButtons ?: listOf(
|
||||||
|
MainActivity.DRAWER_ITEM_HOME,
|
||||||
|
MainActivity.DRAWER_ITEM_TIMETABLE,
|
||||||
|
MainActivity.DRAWER_ITEM_AGENDA,
|
||||||
|
MainActivity.DRAWER_ITEM_GRADES,
|
||||||
|
MainActivity.DRAWER_ITEM_MESSAGES,
|
||||||
|
MainActivity.DRAWER_ITEM_HOMEWORK,
|
||||||
|
MainActivity.DRAWER_ITEM_SETTINGS
|
||||||
|
)
|
||||||
|
dataVersion = 1
|
||||||
|
}
|
||||||
|
if (dataVersion < 2) {
|
||||||
|
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()
|
||||||
|
ui.language = p.getString("$s.language", null).fix()
|
||||||
|
appVersion = p.getString("$s.lastAppVersion", null)?.toIntOrNull() ?: BuildConfig.VERSION_CODE
|
||||||
|
appInstalledTime = p.getString("$s.appInstalledTime", null)?.toLongOrNull() ?: 0
|
||||||
|
grades.orderBy = p.getString("$s.gradesOrderBy", null)?.toIntOrNull() ?: 0
|
||||||
|
sync.quietDuringLessons = p.getString("$s.quietDuringLessons", null)?.toBoolean() ?: false
|
||||||
|
ui.miniMenuVisible = p.getString("$s.miniDrawerVisible", null)?.toBoolean() ?: false
|
||||||
|
loginFinished = p.getString("$s.loginFinished", null)?.toBoolean() ?: false
|
||||||
|
sync.onlyWifi = p.getString("$s.registerSyncOnlyWifi", null)?.toBoolean() ?: false
|
||||||
|
sync.notifyAboutUpdates = p.getString("$s.notifyAboutUpdates", null)?.toBoolean() ?: true
|
||||||
|
timetable.bellSyncDiff = p.getString("$s.bellSyncDiff", null)?.let { Gson().fromJson(it, Time::class.java) }
|
||||||
|
|
||||||
|
sync.tokenMobidziennikList = listOf()
|
||||||
|
sync.tokenVulcanList = listOf()
|
||||||
|
sync.tokenLibrusList = listOf()
|
||||||
|
val tokens = p.getString("$s.fcmTokens", null)?.let { Gson().fromJson<Map<Int, Pair<String, List<Int>>>>(it, object: TypeToken<Map<Int, Pair<String, List<Int>>>>(){}.type) }
|
||||||
|
tokens?.forEach {
|
||||||
|
val token = it.value.first
|
||||||
|
when (it.key) {
|
||||||
|
LOGIN_TYPE_MOBIDZIENNIK -> sync.tokenMobidziennik = token
|
||||||
|
LOGIN_TYPE_VULCAN -> sync.tokenVulcan = token
|
||||||
|
LOGIN_TYPE_LIBRUS -> sync.tokenLibrus = token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dataVersion = 2
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
private fun String?.fix(): String? {
|
||||||
|
return this?.replace("\"", "")?.let { if (it == "null") null else it }
|
||||||
|
}
|
||||||
|
}
|
@ -37,6 +37,9 @@ fun AbstractConfig.set(key: String, value: JsonElement?) {
|
|||||||
fun AbstractConfig.set(key: String, value: List<Any>?) {
|
fun AbstractConfig.set(key: String, value: List<Any>?) {
|
||||||
set(key, value?.let { gson.toJson(it) })
|
set(key, value?.let { gson.toJson(it) })
|
||||||
}
|
}
|
||||||
|
fun AbstractConfig.set(key: String, value: Any?) {
|
||||||
|
set(key, value?.let { gson.toJson(it) })
|
||||||
|
}
|
||||||
fun AbstractConfig.setStringList(key: String, value: List<String>?) {
|
fun AbstractConfig.setStringList(key: String, value: List<String>?) {
|
||||||
set(key, value?.let { gson.toJson(it) })
|
set(key, value?.let { gson.toJson(it) })
|
||||||
}
|
}
|
||||||
@ -74,6 +77,9 @@ fun HashMap<String, String?>.get(key: String, default: JsonObject?): JsonObject?
|
|||||||
fun HashMap<String, String?>.get(key: String, default: JsonArray?): JsonArray? {
|
fun HashMap<String, String?>.get(key: String, default: JsonArray?): JsonArray? {
|
||||||
return this[key]?.let { JsonParser().parse(it)?.asJsonArray } ?: default
|
return this[key]?.let { JsonParser().parse(it)?.asJsonArray } ?: default
|
||||||
}
|
}
|
||||||
|
inline fun <reified T> HashMap<String, String?>.get(key: String, default: T?): T? {
|
||||||
|
return this[key]?.let { Gson().fromJson(it, T::class.java) } ?: default
|
||||||
|
}
|
||||||
/* !!! cannot use mutable list here - modifying it will not update the DB */
|
/* !!! cannot use mutable list here - modifying it will not update the DB */
|
||||||
fun <T> HashMap<String, String?>.get(key: String, default: List<T>?, classOfT: Class<T>): List<T>? {
|
fun <T> HashMap<String, String?>.get(key: String, default: List<T>?, classOfT: Class<T>): List<T>? {
|
||||||
return this[key]?.let { ConfigGsonUtils().deserializeList<T>(gson, it, classOfT) } ?: default
|
return this[key]?.let { ConfigGsonUtils().deserializeList<T>(gson, it, classOfT) } ?: default
|
||||||
|
@ -5,32 +5,32 @@
|
|||||||
package pl.szczodrzynski.edziennik.config.utils
|
package pl.szczodrzynski.edziennik.config.utils
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.google.gson.reflect.TypeToken
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.BuildConfig
|
import pl.szczodrzynski.edziennik.BuildConfig
|
||||||
|
import pl.szczodrzynski.edziennik.HOUR
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
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.config.Config
|
import pl.szczodrzynski.edziennik.config.Config
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.config.ConfigGrades.Companion.ORDER_BY_DATE_DESC
|
||||||
|
|
||||||
class ConfigMigration(app: App, config: Config) {
|
class ConfigMigration(app: App, config: Config) {
|
||||||
init { config.apply {
|
init { config.apply {
|
||||||
val p = app.getSharedPreferences("pl.szczodrzynski.edziennik_profiles", Context.MODE_PRIVATE)
|
|
||||||
val s = "app.appConfig"
|
|
||||||
|
|
||||||
if (dataVersion < 1) {
|
val p = app.getSharedPreferences("pl.szczodrzynski.edziennik_profiles", Context.MODE_PRIVATE)
|
||||||
ui.theme = p.getString("$s.appTheme", null)?.toIntOrNull() ?: 1
|
if (p.contains("app.appConfig.appTheme")) {
|
||||||
sync.enabled = p.getString("$s.registerSyncEnabled", null)?.toBoolean() ?: true
|
// migrate appConfig from app version 3.x and lower.
|
||||||
sync.interval = p.getString("$s.registerSyncEnabled", null)?.toIntOrNull() ?: 3600
|
// Updates dataVersion to level 2.
|
||||||
val oldButtons = p.getString("$s.miniDrawerButtonIds", null)?.let { str ->
|
AppConfigMigrationV3(p, config)
|
||||||
str.replace("[\\[\\]]*".toRegex(), "")
|
|
||||||
.split(",\\s?".toRegex())
|
|
||||||
.mapNotNull { it.toIntOrNull() }
|
|
||||||
}
|
}
|
||||||
ui.miniMenuButtons = oldButtons ?: listOf(
|
|
||||||
|
if (dataVersion < 2) {
|
||||||
|
appVersion = BuildConfig.VERSION_CODE
|
||||||
|
loginFinished = false
|
||||||
|
ui.language = null
|
||||||
|
ui.theme = 1
|
||||||
|
ui.appBackground = null
|
||||||
|
ui.headerBackground = null
|
||||||
|
ui.miniMenuVisible = false
|
||||||
|
ui.miniMenuButtons = listOf(
|
||||||
MainActivity.DRAWER_ITEM_HOME,
|
MainActivity.DRAWER_ITEM_HOME,
|
||||||
MainActivity.DRAWER_ITEM_TIMETABLE,
|
MainActivity.DRAWER_ITEM_TIMETABLE,
|
||||||
MainActivity.DRAWER_ITEM_AGENDA,
|
MainActivity.DRAWER_ITEM_AGENDA,
|
||||||
@ -39,46 +39,36 @@ class ConfigMigration(app: App, config: Config) {
|
|||||||
MainActivity.DRAWER_ITEM_HOMEWORK,
|
MainActivity.DRAWER_ITEM_HOMEWORK,
|
||||||
MainActivity.DRAWER_ITEM_SETTINGS
|
MainActivity.DRAWER_ITEM_SETTINGS
|
||||||
)
|
)
|
||||||
dataVersion = 1
|
sync.enabled = true
|
||||||
}
|
sync.interval = 1*HOUR.toInt()
|
||||||
if (dataVersion < 2) {
|
sync.notifyAboutUpdates = true
|
||||||
devModePassword = p.getString("$s.devModePassword", null).fix()
|
sync.onlyWifi = false
|
||||||
sync.tokenApp = p.getString("$s.fcmToken", null).fix()
|
sync.quietHoursStart = 0
|
||||||
timetable.bellSyncMultiplier = p.getString("$s.bellSyncMultiplier", null)?.toIntOrNull() ?: 0
|
sync.quietHoursEnd = 0
|
||||||
sync.quietHoursStart = p.getString("$s.quietHoursStart", null)?.toLongOrNull() ?: 0
|
sync.quietDuringLessons = false
|
||||||
appRateSnackbarTime = p.getString("$s.appRateSnackbarTime", null)?.toLongOrNull() ?: 0
|
sync.tokenApp = null
|
||||||
sync.quietHoursEnd = p.getString("$s.quietHoursEnd", null)?.toLongOrNull() ?: 0
|
sync.tokenMobidziennik = null
|
||||||
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()
|
|
||||||
ui.language = p.getString("$s.language", null).fix()
|
|
||||||
appVersion = p.getString("$s.lastAppVersion", null)?.toIntOrNull() ?: BuildConfig.VERSION_CODE
|
|
||||||
appInstalledTime = p.getString("$s.appInstalledTime", null)?.toLongOrNull() ?: 0
|
|
||||||
grades.orderBy = p.getString("$s.gradesOrderBy", null)?.toIntOrNull() ?: 0
|
|
||||||
sync.quietDuringLessons = p.getString("$s.quietDuringLessons", null)?.toBoolean() ?: false
|
|
||||||
ui.miniMenuVisible = p.getString("$s.miniDrawerVisible", null)?.toBoolean() ?: false
|
|
||||||
loginFinished = p.getString("$s.loginFinished", null)?.toBoolean() ?: false
|
|
||||||
sync.onlyWifi = p.getString("$s.registerSyncOnlyWifi", null)?.toBoolean() ?: false
|
|
||||||
sync.notifyAboutUpdates = p.getString("$s.notifyAboutUpdates", null)?.toBoolean() ?: true
|
|
||||||
timetable.bellSyncDiff = p.getString("$s.bellSyncDiff", null)?.let { Gson().fromJson(it, Time::class.java) }
|
|
||||||
|
|
||||||
sync.tokenMobidziennikList = listOf()
|
sync.tokenMobidziennikList = listOf()
|
||||||
sync.tokenVulcanList = listOf()
|
sync.tokenLibrus = null
|
||||||
sync.tokenLibrusList = listOf()
|
sync.tokenLibrusList = listOf()
|
||||||
val tokens = p.getString("$s.fcmTokens", null)?.let { Gson().fromJson<Map<Int, Pair<String, List<Int>>>>(it, object: TypeToken<Map<Int, Pair<String, List<Int>>>>(){}.type) }
|
sync.tokenVulcan = null
|
||||||
tokens?.forEach {
|
sync.tokenVulcanList = listOf()
|
||||||
val token = it.value.first
|
timetable.bellSyncMultiplier = 0
|
||||||
when (it.key) {
|
timetable.bellSyncDiff = null
|
||||||
LOGIN_TYPE_MOBIDZIENNIK -> sync.tokenMobidziennik = token
|
timetable.countInSeconds = false
|
||||||
LOGIN_TYPE_VULCAN -> sync.tokenVulcan = token
|
grades.orderBy = ORDER_BY_DATE_DESC
|
||||||
LOGIN_TYPE_LIBRUS -> sync.tokenLibrus = token
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dataVersion = 2
|
dataVersion = 2
|
||||||
}
|
}
|
||||||
}}
|
|
||||||
|
|
||||||
private fun String?.fix(): String? {
|
if (dataVersion < 10) {
|
||||||
return this?.replace("\"", "")?.let { if (it == "null") null else it }
|
ui.openDrawerOnBackPressed = false
|
||||||
|
ui.homeCards = listOf()
|
||||||
|
ui.snowfall = false
|
||||||
|
ui.bottomSheetOpened = false
|
||||||
|
sync.dontShowAppManagerDialog = false
|
||||||
|
|
||||||
|
dataVersion = 10
|
||||||
}
|
}
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
@ -4,23 +4,21 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.config.utils
|
package pl.szczodrzynski.edziennik.config.utils
|
||||||
|
|
||||||
import android.content.Context
|
import pl.szczodrzynski.edziennik.config.ProfileConfig
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.AGENDA_DEFAULT
|
||||||
import pl.szczodrzynski.edziennik.config.Config
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.COLOR_MODE_WEIGHTED
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.YEAR_ALL_GRADES
|
||||||
|
|
||||||
class ProfileConfigMigration(app: App, config: Config) {
|
class ProfileConfigMigration(config: ProfileConfig) {
|
||||||
init { config.apply {
|
init { config.apply {
|
||||||
val p = app.getSharedPreferences("pl.szczodrzynski.edziennik_profiles", Context.MODE_PRIVATE)
|
|
||||||
val s = "app.appConfig"
|
|
||||||
|
|
||||||
if (dataVersion < 1) {
|
if (dataVersion < 1) {
|
||||||
|
grades.colorMode = COLOR_MODE_WEIGHTED
|
||||||
|
grades.countZeroToAvg = true
|
||||||
|
grades.yearAverageMode = YEAR_ALL_GRADES
|
||||||
|
ui.agendaViewType = AGENDA_DEFAULT
|
||||||
|
|
||||||
//dataVersion = 1
|
dataVersion = 1
|
||||||
}
|
|
||||||
if (dataVersion < 2) {
|
|
||||||
//gradesColorMode do profilu !
|
|
||||||
//agendaViewType do profilu !
|
|
||||||
// app.appConfig.dontCountZeroToAverage do profilu !
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
}
|
}
|
@ -12,12 +12,15 @@ import org.greenrobot.eventbus.EventBus
|
|||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.*
|
import pl.szczodrzynski.edziennik.data.api.events.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.requests.ServiceCloseRequest
|
import pl.szczodrzynski.edziennik.data.api.events.requests.ServiceCloseRequest
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.requests.TaskCancelRequest
|
import pl.szczodrzynski.edziennik.data.api.events.requests.TaskCancelRequest
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.*
|
import pl.szczodrzynski.edziennik.data.api.task.ErrorReportTask
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.task.SzkolnyTask
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
@ -40,11 +43,8 @@ class ApiService : Service() {
|
|||||||
|
|
||||||
private val syncingProfiles = mutableListOf<Profile>()
|
private val syncingProfiles = mutableListOf<Profile>()
|
||||||
|
|
||||||
private val finishingTaskQueue = mutableListOf(
|
private var szkolnyTaskFinished = false
|
||||||
SzkolnyTask.sync(syncingProfiles),
|
private val allTaskRequestList = mutableListOf<Any>()
|
||||||
NotifyTask()
|
|
||||||
)
|
|
||||||
private val allTaskList = mutableListOf<IApiTask>()
|
|
||||||
private val taskQueue = mutableListOf<IApiTask>()
|
private val taskQueue = mutableListOf<IApiTask>()
|
||||||
private val errorList = mutableListOf<ApiError>()
|
private val errorList = mutableListOf<ApiError>()
|
||||||
|
|
||||||
@ -132,14 +132,20 @@ class ApiService : Service() {
|
|||||||
checkIfTaskFrozen()
|
checkIfTaskFrozen()
|
||||||
if (taskIsRunning)
|
if (taskIsRunning)
|
||||||
return
|
return
|
||||||
if (taskCancelled || serviceClosed || (taskQueue.isEmpty() && finishingTaskQueue.isEmpty())) {
|
if (taskCancelled || serviceClosed || (taskQueue.isEmpty() && szkolnyTaskFinished)) {
|
||||||
allCompleted()
|
allCompleted()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lastEventTime = System.currentTimeMillis()
|
lastEventTime = System.currentTimeMillis()
|
||||||
|
|
||||||
val task = if (taskQueue.isEmpty()) finishingTaskQueue.removeAt(0) else taskQueue.removeAt(0)
|
val task = if (taskQueue.isNotEmpty()) {
|
||||||
|
taskQueue.removeAt(0)
|
||||||
|
} else {
|
||||||
|
szkolnyTaskFinished = true
|
||||||
|
SzkolnyTask(app, syncingProfiles)
|
||||||
|
}
|
||||||
|
|
||||||
task.taskId = ++taskMaximumId
|
task.taskId = ++taskMaximumId
|
||||||
task.prepare(app)
|
task.prepare(app)
|
||||||
taskIsRunning = true
|
taskIsRunning = true
|
||||||
@ -162,9 +168,8 @@ class ApiService : Service() {
|
|||||||
try {
|
try {
|
||||||
when (task) {
|
when (task) {
|
||||||
is EdziennikTask -> task.run(app, taskCallback)
|
is EdziennikTask -> task.run(app, taskCallback)
|
||||||
is NotifyTask -> task.run(app, taskCallback)
|
|
||||||
is ErrorReportTask -> task.run(app, taskCallback, notification, errorList)
|
is ErrorReportTask -> task.run(app, taskCallback, notification, errorList)
|
||||||
is SzkolnyTask -> task.run(app, taskCallback)
|
is SzkolnyTask -> task.run(taskCallback)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
taskCallback.onError(ApiError(TAG, EXCEPTION_API_TASK).withThrowable(e))
|
taskCallback.onError(ApiError(TAG, EXCEPTION_API_TASK).withThrowable(e))
|
||||||
@ -230,10 +235,12 @@ class ApiService : Service() {
|
|||||||
EventBus.getDefault().removeStickyEvent(task)
|
EventBus.getDefault().removeStickyEvent(task)
|
||||||
d(TAG, task.toString())
|
d(TAG, task.toString())
|
||||||
|
|
||||||
|
if (task is EdziennikTask) {
|
||||||
// fix for duplicated tasks, thank you EventBus
|
// fix for duplicated tasks, thank you EventBus
|
||||||
if (task in allTaskList)
|
if (task.request in allTaskRequestList)
|
||||||
return
|
return
|
||||||
allTaskList += task
|
allTaskRequestList += task.request
|
||||||
|
}
|
||||||
|
|
||||||
if (task is EdziennikTask) {
|
if (task is EdziennikTask) {
|
||||||
when (task.request) {
|
when (task.request) {
|
||||||
|
@ -1,206 +0,0 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_AGENDA
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_ANNOUNCEMENTS
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_ATTENDANCE
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_BEHAVIOUR
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_GRADES
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOME
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOMEWORK
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.Data
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_LUCKY_NUMBER
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_ANNOUNCEMENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_ATTENDANCE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_EVENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_GRADE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_HOMEWORK
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_MESSAGE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_NOTICE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_TIMETABLE_LESSON_CHANGE
|
|
||||||
import pl.szczodrzynski.edziennik.getNotificationTitle
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class DataNotifications(val data: Data) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "DataNotifications"
|
|
||||||
}
|
|
||||||
|
|
||||||
val app = data.app
|
|
||||||
val profileId = data.profile?.id ?: -1
|
|
||||||
val profileName = data.profile?.name ?: ""
|
|
||||||
val profile = data.profile
|
|
||||||
val loginStore = data.loginStore
|
|
||||||
|
|
||||||
init { run {
|
|
||||||
if (profile == null) {
|
|
||||||
return@run
|
|
||||||
}
|
|
||||||
|
|
||||||
val today = Date.getToday()
|
|
||||||
val todayValue = today.value
|
|
||||||
|
|
||||||
for (lesson in app.db.timetableDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val text = app.getString(R.string.notification_lesson_change_format, lesson.getDisplayChangeType(app), if (lesson.displayDate == null) "" else lesson.displayDate!!.formattedString, lesson.changeSubjectName)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_TIMETABLE_LESSON_CHANGE),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_TIMETABLE_LESSON_CHANGE,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_TIMETABLE,
|
|
||||||
addedDate = lesson.addedDate
|
|
||||||
).addExtra("timetableDate", lesson.displayDate?.stringY_m_d ?: "")
|
|
||||||
}
|
|
||||||
|
|
||||||
for (event in app.db.eventDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val text = if (event.type == Event.TYPE_HOMEWORK)
|
|
||||||
app.getString(
|
|
||||||
if (event.subjectLongName.isNullOrEmpty())
|
|
||||||
R.string.notification_homework_no_subject_format
|
|
||||||
else
|
|
||||||
R.string.notification_homework_format,
|
|
||||||
event.subjectLongName,
|
|
||||||
event.eventDate.formattedString
|
|
||||||
)
|
|
||||||
else
|
|
||||||
app.getString(
|
|
||||||
if (event.subjectLongName.isNullOrEmpty())
|
|
||||||
R.string.notification_event_no_subject_format
|
|
||||||
else
|
|
||||||
R.string.notification_event_format,
|
|
||||||
event.typeName,
|
|
||||||
event.eventDate.formattedString,
|
|
||||||
event.subjectLongName
|
|
||||||
)
|
|
||||||
val type = if (event.type == Event.TYPE_HOMEWORK) TYPE_NEW_HOMEWORK else TYPE_NEW_EVENT
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(type),
|
|
||||||
text = text,
|
|
||||||
type = type,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = if (event.type == Event.TYPE_HOMEWORK) DRAWER_ITEM_HOMEWORK else DRAWER_ITEM_AGENDA,
|
|
||||||
addedDate = event.addedDate
|
|
||||||
).addExtra("eventId", event.id).addExtra("eventDate", event.eventDate.value.toLong())
|
|
||||||
}
|
|
||||||
|
|
||||||
for (grade in app.db.gradeDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val gradeName = when (grade.type) {
|
|
||||||
TYPE_SEMESTER1_PROPOSED, TYPE_SEMESTER2_PROPOSED -> app.getString(R.string.grade_semester_proposed_format_2, grade.name)
|
|
||||||
TYPE_SEMESTER1_FINAL, TYPE_SEMESTER2_FINAL -> app.getString(R.string.grade_semester_final_format_2, grade.name)
|
|
||||||
TYPE_YEAR_PROPOSED -> app.getString(R.string.grade_year_proposed_format_2, grade.name)
|
|
||||||
TYPE_YEAR_FINAL -> app.getString(R.string.grade_year_final_format_2, grade.name)
|
|
||||||
else -> grade.name
|
|
||||||
}
|
|
||||||
val text = app.getString(R.string.notification_grade_format, gradeName, grade.subjectLongName)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_NEW_GRADE),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_NEW_GRADE,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_GRADES,
|
|
||||||
addedDate = grade.addedDate
|
|
||||||
).addExtra("gradeId", grade.id).addExtra("gradesSubjectId", grade.subjectId)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (notice in app.db.noticeDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val noticeTypeStr = if (notice.type == Notice.TYPE_POSITIVE) app.getString(R.string.notification_notice_praise) else if (notice.type == Notice.TYPE_NEGATIVE) app.getString(R.string.notification_notice_warning) else app.getString(R.string.notification_notice_new)
|
|
||||||
val text = app.getString(R.string.notification_notice_format, noticeTypeStr, notice.teacherFullName, Date.fromMillis(notice.addedDate).formattedString)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_NEW_NOTICE),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_NEW_NOTICE,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_BEHAVIOUR,
|
|
||||||
addedDate = notice.addedDate
|
|
||||||
).addExtra("noticeId", notice.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (attendance in app.db.attendanceDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val attendanceTypeStr = when (attendance.type) {
|
|
||||||
Attendance.TYPE_ABSENT -> app.getString(R.string.notification_absence)
|
|
||||||
Attendance.TYPE_ABSENT_EXCUSED -> app.getString(R.string.notification_absence_excused)
|
|
||||||
Attendance.TYPE_BELATED -> app.getString(R.string.notification_belated)
|
|
||||||
Attendance.TYPE_BELATED_EXCUSED -> app.getString(R.string.notification_belated_excused)
|
|
||||||
Attendance.TYPE_RELEASED -> app.getString(R.string.notification_release)
|
|
||||||
Attendance.TYPE_DAY_FREE -> app.getString(R.string.notification_day_free)
|
|
||||||
else -> app.getString(R.string.notification_type_attendance)
|
|
||||||
}
|
|
||||||
val text = app.getString(
|
|
||||||
if (attendance.subjectLongName.isNullOrEmpty())
|
|
||||||
R.string.notification_attendance_no_lesson_format
|
|
||||||
else
|
|
||||||
R.string.notification_attendance_format,
|
|
||||||
attendanceTypeStr,
|
|
||||||
attendance.subjectLongName,
|
|
||||||
attendance.lessonDate.formattedString
|
|
||||||
)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_NEW_ATTENDANCE),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_NEW_ATTENDANCE,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_ATTENDANCE,
|
|
||||||
addedDate = attendance.addedDate
|
|
||||||
).addExtra("attendanceId", attendance.id).addExtra("attendanceSubjectId", attendance.subjectId)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (announcement in app.db.announcementDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val text = app.context.getString(R.string.notification_announcement_format, announcement.subject)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_NEW_ANNOUNCEMENT),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_NEW_ANNOUNCEMENT,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_ANNOUNCEMENTS,
|
|
||||||
addedDate = announcement.addedDate
|
|
||||||
).addExtra("announcementId", announcement.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (message in app.db.messageDao().getReceivedNotNotifiedNow(profileId)) {
|
|
||||||
val text = app.context.getString(R.string.notification_message_format, message.senderFullName, message.subject)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_NEW_MESSAGE),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_NEW_MESSAGE,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_MESSAGES,
|
|
||||||
addedDate = message.addedDate
|
|
||||||
).addExtra("messageType", Message.TYPE_RECEIVED.toLong()).addExtra("messageId", message.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
val luckyNumbers = app.db.luckyNumberDao().getNotNotifiedNow(profileId)
|
|
||||||
luckyNumbers?.removeAll { it.date < today }
|
|
||||||
luckyNumbers?.forEach { luckyNumber ->
|
|
||||||
val text = when (luckyNumber.date.value) {
|
|
||||||
todayValue -> // LN for today
|
|
||||||
app.getString(if (profile.studentNumber != -1 && profile.studentNumber == luckyNumber.number) R.string.notification_lucky_number_yours_format else R.string.notification_lucky_number_format, luckyNumber.number)
|
|
||||||
todayValue + 1 -> // LN for tomorrow
|
|
||||||
app.getString(if (profile.studentNumber != -1 && profile.studentNumber == luckyNumber.number) R.string.notification_lucky_number_yours_tomorrow_format else R.string.notification_lucky_number_tomorrow_format, luckyNumber.number)
|
|
||||||
else -> // LN for later
|
|
||||||
app.getString(if (profile.studentNumber != -1 && profile.studentNumber == luckyNumber.number) R.string.notification_lucky_number_yours_later_format else R.string.notification_lucky_number_later_format, luckyNumber.date.formattedString, luckyNumber.number)
|
|
||||||
}
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_LUCKY_NUMBER),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_LUCKY_NUMBER,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_HOME,
|
|
||||||
addedDate = luckyNumber.addedDate
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
data.db.metadataDao().setAllNotified(profileId, true)
|
|
||||||
}}
|
|
||||||
}
|
|
@ -1,4 +1,8 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api.task
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
@ -12,11 +16,12 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.template.Template
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.Vulcan
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.Vulcan
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
|
|
||||||
open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) {
|
open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) {
|
||||||
companion object {
|
companion object {
|
@ -15,12 +15,12 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.Edudzienn
|
|||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
||||||
@ -41,10 +41,8 @@ class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStor
|
|||||||
|
|
||||||
private fun completed() {
|
private fun completed() {
|
||||||
data.saveData()
|
data.saveData()
|
||||||
data.notify {
|
|
||||||
callback.onCompleted()
|
callback.onCompleted()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* _______ _ _ _ _ _
|
/* _______ _ _ _ _ _
|
||||||
|__ __| | /\ | | (_) | | |
|
|__ __| | /\ | | (_) | | |
|
||||||
|
@ -13,9 +13,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_EXAMS
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_EXAMS
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ class EdudziennikWebExams(override val data: DataEdudziennik,
|
|||||||
startTime,
|
startTime,
|
||||||
topic,
|
topic,
|
||||||
-1,
|
-1,
|
||||||
eventType.id.toInt(),
|
eventType.id,
|
||||||
false,
|
false,
|
||||||
-1,
|
-1,
|
||||||
subject.id,
|
subject.id,
|
||||||
|
@ -17,12 +17,12 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login.IdziennikLo
|
|||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
||||||
@ -43,10 +43,8 @@ class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
|||||||
|
|
||||||
private fun completed() {
|
private fun completed() {
|
||||||
data.saveData()
|
data.saveData()
|
||||||
data.notify {
|
|
||||||
callback.onCompleted()
|
callback.onCompleted()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* _______ _ _ _ _ _
|
/* _______ _ _ _ _ _
|
||||||
|__ __| | /\ | | (_) | | |
|
|__ __| | /\ | | (_) | | |
|
||||||
|
@ -19,12 +19,12 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLogin
|
|||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
||||||
@ -45,10 +45,8 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
|
|
||||||
private fun completed() {
|
private fun completed() {
|
||||||
data.saveData()
|
data.saveData()
|
||||||
data.notify {
|
|
||||||
callback.onCompleted()
|
callback.onCompleted()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* _______ _ _ _ _ _
|
/* _______ _ _ _ _ _
|
||||||
|__ __| | /\ | | (_) | | |
|
|__ __| | /\ | | (_) | | |
|
||||||
|
@ -10,9 +10,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_EVENTS
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_EVENTS
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ class LibrusApiEvents(override val data: DataLibrus,
|
|||||||
val id = event.getLong("Id") ?: return@forEach
|
val id = event.getLong("Id") ?: return@forEach
|
||||||
val eventDate = Date.fromY_m_d(event.getString("Date"))
|
val eventDate = Date.fromY_m_d(event.getString("Date"))
|
||||||
val topic = event.getString("Content") ?: ""
|
val topic = event.getString("Content") ?: ""
|
||||||
val type = event.getJsonObject("Category")?.getInt("Id") ?: -1
|
val type = event.getJsonObject("Category")?.getLong("Id") ?: -1
|
||||||
val teacherId = event.getJsonObject("CreatedBy")?.getLong("Id") ?: -1
|
val teacherId = event.getJsonObject("CreatedBy")?.getLong("Id") ?: -1
|
||||||
val subjectId = event.getJsonObject("Subject")?.getLong("Id") ?: -1
|
val subjectId = event.getJsonObject("Subject")?.getLong("Id") ?: -1
|
||||||
val teamId = event.getJsonObject("Class")?.getLong("Id") ?: -1
|
val teamId = event.getJsonObject("Class")?.getLong("Id") ?: -1
|
||||||
|
@ -17,12 +17,12 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.login.Mobidzie
|
|||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
||||||
@ -45,10 +45,8 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
|
|||||||
|
|
||||||
private fun completed() {
|
private fun completed() {
|
||||||
data.saveData()
|
data.saveData()
|
||||||
data.notify {
|
|
||||||
callback.onCompleted()
|
callback.onCompleted()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* _______ _ _ _ _ _
|
/* _______ _ _ _ _ _
|
||||||
|__ __| | /\ | | (_) | | |
|
|__ __| | /\ | | (_) | | |
|
||||||
|
@ -15,12 +15,12 @@ import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
|||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.prepare
|
import pl.szczodrzynski.edziennik.data.api.prepare
|
||||||
import pl.szczodrzynski.edziennik.data.api.templateLoginMethods
|
import pl.szczodrzynski.edziennik.data.api.templateLoginMethods
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
class Template(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
class Template(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
||||||
@ -40,10 +40,8 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
|||||||
|
|
||||||
private fun completed() {
|
private fun completed() {
|
||||||
data.saveData()
|
data.saveData()
|
||||||
data.notify {
|
|
||||||
callback.onCompleted()
|
callback.onCompleted()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* _______ _ _ _ _ _
|
/* _______ _ _ _ _ _
|
||||||
|__ __| | /\ | | (_) | | |
|
|__ __| | /\ | | (_) | | |
|
||||||
|
@ -18,12 +18,12 @@ import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|||||||
import pl.szczodrzynski.edziennik.data.api.prepare
|
import pl.szczodrzynski.edziennik.data.api.prepare
|
||||||
import pl.szczodrzynski.edziennik.data.api.prepareFor
|
import pl.szczodrzynski.edziennik.data.api.prepareFor
|
||||||
import pl.szczodrzynski.edziennik.data.api.vulcanLoginMethods
|
import pl.szczodrzynski.edziennik.data.api.vulcanLoginMethods
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
||||||
@ -44,10 +44,8 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
|
|
||||||
private fun completed() {
|
private fun completed() {
|
||||||
data.saveData()
|
data.saveData()
|
||||||
data.notify {
|
|
||||||
callback.onCompleted()
|
callback.onCompleted()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* _______ _ _ _ _ _
|
/* _______ _ _ _ _ _
|
||||||
|__ __| | /\ | | (_) | | |
|
|__ __| | /\ | | (_) | | |
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.events
|
||||||
|
|
||||||
|
class ProfileListEmptyEvent
|
@ -194,7 +194,6 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
|
|||||||
if (profile == null)
|
if (profile == null)
|
||||||
return // return on first login
|
return // return on first login
|
||||||
|
|
||||||
profile.empty = false
|
|
||||||
profile.userCode = generateUserCode()
|
profile.userCode = generateUserCode()
|
||||||
|
|
||||||
db.profileDao().add(profile)
|
db.profileDao().add(profile)
|
||||||
@ -294,21 +293,6 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
|
|||||||
db.messageRecipientDao().addAllIgnore(messageRecipientIgnoreList)
|
db.messageRecipientDao().addAllIgnore(messageRecipientIgnoreList)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun notify(onSuccess: () -> Unit) {
|
|
||||||
if (profile == null) {
|
|
||||||
onSuccess()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
DataNotifications(this)
|
|
||||||
db.notificationDao().addAll(notifications)
|
|
||||||
onSuccess()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
error(ApiError(TAG, EXCEPTION_NOTIFY)
|
|
||||||
.withThrowable(e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setSyncNext(endpointId: Int, syncIn: Long? = null, viewId: Int? = null, syncAt: Long? = null) {
|
fun setSyncNext(endpointId: Int, syncIn: Long? = null, viewId: Int? = null, syncAt: Long? = null) {
|
||||||
EndpointTimer(profile?.id
|
EndpointTimer(profile?.id
|
||||||
?: -1, endpointId).apply {
|
?: -1, endpointId).apply {
|
||||||
|
@ -47,11 +47,11 @@ open class DataRemoveModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Events(private val type: Int?, private val exceptType: Int?, private val exceptTypes: List<Int>?) : DataRemoveModel() {
|
class Events(private val type: Long?, private val exceptType: Long?, private val exceptTypes: List<Long>?) : DataRemoveModel() {
|
||||||
companion object {
|
companion object {
|
||||||
fun futureExceptType(exceptType: Int) = Events(null, exceptType, null)
|
fun futureExceptType(exceptType: Long) = Events(null, exceptType, null)
|
||||||
fun futureExceptTypes(exceptTypes: List<Int>) = Events(null, null, exceptTypes)
|
fun futureExceptTypes(exceptTypes: List<Long>) = Events(null, null, exceptTypes)
|
||||||
fun futureWithType(type: Int) = Events(type, null, null)
|
fun futureWithType(type: Long) = Events(type, null, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun commit(profileId: Int, dao: EventDao) {
|
fun commit(profileId: Int, dao: EventDao) {
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-13
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.szkolny
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
|
|
||||||
class Szkolny(val app: App, val callback: EdziennikCallback) {
|
|
||||||
|
|
||||||
private val api = SzkolnyApi(app)
|
|
||||||
|
|
||||||
fun sync(profileList: List<Profile>) {
|
|
||||||
val profiles = profileList.filter { it.registration == Profile.REGISTRATION_ENABLED }
|
|
||||||
if (profiles.isNotEmpty()) {
|
|
||||||
val events = api.getEvents(profiles)
|
|
||||||
|
|
||||||
if (events.isNotEmpty()) {
|
|
||||||
app.db.eventDao().addAll(events)
|
|
||||||
app.db.metadataDao().addAllIgnore(events.map { event ->
|
|
||||||
Metadata(
|
|
||||||
event.profileId,
|
|
||||||
Metadata.TYPE_EVENT,
|
|
||||||
event.id,
|
|
||||||
event.seen,
|
|
||||||
event.notified,
|
|
||||||
event.addedDate
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
completed()
|
|
||||||
}
|
|
||||||
|
|
||||||
/*fun shareEvent(event: EventFull) {
|
|
||||||
api.shareEvent(event)
|
|
||||||
completed()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun unshareEvent(event: EventFull) {
|
|
||||||
api.unshareEvent(event)
|
|
||||||
completed()
|
|
||||||
}*/
|
|
||||||
|
|
||||||
private fun completed() {
|
|
||||||
callback.onCompleted()
|
|
||||||
}
|
|
||||||
}
|
|
@ -12,15 +12,14 @@ import pl.szczodrzynski.edziennik.BuildConfig
|
|||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.adapter.DateAdapter
|
import pl.szczodrzynski.edziennik.data.api.szkolny.adapter.DateAdapter
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.adapter.TimeAdapter
|
import pl.szczodrzynski.edziennik.data.api.szkolny.adapter.TimeAdapter
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.SignatureInterceptor
|
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.SignatureInterceptor
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.request.ErrorReportRequest
|
import pl.szczodrzynski.edziennik.data.api.szkolny.request.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.request.EventShareRequest
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.request.ServerSyncRequest
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.request.WebPushRequest
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.ApiResponse
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.ApiResponse
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.WebPushResponse
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.WebPushResponse
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
import pl.szczodrzynski.edziennik.md5
|
import pl.szczodrzynski.edziennik.md5
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
@ -56,9 +55,8 @@ class SzkolnyApi(val app: App) {
|
|||||||
api = retrofit.create()
|
api = retrofit.create()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getEvents(profiles: List<Profile>): List<EventFull> {
|
fun getEvents(profiles: List<Profile>, notifications: List<Notification>, blacklistedIds: List<Long>): List<EventFull> {
|
||||||
val teams = app.db.teamDao().allNow
|
val teams = app.db.teamDao().allNow
|
||||||
val notifications = app.db.notificationDao().getNotPostedNow()
|
|
||||||
|
|
||||||
val response = api.serverSync(ServerSyncRequest(
|
val response = api.serverSync(ServerSyncRequest(
|
||||||
deviceId = app.deviceId,
|
deviceId = app.deviceId,
|
||||||
@ -88,8 +86,8 @@ class SzkolnyApi(val app: App) {
|
|||||||
val config = app.config.getFor(profile.id)
|
val config = app.config.getFor(profile.id)
|
||||||
val user = ServerSyncRequest.User(
|
val user = ServerSyncRequest.User(
|
||||||
profile.userCode,
|
profile.userCode,
|
||||||
profile.studentNameLong ?: "",
|
profile.studentNameLong,
|
||||||
profile.studentNameShort ?: "",
|
profile.studentNameShort,
|
||||||
profile.loginStoreType,
|
profile.loginStoreType,
|
||||||
teams.filter { it.profileId == profile.id }.map { it.code }
|
teams.filter { it.profileId == profile.id }.map { it.code }
|
||||||
)
|
)
|
||||||
@ -108,17 +106,19 @@ class SzkolnyApi(val app: App) {
|
|||||||
val events = mutableListOf<EventFull>()
|
val events = mutableListOf<EventFull>()
|
||||||
|
|
||||||
response?.data?.events?.forEach { event ->
|
response?.data?.events?.forEach { event ->
|
||||||
teams.filter { it.code == event.teamCode }.forEach { team ->
|
if (event.id in blacklistedIds)
|
||||||
val profile = profiles.firstOrNull { it.id == team.profileId }
|
return@forEach
|
||||||
|
teams.filter { it.code == event.teamCode }.onEach { team ->
|
||||||
|
val profile = profiles.firstOrNull { it.id == team.profileId } ?: return@onEach
|
||||||
|
|
||||||
events.add(event.apply {
|
events.add(EventFull(event).apply {
|
||||||
profileId = team.profileId
|
profileId = team.profileId
|
||||||
teamId = team.id
|
teamId = team.id
|
||||||
addedManually = true
|
addedManually = true
|
||||||
seen = profile?.empty ?: false
|
seen = profile.empty
|
||||||
notified = profile?.empty ?: false
|
notified = profile.empty
|
||||||
|
|
||||||
if (profile?.userCode == event.sharedBy) sharedBy = "self"
|
if (profile.userCode == event.sharedBy) sharedBy = "self"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,4 +193,15 @@ class SzkolnyApi(val app: App) {
|
|||||||
errors = errors
|
errors = errors
|
||||||
)).execute().body()
|
)).execute().body()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun unregisterAppUser(userCode: String): ApiResponse<Nothing>? {
|
||||||
|
return api.appUser(AppUserRequest(
|
||||||
|
deviceId = app.deviceId,
|
||||||
|
userCode = userCode
|
||||||
|
)).execute().body()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getUpdate(): ApiResponse<List<Update>>? {
|
||||||
|
return api.updates().execute().body()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,16 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.szkolny
|
package pl.szczodrzynski.edziennik.data.api.szkolny
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.request.ErrorReportRequest
|
import pl.szczodrzynski.edziennik.data.api.szkolny.request.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.request.EventShareRequest
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.request.ServerSyncRequest
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.request.WebPushRequest
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.ApiResponse
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.ApiResponse
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.ServerSyncResponse
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.ServerSyncResponse
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.WebPushResponse
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.WebPushResponse
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.http.Body
|
import retrofit2.http.Body
|
||||||
|
import retrofit2.http.GET
|
||||||
import retrofit2.http.POST
|
import retrofit2.http.POST
|
||||||
|
import retrofit2.http.Query
|
||||||
|
|
||||||
interface SzkolnyService {
|
interface SzkolnyService {
|
||||||
|
|
||||||
@ -28,4 +28,10 @@ interface SzkolnyService {
|
|||||||
|
|
||||||
@POST("errorReport")
|
@POST("errorReport")
|
||||||
fun errorReport(@Body request: ErrorReportRequest): Call<ApiResponse<Nothing>>
|
fun errorReport(@Body request: ErrorReportRequest): Call<ApiResponse<Nothing>>
|
||||||
|
|
||||||
|
@POST("appUser")
|
||||||
|
fun appUser(@Body request: AppUserRequest): Call<ApiResponse<Nothing>>
|
||||||
|
|
||||||
|
@GET("updates/app")
|
||||||
|
fun updates(@Query("channel") channel: String = "release"): Call<ApiResponse<List<Update>>>
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.szkolny.request
|
||||||
|
|
||||||
|
data class AppUserRequest(
|
||||||
|
val action: String = "unregister",
|
||||||
|
|
||||||
|
val deviceId: String,
|
||||||
|
val userCode: String
|
||||||
|
)
|
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.szkolny.response
|
||||||
|
|
||||||
|
data class Update(
|
||||||
|
val versionCode: Int,
|
||||||
|
val versionName: String,
|
||||||
|
val releaseDate: String,
|
||||||
|
val releaseNotes: String?,
|
||||||
|
val releaseType: String,
|
||||||
|
val isOnGooglePlay: Boolean,
|
||||||
|
val downloadUrl: String?
|
||||||
|
)
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.task
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
|
|
||||||
|
class AppSync(val app: App, val notifications: MutableList<Notification>, val profiles: List<Profile>, val api: SzkolnyApi) {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "AppSync"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the app sync, sending all pending notifications
|
||||||
|
* and retrieving a list of shared events.
|
||||||
|
*
|
||||||
|
* Events are automatically saved to app database,
|
||||||
|
* along with corresponding metadata objects.
|
||||||
|
*
|
||||||
|
* @return a number of events inserted to DB, possibly needing a notification
|
||||||
|
*/
|
||||||
|
fun run(): Int {
|
||||||
|
val profiles = profiles.filter { it.registration == Profile.REGISTRATION_ENABLED && !it.archived }
|
||||||
|
if (profiles.isNotEmpty()) {
|
||||||
|
val blacklistedIds = app.db.eventDao().blacklistedIds;
|
||||||
|
val events = api.getEvents(profiles, notifications, blacklistedIds)
|
||||||
|
|
||||||
|
if (events.isNotEmpty()) {
|
||||||
|
app.db.metadataDao().addAllIgnore(events.map { event ->
|
||||||
|
Metadata(
|
||||||
|
event.profileId,
|
||||||
|
Metadata.TYPE_EVENT,
|
||||||
|
event.id,
|
||||||
|
event.seen,
|
||||||
|
event.notified,
|
||||||
|
event.addedDate
|
||||||
|
)
|
||||||
|
})
|
||||||
|
return app.db.eventDao().addAll(events).size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,277 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.task
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.*
|
||||||
|
import pl.szczodrzynski.edziennik.getNotificationTitle
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
|
class Notifications(val app: App, val notifications: MutableList<Notification>, val profiles: List<Profile>) {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "Notifications"
|
||||||
|
}
|
||||||
|
|
||||||
|
private val today by lazy { Date.getToday() }
|
||||||
|
private val todayValue by lazy { today.value }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a [Notification] from every possible
|
||||||
|
* data type. Notifications are posted whenever
|
||||||
|
* the object's metadata `notified` property is
|
||||||
|
* set to false.
|
||||||
|
*/
|
||||||
|
fun run() {
|
||||||
|
timetableNotifications()
|
||||||
|
eventNotifications()
|
||||||
|
gradeNotifications()
|
||||||
|
behaviourNotifications()
|
||||||
|
attendanceNotifications()
|
||||||
|
announcementNotifications()
|
||||||
|
messageNotifications()
|
||||||
|
luckyNumberNotifications()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun timetableNotifications() {
|
||||||
|
for (lesson in app.db.timetableDao().getNotNotifiedNow()) {
|
||||||
|
val text = app.getString(
|
||||||
|
R.string.notification_lesson_change_format,
|
||||||
|
lesson.getDisplayChangeType(app),
|
||||||
|
if (lesson.displayDate == null) "" else lesson.displayDate!!.formattedString,
|
||||||
|
lesson.changeSubjectName
|
||||||
|
)
|
||||||
|
notifications += Notification(
|
||||||
|
id = Notification.buildId(lesson.profileId, Notification.TYPE_TIMETABLE_LESSON_CHANGE, lesson.id),
|
||||||
|
title = app.getNotificationTitle(Notification.TYPE_TIMETABLE_LESSON_CHANGE),
|
||||||
|
text = text,
|
||||||
|
type = Notification.TYPE_TIMETABLE_LESSON_CHANGE,
|
||||||
|
profileId = lesson.profileId,
|
||||||
|
profileName = profiles.singleOrNull { it.id == lesson.profileId }?.name,
|
||||||
|
viewId = MainActivity.DRAWER_ITEM_TIMETABLE,
|
||||||
|
addedDate = lesson.addedDate
|
||||||
|
).addExtra("timetableDate", lesson.displayDate?.stringY_m_d ?: "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun eventNotifications() {
|
||||||
|
for (event in app.db.eventDao().notNotifiedNow) {
|
||||||
|
val text = if (event.type == Event.TYPE_HOMEWORK)
|
||||||
|
app.getString(
|
||||||
|
if (event.subjectLongName.isNullOrEmpty())
|
||||||
|
R.string.notification_homework_no_subject_format
|
||||||
|
else
|
||||||
|
R.string.notification_homework_format,
|
||||||
|
event.subjectLongName,
|
||||||
|
event.eventDate.formattedString
|
||||||
|
)
|
||||||
|
else
|
||||||
|
app.getString(
|
||||||
|
if (event.subjectLongName.isNullOrEmpty())
|
||||||
|
R.string.notification_event_no_subject_format
|
||||||
|
else
|
||||||
|
R.string.notification_event_format,
|
||||||
|
event.typeName,
|
||||||
|
event.eventDate.formattedString,
|
||||||
|
event.subjectLongName
|
||||||
|
)
|
||||||
|
val type = if (event.type == Event.TYPE_HOMEWORK) Notification.TYPE_NEW_HOMEWORK else Notification.TYPE_NEW_EVENT
|
||||||
|
notifications += Notification(
|
||||||
|
id = Notification.buildId(event.profileId, type, event.id),
|
||||||
|
title = app.getNotificationTitle(type),
|
||||||
|
text = text,
|
||||||
|
type = type,
|
||||||
|
profileId = event.profileId,
|
||||||
|
profileName = profiles.singleOrNull { it.id == event.profileId }?.name,
|
||||||
|
viewId = if (event.type == Event.TYPE_HOMEWORK) MainActivity.DRAWER_ITEM_HOMEWORK else MainActivity.DRAWER_ITEM_AGENDA,
|
||||||
|
addedDate = event.addedDate
|
||||||
|
).addExtra("eventId", event.id).addExtra("eventDate", event.eventDate.value.toLong())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sharedEventNotifications() {
|
||||||
|
for (event in app.db.eventDao().notNotifiedNow.filter { it.sharedBy != null }) {
|
||||||
|
val text = app.getString(
|
||||||
|
R.string.notification_shared_event_format,
|
||||||
|
event.sharedByName,
|
||||||
|
event.typeName ?: "wydarzenie",
|
||||||
|
event.eventDate.formattedString,
|
||||||
|
event.topic
|
||||||
|
)
|
||||||
|
val type = if (event.type == Event.TYPE_HOMEWORK) Notification.TYPE_NEW_HOMEWORK else Notification.TYPE_NEW_EVENT
|
||||||
|
notifications += Notification(
|
||||||
|
id = Notification.buildId(event.profileId, type, event.id),
|
||||||
|
title = app.getNotificationTitle(type),
|
||||||
|
text = text,
|
||||||
|
type = type,
|
||||||
|
profileId = event.profileId,
|
||||||
|
profileName = profiles.singleOrNull { it.id == event.profileId }?.name,
|
||||||
|
viewId = if (event.type == Event.TYPE_HOMEWORK) MainActivity.DRAWER_ITEM_HOMEWORK else MainActivity.DRAWER_ITEM_AGENDA,
|
||||||
|
addedDate = event.addedDate
|
||||||
|
).addExtra("eventId", event.id).addExtra("eventDate", event.eventDate.value.toLong())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun gradeNotifications() {
|
||||||
|
for (grade in app.db.gradeDao().notNotifiedNow) {
|
||||||
|
val gradeName = when (grade.type) {
|
||||||
|
Grade.TYPE_SEMESTER1_PROPOSED, Grade.TYPE_SEMESTER2_PROPOSED -> app.getString(R.string.grade_semester_proposed_format_2, grade.name)
|
||||||
|
Grade.TYPE_SEMESTER1_FINAL, Grade.TYPE_SEMESTER2_FINAL -> app.getString(R.string.grade_semester_final_format_2, grade.name)
|
||||||
|
Grade.TYPE_YEAR_PROPOSED -> app.getString(R.string.grade_year_proposed_format_2, grade.name)
|
||||||
|
Grade.TYPE_YEAR_FINAL -> app.getString(R.string.grade_year_final_format_2, grade.name)
|
||||||
|
else -> grade.name
|
||||||
|
}
|
||||||
|
val text = app.getString(
|
||||||
|
R.string.notification_grade_format,
|
||||||
|
gradeName,
|
||||||
|
grade.subjectLongName
|
||||||
|
)
|
||||||
|
notifications += Notification(
|
||||||
|
id = Notification.buildId(grade.profileId, Notification.TYPE_NEW_GRADE, grade.id),
|
||||||
|
title = app.getNotificationTitle(Notification.TYPE_NEW_GRADE),
|
||||||
|
text = text,
|
||||||
|
type = Notification.TYPE_NEW_GRADE,
|
||||||
|
profileId = grade.profileId,
|
||||||
|
profileName = profiles.singleOrNull { it.id == grade.profileId }?.name,
|
||||||
|
viewId = MainActivity.DRAWER_ITEM_GRADES,
|
||||||
|
addedDate = grade.addedDate
|
||||||
|
).addExtra("gradeId", grade.id).addExtra("gradesSubjectId", grade.subjectId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun behaviourNotifications() {
|
||||||
|
for (notice in app.db.noticeDao().notNotifiedNow) {
|
||||||
|
|
||||||
|
val noticeTypeStr = when (notice.type) {
|
||||||
|
Notice.TYPE_POSITIVE -> app.getString(R.string.notification_notice_praise)
|
||||||
|
Notice.TYPE_NEGATIVE -> app.getString(R.string.notification_notice_warning)
|
||||||
|
else -> app.getString(R.string.notification_notice_new)
|
||||||
|
}
|
||||||
|
|
||||||
|
val text = app.getString(
|
||||||
|
R.string.notification_notice_format,
|
||||||
|
noticeTypeStr,
|
||||||
|
notice.teacherFullName,
|
||||||
|
Date.fromMillis(notice.addedDate).formattedString
|
||||||
|
)
|
||||||
|
notifications += Notification(
|
||||||
|
id = Notification.buildId(notice.profileId, Notification.TYPE_NEW_NOTICE, notice.id),
|
||||||
|
title = app.getNotificationTitle(Notification.TYPE_NEW_NOTICE),
|
||||||
|
text = text,
|
||||||
|
type = Notification.TYPE_NEW_NOTICE,
|
||||||
|
profileId = notice.profileId,
|
||||||
|
profileName = profiles.singleOrNull { it.id == notice.profileId }?.name,
|
||||||
|
viewId = MainActivity.DRAWER_ITEM_BEHAVIOUR,
|
||||||
|
addedDate = notice.addedDate
|
||||||
|
).addExtra("noticeId", notice.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun attendanceNotifications() {
|
||||||
|
for (attendance in app.db.attendanceDao().notNotifiedNow) {
|
||||||
|
|
||||||
|
val attendanceTypeStr = when (attendance.type) {
|
||||||
|
Attendance.TYPE_ABSENT -> app.getString(R.string.notification_absence)
|
||||||
|
Attendance.TYPE_ABSENT_EXCUSED -> app.getString(R.string.notification_absence_excused)
|
||||||
|
Attendance.TYPE_BELATED -> app.getString(R.string.notification_belated)
|
||||||
|
Attendance.TYPE_BELATED_EXCUSED -> app.getString(R.string.notification_belated_excused)
|
||||||
|
Attendance.TYPE_RELEASED -> app.getString(R.string.notification_release)
|
||||||
|
Attendance.TYPE_DAY_FREE -> app.getString(R.string.notification_day_free)
|
||||||
|
else -> app.getString(R.string.notification_type_attendance)
|
||||||
|
}
|
||||||
|
|
||||||
|
val text = app.getString(
|
||||||
|
if (attendance.subjectLongName.isNullOrEmpty())
|
||||||
|
R.string.notification_attendance_no_lesson_format
|
||||||
|
else
|
||||||
|
R.string.notification_attendance_format,
|
||||||
|
attendanceTypeStr,
|
||||||
|
attendance.subjectLongName,
|
||||||
|
attendance.lessonDate.formattedString
|
||||||
|
)
|
||||||
|
notifications += Notification(
|
||||||
|
id = Notification.buildId(attendance.profileId, Notification.TYPE_NEW_ATTENDANCE, attendance.id),
|
||||||
|
title = app.getNotificationTitle(Notification.TYPE_NEW_ATTENDANCE),
|
||||||
|
text = text,
|
||||||
|
type = Notification.TYPE_NEW_ATTENDANCE,
|
||||||
|
profileId = attendance.profileId,
|
||||||
|
profileName = profiles.singleOrNull { it.id == attendance.profileId }?.name,
|
||||||
|
viewId = MainActivity.DRAWER_ITEM_ATTENDANCE,
|
||||||
|
addedDate = attendance.addedDate
|
||||||
|
).addExtra("attendanceId", attendance.id).addExtra("attendanceSubjectId", attendance.subjectId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun announcementNotifications() {
|
||||||
|
for (announcement in app.db.announcementDao().notNotifiedNow) {
|
||||||
|
val text = app.getString(
|
||||||
|
R.string.notification_announcement_format,
|
||||||
|
announcement.teacherFullName,
|
||||||
|
announcement.subject
|
||||||
|
)
|
||||||
|
notifications += Notification(
|
||||||
|
id = Notification.buildId(announcement.profileId, Notification.TYPE_NEW_ANNOUNCEMENT, announcement.id),
|
||||||
|
title = app.getNotificationTitle(Notification.TYPE_NEW_ANNOUNCEMENT),
|
||||||
|
text = text,
|
||||||
|
type = Notification.TYPE_NEW_ANNOUNCEMENT,
|
||||||
|
profileId = announcement.profileId,
|
||||||
|
profileName = profiles.singleOrNull { it.id == announcement.profileId }?.name,
|
||||||
|
viewId = MainActivity.DRAWER_ITEM_ANNOUNCEMENTS,
|
||||||
|
addedDate = announcement.addedDate
|
||||||
|
).addExtra("announcementId", announcement.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun messageNotifications() {
|
||||||
|
for (message in app.db.messageDao().receivedNotNotifiedNow) {
|
||||||
|
val text = app.getString(
|
||||||
|
R.string.notification_message_format,
|
||||||
|
message.senderFullName,
|
||||||
|
message.subject
|
||||||
|
)
|
||||||
|
notifications += Notification(
|
||||||
|
id = Notification.buildId(message.profileId, Notification.TYPE_NEW_MESSAGE, message.id),
|
||||||
|
title = app.getNotificationTitle(Notification.TYPE_NEW_MESSAGE),
|
||||||
|
text = text,
|
||||||
|
type = Notification.TYPE_NEW_MESSAGE,
|
||||||
|
profileId = message.profileId,
|
||||||
|
profileName = profiles.singleOrNull { it.id == message.profileId }?.name,
|
||||||
|
viewId = MainActivity.DRAWER_ITEM_MESSAGES,
|
||||||
|
addedDate = message.addedDate
|
||||||
|
).addExtra("messageType", Message.TYPE_RECEIVED.toLong()).addExtra("messageId", message.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun luckyNumberNotifications() {
|
||||||
|
val luckyNumbers = app.db.luckyNumberDao().notNotifiedNow
|
||||||
|
luckyNumbers?.removeAll { it.date < today }
|
||||||
|
luckyNumbers?.forEach { luckyNumber ->
|
||||||
|
val profile = profiles.singleOrNull { it.id == luckyNumber.profileId } ?: return@forEach
|
||||||
|
val text = when (profile.studentNumber != -1 && profile.studentNumber == luckyNumber.number) {
|
||||||
|
true -> when (luckyNumber.date.value) {
|
||||||
|
todayValue -> R.string.notification_lucky_number_yours_format
|
||||||
|
todayValue + 1 -> R.string.notification_lucky_number_yours_tomorrow_format
|
||||||
|
else -> R.string.notification_lucky_number_yours_later_format
|
||||||
|
}
|
||||||
|
else -> when (luckyNumber.date.value) {
|
||||||
|
todayValue -> R.string.notification_lucky_number_format
|
||||||
|
todayValue + 1 -> R.string.notification_lucky_number_tomorrow_format
|
||||||
|
else -> R.string.notification_lucky_number_later_format
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notifications += Notification(
|
||||||
|
id = Notification.buildId(luckyNumber.profileId, Notification.TYPE_LUCKY_NUMBER, luckyNumber.date.value.toLong()),
|
||||||
|
title = app.getNotificationTitle(Notification.TYPE_LUCKY_NUMBER),
|
||||||
|
text = app.getString(text, luckyNumber.date.formattedString, luckyNumber.number),
|
||||||
|
type = Notification.TYPE_LUCKY_NUMBER,
|
||||||
|
profileId = luckyNumber.profileId,
|
||||||
|
profileName = profile.name,
|
||||||
|
viewId = MainActivity.DRAWER_ITEM_HOME,
|
||||||
|
addedDate = luckyNumber.addedDate
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,90 +0,0 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api.task
|
|
||||||
|
|
||||||
import android.app.PendingIntent
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Build
|
|
||||||
import androidx.core.app.NotificationCompat
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
|
||||||
import pl.szczodrzynski.edziennik.Notifier.ID_NOTIFICATIONS
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
|
||||||
import pl.szczodrzynski.edziennik.getNotificationTitle
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Notification
|
|
||||||
import kotlin.math.min
|
|
||||||
|
|
||||||
class NotifyTask : IApiTask(-1) {
|
|
||||||
override fun prepare(app: App) {
|
|
||||||
taskName = app.getString(R.string.edziennik_notification_api_notify_title)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun cancel() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun run(app: App, taskCallback: EdziennikCallback) {
|
|
||||||
val list = app.db.notificationDao().getNotPostedNow()
|
|
||||||
val notificationList = list.subList(0, min(10, list.size))
|
|
||||||
|
|
||||||
val unreadCount = list.size
|
|
||||||
|
|
||||||
for (notification in notificationList) {
|
|
||||||
val intent = Intent(app, MainActivity::class.java)
|
|
||||||
notification.fillIntent(intent)
|
|
||||||
val pendingIntent = PendingIntent.getActivity(app, notification.id, intent, 0)
|
|
||||||
val notificationBuilder = NotificationCompat.Builder(app, app.notifier.notificationGroup)
|
|
||||||
// title, text, type, date
|
|
||||||
.setContentTitle(notification.profileName)
|
|
||||||
.setContentText(notification.text)
|
|
||||||
.setSubText(app.getNotificationTitle(notification.type))
|
|
||||||
.setWhen(notification.addedDate)
|
|
||||||
.setTicker(app.getString(R.string.notification_ticker_format, Notification.stringType(app, notification.type)))
|
|
||||||
// icon, color, lights, priority
|
|
||||||
.setSmallIcon(R.drawable.ic_notification)
|
|
||||||
.setColor(app.notifier.notificationColor)
|
|
||||||
.setLights(-0xff0001, 2000, 2000)
|
|
||||||
.setPriority(app.notifier.notificationPriority)
|
|
||||||
// channel, group, style
|
|
||||||
.setChannelId(app.notifier.notificationGroup)
|
|
||||||
.setGroup(app.notifier.notificationGroup)
|
|
||||||
.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY)
|
|
||||||
.setStyle(NotificationCompat.BigTextStyle().bigText(notification.text))
|
|
||||||
// intent, auto cancel
|
|
||||||
.setContentIntent(pendingIntent)
|
|
||||||
.setAutoCancel(true)
|
|
||||||
if (!app.notifier.shouldBeQuiet()) {
|
|
||||||
notificationBuilder.setDefaults(app.notifier.notificationDefaults)
|
|
||||||
}
|
|
||||||
app.notifier.notificationManager.notify(notification.id, notificationBuilder.build())
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notificationList.isNotEmpty() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
||||||
val intent = Intent(app, MainActivity::class.java)
|
|
||||||
intent.action = "android.intent.action.MAIN"
|
|
||||||
intent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_NOTIFICATIONS)
|
|
||||||
val pendingIntent = PendingIntent.getActivity(app, ID_NOTIFICATIONS,
|
|
||||||
intent, 0)
|
|
||||||
|
|
||||||
val groupBuilder = NotificationCompat.Builder(app, app.notifier.notificationGroup)
|
|
||||||
.setSmallIcon(R.drawable.ic_notification)
|
|
||||||
.setColor(app.notifier.notificationColor)
|
|
||||||
.setContentTitle(app.getString(R.string.notification_new_notification_title_format, unreadCount))
|
|
||||||
.setGroupSummary(true)
|
|
||||||
.setAutoCancel(true)
|
|
||||||
.setChannelId(app.notifier.notificationGroup)
|
|
||||||
.setGroup(app.notifier.notificationGroup)
|
|
||||||
.setLights(-0xff0001, 2000, 2000)
|
|
||||||
.setPriority(app.notifier.notificationPriority)
|
|
||||||
.setContentIntent(pendingIntent)
|
|
||||||
.setStyle(NotificationCompat.BigTextStyle())
|
|
||||||
if (!app.notifier.shouldBeQuiet()) {
|
|
||||||
groupBuilder.setDefaults(app.notifier.notificationDefaults)
|
|
||||||
}
|
|
||||||
app.notifier.notificationManager.notify(ID_NOTIFICATIONS, groupBuilder.build())
|
|
||||||
}
|
|
||||||
|
|
||||||
app.db.notificationDao().setAllPosted()
|
|
||||||
|
|
||||||
taskCallback.onCompleted()
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,169 @@
|
|||||||
|
package pl.szczodrzynski.edziennik.data.api.task
|
||||||
|
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Build
|
||||||
|
import android.util.SparseIntArray
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.util.forEach
|
||||||
|
import androidx.core.util.set
|
||||||
|
import pl.szczodrzynski.edziennik.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Notification as AppNotification
|
||||||
|
|
||||||
|
class PostNotifications(val app: App, nList: MutableList<AppNotification>) {
|
||||||
|
companion object {
|
||||||
|
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();
|
||||||
|
if (start > end) {
|
||||||
|
end += 1000 * 60 * 60 * 24;
|
||||||
|
//Log.d(TAG, "Night passing");
|
||||||
|
}
|
||||||
|
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
|
||||||
|
|
||||||
|
private fun buildSummaryText(summaryCounts: SparseIntArray): CharSequence {
|
||||||
|
val summaryTexts = mutableListOf<String>()
|
||||||
|
summaryCounts.forEach { key, value ->
|
||||||
|
if (value <= 0)
|
||||||
|
return@forEach
|
||||||
|
val pluralRes = when (key) {
|
||||||
|
AppNotification.TYPE_TIMETABLE_LESSON_CHANGE -> R.plurals.notification_new_timetable_change_format
|
||||||
|
AppNotification.TYPE_NEW_GRADE -> R.plurals.notification_new_grades_format
|
||||||
|
AppNotification.TYPE_NEW_EVENT -> R.plurals.notification_new_events_format
|
||||||
|
AppNotification.TYPE_NEW_HOMEWORK -> R.plurals.notification_new_homework_format
|
||||||
|
AppNotification.TYPE_NEW_SHARED_EVENT -> R.plurals.notification_new_shared_events_format
|
||||||
|
AppNotification.TYPE_NEW_SHARED_HOMEWORK -> R.plurals.notification_new_shared_homework_format
|
||||||
|
AppNotification.TYPE_NEW_MESSAGE -> R.plurals.notification_new_messages_format
|
||||||
|
AppNotification.TYPE_NEW_NOTICE -> R.plurals.notification_new_notices_format
|
||||||
|
AppNotification.TYPE_NEW_ATTENDANCE -> R.plurals.notification_new_attendance_format
|
||||||
|
AppNotification.TYPE_LUCKY_NUMBER -> R.plurals.notification_new_lucky_number_format
|
||||||
|
AppNotification.TYPE_NEW_ANNOUNCEMENT -> R.plurals.notification_new_announcements_format
|
||||||
|
else -> R.plurals.notification_other_format
|
||||||
|
}
|
||||||
|
summaryTexts += app.resources.getQuantityString(pluralRes, value, value)
|
||||||
|
}
|
||||||
|
return summaryTexts.concat(", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val notificationManager = app.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
|
val count = nList.size
|
||||||
|
val summaryCounts = SparseIntArray()
|
||||||
|
|
||||||
|
val newNotificationsText = app.resources.getQuantityString(R.plurals.notification_count_format, count, count)
|
||||||
|
val newNotificationsShortText = app.resources.getQuantityString(R.plurals.notification_count_short_format, count, count)
|
||||||
|
|
||||||
|
val intent = Intent(
|
||||||
|
app,
|
||||||
|
MainActivity::class.java,
|
||||||
|
"fragmentId" to MainActivity.DRAWER_ITEM_NOTIFICATIONS
|
||||||
|
)
|
||||||
|
val summaryIntent = PendingIntent.getActivity(app, app.notifications.dataId, intent, PendingIntent.FLAG_ONE_SHOT)
|
||||||
|
|
||||||
|
// On Nougat or newer - show maximum 8 notifications
|
||||||
|
// On Marshmallow or older - show maximum 4 notifications
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && count > 4 || Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && count > 8) {
|
||||||
|
val summaryList = mutableListOf<CharSequence>()
|
||||||
|
nList.forEach {
|
||||||
|
summaryCounts[it.type]++
|
||||||
|
summaryList += listOf(
|
||||||
|
it.profileName.asBoldSpannable(),
|
||||||
|
it.text
|
||||||
|
).concat(": ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a summary to show *instead* of notifications
|
||||||
|
val combined = NotificationCompat.Builder(app, app.notifications.dataKey)
|
||||||
|
.setContentTitle(app.getString(R.string.app_name))
|
||||||
|
.setContentText(buildSummaryText(summaryCounts))
|
||||||
|
.setTicker(newNotificationsText)
|
||||||
|
.setSmallIcon(R.drawable.ic_notification)
|
||||||
|
.setStyle(NotificationCompat.InboxStyle()
|
||||||
|
.also {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
it.setBigContentTitle(app.getString(R.string.app_name))
|
||||||
|
it.setSummaryText(newNotificationsShortText)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
it.setBigContentTitle(newNotificationsText)
|
||||||
|
it.setSummaryText(app.getString(R.string.notification_click_to_see_all))
|
||||||
|
}
|
||||||
|
summaryList.forEach { line ->
|
||||||
|
it.addLine(line)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setColor(0xff2196f3.toInt())
|
||||||
|
.setLights(0xff2196f3.toInt(), 2000, 2000)
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_MAX)
|
||||||
|
.setDefaults(NotificationCompat.DEFAULT_ALL)
|
||||||
|
.setGroup(app.notifications.dataKey)
|
||||||
|
.setContentIntent(summaryIntent)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.build()
|
||||||
|
notificationManager.notify(System.currentTimeMillis().toInt(), combined)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Less than 8 notifications
|
||||||
|
val notifications = nList.map {
|
||||||
|
summaryCounts[it.type]++
|
||||||
|
NotificationCompat.Builder(app, app.notifications.dataKey)
|
||||||
|
.setContentTitle(it.profileName ?: app.getString(R.string.app_name))
|
||||||
|
.setContentText(it.text)
|
||||||
|
.setSubText(it.title)
|
||||||
|
.setTicker("${it.profileName}: ${it.title}")
|
||||||
|
.setSmallIcon(R.drawable.ic_notification)
|
||||||
|
.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.notifications.dataKey)
|
||||||
|
.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY)
|
||||||
|
.setContentIntent(it.getPendingIntent(app))
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
val time = System.currentTimeMillis()
|
||||||
|
notificationManager.apply {
|
||||||
|
notifications.forEachIndexed { index, it ->
|
||||||
|
notificationManager.notify((time + index).toInt(), it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
val summary = NotificationCompat.Builder(app, app.notifications.dataKey)
|
||||||
|
.setContentTitle(newNotificationsText)
|
||||||
|
.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.notifications.dataKey)
|
||||||
|
.setGroupSummary(true)
|
||||||
|
.setContentIntent(summaryIntent)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
notificationManager.notify(app.notifications.dataId, summary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,39 +7,39 @@ package pl.szczodrzynski.edziennik.data.api.task
|
|||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.Szkolny
|
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
class SzkolnyTask(val request: Any) : IApiTask(-1) {
|
class SzkolnyTask(val app: App, val syncingProfiles: List<Profile>) : IApiTask(-1) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "SzkolnyTask"
|
private const val TAG = "SzkolnyTask"
|
||||||
|
|
||||||
fun sync(profiles: List<Profile>) = SzkolnyTask(SyncRequest(profiles))
|
|
||||||
/*fun shareEvent(event: EventFull) = SzkolnyTask(ShareEventRequest(event))
|
|
||||||
fun unshareEvent(event: EventFull) = SzkolnyTask(UnshareEventRequest(event))*/
|
|
||||||
}
|
}
|
||||||
|
private val api by lazy { SzkolnyApi(app) }
|
||||||
|
private val profiles by lazy { app.db.profileDao().allNow }
|
||||||
|
override fun prepare(app: App) { taskName = app.getString(R.string.edziennik_szkolny_creating_notifications) }
|
||||||
|
override fun cancel() {}
|
||||||
|
|
||||||
private lateinit var szkolny: Szkolny
|
private val notificationList = mutableListOf<Notification>()
|
||||||
|
|
||||||
override fun prepare(app: App) {
|
internal fun run(taskCallback: EdziennikCallback) {
|
||||||
taskName = app.getString(R.string.edziennik_szkolny_api_sync_title)
|
val startTime = System.currentTimeMillis()
|
||||||
}
|
val notifications = Notifications(app, notificationList, profiles)
|
||||||
|
// create all e-register data notifications
|
||||||
override fun cancel() {
|
notifications.run()
|
||||||
// TODO
|
// send notifications to web push, get shared events
|
||||||
}
|
AppSync(app, notificationList, profiles, api).run()
|
||||||
|
// create notifications for shared events (not present before app sync)
|
||||||
internal fun run(app: App, taskCallback: EdziennikCallback) {
|
notifications.sharedEventNotifications()
|
||||||
szkolny = Szkolny(app, taskCallback)
|
d(TAG, "Created ${notificationList.count()} notifications.")
|
||||||
|
// update the database
|
||||||
when (request) {
|
app.db.metadataDao().setAllNotified(true)
|
||||||
is SyncRequest -> szkolny.sync(request.profiles)
|
app.db.notificationDao().addAll(notificationList)
|
||||||
/*is ShareEventRequest -> szkolny.shareEvent(request.event)
|
app.db.profileDao().setAllNotEmpty()
|
||||||
is UnshareEventRequest -> szkolny.unshareEvent(request.event)*/
|
// post all notifications
|
||||||
|
PostNotifications(app, notificationList)
|
||||||
|
d(TAG, "SzkolnyTask: finished in ${System.currentTimeMillis()-startTime} ms.")
|
||||||
|
taskCallback.onCompleted()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class SyncRequest(val profiles: List<Profile>)
|
|
||||||
/*data class ShareEventRequest(val event: EventFull)
|
|
||||||
data class UnshareEventRequest(val event: EventFull)*/
|
|
||||||
}
|
|
||||||
|
@ -16,8 +16,8 @@ import androidx.sqlite.db.SupportSQLiteQuery;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Announcement;
|
import pl.szczodrzynski.edziennik.data.db.entity.Announcement;
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata;
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata;
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull;
|
||||||
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_ANNOUNCEMENT;
|
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_ANNOUNCEMENT;
|
||||||
|
|
||||||
@ -69,4 +69,14 @@ public abstract class AnnouncementDao {
|
|||||||
public List<AnnouncementFull> getNotNotifiedNow(int profileId) {
|
public List<AnnouncementFull> getNotNotifiedNow(int profileId) {
|
||||||
return getAllNow(profileId, "notified = 0");
|
return getAllNow(profileId, "notified = 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Query("SELECT " +
|
||||||
|
"*, " +
|
||||||
|
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName " +
|
||||||
|
"FROM announcements " +
|
||||||
|
"LEFT JOIN teachers USING(profileId, teacherId) " +
|
||||||
|
"LEFT JOIN metadata ON announcementId = thingId AND thingType = "+TYPE_ANNOUNCEMENT+" AND metadata.profileId = announcements.profileId " +
|
||||||
|
"WHERE notified = 0 " +
|
||||||
|
"ORDER BY addedDate DESC")
|
||||||
|
public abstract List<AnnouncementFull> getNotNotifiedNow();
|
||||||
}
|
}
|
||||||
|
@ -5,20 +5,20 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.db.dao;
|
package pl.szczodrzynski.edziennik.data.db.dao;
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.sqlite.db.SimpleSQLiteQuery;
|
|
||||||
import androidx.sqlite.db.SupportSQLiteQuery;
|
|
||||||
import androidx.room.Dao;
|
import androidx.room.Dao;
|
||||||
import androidx.room.Insert;
|
import androidx.room.Insert;
|
||||||
import androidx.room.OnConflictStrategy;
|
import androidx.room.OnConflictStrategy;
|
||||||
import androidx.room.Query;
|
import androidx.room.Query;
|
||||||
import androidx.room.RawQuery;
|
import androidx.room.RawQuery;
|
||||||
|
import androidx.sqlite.db.SimpleSQLiteQuery;
|
||||||
|
import androidx.sqlite.db.SupportSQLiteQuery;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance;
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance;
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull;
|
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull;
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date;
|
import pl.szczodrzynski.edziennik.utils.models.Date;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_ATTENDANCE;
|
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_ATTENDANCE;
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
@ -72,6 +72,13 @@ public abstract class AttendanceDao {
|
|||||||
return getAllNow(profileId, "notified = 0");
|
return getAllNow(profileId, "notified = 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Query("SELECT * FROM attendances " +
|
||||||
|
"LEFT JOIN subjects USING(profileId, subjectId) " +
|
||||||
|
"LEFT JOIN metadata ON attendanceId = thingId AND thingType = " + TYPE_ATTENDANCE + " AND metadata.profileId = attendances.profileId " +
|
||||||
|
"WHERE notified = 0 " +
|
||||||
|
"ORDER BY attendanceLessonDate DESC, attendanceStartTime DESC")
|
||||||
|
public abstract List<AttendanceFull> getNotNotifiedNow();
|
||||||
|
|
||||||
// only absent and absent_excused count as absences
|
// only absent and absent_excused count as absences
|
||||||
// all the other types are counted as being present
|
// all the other types are counted as being present
|
||||||
@Query("SELECT \n" +
|
@Query("SELECT \n" +
|
||||||
|
@ -34,7 +34,7 @@ public abstract class EventDao {
|
|||||||
public abstract long add(Event event);
|
public abstract long add(Event event);
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
public abstract void addAll(List<Event> eventList);
|
public abstract long[] addAll(List<Event> eventList);
|
||||||
|
|
||||||
@Query("DELETE FROM events WHERE profileId = :profileId")
|
@Query("DELETE FROM events WHERE profileId = :profileId")
|
||||||
public abstract void clear(int profileId);
|
public abstract void clear(int profileId);
|
||||||
@ -44,7 +44,7 @@ public abstract class EventDao {
|
|||||||
@Query("DELETE FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND thingId = :thingId")
|
@Query("DELETE FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND thingId = :thingId")
|
||||||
public abstract void removeMetadata(int profileId, int thingType, long thingId);
|
public abstract void removeMetadata(int profileId, int thingType, long thingId);
|
||||||
@Transaction
|
@Transaction
|
||||||
public void remove(int profileId, int type, long id) {
|
public void remove(int profileId, long type, long id) {
|
||||||
remove(profileId, id);
|
remove(profileId, id);
|
||||||
removeMetadata(profileId, type == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, id);
|
removeMetadata(profileId, type == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, id);
|
||||||
}
|
}
|
||||||
@ -88,7 +88,7 @@ public abstract class EventDao {
|
|||||||
public LiveData<List<EventFull>> getAllWhere(int profileId, String filter) {
|
public LiveData<List<EventFull>> getAllWhere(int profileId, String filter) {
|
||||||
return getAll(profileId, filter);
|
return getAll(profileId, filter);
|
||||||
}
|
}
|
||||||
public LiveData<List<EventFull>> getAllByType(int profileId, int type, String filter) {
|
public LiveData<List<EventFull>> getAllByType(int profileId, long type, String filter) {
|
||||||
return getAll(profileId, "eventType = "+type+" AND "+filter);
|
return getAll(profileId, "eventType = "+type+" AND "+filter);
|
||||||
}
|
}
|
||||||
public LiveData<List<EventFull>> getAllByDate(int profileId, @NonNull Date date) {
|
public LiveData<List<EventFull>> getAllByDate(int profileId, @NonNull Date date) {
|
||||||
@ -125,6 +125,24 @@ public abstract class EventDao {
|
|||||||
return getAllNow(profileId, "notified = 0");
|
return getAllNow(profileId, "notified = 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Query("SELECT eventId FROM events WHERE profileId = :profileId AND eventBlacklisted = 1")
|
||||||
|
public abstract List<Long> getBlacklistedIds(int profileId);
|
||||||
|
@Query("SELECT eventId FROM events WHERE eventBlacklisted = 1")
|
||||||
|
public abstract List<Long> getBlacklistedIds();
|
||||||
|
|
||||||
|
@Query("SELECT " +
|
||||||
|
"*, " +
|
||||||
|
"eventTypes.eventTypeName AS typeName, " +
|
||||||
|
"eventTypes.eventTypeColor AS typeColor " +
|
||||||
|
"FROM events " +
|
||||||
|
"LEFT JOIN subjects USING(profileId, subjectId) " +
|
||||||
|
"LEFT JOIN eventTypes USING(profileId, eventType) " +
|
||||||
|
"LEFT JOIN metadata ON eventId = thingId AND (thingType = " + TYPE_EVENT + " OR thingType = " + TYPE_HOMEWORK + ") AND metadata.profileId = events.profileId " +
|
||||||
|
"WHERE events.eventBlacklisted = 0 AND notified = 0 " +
|
||||||
|
"GROUP BY eventId " +
|
||||||
|
"ORDER BY addedDate ASC")
|
||||||
|
public abstract List<EventFull> getNotNotifiedNow();
|
||||||
|
|
||||||
public EventFull getByIdNow(int profileId, long eventId) {
|
public EventFull getByIdNow(int profileId, long eventId) {
|
||||||
List<EventFull> eventList = getAllNow(profileId, "eventId = "+eventId);
|
List<EventFull> eventList = getAllNow(profileId, "eventId = "+eventId);
|
||||||
return eventList.size() == 0 ? null : eventList.get(0);
|
return eventList.size() == 0 ? null : eventList.get(0);
|
||||||
@ -146,13 +164,13 @@ public abstract class EventDao {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Query("DELETE FROM events WHERE profileId = :profileId AND eventAddedManually = 0 AND eventDate >= :todayDate AND eventType = :type")
|
@Query("DELETE FROM events WHERE profileId = :profileId AND eventAddedManually = 0 AND eventDate >= :todayDate AND eventType = :type")
|
||||||
public abstract void removeFutureWithType(int profileId, Date todayDate, int type);
|
public abstract void removeFutureWithType(int profileId, Date todayDate, long type);
|
||||||
|
|
||||||
@Query("DELETE FROM events WHERE profileId = :profileId AND eventAddedManually = 0 AND eventDate >= :todayDate AND eventType != :exceptType")
|
@Query("DELETE FROM events WHERE profileId = :profileId AND eventAddedManually = 0 AND eventDate >= :todayDate AND eventType != :exceptType")
|
||||||
public abstract void removeFutureExceptType(int profileId, Date todayDate, int exceptType);
|
public abstract void removeFutureExceptType(int profileId, Date todayDate, long exceptType);
|
||||||
|
|
||||||
@Transaction
|
@Transaction
|
||||||
public void removeFutureExceptTypes(int profileId, Date todayDate, List<Integer> exceptTypes) {
|
public void removeFutureExceptTypes(int profileId, Date todayDate, List<Long> exceptTypes) {
|
||||||
removeFuture(profileId, todayDate, "eventType NOT IN " + exceptTypes.toString().replace('[', '(').replace(']', ')'));
|
removeFuture(profileId, todayDate, "eventType NOT IN " + exceptTypes.toString().replace('[', '(').replace(']', ')'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.db.dao;
|
package pl.szczodrzynski.edziennik.data.db.dao;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.room.Dao;
|
import androidx.room.Dao;
|
||||||
import androidx.room.Insert;
|
import androidx.room.Insert;
|
||||||
import androidx.room.OnConflictStrategy;
|
import androidx.room.OnConflictStrategy;
|
||||||
import androidx.room.Query;
|
import androidx.room.Query;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.EventType;
|
import pl.szczodrzynski.edziennik.data.db.entity.EventType;
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
@ -26,11 +26,14 @@ public interface EventTypeDao {
|
|||||||
void clear(int profileId);
|
void clear(int profileId);
|
||||||
|
|
||||||
@Query("SELECT * FROM eventTypes WHERE profileId = :profileId AND eventType = :typeId")
|
@Query("SELECT * FROM eventTypes WHERE profileId = :profileId AND eventType = :typeId")
|
||||||
EventType getByIdNow(int profileId, int typeId);
|
EventType getByIdNow(int profileId, long typeId);
|
||||||
|
|
||||||
@Query("SELECT * FROM eventTypes WHERE profileId = :profileId")
|
@Query("SELECT * FROM eventTypes WHERE profileId = :profileId")
|
||||||
LiveData<List<EventType>> getAll(int profileId);
|
LiveData<List<EventType>> getAll(int profileId);
|
||||||
|
|
||||||
@Query("SELECT * FROM eventTypes WHERE profileId = :profileId")
|
@Query("SELECT * FROM eventTypes WHERE profileId = :profileId")
|
||||||
List<EventType> getAllNow(int profileId);
|
List<EventType> getAllNow(int profileId);
|
||||||
|
|
||||||
|
@Query("SELECT * FROM eventTypes")
|
||||||
|
List<EventType> getAllNow();
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,13 @@ public abstract class GradeDao {
|
|||||||
return getAllNow(profileId, "gradeParentId = "+parentId);
|
return getAllNow(profileId, "gradeParentId = "+parentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Query("SELECT * FROM grades " +
|
||||||
|
"LEFT JOIN subjects USING(profileId, subjectId) " +
|
||||||
|
"LEFT JOIN metadata ON gradeId = thingId AND thingType = " + TYPE_GRADE + " AND metadata.profileId = grades.profileId " +
|
||||||
|
"WHERE notified = 0 " +
|
||||||
|
"ORDER BY addedDate DESC")
|
||||||
|
public abstract List<GradeFull> getNotNotifiedNow();
|
||||||
|
|
||||||
@RawQuery
|
@RawQuery
|
||||||
abstract GradeFull getNow(SupportSQLiteQuery query);
|
abstract GradeFull getNow(SupportSQLiteQuery query);
|
||||||
public GradeFull getNow(int profileId, String filter) {
|
public GradeFull getNow(int profileId, String filter) {
|
||||||
|
@ -20,4 +20,7 @@ interface LibrusLessonDao {
|
|||||||
|
|
||||||
@Query("SELECT * FROM librusLessons WHERE profileId = :profileId")
|
@Query("SELECT * FROM librusLessons WHERE profileId = :profileId")
|
||||||
fun getAllNow(profileId: Int): List<LibrusLesson>
|
fun getAllNow(profileId: Int): List<LibrusLesson>
|
||||||
|
|
||||||
|
@Query("DELETE FROM librusLessons WHERE profileId = :profileId")
|
||||||
|
fun clear(profileId: Int)
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,9 @@ import androidx.sqlite.db.SupportSQLiteQuery;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber;
|
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber;
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.LuckyNumberFull;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata;
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata;
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice;
|
import pl.szczodrzynski.edziennik.data.db.entity.Notice;
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.LuckyNumberFull;
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date;
|
import pl.szczodrzynski.edziennik.utils.models.Date;
|
||||||
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_LUCKY_NUMBER;
|
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_LUCKY_NUMBER;
|
||||||
@ -78,4 +78,10 @@ public abstract class LuckyNumberDao {
|
|||||||
public List<LuckyNumberFull> getNotNotifiedNow(int profileId) {
|
public List<LuckyNumberFull> getNotNotifiedNow(int profileId) {
|
||||||
return getAllNow(profileId, "notified = 0");
|
return getAllNow(profileId, "notified = 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Query("SELECT * FROM luckyNumbers\n" +
|
||||||
|
"LEFT JOIN metadata ON luckyNumberDate = thingId AND thingType = "+TYPE_LUCKY_NUMBER+" AND metadata.profileId = luckyNumbers.profileId " +
|
||||||
|
"WHERE notified = 0 " +
|
||||||
|
"ORDER BY addedDate DESC")
|
||||||
|
public abstract List<LuckyNumberFull> getNotNotifiedNow();
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,8 @@ import androidx.sqlite.db.SupportSQLiteQuery;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message;
|
import pl.szczodrzynski.edziennik.data.db.entity.Message;
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata;
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata;
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull;
|
||||||
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_DELETED;
|
import static pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_DELETED;
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED;
|
import static pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED;
|
||||||
@ -101,4 +101,14 @@ public abstract class MessageDao {
|
|||||||
public List<MessageFull> getReceivedNotNotifiedNow(int profileId) {
|
public List<MessageFull> getReceivedNotNotifiedNow(int profileId) {
|
||||||
return getReceivedNow(profileId, "notified = 0");
|
return getReceivedNow(profileId, "notified = 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Query("SELECT " +
|
||||||
|
"*, " +
|
||||||
|
"teachers.teacherName || ' ' || teachers.teacherSurname AS senderFullName " +
|
||||||
|
"FROM messages " +
|
||||||
|
"LEFT JOIN teachers ON teachers.profileId = messages.profileId AND teacherId = senderId " +
|
||||||
|
"LEFT JOIN metadata ON messageId = thingId AND thingType = "+TYPE_MESSAGE+" AND metadata.profileId = messages.profileId " +
|
||||||
|
"WHERE messageType = 0 AND notified = 0 " +
|
||||||
|
"ORDER BY addedDate DESC")
|
||||||
|
public abstract List<MessageFull> getReceivedNotNotifiedNow();
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,9 @@ public abstract class MetadataDao {
|
|||||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||||
public abstract void addAllIgnore(List<Metadata> metadataList);
|
public abstract void addAllIgnore(List<Metadata> metadataList);
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
public abstract void addAllReplace(List<Metadata> metadataList);
|
||||||
|
|
||||||
@Query("UPDATE metadata SET seen = :seen WHERE thingId = :thingId AND thingType = :thingType AND profileId = :profileId")
|
@Query("UPDATE metadata SET seen = :seen WHERE thingId = :thingId AND thingType = :thingType AND profileId = :profileId")
|
||||||
abstract void updateSeen(int profileId, int thingType, long thingId, boolean seen);
|
abstract void updateSeen(int profileId, int thingType, long thingId, boolean seen);
|
||||||
|
|
||||||
@ -165,6 +168,9 @@ public abstract class MetadataDao {
|
|||||||
@Query("UPDATE metadata SET notified = :notified WHERE profileId = :profileId")
|
@Query("UPDATE metadata SET notified = :notified WHERE profileId = :profileId")
|
||||||
public abstract void setAllNotified(int profileId, boolean notified);
|
public abstract void setAllNotified(int profileId, boolean notified);
|
||||||
|
|
||||||
|
@Query("UPDATE metadata SET notified = :notified")
|
||||||
|
public abstract void setAllNotified(boolean notified);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Query("SELECT count() FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND seen = 0")
|
@Query("SELECT count() FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND seen = 0")
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.db.dao;
|
package pl.szczodrzynski.edziennik.data.db.dao;
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.sqlite.db.SimpleSQLiteQuery;
|
|
||||||
import androidx.sqlite.db.SupportSQLiteQuery;
|
|
||||||
import androidx.room.Dao;
|
import androidx.room.Dao;
|
||||||
import androidx.room.Insert;
|
import androidx.room.Insert;
|
||||||
import androidx.room.OnConflictStrategy;
|
import androidx.room.OnConflictStrategy;
|
||||||
import androidx.room.Query;
|
import androidx.room.Query;
|
||||||
import androidx.room.RawQuery;
|
import androidx.room.RawQuery;
|
||||||
|
import androidx.sqlite.db.SimpleSQLiteQuery;
|
||||||
|
import androidx.sqlite.db.SupportSQLiteQuery;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -69,4 +69,14 @@ public abstract class NoticeDao {
|
|||||||
public List<NoticeFull> getNotNotifiedNow(int profileId) {
|
public List<NoticeFull> getNotNotifiedNow(int profileId) {
|
||||||
return getAllNow(profileId, "notified = 0");
|
return getAllNow(profileId, "notified = 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Query("SELECT " +
|
||||||
|
"*, " +
|
||||||
|
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName " +
|
||||||
|
"FROM notices " +
|
||||||
|
"LEFT JOIN teachers USING(profileId, teacherId) " +
|
||||||
|
"LEFT JOIN metadata ON noticeId = thingId AND thingType = "+TYPE_NOTICE+" AND metadata.profileId = notices.profileId " +
|
||||||
|
"WHERE notified = 0 " +
|
||||||
|
"ORDER BY addedDate DESC")
|
||||||
|
public abstract List<NoticeFull> getNotNotifiedNow();
|
||||||
}
|
}
|
||||||
|
@ -52,9 +52,12 @@ interface ProfileDao {
|
|||||||
@Query("SELECT profiles.* FROM teams JOIN profiles USING(profileId) WHERE teamCode = :teamCode AND registration = " + Profile.REGISTRATION_ENABLED + " AND enableSharedEvents = 1")
|
@Query("SELECT profiles.* FROM teams JOIN profiles USING(profileId) WHERE teamCode = :teamCode AND registration = " + Profile.REGISTRATION_ENABLED + " AND enableSharedEvents = 1")
|
||||||
fun getByTeamCodeNowWithRegistration(teamCode: String?): List<Profile>
|
fun getByTeamCodeNowWithRegistration(teamCode: String?): List<Profile>
|
||||||
|
|
||||||
@get:Query("SELECT profileId FROM profiles WHERE profileId >= 0 ORDER BY profileId ASC LIMIT 1")
|
@get:Query("SELECT profileId FROM profiles WHERE profileId > 0 ORDER BY profileId ASC LIMIT 1")
|
||||||
val firstId: Int?
|
val firstId: Int?
|
||||||
|
|
||||||
@get:Query("SELECT profileId FROM profiles WHERE profileId >= 0 ORDER BY profileId DESC LIMIT 1")
|
@get:Query("SELECT profileId FROM profiles WHERE profileId > 0 ORDER BY profileId DESC LIMIT 1")
|
||||||
val lastId: Int?
|
val lastId: Int?
|
||||||
|
|
||||||
|
@Query("UPDATE profiles SET empty = 0")
|
||||||
|
fun setAllNotEmpty()
|
||||||
}
|
}
|
||||||
|
@ -107,4 +107,18 @@ interface TimetableDao {
|
|||||||
WHERE timetable.profileId = :profileId AND timetable.type NOT IN (${Lesson.TYPE_NORMAL}, ${Lesson.TYPE_NO_LESSONS}, ${Lesson.TYPE_SHIFTED_SOURCE}) AND metadata.notified = 0
|
WHERE timetable.profileId = :profileId AND timetable.type NOT IN (${Lesson.TYPE_NORMAL}, ${Lesson.TYPE_NO_LESSONS}, ${Lesson.TYPE_SHIFTED_SOURCE}) AND metadata.notified = 0
|
||||||
""")
|
""")
|
||||||
fun getNotNotifiedNow(profileId: Int): List<LessonFull>
|
fun getNotNotifiedNow(profileId: Int): List<LessonFull>
|
||||||
|
|
||||||
|
@Query("""
|
||||||
|
SELECT
|
||||||
|
timetable.*,
|
||||||
|
teachers.teacherName ||" "|| teachers.teacherSurname AS teacherName,
|
||||||
|
oldT.teacherName ||" "|| oldT.teacherSurname AS oldTeacherName,
|
||||||
|
metadata.seen, metadata.notified, metadata.addedDate
|
||||||
|
FROM timetable
|
||||||
|
LEFT JOIN teachers USING(profileId, teacherId)
|
||||||
|
LEFT JOIN teachers AS oldT ON timetable.profileId = oldT.profileId AND timetable.oldTeacherId = oldT.teacherId
|
||||||
|
LEFT JOIN metadata ON id = thingId AND thingType = ${Metadata.TYPE_LESSON_CHANGE} AND metadata.profileId = timetable.profileId
|
||||||
|
WHERE timetable.type NOT IN (${Lesson.TYPE_NORMAL}, ${Lesson.TYPE_NO_LESSONS}, ${Lesson.TYPE_SHIFTED_SOURCE}) AND metadata.notified = 0
|
||||||
|
""")
|
||||||
|
fun getNotNotifiedNow(): List<LessonFull>
|
||||||
}
|
}
|
||||||
|
@ -32,19 +32,19 @@ public class Event {
|
|||||||
public String topic;
|
public String topic;
|
||||||
@ColumnInfo(name = "eventColor")
|
@ColumnInfo(name = "eventColor")
|
||||||
public int color = -1;
|
public int color = -1;
|
||||||
public static final int TYPE_UNDEFINED = -2;
|
public static final long TYPE_UNDEFINED = -2;
|
||||||
public static final int TYPE_HOMEWORK = -1;
|
public static final long TYPE_HOMEWORK = -1;
|
||||||
public static final int TYPE_DEFAULT = 0;
|
public static final long TYPE_DEFAULT = 0;
|
||||||
public static final int TYPE_EXAM = 1;
|
public static final long TYPE_EXAM = 1;
|
||||||
public static final int TYPE_SHORT_QUIZ = 2;
|
public static final long TYPE_SHORT_QUIZ = 2;
|
||||||
public static final int TYPE_ESSAY = 3;
|
public static final long TYPE_ESSAY = 3;
|
||||||
public static final int TYPE_PROJECT = 4;
|
public static final long TYPE_PROJECT = 4;
|
||||||
public static final int TYPE_PT_MEETING = 5;
|
public static final long TYPE_PT_MEETING = 5;
|
||||||
public static final int TYPE_EXCURSION = 6;
|
public static final long TYPE_EXCURSION = 6;
|
||||||
public static final int TYPE_READING = 7;
|
public static final long TYPE_READING = 7;
|
||||||
public static final int TYPE_CLASS_EVENT = 8;
|
public static final long TYPE_CLASS_EVENT = 8;
|
||||||
public static final int TYPE_INFORMATION = 9;
|
public static final long TYPE_INFORMATION = 9;
|
||||||
public static final int TYPE_TEACHER_ABSENCE = 10;
|
public static final long TYPE_TEACHER_ABSENCE = 10;
|
||||||
public static final int COLOR_HOMEWORK = 0xff795548;
|
public static final int COLOR_HOMEWORK = 0xff795548;
|
||||||
public static final int COLOR_DEFAULT = 0xffffc107;
|
public static final int COLOR_DEFAULT = 0xffffc107;
|
||||||
public static final int COLOR_EXAM = 0xfff44336;
|
public static final int COLOR_EXAM = 0xfff44336;
|
||||||
@ -58,7 +58,7 @@ public class Event {
|
|||||||
public static final int COLOR_INFORMATION = 0xff039be5;
|
public static final int COLOR_INFORMATION = 0xff039be5;
|
||||||
public static final int COLOR_TEACHER_ABSENCE = 0xff039be5;
|
public static final int COLOR_TEACHER_ABSENCE = 0xff039be5;
|
||||||
@ColumnInfo(name = "eventType")
|
@ColumnInfo(name = "eventType")
|
||||||
public int type = TYPE_DEFAULT;
|
public long type = TYPE_DEFAULT;
|
||||||
@ColumnInfo(name = "eventAddedManually")
|
@ColumnInfo(name = "eventAddedManually")
|
||||||
public boolean addedManually;
|
public boolean addedManually;
|
||||||
@ColumnInfo(name = "eventSharedBy")
|
@ColumnInfo(name = "eventSharedBy")
|
||||||
@ -76,7 +76,7 @@ public class Event {
|
|||||||
@Ignore
|
@Ignore
|
||||||
public Event() {}
|
public Event() {}
|
||||||
|
|
||||||
public Event(int profileId, long id, Date eventDate, @Nullable Time startTime, String topic, int color, int type, boolean addedManually, long teacherId, long subjectId, long teamId)
|
public Event(int profileId, long id, Date eventDate, @Nullable Time startTime, String topic, int color, long type, boolean addedManually, long teacherId, long subjectId, long teamId)
|
||||||
{
|
{
|
||||||
this.profileId = profileId;
|
this.profileId = profileId;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@ -97,8 +97,8 @@ public class Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Event clone() throws CloneNotSupportedException {
|
public Event clone() {
|
||||||
return new Event(
|
Event event = new Event(
|
||||||
profileId,
|
profileId,
|
||||||
id,
|
id,
|
||||||
eventDate.clone(),
|
eventDate.clone(),
|
||||||
@ -111,6 +111,10 @@ public class Event {
|
|||||||
teacherId,
|
teacherId,
|
||||||
teamId
|
teamId
|
||||||
);
|
);
|
||||||
|
event.sharedBy = sharedBy;
|
||||||
|
event.sharedByName = sharedByName;
|
||||||
|
event.blacklisted = blacklisted;
|
||||||
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -4,34 +4,18 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.db.entity
|
package pl.szczodrzynski.edziennik.data.db.entity
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_AUTO_ARCHIVING
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_ERROR
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_FEEDBACK_MESSAGE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_GENERAL
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_LUCKY_NUMBER
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_ANNOUNCEMENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_ATTENDANCE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_EVENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_GRADE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_HOMEWORK
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_MESSAGE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_NOTICE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_SHARED_EVENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_SERVER_MESSAGE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_TIMETABLE_CHANGED
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_TIMETABLE_LESSON_CHANGE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_UPDATE
|
|
||||||
|
|
||||||
@Entity(tableName = "notifications")
|
@Entity(tableName = "notifications")
|
||||||
data class Notification(
|
data class Notification(
|
||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
val id: Int = 0,
|
val id: Long = 0,
|
||||||
|
|
||||||
val title: String,
|
val title: String,
|
||||||
val text: String,
|
val text: String,
|
||||||
@ -41,7 +25,7 @@ data class Notification(
|
|||||||
val profileId: Int?,
|
val profileId: Int?,
|
||||||
val profileName: String?,
|
val profileName: String?,
|
||||||
|
|
||||||
var posted: Boolean = false,
|
var posted: Boolean = true,
|
||||||
|
|
||||||
var viewId: Int? = null,
|
var viewId: Int? = null,
|
||||||
var extras: JsonObject? = null,
|
var extras: JsonObject? = null,
|
||||||
@ -59,6 +43,7 @@ data class Notification(
|
|||||||
const val TYPE_NEW_HOMEWORK = 10
|
const val TYPE_NEW_HOMEWORK = 10
|
||||||
const val TYPE_NEW_SHARED_EVENT = 7
|
const val TYPE_NEW_SHARED_EVENT = 7
|
||||||
const val TYPE_NEW_SHARED_HOMEWORK = 12
|
const val TYPE_NEW_SHARED_HOMEWORK = 12
|
||||||
|
const val TYPE_REMOVED_SHARED_EVENT = 18
|
||||||
const val TYPE_NEW_MESSAGE = 8
|
const val TYPE_NEW_MESSAGE = 8
|
||||||
const val TYPE_NEW_NOTICE = 9
|
const val TYPE_NEW_NOTICE = 9
|
||||||
const val TYPE_NEW_ATTENDANCE = 13
|
const val TYPE_NEW_ATTENDANCE = 13
|
||||||
@ -67,6 +52,10 @@ data class Notification(
|
|||||||
const val TYPE_NEW_ANNOUNCEMENT = 15
|
const val TYPE_NEW_ANNOUNCEMENT = 15
|
||||||
const val TYPE_FEEDBACK_MESSAGE = 16
|
const val TYPE_FEEDBACK_MESSAGE = 16
|
||||||
const val TYPE_AUTO_ARCHIVING = 17
|
const val TYPE_AUTO_ARCHIVING = 17
|
||||||
|
|
||||||
|
fun buildId(profileId: Int, type: Int, itemId: Long): Long {
|
||||||
|
return 1000000000000 + profileId*10000000000 + type*100000000 + itemId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addExtra(key: String, value: Long?): Notification {
|
fun addExtra(key: String, value: Long?): Notification {
|
||||||
@ -100,4 +89,10 @@ data class Notification(
|
|||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getPendingIntent(context: Context): PendingIntent {
|
||||||
|
val intent = Intent(context, MainActivity::class.java)
|
||||||
|
fillIntent(intent)
|
||||||
|
return PendingIntent.getActivity(context, id.toInt(), intent, PendingIntent.FLAG_ONE_SHOT)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,21 +30,21 @@ open class Profile(
|
|||||||
val loginStoreId: Int,
|
val loginStoreId: Int,
|
||||||
val loginStoreType: Int,
|
val loginStoreType: Int,
|
||||||
|
|
||||||
override var name: String,
|
override var name: String = "",
|
||||||
override var subname: String?,
|
override var subname: String? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the student.
|
* The name of the student.
|
||||||
* This doesn't change, no matter if it's a parent or student account.
|
* This doesn't change, no matter if it's a parent or student account.
|
||||||
*/
|
*/
|
||||||
var studentNameLong: String,
|
var studentNameLong: String = "",
|
||||||
var studentNameShort: String,
|
var studentNameShort: String = "",
|
||||||
/**
|
/**
|
||||||
* A full name of the account owner.
|
* A full name of the account owner.
|
||||||
* If null, then it's a student account.
|
* If null, then it's a student account.
|
||||||
* If not null, then it's a parent account with this name.
|
* If not null, then it's a parent account with this name.
|
||||||
*/
|
*/
|
||||||
var accountName: String?,
|
var accountName: String? = null,
|
||||||
|
|
||||||
val studentData: JsonObject = JsonObject()
|
val studentData: JsonObject = JsonObject()
|
||||||
|
|
||||||
|
@ -45,6 +45,35 @@ public class EventFull extends Event {
|
|||||||
this.sharedByName = event.sharedByName;
|
this.sharedByName = event.sharedByName;
|
||||||
this.blacklisted = event.blacklisted;
|
this.blacklisted = event.blacklisted;
|
||||||
}
|
}
|
||||||
|
public EventFull(EventFull event) {
|
||||||
|
super(
|
||||||
|
event.profileId,
|
||||||
|
event.id,
|
||||||
|
event.eventDate.clone(),
|
||||||
|
event.startTime == null ? null : event.startTime.clone(),
|
||||||
|
event.topic,
|
||||||
|
event.color,
|
||||||
|
event.type,
|
||||||
|
event.addedManually,
|
||||||
|
event.teacherId,
|
||||||
|
event.subjectId,
|
||||||
|
event.teamId
|
||||||
|
);
|
||||||
|
|
||||||
|
this.sharedBy = event.sharedBy;
|
||||||
|
this.sharedByName = event.sharedByName;
|
||||||
|
this.blacklisted = event.blacklisted;
|
||||||
|
this.typeName = event.typeName;
|
||||||
|
this.typeColor = event.typeColor;
|
||||||
|
this.teacherFullName = event.teacherFullName;
|
||||||
|
this.subjectLongName = event.subjectLongName;
|
||||||
|
this.subjectShortName = event.subjectShortName;
|
||||||
|
this.teamName = event.teamName;
|
||||||
|
this.teamCode = event.teamCode;
|
||||||
|
this.seen = event.seen;
|
||||||
|
this.notified = event.notified;
|
||||||
|
this.addedDate = event.addedDate;
|
||||||
|
}
|
||||||
|
|
||||||
public EventFull(Event event, Metadata metadata) {
|
public EventFull(Event event, Metadata metadata) {
|
||||||
this(event);
|
this(event);
|
||||||
|
@ -11,11 +11,14 @@ import android.content.Intent
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.google.firebase.iid.zzaq
|
import com.google.firebase.iid.zzaq
|
||||||
import com.google.firebase.iid.zzv
|
import com.google.firebase.iid.zzv
|
||||||
import com.google.firebase.messaging.MessagingAnalytics
|
|
||||||
import com.google.firebase.messaging.zzc
|
import com.google.firebase.messaging.zzc
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import com.google.firebase.messaging.zzo.zza as logNotificationOpen
|
||||||
|
import com.google.firebase.messaging.zzo.zza as logNotificationReceived
|
||||||
|
import com.google.firebase.messaging.zzo.zzb as logNotificationDismiss
|
||||||
|
import com.google.firebase.messaging.zzo.zzd as shouldUploadMetrics
|
||||||
|
|
||||||
@SuppressLint("Registered")
|
@SuppressLint("Registered")
|
||||||
open class FirebaseService : zzc() {
|
open class FirebaseService : zzc() {
|
||||||
@ -45,8 +48,8 @@ open class FirebaseService : zzc() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MessagingAnalytics.shouldUploadMetrics(intent)) {
|
if (shouldUploadMetrics(intent)) {
|
||||||
MessagingAnalytics.logNotificationOpen(intent)
|
logNotificationOpen(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -62,8 +65,8 @@ open class FirebaseService : zzc() {
|
|||||||
|
|
||||||
when (action) {
|
when (action) {
|
||||||
"com.google.firebase.messaging.NOTIFICATION_DISMISS" -> {
|
"com.google.firebase.messaging.NOTIFICATION_DISMISS" -> {
|
||||||
if (MessagingAnalytics.shouldUploadMetrics(intent)) {
|
if (shouldUploadMetrics(intent)) {
|
||||||
MessagingAnalytics.logNotificationDismiss(intent)
|
logNotificationDismiss(intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"com.google.firebase.messaging.NEW_TOKEN" -> {
|
"com.google.firebase.messaging.NEW_TOKEN" -> {
|
||||||
@ -106,8 +109,8 @@ open class FirebaseService : zzc() {
|
|||||||
// get the message type
|
// get the message type
|
||||||
when (val it = json.getString("message_type") ?: "gcm") {
|
when (val it = json.getString("message_type") ?: "gcm") {
|
||||||
"gcm" -> { // 0
|
"gcm" -> { // 0
|
||||||
if (MessagingAnalytics.shouldUploadMetrics(intent)) {
|
if (shouldUploadMetrics(intent)) {
|
||||||
MessagingAnalytics.logNotificationReceived(intent)
|
logNotificationReceived(intent, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
onMessageReceived(Message(messageId, json))
|
onMessageReceived(Message(messageId, json))
|
||||||
|
@ -5,36 +5,19 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.firebase;
|
package pl.szczodrzynski.edziennik.data.firebase;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.google.firebase.messaging.FirebaseMessagingService;
|
import com.google.firebase.messaging.FirebaseMessagingService;
|
||||||
import com.google.firebase.messaging.RemoteMessage;
|
import com.google.firebase.messaging.RemoteMessage;
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.App;
|
import pl.szczodrzynski.edziennik.App;
|
||||||
import pl.szczodrzynski.edziennik.BuildConfig;
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask;
|
||||||
import pl.szczodrzynski.edziennik.MainActivity;
|
|
||||||
import pl.szczodrzynski.edziennik.R;
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.EventType;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore;
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore;
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile;
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile;
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Team;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull;
|
|
||||||
import pl.szczodrzynski.edziennik.network.ServerRequest;
|
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.base.DebugFragment;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Notification;
|
|
||||||
|
|
||||||
import static pl.szczodrzynski.edziennik.App.APP_URL;
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.Event.TYPE_HOMEWORK;
|
|
||||||
import static pl.szczodrzynski.edziennik.utils.Utils.d;
|
import static pl.szczodrzynski.edziennik.utils.Utils.d;
|
||||||
import static pl.szczodrzynski.edziennik.utils.Utils.strToInt;
|
import static pl.szczodrzynski.edziennik.utils.Utils.strToInt;
|
||||||
|
|
||||||
@ -45,16 +28,16 @@ public class MyFirebaseMessagingService extends FirebaseMessagingService {
|
|||||||
public void onNewToken(String s) {
|
public void onNewToken(String s) {
|
||||||
super.onNewToken(s);
|
super.onNewToken(s);
|
||||||
|
|
||||||
Log.d(TAG, "New token: "+s);
|
/* Log.d(TAG, "New token: "+s);
|
||||||
App app = (App)getApplicationContext();
|
App app = (App)getApplicationContext();
|
||||||
if (app.config.getSync().getTokenApp() == null || !app.config.getSync().getTokenApp().equals(s)) {
|
if (app.config.getSync().getTokenApp() == null || !app.config.getSync().getTokenApp().equals(s)) {
|
||||||
app.config.getSync().setTokenApp(s);
|
app.config.getSync().setTokenApp(s);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessageReceived(RemoteMessage remoteMessage) {
|
public void onMessageReceived(RemoteMessage remoteMessage) {
|
||||||
App app = ((App) getApplicationContext());
|
/*App app = ((App) getApplicationContext());
|
||||||
// Not getting messages here? See why this may be: https://goo.gl/39bRNJ
|
// Not getting messages here? See why this may be: https://goo.gl/39bRNJ
|
||||||
|
|
||||||
String from = remoteMessage.getFrom();
|
String from = remoteMessage.getFrom();
|
||||||
@ -78,7 +61,7 @@ public class MyFirebaseMessagingService extends FirebaseMessagingService {
|
|||||||
processVulcanPush(app, remoteMessage);
|
processVulcanPush(app, remoteMessage);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processMobidziennikPush(App app, RemoteMessage remoteMessage) {
|
private void processMobidziennikPush(App app, RemoteMessage remoteMessage) {
|
||||||
@ -102,14 +85,7 @@ public class MyFirebaseMessagingService extends FirebaseMessagingService {
|
|||||||
|
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
if (remoteMessage.getData().get("id_wiadomosci") != null) {
|
if (remoteMessage.getData().get("id_wiadomosci") != null) {
|
||||||
/*app.notifier.add(new Notification(app.getContext(), remoteMessage.getData().get("message"))
|
|
||||||
.withProfileData(profile.id, profile.name)
|
|
||||||
.withTitle(remoteMessage.getData().get("title"))
|
|
||||||
.withType(Notification.TYPE_NEW_MESSAGE)
|
|
||||||
.withFragmentRedirect(MainActivity.DRAWER_ITEM_MESSAGES)
|
|
||||||
);
|
|
||||||
app.notifier.postAll(profile);
|
|
||||||
app.saveConfig("notifications");*/
|
|
||||||
d(TAG, "Syncing profile " + profile.getId());
|
d(TAG, "Syncing profile " + profile.getId());
|
||||||
EdziennikTask.Companion.syncProfile(profile.getId(), null, null).enqueue(app);
|
EdziennikTask.Companion.syncProfile(profile.getId(), null, null).enqueue(app);
|
||||||
} else {
|
} else {
|
||||||
@ -141,7 +117,7 @@ public class MyFirebaseMessagingService extends FirebaseMessagingService {
|
|||||||
|
|
||||||
private void processAppPush(App app, RemoteMessage remoteMessage) {
|
private void processAppPush(App app, RemoteMessage remoteMessage) {
|
||||||
// Check if message contains a data payload.
|
// Check if message contains a data payload.
|
||||||
String type = remoteMessage.getData().get("type");
|
/*String type = remoteMessage.getData().get("type");
|
||||||
if (remoteMessage.getData().size() > 0
|
if (remoteMessage.getData().size() > 0
|
||||||
&& type != null) {
|
&& type != null) {
|
||||||
//Log.d(TAG, "Message data payload: " + remoteMessage.sync());
|
//Log.d(TAG, "Message data payload: " + remoteMessage.sync());
|
||||||
@ -239,90 +215,8 @@ public class MyFirebaseMessagingService extends FirebaseMessagingService {
|
|||||||
break;
|
break;
|
||||||
case "ping":
|
case "ping":
|
||||||
// just a ping
|
// just a ping
|
||||||
break;
|
break
|
||||||
/* ______ _ _
|
|
||||||
| ____| | | | |
|
|
||||||
| |____ _____ _ __ | |_ ______ ___| |__ __ _ _ __ ___
|
|
||||||
| __\ \ / / _ \ '_ \| __| |______| / __| '_ \ / _` | '__/ _ \
|
|
||||||
| |___\ V / __/ | | | |_ \__ \ | | | (_| | | | __/
|
|
||||||
|______\_/ \___|_| |_|\__| |___/_| |_|\__,_|_| \__*/
|
|
||||||
case "event":
|
|
||||||
case "event_removed":
|
|
||||||
AsyncTask.execute(() -> {
|
|
||||||
String teamCode = remoteMessage.getData().get("team");
|
|
||||||
String teamUnshareCode = remoteMessage.getData().get("team_unshare");
|
|
||||||
while (teamCode != null || teamUnshareCode != null) {
|
|
||||||
d(TAG, "Got an event for teamCode " + teamCode + " and teamUnshareCode " + teamUnshareCode);
|
|
||||||
// get the target Profile by the corresponding teamCode
|
|
||||||
List<Profile> profiles = app.db.profileDao().getByTeamCodeNowWithRegistration(teamCode == null ? teamUnshareCode : teamCode);
|
|
||||||
for (Profile profile : profiles) {
|
|
||||||
d(TAG, "Matched profile " + profile.getName());
|
|
||||||
if (teamCode != null) {
|
|
||||||
// SHARING
|
|
||||||
JsonObject jEvent = new JsonParser().parse(remoteMessage.getData().get("data")).getAsJsonObject();
|
|
||||||
d(TAG, "An event is there! " + jEvent.toString());
|
|
||||||
// get the target Team from teamCode
|
|
||||||
Team team = app.db.teamDao().getByCodeNow(profile.getId(), teamCode);
|
|
||||||
if (team != null) {
|
|
||||||
d(TAG, "The target team is " + team.name + ", ID " + team.id);
|
|
||||||
// create the event from Json. Add the missing teamId and !!profileId!!
|
|
||||||
Event event = app.gson.fromJson(jEvent.toString(), Event.class);
|
|
||||||
if (jEvent.get("colorDefault") != null) {
|
|
||||||
event.color = -1;
|
|
||||||
}
|
|
||||||
event.profileId = profile.getId();
|
|
||||||
event.teamId = team.id;
|
|
||||||
d(TAG, "Created the event! " + event);
|
|
||||||
|
|
||||||
// TODO? i guess
|
|
||||||
Event oldEvent = app.db.eventDao().getByIdNow(profile.getId(), event.id);
|
|
||||||
if (event.sharedBy != null && event.sharedBy.equals(profile.getUserCode())) {
|
|
||||||
d(TAG, "Shared by self! Changing name");
|
|
||||||
event.sharedBy = "self";
|
|
||||||
event.sharedByName = profile.getStudentNameLong();
|
|
||||||
}
|
|
||||||
d(TAG, "Old event found? " + oldEvent);
|
|
||||||
EventType eventType = app.db.eventTypeDao().getByIdNow(profile.getId(), event.type);
|
|
||||||
app.notifier.add(new Notification(app.getContext(), app.getString((oldEvent == null ? R.string.notification_shared_event_format : R.string.notification_shared_event_modified_format), event.sharedByName, eventType == null ? "wydarzenie" : eventType.name, event.eventDate.getFormattedString(), event.topic))
|
|
||||||
.withProfileData(profile.getId(), profile.getName())
|
|
||||||
.withType(event.type == TYPE_HOMEWORK ? pl.szczodrzynski.edziennik.data.db.entity.Notification.TYPE_NEW_SHARED_HOMEWORK : pl.szczodrzynski.edziennik.data.db.entity.Notification.TYPE_NEW_SHARED_EVENT)
|
|
||||||
.withFragmentRedirect(event.type == TYPE_HOMEWORK ? MainActivity.DRAWER_ITEM_HOMEWORK : MainActivity.DRAWER_ITEM_AGENDA)
|
|
||||||
.withLongExtra("eventDate", event.eventDate.getValue())
|
|
||||||
);
|
|
||||||
d(TAG, "Finishing adding event " + event);
|
|
||||||
app.db.eventDao().add(event);
|
|
||||||
try {
|
|
||||||
app.db.metadataDao().setBoth(profile.getId(), event, false, true, jEvent.get("addedDate").getAsLong());
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// UNSHARING
|
|
||||||
long eventId = Long.parseLong(remoteMessage.getData().get("remove_id"));
|
|
||||||
EventFull oldEvent = app.db.eventDao().getByIdNow(profile.getId(), eventId);
|
|
||||||
if (oldEvent != null) {
|
|
||||||
app.notifier.add(new Notification(app.getContext(), app.getString(R.string.notification_shared_event_removed_format, oldEvent.sharedByName, oldEvent.typeName, oldEvent.eventDate.getFormattedString(), oldEvent.topic))
|
|
||||||
.withProfileData(profile.getId(), profile.getName())
|
|
||||||
.withType(oldEvent.type == TYPE_HOMEWORK ? pl.szczodrzynski.edziennik.data.db.entity.Notification.TYPE_NEW_SHARED_HOMEWORK : pl.szczodrzynski.edziennik.data.db.entity.Notification.TYPE_NEW_SHARED_EVENT)
|
|
||||||
.withFragmentRedirect(oldEvent.type == TYPE_HOMEWORK ? MainActivity.DRAWER_ITEM_HOMEWORK : MainActivity.DRAWER_ITEM_AGENDA)
|
|
||||||
.withLongExtra("eventDate", oldEvent.eventDate.getValue())
|
|
||||||
);
|
|
||||||
app.db.eventDao().remove(oldEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (teamCode != null) {
|
|
||||||
teamCode = null;
|
|
||||||
} else {
|
|
||||||
teamUnshareCode = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
app.notifier.postAll();
|
|
||||||
app.saveConfig();
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,129 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.firebase
|
package pl.szczodrzynski.edziennik.data.firebase
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
import com.google.gson.JsonParser
|
||||||
|
import pl.szczodrzynski.edziennik.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.task.PostNotifications
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
|
||||||
class SzkolnyAppFirebase(val app: App, val profiles: List<Profile>, val message: FirebaseService.Message) {
|
class SzkolnyAppFirebase(val app: App, val profiles: List<Profile>, val message: FirebaseService.Message) {
|
||||||
init {
|
init {
|
||||||
|
run {
|
||||||
|
val type = message.data.getString("type") ?: return@run
|
||||||
|
when (type) {
|
||||||
|
"sharedEvent" -> sharedEvent(
|
||||||
|
message.data.getString("shareTeamCode") ?: return@run,
|
||||||
|
message.data.getString("event") ?: return@run,
|
||||||
|
message.data.getString("message") ?: return@run
|
||||||
|
)
|
||||||
|
"unsharedEvent" -> unsharedEvent(
|
||||||
|
message.data.getString("unshareTeamCode") ?: return@run,
|
||||||
|
message.data.getLong("eventId") ?: return@run,
|
||||||
|
message.data.getString("message") ?: return@run
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sharedEvent(teamCode: String, jsonStr: String, message: String) {
|
||||||
|
val json = JsonParser().parse(jsonStr).asJsonObject
|
||||||
|
val teams = app.db.teamDao().allNow
|
||||||
|
val eventTypes = app.db.eventTypeDao().allNow
|
||||||
|
|
||||||
|
val events = mutableListOf<Event>()
|
||||||
|
val metadataList = mutableListOf<Metadata>()
|
||||||
|
val notificationList = mutableListOf<Notification>()
|
||||||
|
|
||||||
|
teams.filter { it.code == teamCode }.distinctBy { it.profileId }.forEach { team ->
|
||||||
|
val profile = profiles.firstOrNull { it.id == team.profileId }
|
||||||
|
val event = Event(
|
||||||
|
team.profileId,
|
||||||
|
json.getLong("id") ?: return,
|
||||||
|
json.getInt("eventDate")?.let { Date.fromValue(it) } ?: return,
|
||||||
|
json.getInt("startTime")?.let { Time.fromValue(it) },
|
||||||
|
json.getString("topic") ?: "",
|
||||||
|
json.getInt("color") ?: -1,
|
||||||
|
json.getLong("type") ?: 0,
|
||||||
|
true,
|
||||||
|
json.getLong("teacherId") ?: -1,
|
||||||
|
json.getLong("subjectId") ?: -1,
|
||||||
|
team.id
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO? i guess - this comment is here for like a year
|
||||||
|
//val oldEvent: Event? = app.db.eventDao().getByIdNow(profile?.id ?: -1, event.id)
|
||||||
|
|
||||||
|
event.sharedBy = json.getString("sharedBy")
|
||||||
|
event.sharedByName = json.getString("sharedByName")
|
||||||
|
if (profile?.userCode == event.sharedBy) event.sharedBy = "self"
|
||||||
|
|
||||||
|
val metadata = Metadata(
|
||||||
|
event.profileId,
|
||||||
|
if (event.type == Event.TYPE_HOMEWORK) Metadata.TYPE_HOMEWORK else Metadata.TYPE_EVENT,
|
||||||
|
event.id,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
json.getLong("addedDate") ?: System.currentTimeMillis()
|
||||||
|
)
|
||||||
|
|
||||||
|
//val eventType = eventTypes.firstOrNull { it.profileId == profile?.id && it.id == event.type }
|
||||||
|
|
||||||
|
/*val text = app.getString(
|
||||||
|
if (oldEvent == null)
|
||||||
|
R.string.notification_shared_event_format
|
||||||
|
else
|
||||||
|
R.string.notification_shared_event_modified_format,
|
||||||
|
event.sharedByName,
|
||||||
|
eventType?.name ?: "wydarzenie",
|
||||||
|
event.eventDate.formattedString,
|
||||||
|
event.topic
|
||||||
|
)*/
|
||||||
|
val type = if (event.type == Event.TYPE_HOMEWORK) Notification.TYPE_NEW_SHARED_HOMEWORK else Notification.TYPE_NEW_SHARED_EVENT
|
||||||
|
val notification = Notification(
|
||||||
|
id = Notification.buildId(event.profileId, type, event.id),
|
||||||
|
title = app.getNotificationTitle(type),
|
||||||
|
text = message,
|
||||||
|
type = type,
|
||||||
|
profileId = profile?.id,
|
||||||
|
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())
|
||||||
|
|
||||||
|
events += event
|
||||||
|
metadataList += metadata
|
||||||
|
notificationList += notification
|
||||||
|
}
|
||||||
|
app.db.eventDao().addAll(events)
|
||||||
|
app.db.metadataDao().addAllReplace(metadataList)
|
||||||
|
app.db.notificationDao().addAll(notificationList)
|
||||||
|
PostNotifications(app, notificationList)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun unsharedEvent(teamCode: String, eventId: Long, message: String) {
|
||||||
|
val teams = app.db.teamDao().allNow
|
||||||
|
val notificationList = mutableListOf<Notification>()
|
||||||
|
|
||||||
|
teams.filter { it.code == teamCode }.distinctBy { it.profileId }.forEach { team ->
|
||||||
|
val profile = profiles.firstOrNull { it.id == team.profileId }
|
||||||
|
val notification = Notification(
|
||||||
|
id = Notification.buildId(profile?.id ?: 0, Notification.TYPE_REMOVED_SHARED_EVENT, eventId),
|
||||||
|
title = app.getNotificationTitle(Notification.TYPE_REMOVED_SHARED_EVENT),
|
||||||
|
text = message,
|
||||||
|
type = Notification.TYPE_REMOVED_SHARED_EVENT,
|
||||||
|
profileId = profile?.id,
|
||||||
|
profileName = profile?.name,
|
||||||
|
viewId = MainActivity.DRAWER_ITEM_AGENDA
|
||||||
|
)
|
||||||
|
notificationList += notification
|
||||||
|
app.db.eventDao().remove(team.profileId, eventId)
|
||||||
|
}
|
||||||
|
app.db.notificationDao().addAll(notificationList)
|
||||||
|
PostNotifications(app, notificationList)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,7 +5,7 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.firebase
|
package pl.szczodrzynski.edziennik.data.firebase
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
|
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.getString
|
import pl.szczodrzynski.edziennik.getString
|
||||||
|
@ -9,7 +9,7 @@ import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_ATTENDANCE
|
|||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_BEHAVIOUR
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_BEHAVIOUR
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_GRADES
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_GRADES
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
|
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
|
@ -22,7 +22,7 @@ public class NetworkUtils {
|
|||||||
public boolean isOnline() {
|
public boolean isOnline() {
|
||||||
assert app != null;
|
assert app != null;
|
||||||
ConnectivityManager cm =
|
ConnectivityManager cm =
|
||||||
(ConnectivityManager) app.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
|
(ConnectivityManager) app.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
assert cm != null;
|
assert cm != null;
|
||||||
NetworkInfo netInfo = cm.getActiveNetworkInfo();
|
NetworkInfo netInfo = cm.getActiveNetworkInfo();
|
||||||
return netInfo != null && netInfo.isConnectedOrConnecting();
|
return netInfo != null && netInfo.isConnectedOrConnecting();
|
||||||
@ -30,7 +30,7 @@ public class NetworkUtils {
|
|||||||
|
|
||||||
public int checkBackgroundDataRestricted() {
|
public int checkBackgroundDataRestricted() {
|
||||||
|
|
||||||
ConnectivityManager connMgr = (ConnectivityManager) app.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
|
ConnectivityManager connMgr = (ConnectivityManager) app.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
assert connMgr != null;
|
assert connMgr != null;
|
||||||
|
@ -29,7 +29,7 @@ public class ServerRequest {
|
|||||||
private String source = "";
|
private String source = "";
|
||||||
|
|
||||||
public ServerRequest(App app, String url, String source) {
|
public ServerRequest(App app, String url, String source) {
|
||||||
this(app, url, source, app.profile);
|
this(app, url, source, App.Companion.getProfile());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerRequest(App app, String url, String source, Profile profileFull) {
|
public ServerRequest(App app, String url, String source, Profile profileFull) {
|
||||||
@ -40,7 +40,7 @@ public class ServerRequest {
|
|||||||
this.app = app;
|
this.app = app;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.params = new ArrayList<>();
|
this.params = new ArrayList<>();
|
||||||
this.username = (profile != null && profile.getRegistration() == REGISTRATION_ENABLED ? usernameId : app.deviceId);
|
this.username = (profile != null && profile.getRegistration() == REGISTRATION_ENABLED ? usernameId : app.getDeviceId());
|
||||||
this.source = source;
|
this.source = source;
|
||||||
if (profile != null && profile.getRegistration() == REGISTRATION_ENABLED) {
|
if (profile != null && profile.getRegistration() == REGISTRATION_ENABLED) {
|
||||||
this.setBodyParameter("login_type", Integer.toString(loginStoreType));
|
this.setBodyParameter("login_type", Integer.toString(loginStoreType));
|
||||||
@ -51,7 +51,7 @@ public class ServerRequest {
|
|||||||
this.setBodyParameter("team_ids", "UI_THREAD");
|
this.setBodyParameter("team_ids", "UI_THREAD");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.setBodyParameter("team_ids", app.gson.toJson(app.db.teamDao().getAllCodesNow(profile.getId())));
|
this.setBodyParameter("team_ids", app.getGson().toJson(App.db.teamDao().getAllCodesNow(profile.getId())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,15 +86,15 @@ public class ServerRequest {
|
|||||||
.addParameter("app_version_build_type", BuildConfig.BUILD_TYPE)
|
.addParameter("app_version_build_type", BuildConfig.BUILD_TYPE)
|
||||||
.addParameter("app_version_code", Integer.toString(BuildConfig.VERSION_CODE))
|
.addParameter("app_version_code", Integer.toString(BuildConfig.VERSION_CODE))
|
||||||
.addParameter("app_version", BuildConfig.VERSION_NAME + " " + BuildConfig.BUILD_TYPE + " (" + BuildConfig.VERSION_CODE + ")")
|
.addParameter("app_version", BuildConfig.VERSION_NAME + " " + BuildConfig.BUILD_TYPE + " (" + BuildConfig.VERSION_CODE + ")")
|
||||||
.addParameter("device_id", Settings.Secure.getString(app.getContext().getContentResolver(), Settings.Secure.ANDROID_ID))
|
.addParameter("device_id", Settings.Secure.getString(app.getContentResolver(), Settings.Secure.ANDROID_ID))
|
||||||
.addParameter("device_model", Build.MANUFACTURER+" "+Build.MODEL)
|
.addParameter("device_model", Build.MANUFACTURER+" "+Build.MODEL)
|
||||||
.addParameter("device_os_version", Build.VERSION.RELEASE)
|
.addParameter("device_os_version", Build.VERSION.RELEASE)
|
||||||
.addParameter("fcm_token", app.config.getSync().getTokenApp())
|
.addParameter("fcm_token", app.getConfig().getSync().getTokenApp())
|
||||||
.addParameter("signature", sign(app.signature, timestamp))
|
.addParameter("signature", "TODO")
|
||||||
.addParameter("signature_timestamp", timestamp)
|
.addParameter("signature_timestamp", timestamp)
|
||||||
.addParameter("package_name", "pl.szczodrzynski.edziennik")
|
.addParameter("package_name", "pl.szczodrzynski.edziennik")
|
||||||
.addParameter("source", source)
|
.addParameter("source", source)
|
||||||
.addParameter("update_frequency", app.config.getSync().getEnabled() ? app.config.getSync().getInterval() : -1)
|
.addParameter("update_frequency", app.getConfig().getSync().getEnabled() ? app.getConfig().getSync().getInterval() : -1)
|
||||||
.post()
|
.post()
|
||||||
.callback(new JsonCallbackHandler() {
|
.callback(new JsonCallbackHandler() {
|
||||||
@Override
|
@Override
|
||||||
@ -123,15 +123,15 @@ public class ServerRequest {
|
|||||||
.addParameter("app_version_build_type", BuildConfig.BUILD_TYPE)
|
.addParameter("app_version_build_type", BuildConfig.BUILD_TYPE)
|
||||||
.addParameter("app_version_code", Integer.toString(BuildConfig.VERSION_CODE))
|
.addParameter("app_version_code", Integer.toString(BuildConfig.VERSION_CODE))
|
||||||
.addParameter("app_version", BuildConfig.VERSION_NAME + " " + BuildConfig.BUILD_TYPE + " (" + BuildConfig.VERSION_CODE + ")")
|
.addParameter("app_version", BuildConfig.VERSION_NAME + " " + BuildConfig.BUILD_TYPE + " (" + BuildConfig.VERSION_CODE + ")")
|
||||||
.addParameter("device_id", Settings.Secure.getString(app.getContext().getContentResolver(), Settings.Secure.ANDROID_ID))
|
.addParameter("device_id", Settings.Secure.getString(app.getContentResolver(), Settings.Secure.ANDROID_ID))
|
||||||
.addParameter("device_model", Build.MANUFACTURER+" "+Build.MODEL)
|
.addParameter("device_model", Build.MANUFACTURER+" "+Build.MODEL)
|
||||||
.addParameter("device_os_version", Build.VERSION.RELEASE)
|
.addParameter("device_os_version", Build.VERSION.RELEASE)
|
||||||
.addParameter("fcm_token", app.config.getSync().getTokenApp())
|
.addParameter("fcm_token", app.getConfig().getSync().getTokenApp())
|
||||||
.addParameter("signature", sign(app.signature, timestamp))
|
.addParameter("signature", "TODO")
|
||||||
.addParameter("signature_timestamp", timestamp)
|
.addParameter("signature_timestamp", timestamp)
|
||||||
.addParameter("package_name", "pl.szczodrzynski.edziennik")
|
.addParameter("package_name", "pl.szczodrzynski.edziennik")
|
||||||
.addParameter("source", source)
|
.addParameter("source", source)
|
||||||
.addParameter("update_frequency", app.config.getSync().getEnabled() ? app.config.getSync().getInterval() : -1)
|
.addParameter("update_frequency", app.getConfig().getSync().getEnabled() ? app.getConfig().getSync().getInterval() : -1)
|
||||||
.post()
|
.post()
|
||||||
.build()
|
.build()
|
||||||
.execute();
|
.execute();
|
||||||
|
@ -1,287 +0,0 @@
|
|||||||
package pl.szczodrzynski.edziennik.receivers;
|
|
||||||
|
|
||||||
import android.app.AlarmManager;
|
|
||||||
import android.app.DownloadManager;
|
|
||||||
import android.app.IntentService;
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.content.pm.ResolveInfo;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.core.content.FileProvider;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.App;
|
|
||||||
import pl.szczodrzynski.edziennik.R;
|
|
||||||
import pl.szczodrzynski.edziennik.network.ServerRequest;
|
|
||||||
import pl.szczodrzynski.edziennik.sync.SyncWorker;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils;
|
|
||||||
|
|
||||||
import static android.content.Context.DOWNLOAD_SERVICE;
|
|
||||||
import static pl.szczodrzynski.edziennik.App.APP_URL;
|
|
||||||
import static pl.szczodrzynski.edziennik.App.UPDATES_ON_PLAY_STORE;
|
|
||||||
|
|
||||||
public class BootReceiver extends BroadcastReceiver {
|
|
||||||
|
|
||||||
private static final int NO_INTERNET_RETRY_TIMEOUT = 60;
|
|
||||||
private static boolean alarmSet = false;
|
|
||||||
public static long update_download_id;
|
|
||||||
public static String update_url;
|
|
||||||
public static String update_filename;
|
|
||||||
private static final String TAG = "receivers.BootReceiver";
|
|
||||||
private App app;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReceive(final Context context, final Intent intent) {
|
|
||||||
app = (App)context.getApplicationContext();
|
|
||||||
if (intent.getBooleanExtra("ExecutedByAlarm", false))
|
|
||||||
{
|
|
||||||
alarmSet = false;
|
|
||||||
}
|
|
||||||
if (intent.getAction() != null && intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
|
|
||||||
{
|
|
||||||
long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
|
|
||||||
if(referenceId == update_download_id) {
|
|
||||||
Intent downloadIntent;
|
|
||||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
if (!app.permissionChecker.canRequestApkInstall()) {
|
|
||||||
app.permissionChecker.requestApkInstall();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File fileLocation = new File(app.getContext().getExternalFilesDir(null), update_filename);
|
|
||||||
Uri apkUri = FileProvider.getUriForFile(app.getContext(), app.getContext().getApplicationContext().getPackageName() + ".provider", fileLocation);
|
|
||||||
|
|
||||||
downloadIntent = new Intent(Intent.ACTION_VIEW);
|
|
||||||
downloadIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
|
||||||
downloadIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
downloadIntent.setDataAndType(apkUri, "application/vnd.android.package-archive");
|
|
||||||
|
|
||||||
List<ResolveInfo> resInfoList = app.getContext().getPackageManager().queryIntentActivities(downloadIntent, PackageManager.MATCH_DEFAULT_ONLY);
|
|
||||||
for (ResolveInfo resolveInfo : resInfoList) {
|
|
||||||
String packageName = resolveInfo.activityInfo.packageName;
|
|
||||||
app.getContext().grantUriPermission(packageName, apkUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
File fileLocation = new File(app.getContext().getExternalFilesDir(null), update_filename);
|
|
||||||
downloadIntent = new Intent(Intent.ACTION_VIEW);
|
|
||||||
downloadIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
downloadIntent.setDataAndType(Uri.fromFile(fileLocation), "application/vnd.android.package-archive");
|
|
||||||
}
|
|
||||||
app.getContext().startActivity(downloadIntent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SyncWorker.Companion.scheduleNext(app, false);
|
|
||||||
if (app.networkUtils.isOnline())
|
|
||||||
{
|
|
||||||
checkUpdate(context, intent);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Toast.makeText(context, "No internet, retrying in "+NO_INTERNET_RETRY_TIMEOUT+" seconds", Toast.LENGTH_SHORT).show();
|
|
||||||
scheduleUpdateCheck(context, NO_INTERNET_RETRY_TIMEOUT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean scheduleUpdateCheck(Context context, int secondsLater)
|
|
||||||
{
|
|
||||||
Intent alarmIntent = new Intent(context, BootReceiver.class);
|
|
||||||
alarmIntent.putExtra("ExecutedByAlarm", true);
|
|
||||||
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(context, 234324243, alarmIntent, 0);
|
|
||||||
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
|
||||||
if (alarmManager != null) {
|
|
||||||
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (secondsLater * 1000), alarmPendingIntent);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkUpdate(final Context context, final Intent intent)
|
|
||||||
{
|
|
||||||
if (!alarmSet) {
|
|
||||||
//Toast.makeText(context, "Update scheduled for 48 hours since now", Toast.LENGTH_SHORT).show();
|
|
||||||
alarmSet = scheduleUpdateCheck(context, 48 * 60 * 60);
|
|
||||||
}
|
|
||||||
|
|
||||||
//app.networkUtils.setSelfSignedSSL(app.getContext(), null);
|
|
||||||
|
|
||||||
new ServerRequest(app, app.requestScheme + APP_URL + "main.php?get_update", "BootReceiver/UPD")
|
|
||||||
.run(((e, result) -> {
|
|
||||||
if (result != null) {
|
|
||||||
if (result.get("update_available").getAsBoolean()) {
|
|
||||||
String updateVersion = result.get("update_version").getAsString();
|
|
||||||
String updateUrl = result.get("update_url").getAsString();
|
|
||||||
String updateFilename = result.get("update_filename").getAsString();
|
|
||||||
boolean updateMandatory = result.get("update_mandatory").getAsBoolean();
|
|
||||||
boolean updateDirect = result.get("update_direct").getAsBoolean();
|
|
||||||
|
|
||||||
if (app.appConfig.updateVersion == null || !app.appConfig.updateVersion.equals(updateVersion)) {
|
|
||||||
app.appConfig.updateVersion = updateVersion;
|
|
||||||
app.appConfig.updateUrl = updateUrl;
|
|
||||||
app.appConfig.updateFilename = updateFilename;
|
|
||||||
app.appConfig.updateMandatory = updateMandatory;
|
|
||||||
app.appConfig.updateDirect = updateDirect;
|
|
||||||
app.saveConfig();
|
|
||||||
}
|
|
||||||
if (!UPDATES_ON_PLAY_STORE || intent.getBooleanExtra("UserChecked", false)) {
|
|
||||||
app.notifier.notificationUpdatesShow(
|
|
||||||
updateVersion,
|
|
||||||
updateUrl,
|
|
||||||
updateFilename,
|
|
||||||
updateDirect);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (app.appConfig.updateVersion == null || !app.appConfig.updateVersion.equals("")) {
|
|
||||||
app.appConfig.updateVersion = "";
|
|
||||||
app.appConfig.updateMandatory = false;
|
|
||||||
app.saveConfig();
|
|
||||||
}
|
|
||||||
app.notifier.notificationUpdatesHide();
|
|
||||||
|
|
||||||
if (intent.getBooleanExtra("UserChecked", false)) {
|
|
||||||
Toast.makeText(context, context.getString(R.string.notification_no_update), Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Toast.makeText(context, "Server returned nothing, retrying in "+NO_INTERNET_RETRY_TIMEOUT+" seconds", Toast.LENGTH_SHORT).show();
|
|
||||||
scheduleUpdateCheck(context, NO_INTERNET_RETRY_TIMEOUT);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
/*Ion.with(app.getContext())
|
|
||||||
.load(app.requestScheme + APP_URL + "main.php?get_update")
|
|
||||||
.setBodyParameter("username", (app.profile.autoRegistrationAllowed ? app.profile.registrationUsername : app.appConfig.deviceId))
|
|
||||||
.setBodyParameter("app_version_build_type", BuildConfig.BUILD_TYPE)
|
|
||||||
.setBodyParameter("app_version_code", Integer.toString(BuildConfig.VERSION_CODE))
|
|
||||||
.setBodyParameter("app_version", BuildConfig.VERSION_NAME + " " + BuildConfig.BUILD_TYPE + " (" + BuildConfig.VERSION_CODE + ")")
|
|
||||||
.setBodyParameter("device_id", Settings.Secure.getString(app.getContext().getContentResolver(), Settings.Secure.ANDROID_ID))
|
|
||||||
.setBodyParameter("device_model", Build.MANUFACTURER+" "+Build.MODEL)
|
|
||||||
.setBodyParameter("device_os_version", Build.VERSION.RELEASE)
|
|
||||||
.setBodyParameter("fcm_token", app.appConfig.fcmToken)
|
|
||||||
.asJsonObject()
|
|
||||||
.setCallback((e, result) -> {
|
|
||||||
// do stuff with the result or error
|
|
||||||
if (result != null) {
|
|
||||||
if (result.get("update_available").getAsBoolean()) {
|
|
||||||
String updateVersion = result.get("update_version").getAsString();
|
|
||||||
String updateUrl = result.get("update_url").getAsString();
|
|
||||||
String updateFilename = result.get("update_filename").getAsString();
|
|
||||||
|
|
||||||
if (app.appConfig.updateVersion == null || !app.appConfig.updateVersion.equals(updateVersion)) {
|
|
||||||
app.appConfig.updateVersion = updateVersion;
|
|
||||||
app.appConfig.updateUrl = updateUrl;
|
|
||||||
app.appConfig.updateFilename = updateFilename;
|
|
||||||
app.saveConfig();
|
|
||||||
}
|
|
||||||
app.notifier.notificationUpdatesShow(
|
|
||||||
updateVersion,
|
|
||||||
updateUrl,
|
|
||||||
updateFilename);
|
|
||||||
} else {
|
|
||||||
if (app.appConfig.updateVersion == null || !app.appConfig.updateVersion.equals("")) {
|
|
||||||
app.appConfig.updateVersion = "";
|
|
||||||
app.saveConfig();
|
|
||||||
}
|
|
||||||
app.notifier.notificationUpdatesHide();
|
|
||||||
|
|
||||||
if (intent.getBooleanExtra("UserChecked", false)) {
|
|
||||||
Toast.makeText(context, context.getString(R.string.notification_no_update), Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Toast.makeText(context, "Server returned nothing, retrying in "+NO_INTERNET_RETRY_TIMEOUT+" seconds", Toast.LENGTH_SHORT).show();
|
|
||||||
scheduleUpdateCheck(context, NO_INTERNET_RETRY_TIMEOUT);
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
}
|
|
||||||
|
|
||||||
private static DownloadManager downloadManager;
|
|
||||||
|
|
||||||
public static long downloadFile(Context context) {
|
|
||||||
Toast.makeText(context, R.string.downloading, Toast.LENGTH_SHORT).show();
|
|
||||||
File dir = new File(context.getExternalFilesDir(null)+""/*, update_filename*/);
|
|
||||||
/*if (existingFile.exists())
|
|
||||||
{
|
|
||||||
existingFile.delete();
|
|
||||||
}*/
|
|
||||||
if (dir.isDirectory())
|
|
||||||
{
|
|
||||||
String[] children = dir.list();
|
|
||||||
for (int i = 0; i < children.length; i++)
|
|
||||||
{
|
|
||||||
new File(dir, children[i]).delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Uri uri = Uri.parse(update_url);
|
|
||||||
long downloadReference;
|
|
||||||
// Create request for android download manager
|
|
||||||
downloadManager = (DownloadManager)context.getSystemService(DOWNLOAD_SERVICE);
|
|
||||||
DownloadManager.Request request = new DownloadManager.Request(uri);
|
|
||||||
//Setting title of request
|
|
||||||
request.setTitle(context.getString(R.string.app_name));
|
|
||||||
//Setting description of request
|
|
||||||
request.setDescription(context.getString(R.string.notification_downloading_update));
|
|
||||||
//Set the local destination for the downloaded file to a path within the application's external files directory
|
|
||||||
try {
|
|
||||||
request.setDestinationInExternalFilesDir(context, null, update_filename);
|
|
||||||
}
|
|
||||||
catch (java.lang.IllegalStateException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
Toast.makeText(context, "Failed to get external storage files directory", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
//Enqueue download and save into referenceId
|
|
||||||
downloadReference = downloadManager.enqueue(request);
|
|
||||||
return downloadReference;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class NotificationActionService extends IntentService {
|
|
||||||
private static final String TAG = "BootReceiver/NAS";
|
|
||||||
|
|
||||||
public NotificationActionService() {
|
|
||||||
super(NotificationActionService.class.getSimpleName());
|
|
||||||
//IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
|
|
||||||
//registerReceiver(downloadReceiver, filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onHandleIntent(Intent intent) {
|
|
||||||
if (UPDATES_ON_PLAY_STORE && !intent.getBooleanExtra("update_direct", false)) {
|
|
||||||
Utils.openGooglePlay(this, "pl.szczodrzynski.edziennik");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
App app = (App)getApplication();
|
|
||||||
if (!app.permissionChecker.canRequestApkInstall()) {
|
|
||||||
app.permissionChecker.requestApkInstall();
|
|
||||||
app.notifier.notificationUpdatesShow(
|
|
||||||
intent.getStringExtra("update_version"),
|
|
||||||
intent.getStringExtra("update_url"),
|
|
||||||
intent.getStringExtra("update_filename"),
|
|
||||||
intent.getBooleanExtra("update_direct", false));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
update_url = intent.getStringExtra("update_url");
|
|
||||||
update_filename = intent.getStringExtra("update_filename");
|
|
||||||
//update_filename = "Edziennik_update.apk";
|
|
||||||
update_download_id = downloadFile(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,9 +8,9 @@ import android.content.BroadcastReceiver
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import pl.szczodrzynski.edziennik.data.api.ApiService
|
import pl.szczodrzynski.edziennik.data.api.ApiService
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.requests.ServiceCloseRequest
|
import pl.szczodrzynski.edziennik.data.api.events.requests.ServiceCloseRequest
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.requests.TaskCancelRequest
|
import pl.szczodrzynski.edziennik.data.api.events.requests.TaskCancelRequest
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask
|
|
||||||
|
|
||||||
class SzkolnyReceiver : BroadcastReceiver() {
|
class SzkolnyReceiver : BroadcastReceiver() {
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -2,13 +2,9 @@ package pl.szczodrzynski.edziennik.sync
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.AsyncTask
|
|
||||||
import androidx.work.*
|
import androidx.work.*
|
||||||
import androidx.work.impl.WorkManagerImpl
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.MINUTE
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask
|
|
||||||
import pl.szczodrzynski.edziennik.formatDate
|
import pl.szczodrzynski.edziennik.formatDate
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@ -22,37 +18,10 @@ class SyncWorker(val context: Context, val params: WorkerParameters) : Worker(co
|
|||||||
*/
|
*/
|
||||||
@SuppressLint("RestrictedApi")
|
@SuppressLint("RestrictedApi")
|
||||||
fun scheduleNext(app: App, rescheduleIfFailedFound: Boolean = true) {
|
fun scheduleNext(app: App, rescheduleIfFailedFound: Boolean = true) {
|
||||||
AsyncTask.execute {
|
WorkerUtils.scheduleNext(app, rescheduleIfFailedFound) {
|
||||||
val workManager = WorkManager.getInstance(app) as WorkManagerImpl
|
|
||||||
val scheduledWork = workManager.workDatabase.workSpecDao().scheduledWork
|
|
||||||
scheduledWork.forEach {
|
|
||||||
d(TAG, "Work: ${it.id} at ${(it.periodStartTime+it.initialDelay).formatDate()}. State = ${it.state} (finished = ${it.state.isFinished})")
|
|
||||||
}
|
|
||||||
// remove finished work and other than SyncWorker
|
|
||||||
scheduledWork.removeAll { it.workerClassName != SyncWorker::class.java.canonicalName || it.isPeriodic || it.state.isFinished }
|
|
||||||
d(TAG, "Found ${scheduledWork.size} unfinished work")
|
|
||||||
// remove all enqueued work that had to (but didn't) run at some point in the past (at least 1min ago)
|
|
||||||
val failedWork = scheduledWork.filter { it.state == WorkInfo.State.ENQUEUED && it.periodStartTime+it.initialDelay < System.currentTimeMillis() - 1*MINUTE*1000 }
|
|
||||||
d(TAG, "${failedWork.size} work requests failed to start (out of ${scheduledWork.size} requests)")
|
|
||||||
if (rescheduleIfFailedFound) {
|
|
||||||
if (failedWork.isNotEmpty()) {
|
|
||||||
d(TAG, "App Manager detected!")
|
|
||||||
EventBus.getDefault().postSticky(AppManagerDetectedEvent(failedWork.map { it.periodStartTime + it.initialDelay }))
|
|
||||||
}
|
|
||||||
if (scheduledWork.size - failedWork.size < 1) {
|
|
||||||
d(TAG, "No pending work found, scheduling next:")
|
|
||||||
rescheduleNext(app)
|
rescheduleNext(app)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
d(TAG, "NOT rescheduling: waiting to open the activity")
|
|
||||||
if (scheduledWork.size < 1) {
|
|
||||||
d(TAG, "No work found *at all*, scheduling next:")
|
|
||||||
rescheduleNext(app)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel any existing sync jobs and schedule a new one.
|
* Cancel any existing sync jobs and schedule a new one.
|
||||||
|
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.sync
|
||||||
|
|
||||||
|
import android.app.DownloadManager
|
||||||
|
import android.app.IntentService
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.core.content.FileProvider
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class UpdateDownloaderService : IntentService(UpdateDownloaderService::class.java.simpleName) {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "UpdateDownloaderService"
|
||||||
|
private var downloadId = 0L
|
||||||
|
private var downloadFilename = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun tryUpdateWithGooglePlay(update: Update): Boolean {
|
||||||
|
if (!update.isOnGooglePlay)
|
||||||
|
return false
|
||||||
|
return try {
|
||||||
|
Utils.openGooglePlay(this, application.packageName)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DownloadProgressReceiver : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context, intent: Intent?) {
|
||||||
|
if (intent?.action != DownloadManager.ACTION_DOWNLOAD_COMPLETE)
|
||||||
|
return
|
||||||
|
if (intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1) != downloadId)
|
||||||
|
return
|
||||||
|
val app = context.applicationContext as App
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !app.permissionChecker.canRequestApkInstall()) {
|
||||||
|
app.permissionChecker.requestApkInstall()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val file = File(app.getExternalFilesDir(null), downloadFilename)
|
||||||
|
val installIntent = Intent(Intent.ACTION_VIEW)
|
||||||
|
installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
|
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
installIntent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive")
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
val apkUri = FileProvider.getUriForFile(app, "${app.packageName}.provider", file)
|
||||||
|
installIntent.setDataAndType(apkUri, "application/vnd.android.package-archive")
|
||||||
|
|
||||||
|
val resInfoList = app.packageManager.queryIntentActivities(installIntent, PackageManager.MATCH_DEFAULT_ONLY)
|
||||||
|
for (resolveInfo in resInfoList) {
|
||||||
|
val packageName = resolveInfo.activityInfo.packageName
|
||||||
|
app.grantUriPermission(packageName, apkUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app.startActivity(installIntent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onHandleIntent(intent: Intent?) {
|
||||||
|
val app = application as App
|
||||||
|
val update = App.config.update ?: return
|
||||||
|
|
||||||
|
if (tryUpdateWithGooglePlay(update))
|
||||||
|
return
|
||||||
|
|
||||||
|
if (update.downloadUrl == null) {
|
||||||
|
Toast.makeText(app, "Nie można pobrać tej aktualizacji. Pobierz ręcznie z Google Play.", Toast.LENGTH_LONG).show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !app.permissionChecker.canRequestApkInstall()) {
|
||||||
|
app.permissionChecker.requestApkInstall()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
(app.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager).cancel(app.notifications.updatesId)
|
||||||
|
|
||||||
|
val dir: File? = app.getExternalFilesDir(null)
|
||||||
|
if (dir?.isDirectory == true) {
|
||||||
|
dir.listFiles()?.forEach {
|
||||||
|
it.delete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val uri = Uri.parse(update.downloadUrl)
|
||||||
|
downloadFilename = "${update.versionName}.apk"
|
||||||
|
|
||||||
|
val downloadManager = app.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
|
||||||
|
val request = DownloadManager.Request(uri)
|
||||||
|
request.setTitle(app.getString(R.string.app_name)+" "+update.versionName)
|
||||||
|
request.setDescription(app.getString(R.string.notification_downloading_update))
|
||||||
|
try {
|
||||||
|
request.setDestinationInExternalFilesDir(app, null, downloadFilename)
|
||||||
|
} catch (e: IllegalStateException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
Toast.makeText(app, "Nie można znaleźć katalogu docelowego. Pobierz aktualizację ręcznie z Google Play.", Toast.LENGTH_LONG).show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
downloadId = downloadManager.enqueue(request)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.sync
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.text.Html
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.work.*
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import pl.szczodrzynski.edziennik.*
|
||||||
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
class UpdateWorker(val context: Context, val params: WorkerParameters) : Worker(context, params), CoroutineScope {
|
||||||
|
companion object {
|
||||||
|
const val TAG = "UpdateWorker"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule the sync job only if it's not already scheduled.
|
||||||
|
*/
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
fun scheduleNext(app: App, rescheduleIfFailedFound: Boolean = true) {
|
||||||
|
WorkerUtils.scheduleNext(app, rescheduleIfFailedFound) {
|
||||||
|
rescheduleNext(app)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel any existing sync jobs and schedule a new one.
|
||||||
|
*
|
||||||
|
* If [ConfigSync.enabled] is not true, just cancel every job.
|
||||||
|
*/
|
||||||
|
fun rescheduleNext(app: App) {
|
||||||
|
cancelNext(app)
|
||||||
|
if (!app.config.sync.notifyAboutUpdates) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val syncInterval = 4 * DAY;
|
||||||
|
|
||||||
|
val syncAt = System.currentTimeMillis() + syncInterval*1000
|
||||||
|
Utils.d(TAG, "Scheduling work at ${syncAt.formatDate()}")
|
||||||
|
|
||||||
|
val constraints = Constraints.Builder()
|
||||||
|
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val syncWorkRequest = OneTimeWorkRequestBuilder<UpdateWorker>()
|
||||||
|
.setInitialDelay(syncInterval, TimeUnit.SECONDS)
|
||||||
|
.setConstraints(constraints)
|
||||||
|
.addTag(TAG)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
WorkManager.getInstance(app).enqueue(syncWorkRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel any scheduled sync job.
|
||||||
|
*/
|
||||||
|
fun cancelNext(app: App) {
|
||||||
|
Utils.d(TAG, "Cancelling work by tag $TAG")
|
||||||
|
WorkManager.getInstance(app).cancelAllWorkByTag(TAG)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runNow(app: App) {
|
||||||
|
try {
|
||||||
|
val api = SzkolnyApi(app)
|
||||||
|
val response = api.getUpdate()
|
||||||
|
if (response?.success != true)
|
||||||
|
return
|
||||||
|
val updates = response.data
|
||||||
|
if (updates?.isNotEmpty() != true)
|
||||||
|
return
|
||||||
|
val update = updates[0]
|
||||||
|
|
||||||
|
app.config.update = update
|
||||||
|
|
||||||
|
val notificationIntent = Intent(app, UpdateDownloaderService::class.java)
|
||||||
|
val pendingIntent = PendingIntent.getService(app, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||||
|
val notification = NotificationCompat.Builder(app, app.notifications.updatesKey)
|
||||||
|
.setContentTitle(app.getString(R.string.notification_updates_title))
|
||||||
|
.setContentText(app.getString(R.string.notification_updates_text, update.versionName))
|
||||||
|
.setTicker(app.getString(R.string.notification_updates_summary))
|
||||||
|
.setSmallIcon(R.drawable.ic_notification)
|
||||||
|
.setStyle(NotificationCompat.BigTextStyle()
|
||||||
|
.bigText(listOf(
|
||||||
|
app.getString(R.string.notification_updates_text, update.versionName),
|
||||||
|
update.releaseNotes?.let { Html.fromHtml(it) }
|
||||||
|
).concat("\n")))
|
||||||
|
.setColor(0xff2196f3.toInt())
|
||||||
|
.setLights(0xFF00FFFF.toInt(), 2000, 2000)
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
|
.setDefaults(NotificationCompat.DEFAULT_ALL)
|
||||||
|
.setGroup(app.notifications.updatesKey)
|
||||||
|
.setContentIntent(pendingIntent)
|
||||||
|
.setAutoCancel(false)
|
||||||
|
.build()
|
||||||
|
(app.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager).notify(app.notifications.updatesId, notification)
|
||||||
|
|
||||||
|
} catch (ignore: Exception) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val job = Job()
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = job + Dispatchers.Default
|
||||||
|
|
||||||
|
override fun doWork(): Result {
|
||||||
|
Utils.d(TAG, "Running worker ID ${params.id}")
|
||||||
|
val app = context as App
|
||||||
|
if (!app.config.sync.notifyAboutUpdates) {
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
|
||||||
|
launch {
|
||||||
|
runNow(app)
|
||||||
|
}
|
||||||
|
|
||||||
|
rescheduleNext(this.context)
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.sync
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.os.AsyncTask
|
||||||
|
import androidx.work.WorkInfo
|
||||||
|
import androidx.work.WorkManager
|
||||||
|
import androidx.work.impl.WorkManagerImpl
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.MINUTE
|
||||||
|
import pl.szczodrzynski.edziennik.formatDate
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
|
||||||
|
object WorkerUtils {
|
||||||
|
/**
|
||||||
|
* Schedule the sync job only if it's not already scheduled.
|
||||||
|
*/
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
inline fun scheduleNext(app: App, rescheduleIfFailedFound: Boolean = true, crossinline onReschedule: () -> Unit) {
|
||||||
|
AsyncTask.execute {
|
||||||
|
val workManager = WorkManager.getInstance(app) as WorkManagerImpl
|
||||||
|
val scheduledWork = workManager.workDatabase.workSpecDao().scheduledWork
|
||||||
|
scheduledWork.forEach {
|
||||||
|
Utils.d("WorkerUtils", "Work: ${it.id} at ${(it.periodStartTime + it.initialDelay).formatDate()}. State = ${it.state} (finished = ${it.state.isFinished})")
|
||||||
|
}
|
||||||
|
// remove finished work and other than SyncWorker
|
||||||
|
scheduledWork.removeAll { it.workerClassName != SyncWorker::class.java.canonicalName || it.isPeriodic || it.state.isFinished }
|
||||||
|
Utils.d("WorkerUtils", "Found ${scheduledWork.size} unfinished work")
|
||||||
|
// remove all enqueued work that had to (but didn't) run at some point in the past (at least 1min ago)
|
||||||
|
val failedWork = scheduledWork.filter { it.state == WorkInfo.State.ENQUEUED && it.periodStartTime + it.initialDelay < System.currentTimeMillis() - 1 * MINUTE * 1000 }
|
||||||
|
Utils.d("WorkerUtils", "${failedWork.size} work requests failed to start (out of ${scheduledWork.size} requests)")
|
||||||
|
if (rescheduleIfFailedFound) {
|
||||||
|
if (failedWork.isNotEmpty()) {
|
||||||
|
Utils.d("WorkerUtils", "App Manager detected!")
|
||||||
|
EventBus.getDefault().postSticky(AppManagerDetectedEvent(failedWork.map { it.periodStartTime + it.initialDelay }))
|
||||||
|
}
|
||||||
|
if (scheduledWork.size - failedWork.size < 1) {
|
||||||
|
Utils.d("WorkerUtils", "No pending work found, scheduling next:")
|
||||||
|
onReschedule()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Utils.d("WorkerUtils", "NOT rescheduling: waiting to open the activity")
|
||||||
|
if (scheduledWork.size < 1) {
|
||||||
|
Utils.d("WorkerUtils", "No work found *at all*, scheduling next:")
|
||||||
|
onReschedule()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -44,7 +44,7 @@ class ChangelogDialog(
|
|||||||
|
|
||||||
val text = app.assets.open("pl-changelog.html").bufferedReader().use {
|
val text = app.assets.open("pl-changelog.html").bufferedReader().use {
|
||||||
it.readText()
|
it.readText()
|
||||||
}
|
}.replace("<li>", "<br><li> - ")
|
||||||
textView.text = Html.fromHtml(text)
|
textView.text = Html.fromHtml(text)
|
||||||
|
|
||||||
val scrollView = ScrollView(activity)
|
val scrollView = ScrollView(activity)
|
||||||
|
@ -21,13 +21,8 @@ import kotlinx.coroutines.*
|
|||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_AGENDA
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_AGENDA
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.EventType
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Subject
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Team
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.LessonFull
|
import pl.szczodrzynski.edziennik.data.db.full.LessonFull
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogEventManualV2Binding
|
import pl.szczodrzynski.edziennik.databinding.DialogEventManualV2Binding
|
||||||
import pl.szczodrzynski.edziennik.utils.Anim
|
import pl.szczodrzynski.edziennik.utils.Anim
|
||||||
@ -43,7 +38,7 @@ class EventManualDialog(
|
|||||||
val defaultLesson: LessonFull? = null,
|
val defaultLesson: LessonFull? = null,
|
||||||
val defaultDate: Date? = null,
|
val defaultDate: Date? = null,
|
||||||
val defaultTime: Time? = null,
|
val defaultTime: Time? = null,
|
||||||
val defaultType: Int? = null,
|
val defaultType: Long? = null,
|
||||||
val editingEvent: EventFull? = null,
|
val editingEvent: EventFull? = null,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
val onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
val onDismissListener: ((tag: String) -> Unit)? = null
|
||||||
@ -149,7 +144,7 @@ class EventManualDialog(
|
|||||||
else -> R.string.dialog_event_manual_share_first_notice
|
else -> R.string.dialog_event_manual_share_first_notice
|
||||||
}
|
}
|
||||||
|
|
||||||
b.shareDetails.setText(text)
|
b.shareDetails.setText(text, event.sharedByName ?: "")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadLists() { launch {
|
private fun loadLists() { launch {
|
||||||
@ -588,8 +583,7 @@ class EventManualDialog(
|
|||||||
startTime,
|
startTime,
|
||||||
topic,
|
topic,
|
||||||
customColor ?: -1,
|
customColor ?: -1,
|
||||||
type?.toInt()
|
type ?: Event.TYPE_DEFAULT,
|
||||||
?: Event.TYPE_DEFAULT,
|
|
||||||
true,
|
true,
|
||||||
teacherId ?: -1,
|
teacherId ?: -1,
|
||||||
subjectId ?: -1,
|
subjectId ?: -1,
|
||||||
@ -598,7 +592,7 @@ class EventManualDialog(
|
|||||||
|
|
||||||
val metadataObject = Metadata(
|
val metadataObject = Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
when (type?.toInt()) {
|
when (type) {
|
||||||
Event.TYPE_HOMEWORK -> Metadata.TYPE_HOMEWORK
|
Event.TYPE_HOMEWORK -> Metadata.TYPE_HOMEWORK
|
||||||
else -> Metadata.TYPE_EVENT
|
else -> Metadata.TYPE_EVENT
|
||||||
},
|
},
|
||||||
|
@ -32,7 +32,7 @@ public class GradeDetailsDialog {
|
|||||||
|
|
||||||
public GradeDetailsDialog(Context context) {
|
public GradeDetailsDialog(Context context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.profileId = App.profileId;
|
this.profileId = App.Companion.getProfileId();
|
||||||
}
|
}
|
||||||
public GradeDetailsDialog(Context context, int profileId) {
|
public GradeDetailsDialog(Context context, int profileId) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
@ -74,7 +74,7 @@ public class GradeDetailsDialog {
|
|||||||
b.setGrade(grade);
|
b.setGrade(grade);
|
||||||
|
|
||||||
int gradeColor;
|
int gradeColor;
|
||||||
if (App.getConfig().getFor(profileId).getGrades().getColorMode() == COLOR_MODE_DEFAULT) {
|
if (App.Companion.getConfig().getFor(profileId).getGrades().getColorMode() == COLOR_MODE_DEFAULT) {
|
||||||
gradeColor = grade.color;
|
gradeColor = grade.color;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -103,7 +103,7 @@ public class GradeDetailsDialog {
|
|||||||
|
|
||||||
b.setCommentVisible(false);
|
b.setCommentVisible(false);
|
||||||
|
|
||||||
b.setDevMode(App.devMode);
|
b.setDevMode(App.Companion.getDevMode());
|
||||||
|
|
||||||
b.gradeName.setTextColor(ColorUtils.calculateLuminance(gradeColor) > 0.25 ? 0xff000000 : 0xffffffff);
|
b.gradeName.setTextColor(ColorUtils.calculateLuminance(gradeColor) > 0.25 ? 0xff000000 : 0xffffffff);
|
||||||
b.gradeName.getBackground().setColorFilter(new PorterDuffColorFilter(gradeColor, PorterDuff.Mode.MULTIPLY));
|
b.gradeName.getBackground().setColorFilter(new PorterDuffColorFilter(gradeColor, PorterDuff.Mode.MULTIPLY));
|
||||||
|
@ -19,7 +19,7 @@ public class LessonChangeDialog {
|
|||||||
|
|
||||||
public LessonChangeDialog(Context context) {
|
public LessonChangeDialog(Context context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.profileId = App.profileId;
|
this.profileId = App.Companion.getProfileId();
|
||||||
}
|
}
|
||||||
public LessonChangeDialog(Context context, int profileId) {
|
public LessonChangeDialog(Context context, int profileId) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
@ -12,8 +12,6 @@ import pl.szczodrzynski.edziennik.App
|
|||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogLessonDetailsBinding
|
import pl.szczodrzynski.edziennik.databinding.DialogLessonDetailsBinding
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Notification
|
|
||||||
import java.util.*
|
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class ProfileRemoveDialog(
|
class ProfileRemoveDialog(
|
||||||
@ -52,26 +50,35 @@ class ProfileRemoveDialog(
|
|||||||
val profileObject = app.db.profileDao().getByIdNow(profileId) ?: return@async
|
val profileObject = app.db.profileDao().getByIdNow(profileId) ?: return@async
|
||||||
app.db.announcementDao().clear(profileId)
|
app.db.announcementDao().clear(profileId)
|
||||||
app.db.attendanceDao().clear(profileId)
|
app.db.attendanceDao().clear(profileId)
|
||||||
app.db.eventDao().clear(profileId)
|
|
||||||
app.db.eventTypeDao().clear(profileId)
|
|
||||||
app.db.gradeDao().clear(profileId)
|
|
||||||
app.db.gradeCategoryDao().clear(profileId)
|
|
||||||
app.db.luckyNumberDao().clear(profileId)
|
|
||||||
app.db.noticeDao().clear(profileId)
|
|
||||||
app.db.subjectDao().clear(profileId)
|
|
||||||
app.db.teacherDao().clear(profileId)
|
|
||||||
app.db.teamDao().clear(profileId)
|
|
||||||
app.db.messageRecipientDao().clear(profileId)
|
|
||||||
app.db.messageDao().clear(profileId)
|
|
||||||
app.db.endpointTimerDao().clear(profileId)
|
|
||||||
app.db.attendanceTypeDao().clear(profileId)
|
app.db.attendanceTypeDao().clear(profileId)
|
||||||
app.db.classroomDao().clear(profileId)
|
app.db.classroomDao().clear(profileId)
|
||||||
|
app.db.configDao().clear(profileId)
|
||||||
|
app.db.endpointTimerDao().clear(profileId)
|
||||||
|
app.db.eventDao().clear(profileId)
|
||||||
|
app.db.eventTypeDao().clear(profileId)
|
||||||
|
app.db.gradeCategoryDao().clear(profileId)
|
||||||
|
app.db.gradeDao().clear(profileId)
|
||||||
app.db.lessonRangeDao().clear(profileId)
|
app.db.lessonRangeDao().clear(profileId)
|
||||||
|
app.db.librusLessonDao().clear(profileId)
|
||||||
|
app.db.luckyNumberDao().clear(profileId)
|
||||||
|
app.db.messageDao().clear(profileId)
|
||||||
|
app.db.messageRecipientDao().clear(profileId)
|
||||||
|
app.db.noticeDao().clear(profileId)
|
||||||
app.db.noticeTypeDao().clear(profileId)
|
app.db.noticeTypeDao().clear(profileId)
|
||||||
|
app.db.noticeTypeDao().clear(profileId)
|
||||||
|
app.db.notificationDao().clear(profileId)
|
||||||
|
app.db.subjectDao().clear(profileId)
|
||||||
|
app.db.teacherAbsenceDao().clear(profileId)
|
||||||
app.db.teacherAbsenceDao().clear(profileId)
|
app.db.teacherAbsenceDao().clear(profileId)
|
||||||
app.db.teacherAbsenceTypeDao().clear(profileId)
|
app.db.teacherAbsenceTypeDao().clear(profileId)
|
||||||
|
app.db.teacherDao().clear(profileId)
|
||||||
|
app.db.teamDao().clear(profileId)
|
||||||
app.db.timetableDao().clear(profileId)
|
app.db.timetableDao().clear(profileId)
|
||||||
|
|
||||||
|
val homeCards = app.config.ui.homeCards.toMutableList()
|
||||||
|
homeCards.removeAll { it.profileId == profileId }
|
||||||
|
app.config.ui.homeCards = homeCards
|
||||||
|
|
||||||
val loginStoreId = profileObject.loginStoreId
|
val loginStoreId = profileObject.loginStoreId
|
||||||
val profilesUsingLoginStore = app.db.profileDao().getIdsByLoginStoreIdNow(loginStoreId)
|
val profilesUsingLoginStore = app.db.profileDao().getIdsByLoginStoreIdNow(loginStoreId)
|
||||||
if (profilesUsingLoginStore.size == 1) {
|
if (profilesUsingLoginStore.size == 1) {
|
||||||
@ -80,19 +87,10 @@ class ProfileRemoveDialog(
|
|||||||
app.db.profileDao().remove(profileId)
|
app.db.profileDao().remove(profileId)
|
||||||
app.db.metadataDao().deleteAll(profileId)
|
app.db.metadataDao().deleteAll(profileId)
|
||||||
|
|
||||||
val toRemove = ArrayList<Notification>()
|
if (App.profileId == profileId) {
|
||||||
for (notification in app.appConfig.notifications) {
|
app.profileLoadLast { }
|
||||||
if (notification.profileId == profileId) {
|
|
||||||
toRemove.add(notification)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.appConfig.notifications.removeAll(toRemove)
|
|
||||||
|
|
||||||
app.profile = null
|
|
||||||
App.profileId = -1
|
|
||||||
|
|
||||||
app.profileLoadById(app.profileLastId())
|
|
||||||
}
|
|
||||||
deferred.await()
|
deferred.await()
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
activity.reloadTarget()
|
activity.reloadTarget()
|
||||||
|
@ -12,7 +12,7 @@ import kotlinx.coroutines.Job
|
|||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogLessonDetailsBinding
|
import pl.szczodrzynski.edziennik.databinding.DialogLessonDetailsBinding
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesFragment
|
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesFragment
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
@ -77,6 +77,9 @@ class LessonDetailsDialog(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (App.devMode)
|
||||||
|
b.lessonId.visibility = View.VISIBLE
|
||||||
|
|
||||||
update()
|
update()
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
@ -78,10 +78,10 @@ public class AgendaFragment extends Fragment {
|
|||||||
return null;
|
return null;
|
||||||
app = (App) activity.getApplication();
|
app = (App) activity.getApplication();
|
||||||
getContext().getTheme().applyStyle(Themes.INSTANCE.getAppTheme(), true);
|
getContext().getTheme().applyStyle(Themes.INSTANCE.getAppTheme(), true);
|
||||||
if (app.profile == null)
|
if (app.getProfile() == null)
|
||||||
return inflater.inflate(R.layout.fragment_loading, container, false);
|
return inflater.inflate(R.layout.fragment_loading, container, false);
|
||||||
// activity, context and profile is valid
|
// activity, context and profile is valid
|
||||||
viewType = app.config.getUi().getAgendaViewType();
|
viewType = app.getConfig().forProfile().getUi().getAgendaViewType();
|
||||||
if (viewType == AGENDA_DEFAULT) {
|
if (viewType == AGENDA_DEFAULT) {
|
||||||
b_default = DataBindingUtil.inflate(inflater, R.layout.fragment_agenda_default, container, false);
|
b_default = DataBindingUtil.inflate(inflater, R.layout.fragment_agenda_default, container, false);
|
||||||
return b_default.getRoot();
|
return b_default.getRoot();
|
||||||
@ -94,7 +94,7 @@ public class AgendaFragment extends Fragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
if (app == null || app.profile == null || activity == null || (b_default == null && b_calendar == null) || !isAdded())
|
if (app == null || activity == null || b_default == null && b_calendar == null || !isAdded())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
activity.getBottomSheet().prependItems(
|
activity.getBottomSheet().prependItems(
|
||||||
@ -106,7 +106,7 @@ public class AgendaFragment extends Fragment {
|
|||||||
activity.getBottomSheet().close();
|
activity.getBottomSheet().close();
|
||||||
new EventManualDialog(
|
new EventManualDialog(
|
||||||
activity,
|
activity,
|
||||||
App.profileId,
|
App.Companion.getProfileId(),
|
||||||
null,
|
null,
|
||||||
actualDate,
|
actualDate,
|
||||||
null,
|
null,
|
||||||
@ -122,7 +122,7 @@ public class AgendaFragment extends Fragment {
|
|||||||
.withOnClickListener(v3 -> {
|
.withOnClickListener(v3 -> {
|
||||||
activity.getBottomSheet().close();
|
activity.getBottomSheet().close();
|
||||||
viewType = viewType == AGENDA_DEFAULT ? AGENDA_CALENDAR : AGENDA_DEFAULT;
|
viewType = viewType == AGENDA_DEFAULT ? AGENDA_CALENDAR : AGENDA_DEFAULT;
|
||||||
app.config.getUi().setAgendaViewType(viewType);
|
app.getConfig().forProfile().getUi().setAgendaViewType(viewType);
|
||||||
activity.reloadTarget();
|
activity.reloadTarget();
|
||||||
}),
|
}),
|
||||||
new BottomSheetSeparatorItem(true),
|
new BottomSheetSeparatorItem(true),
|
||||||
@ -131,7 +131,7 @@ public class AgendaFragment extends Fragment {
|
|||||||
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
||||||
.withOnClickListener(v3 -> {
|
.withOnClickListener(v3 -> {
|
||||||
activity.getBottomSheet().close();
|
activity.getBottomSheet().close();
|
||||||
AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_EVENT, true));
|
AsyncTask.execute(() -> App.db.metadataDao().setAllSeen(App.Companion.getProfileId(), TYPE_EVENT, true));
|
||||||
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show();
|
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -141,7 +141,7 @@ public class AgendaFragment extends Fragment {
|
|||||||
activity.getNavView().bottomBar.setFabIcon(CommunityMaterial.Icon2.cmd_plus);
|
activity.getNavView().bottomBar.setFabIcon(CommunityMaterial.Icon2.cmd_plus);
|
||||||
activity.getNavView().setFabOnClickListener(v -> new EventManualDialog(
|
activity.getNavView().setFabOnClickListener(v -> new EventManualDialog(
|
||||||
activity,
|
activity,
|
||||||
App.profileId,
|
App.Companion.getProfileId(),
|
||||||
null,
|
null,
|
||||||
actualDate,
|
actualDate,
|
||||||
null,
|
null,
|
||||||
@ -167,7 +167,7 @@ public class AgendaFragment extends Fragment {
|
|||||||
|
|
||||||
final Handler handler = new Handler();
|
final Handler handler = new Handler();
|
||||||
handler.postDelayed(() -> AsyncTask.execute(() -> {
|
handler.postDelayed(() -> AsyncTask.execute(() -> {
|
||||||
if (app == null || app.profile == null || activity == null || b_default == null || !isAdded())
|
if (app == null || activity == null || b_default == null || !isAdded())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
List<CalendarEvent> eventList = new ArrayList<>();
|
List<CalendarEvent> eventList = new ArrayList<>();
|
||||||
@ -193,8 +193,8 @@ public class AgendaFragment extends Fragment {
|
|||||||
));
|
));
|
||||||
} TODO: Implement new timetable lesson changes */
|
} TODO: Implement new timetable lesson changes */
|
||||||
|
|
||||||
if (app.profile.getStudentData("showTeacherAbsences", true)) {
|
if (app.getProfile().getStudentData("showTeacherAbsences", true)) {
|
||||||
List<TeacherAbsenceFull> teacherAbsenceList = app.db.teacherAbsenceDao().getAllFullNow(App.profileId);
|
List<TeacherAbsenceFull> teacherAbsenceList = App.db.teacherAbsenceDao().getAllFullNow(App.Companion.getProfileId());
|
||||||
List<TeacherAbsenceCounter> teacherAbsenceCounters = new ArrayList<>();
|
List<TeacherAbsenceCounter> teacherAbsenceCounters = new ArrayList<>();
|
||||||
|
|
||||||
for (TeacherAbsenceFull absence : teacherAbsenceList) {
|
for (TeacherAbsenceFull absence : teacherAbsenceList) {
|
||||||
@ -226,7 +226,7 @@ public class AgendaFragment extends Fragment {
|
|||||||
Colors.legibleTextColor(0xffff1744),
|
Colors.legibleTextColor(0xffff1744),
|
||||||
startTime,
|
startTime,
|
||||||
endTime,
|
endTime,
|
||||||
App.profileId,
|
App.Companion.getProfileId(),
|
||||||
date,
|
date,
|
||||||
counter.getTeacherAbsenceCount()
|
counter.getTeacherAbsenceCount()
|
||||||
));
|
));
|
||||||
@ -234,7 +234,7 @@ public class AgendaFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
List<EventFull> events = app.db.eventDao().getAllNow(App.profileId);
|
List<EventFull> events = App.db.eventDao().getAllNow(App.Companion.getProfileId());
|
||||||
for (EventFull event : events) {
|
for (EventFull event : events) {
|
||||||
Calendar startTime = Calendar.getInstance();
|
Calendar startTime = Calendar.getInstance();
|
||||||
Calendar endTime = Calendar.getInstance();
|
Calendar endTime = Calendar.getInstance();
|
||||||
@ -321,7 +321,7 @@ public class AgendaFragment extends Fragment {
|
|||||||
actualDate = Date.fromCalendar(calendar);
|
actualDate = Date.fromCalendar(calendar);
|
||||||
int scrolledDate = actualDate.getValue();
|
int scrolledDate = actualDate.getValue();
|
||||||
if (unreadEventDates.contains(scrolledDate)) {
|
if (unreadEventDates.contains(scrolledDate)) {
|
||||||
AsyncTask.execute(() -> app.db.eventDao().setSeenByDate(App.profileId, Date.fromYmd(intToStr(scrolledDate)), true));
|
AsyncTask.execute(() -> App.db.eventDao().setSeenByDate(App.Companion.getProfileId(), Date.fromYmd(intToStr(scrolledDate)), true));
|
||||||
unreadEventDates.remove((Integer) scrolledDate);
|
unreadEventDates.remove((Integer) scrolledDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -342,7 +342,7 @@ public class AgendaFragment extends Fragment {
|
|||||||
// new EventListDialogOld(activity).show(app, Date.fromCalendar(calendarEvent.getInstanceDay()));
|
// new EventListDialogOld(activity).show(app, Date.fromCalendar(calendarEvent.getInstanceDay()));
|
||||||
new DayDialog(
|
new DayDialog(
|
||||||
activity,
|
activity,
|
||||||
App.profileId,
|
App.Companion.getProfileId(),
|
||||||
Date.fromCalendar(calendarEvent.getInstanceDay()),
|
Date.fromCalendar(calendarEvent.getInstanceDay()),
|
||||||
null,
|
null,
|
||||||
null
|
null
|
||||||
@ -373,7 +373,7 @@ public class AgendaFragment extends Fragment {
|
|||||||
|
|
||||||
final Handler handler = new Handler();
|
final Handler handler = new Handler();
|
||||||
handler.postDelayed(() -> AsyncTask.execute(() -> {
|
handler.postDelayed(() -> AsyncTask.execute(() -> {
|
||||||
if (app == null || app.profile == null || activity == null || b_calendar == null || !isAdded())
|
if (app == null || activity == null || b_calendar == null || !isAdded())
|
||||||
return;
|
return;
|
||||||
Context c = getContext();
|
Context c = getContext();
|
||||||
Activity a = getActivity();
|
Activity a = getActivity();
|
||||||
@ -385,7 +385,7 @@ public class AgendaFragment extends Fragment {
|
|||||||
|
|
||||||
List<EventDay> eventList = new ArrayList<>();
|
List<EventDay> eventList = new ArrayList<>();
|
||||||
|
|
||||||
List<EventFull> events = app.db.eventDao().getAllNow(App.profileId);
|
List<EventFull> events = App.db.eventDao().getAllNow(App.Companion.getProfileId());
|
||||||
for (EventFull event : events) {
|
for (EventFull event : events) {
|
||||||
if (event.eventDate == null)
|
if (event.eventDate == null)
|
||||||
continue;
|
continue;
|
||||||
@ -434,13 +434,13 @@ public class AgendaFragment extends Fragment {
|
|||||||
Date dayDate = Date.fromCalendar(eventDay.getCalendar());
|
Date dayDate = Date.fromCalendar(eventDay.getCalendar());
|
||||||
int scrolledDate = dayDate.getValue();
|
int scrolledDate = dayDate.getValue();
|
||||||
if (unreadEventDates.contains(scrolledDate)) {
|
if (unreadEventDates.contains(scrolledDate)) {
|
||||||
AsyncTask.execute(() -> app.db.eventDao().setSeenByDate(App.profileId, Date.fromYmd(intToStr(scrolledDate)), true));
|
AsyncTask.execute(() -> App.db.eventDao().setSeenByDate(App.Companion.getProfileId(), Date.fromYmd(intToStr(scrolledDate)), true));
|
||||||
unreadEventDates.remove((Integer) scrolledDate);
|
unreadEventDates.remove((Integer) scrolledDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
new DayDialog(
|
new DayDialog(
|
||||||
activity,
|
activity,
|
||||||
App.profileId,
|
App.Companion.getProfileId(),
|
||||||
dayDate,
|
dayDate,
|
||||||
null,
|
null,
|
||||||
null
|
null
|
||||||
|
@ -24,8 +24,8 @@ import org.greenrobot.eventbus.ThreadMode;
|
|||||||
import pl.szczodrzynski.edziennik.App;
|
import pl.szczodrzynski.edziennik.App;
|
||||||
import pl.szczodrzynski.edziennik.MainActivity;
|
import pl.szczodrzynski.edziennik.MainActivity;
|
||||||
import pl.szczodrzynski.edziennik.R;
|
import pl.szczodrzynski.edziennik.R;
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask;
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.AnnouncementGetEvent;
|
import pl.szczodrzynski.edziennik.data.api.events.AnnouncementGetEvent;
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull;
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull;
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogAnnouncementBinding;
|
import pl.szczodrzynski.edziennik.databinding.DialogAnnouncementBinding;
|
||||||
import pl.szczodrzynski.edziennik.databinding.FragmentAnnouncementsBinding;
|
import pl.szczodrzynski.edziennik.databinding.FragmentAnnouncementsBinding;
|
||||||
@ -49,8 +49,6 @@ public class AnnouncementsFragment extends Fragment {
|
|||||||
return null;
|
return null;
|
||||||
app = (App) activity.getApplication();
|
app = (App) activity.getApplication();
|
||||||
getContext().getTheme().applyStyle(Themes.INSTANCE.getAppTheme(), true);
|
getContext().getTheme().applyStyle(Themes.INSTANCE.getAppTheme(), true);
|
||||||
if (app.profile == null)
|
|
||||||
return inflater.inflate(R.layout.fragment_loading, container, false);
|
|
||||||
// activity, context and profile is valid
|
// activity, context and profile is valid
|
||||||
b = DataBindingUtil.inflate(inflater, R.layout.fragment_announcements, container, false);
|
b = DataBindingUtil.inflate(inflater, R.layout.fragment_announcements, container, false);
|
||||||
b.refreshLayout.setParent(activity.getSwipeRefreshLayout());
|
b.refreshLayout.setParent(activity.getSwipeRefreshLayout());
|
||||||
@ -61,7 +59,7 @@ public class AnnouncementsFragment extends Fragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
if (app == null || app.profile == null || activity == null || b == null || !isAdded())
|
if (app == null || activity == null || b == null || !isAdded())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
activity.getBottomSheet().prependItems(
|
activity.getBottomSheet().prependItems(
|
||||||
@ -70,10 +68,10 @@ public class AnnouncementsFragment extends Fragment {
|
|||||||
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
||||||
.withOnClickListener(v3 -> {
|
.withOnClickListener(v3 -> {
|
||||||
activity.getBottomSheet().close();
|
activity.getBottomSheet().close();
|
||||||
if (app.profile.getLoginStoreType() == LOGIN_TYPE_LIBRUS) {
|
if (app.getProfile().getLoginStoreType() == LOGIN_TYPE_LIBRUS) {
|
||||||
EdziennikTask.Companion.announcementsRead(App.profileId).enqueue(requireContext());
|
EdziennikTask.Companion.announcementsRead(App.Companion.getProfileId()).enqueue(requireContext());
|
||||||
} else {
|
} else {
|
||||||
AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_ANNOUNCEMENT, true));
|
AsyncTask.execute(() -> App.db.metadataDao().setAllSeen(App.Companion.getProfileId(), TYPE_ANNOUNCEMENT, true));
|
||||||
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show();
|
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -92,8 +90,8 @@ public class AnnouncementsFragment extends Fragment {
|
|||||||
recyclerView.setLayoutManager(linearLayoutManager);
|
recyclerView.setLayoutManager(linearLayoutManager);
|
||||||
recyclerView.addItemDecoration(new SimpleDividerItemDecoration(view.getContext()));
|
recyclerView.addItemDecoration(new SimpleDividerItemDecoration(view.getContext()));
|
||||||
|
|
||||||
app.db.announcementDao().getAll(App.profileId).observe(this, announcements -> {
|
app.db.announcementDao().getAll(App.Companion.getProfileId()).observe(this, announcements -> {
|
||||||
if (app == null || app.profile == null || activity == null || b == null || !isAdded())
|
if (app == null || activity == null || b == null || !isAdded())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (announcements == null) {
|
if (announcements == null) {
|
||||||
@ -109,8 +107,8 @@ public class AnnouncementsFragment extends Fragment {
|
|||||||
return;
|
return;
|
||||||
}*/
|
}*/
|
||||||
AnnouncementsAdapter announcementsAdapter = new AnnouncementsAdapter(activity, announcements, (v, announcement) -> {
|
AnnouncementsAdapter announcementsAdapter = new AnnouncementsAdapter(activity, announcements, (v, announcement) -> {
|
||||||
if (announcement.text == null || (app.profile.getLoginStoreType() == LOGIN_TYPE_LIBRUS && !announcement.seen && app.networkUtils.isOnline())) {
|
if (announcement.text == null || (app.getProfile().getLoginStoreType() == LOGIN_TYPE_LIBRUS && !announcement.seen && app.getNetworkUtils().isOnline())) {
|
||||||
EdziennikTask.Companion.announcementGet(App.profileId, announcement).enqueue(requireContext());
|
EdziennikTask.Companion.announcementGet(App.Companion.getProfileId(), announcement).enqueue(requireContext());
|
||||||
} else {
|
} else {
|
||||||
showAnnouncementDetailsDialog(announcement);
|
showAnnouncementDetailsDialog(announcement);
|
||||||
}
|
}
|
||||||
@ -157,9 +155,9 @@ public class AnnouncementsFragment extends Fragment {
|
|||||||
.show();
|
.show();
|
||||||
DialogAnnouncementBinding b = DialogAnnouncementBinding.bind(dialog.getCustomView());
|
DialogAnnouncementBinding b = DialogAnnouncementBinding.bind(dialog.getCustomView());
|
||||||
b.text.setText(announcement.teacherFullName+"\n\n"+ (announcement.startDate != null ? announcement.startDate.getFormattedString() : "-") + (announcement.endDate != null ? " do " + announcement.endDate.getFormattedString() : "")+"\n\n" +announcement.text);
|
b.text.setText(announcement.teacherFullName+"\n\n"+ (announcement.startDate != null ? announcement.startDate.getFormattedString() : "-") + (announcement.endDate != null ? " do " + announcement.endDate.getFormattedString() : "")+"\n\n" +announcement.text);
|
||||||
if (!announcement.seen && app.profile.getLoginStoreType() != LOGIN_TYPE_LIBRUS) {
|
if (!announcement.seen && app.getProfile().getLoginStoreType() != LOGIN_TYPE_LIBRUS) {
|
||||||
announcement.seen = true;
|
announcement.seen = true;
|
||||||
AsyncTask.execute(() -> app.db.metadataDao().setSeen(App.profileId, announcement, true));
|
AsyncTask.execute(() -> App.db.metadataDao().setSeen(App.Companion.getProfileId(), announcement, true));
|
||||||
if (recyclerView.getAdapter() != null)
|
if (recyclerView.getAdapter() != null)
|
||||||
recyclerView.getAdapter().notifyDataSetChanged();
|
recyclerView.getAdapter().notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ public class AttendanceAdapter extends RecyclerView.Adapter<AttendanceAdapter.Vi
|
|||||||
holder.attendanceLessonTopic.getBackground().setColorFilter(new PorterDuffColorFilter(0x692196f3, PorterDuff.Mode.MULTIPLY));
|
holder.attendanceLessonTopic.getBackground().setColorFilter(new PorterDuffColorFilter(0x692196f3, PorterDuff.Mode.MULTIPLY));
|
||||||
attendance.seen = true;
|
attendance.seen = true;
|
||||||
AsyncTask.execute(() -> {
|
AsyncTask.execute(() -> {
|
||||||
app.db.metadataDao().setSeen(App.profileId, attendance, true);
|
App.db.metadataDao().setSeen(App.Companion.getProfileId(), attendance, true);
|
||||||
//Intent i = new Intent("android.intent.action.MAIN").putExtra(MainActivity.ACTION_UPDATE_BADGES, "yes, sure");
|
//Intent i = new Intent("android.intent.action.MAIN").putExtra(MainActivity.ACTION_UPDATE_BADGES, "yes, sure");
|
||||||
//context.sendBroadcast(i);
|
//context.sendBroadcast(i);
|
||||||
});
|
});
|
||||||
|
@ -33,8 +33,8 @@ import antonkozyriatskyi.circularprogressindicator.CircularProgressIndicator;
|
|||||||
import pl.szczodrzynski.edziennik.App;
|
import pl.szczodrzynski.edziennik.App;
|
||||||
import pl.szczodrzynski.edziennik.MainActivity;
|
import pl.szczodrzynski.edziennik.MainActivity;
|
||||||
import pl.szczodrzynski.edziennik.R;
|
import pl.szczodrzynski.edziennik.R;
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Subject;
|
import pl.szczodrzynski.edziennik.data.db.entity.Subject;
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull;
|
||||||
import pl.szczodrzynski.edziennik.databinding.FragmentAttendanceBinding;
|
import pl.szczodrzynski.edziennik.databinding.FragmentAttendanceBinding;
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes;
|
import pl.szczodrzynski.edziennik.utils.Themes;
|
||||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem;
|
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem;
|
||||||
@ -73,8 +73,6 @@ public class AttendanceFragment extends Fragment {
|
|||||||
return null;
|
return null;
|
||||||
app = (App) activity.getApplication();
|
app = (App) activity.getApplication();
|
||||||
getContext().getTheme().applyStyle(Themes.INSTANCE.getAppTheme(), true);
|
getContext().getTheme().applyStyle(Themes.INSTANCE.getAppTheme(), true);
|
||||||
if (app.profile == null)
|
|
||||||
return inflater.inflate(R.layout.fragment_loading, container, false);
|
|
||||||
// activity, context and profile is valid
|
// activity, context and profile is valid
|
||||||
b = DataBindingUtil.inflate(inflater, R.layout.fragment_attendance, container, false);
|
b = DataBindingUtil.inflate(inflater, R.layout.fragment_attendance, container, false);
|
||||||
b.refreshLayout.setParent(activity.getSwipeRefreshLayout());
|
b.refreshLayout.setParent(activity.getSwipeRefreshLayout());
|
||||||
@ -83,7 +81,7 @@ public class AttendanceFragment extends Fragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
if (app == null || app.profile == null || activity == null || b == null || !isAdded())
|
if (app == null || activity == null || b == null || !isAdded())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
activity.getBottomSheet().prependItems(
|
activity.getBottomSheet().prependItems(
|
||||||
@ -92,7 +90,7 @@ public class AttendanceFragment extends Fragment {
|
|||||||
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
||||||
.withOnClickListener(v3 -> {
|
.withOnClickListener(v3 -> {
|
||||||
activity.getBottomSheet().close();
|
activity.getBottomSheet().close();
|
||||||
AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_ATTENDANCE, true));
|
AsyncTask.execute(() -> App.db.metadataDao().setAllSeen(App.Companion.getProfileId(), TYPE_ATTENDANCE, true));
|
||||||
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show();
|
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -149,13 +147,13 @@ public class AttendanceFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if (app.profile.getLoginStoreType() == LOGIN_TYPE_MOBIDZIENNIK) {
|
if (app.getProfile().getLoginStoreType() == LOGIN_TYPE_MOBIDZIENNIK) {
|
||||||
b.attendanceSummarySubject.setVisibility(View.GONE);
|
b.attendanceSummarySubject.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
b.attendanceSummarySubject.setOnClickListener((v -> {
|
b.attendanceSummarySubject.setOnClickListener((v -> {
|
||||||
AsyncTask.execute(() -> {
|
AsyncTask.execute(() -> {
|
||||||
List<Subject> subjectList = app.db.subjectDao().getAllNow(App.profileId);
|
List<Subject> subjectList = App.db.subjectDao().getAllNow(App.Companion.getProfileId());
|
||||||
PopupMenu popupMenu = new PopupMenu(activity, b.attendanceSummarySubject, Gravity.END);
|
PopupMenu popupMenu = new PopupMenu(activity, b.attendanceSummarySubject, Gravity.END);
|
||||||
popupMenu.getMenu().add(0, -1, 0, R.string.subject_filter_disabled);
|
popupMenu.getMenu().add(0, -1, 0, R.string.subject_filter_disabled);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@ -187,8 +185,8 @@ public class AttendanceFragment extends Fragment {
|
|||||||
b.attendanceView.setHasFixedSize(true);
|
b.attendanceView.setHasFixedSize(true);
|
||||||
b.attendanceView.setLayoutManager(linearLayoutManager);
|
b.attendanceView.setLayoutManager(linearLayoutManager);
|
||||||
|
|
||||||
app.db.attendanceDao().getAll(App.profileId).observe(this, attendance -> {
|
App.db.attendanceDao().getAll(App.Companion.getProfileId()).observe(this, attendance -> {
|
||||||
if (app == null || app.profile == null || activity == null || b == null || !isAdded())
|
if (app == null || activity == null || b == null || !isAdded())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (attendance == null) {
|
if (attendance == null) {
|
||||||
@ -209,7 +207,7 @@ public class AttendanceFragment extends Fragment {
|
|||||||
subjectTotalCount = new LongSparseArray<>();
|
subjectTotalCount = new LongSparseArray<>();
|
||||||
subjectAbsentCount = new LongSparseArray<>();
|
subjectAbsentCount = new LongSparseArray<>();
|
||||||
for (AttendanceFull attendance: attendanceList) {
|
for (AttendanceFull attendance: attendanceList) {
|
||||||
if (app.profile.getLoginStoreType() == LOGIN_TYPE_VULCAN && attendance.type == TYPE_RELEASED)
|
if (app.getProfile().getLoginStoreType() == LOGIN_TYPE_VULCAN && attendance.type == TYPE_RELEASED)
|
||||||
continue;
|
continue;
|
||||||
int[] subjectTotal = subjectTotalCount.get(attendance.subjectId, new int[3]);
|
int[] subjectTotal = subjectTotalCount.get(attendance.subjectId, new int[3]);
|
||||||
int[] subjectAbsent = subjectAbsentCount.get(attendance.subjectId, new int[3]);
|
int[] subjectAbsent = subjectAbsentCount.get(attendance.subjectId, new int[3]);
|
||||||
@ -228,7 +226,7 @@ public class AttendanceFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateList() {
|
private void updateList() {
|
||||||
if (app == null || app.profile == null || activity == null || b == null || !isAdded())
|
if (app == null || activity == null || b == null || !isAdded())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int presentCount = 0;
|
int presentCount = 0;
|
||||||
@ -306,7 +304,7 @@ public class AttendanceFragment extends Fragment {
|
|||||||
float attendancePercentage;
|
float attendancePercentage;
|
||||||
|
|
||||||
// in Mobidziennik there are no TYPE_PRESENT records so we cannot calculate the percentage
|
// in Mobidziennik there are no TYPE_PRESENT records so we cannot calculate the percentage
|
||||||
if (app.profile.getLoginStoreType() == LOGIN_TYPE_VULCAN) {
|
if (app.getProfile().getLoginStoreType() == LOGIN_TYPE_VULCAN) {
|
||||||
float allCount = presentCount + absentCount + belatedCount; // do not count releases
|
float allCount = presentCount + absentCount + belatedCount; // do not count releases
|
||||||
float present = allCount - absentCount;
|
float present = allCount - absentCount;
|
||||||
attendancePercentage = present / allCount * 100.0f;
|
attendancePercentage = present / allCount * 100.0f;
|
||||||
|
@ -2,9 +2,9 @@ package pl.szczodrzynski.edziennik.ui.modules.base;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.App;
|
|
||||||
import pl.szczodrzynski.edziennik.R;
|
import pl.szczodrzynski.edziennik.R;
|
||||||
|
|
||||||
public class CrashGtfoActivity extends AppCompatActivity {
|
public class CrashGtfoActivity extends AppCompatActivity {
|
||||||
@ -12,7 +12,7 @@ public class CrashGtfoActivity extends AppCompatActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setTheme((((App)getApplication()).getContext()
|
setTheme((getApplication()
|
||||||
.getSharedPreferences(getString(R.string.preference_file_global), Context.MODE_PRIVATE)
|
.getSharedPreferences(getString(R.string.preference_file_global), Context.MODE_PRIVATE)
|
||||||
.getBoolean("dark_theme", false) ? R.style.AppTheme_Dark : R.style.AppTheme));
|
.getBoolean("dark_theme", false) ? R.style.AppTheme_Dark : R.style.AppTheme));
|
||||||
setContentView(R.layout.activity_gtfo);
|
setContentView(R.layout.activity_gtfo);
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.modules.base;
|
package pl.szczodrzynski.edziennik.ui.modules.base;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
import com.google.android.material.textfield.TextInputEditText;
|
import com.google.android.material.textfield.TextInputEditText;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
@ -100,7 +100,7 @@ public class DebugFragment extends Fragment {
|
|||||||
forceType = "i";
|
forceType = "i";
|
||||||
parameter = parameter.substring(0, parameter.length()-1);
|
parameter = parameter.substring(0, parameter.length()-1);
|
||||||
}
|
}
|
||||||
SimpleObj obj = app.gson.fromJson("{\"value\":"+parameter+"}", SimpleObj.class);
|
SimpleObj obj = app.getGson().fromJson("{\"value\":"+parameter+"}", SimpleObj.class);
|
||||||
Class type = obj.value.getClass();
|
Class type = obj.value.getClass();
|
||||||
Object value = obj.value;
|
Object value = obj.value;
|
||||||
if ("d".equals(forceType)) {
|
if ("d".equals(forceType)) {
|
||||||
@ -180,7 +180,7 @@ public class DebugFragment extends Fragment {
|
|||||||
getByPath(app, target, path, true);
|
getByPath(app, target, path, true);
|
||||||
// set the value if specified
|
// set the value if specified
|
||||||
if (valueToSet != null) {
|
if (valueToSet != null) {
|
||||||
targetField.set(target, app.gson.fromJson(valueToSet, targetField.getGenericType()));
|
targetField.set(target, app.getGson().fromJson(valueToSet, targetField.getGenericType()));
|
||||||
targetField = null;
|
targetField = null;
|
||||||
}
|
}
|
||||||
if (targetField != null) {
|
if (targetField != null) {
|
||||||
@ -194,7 +194,7 @@ public class DebugFragment extends Fragment {
|
|||||||
return Log.getStackTraceString(e);
|
return Log.getStackTraceString(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return app.gson.toJson(target);
|
return app.getGson().toJson(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -218,13 +218,13 @@ public class DebugFragment extends Fragment {
|
|||||||
getView().findViewById(R.id.debugAppconfig).setOnClickListener(v -> {
|
getView().findViewById(R.id.debugAppconfig).setOnClickListener(v -> {
|
||||||
JsonRecyclerView mRecyclerView = getView().findViewById(R.id.rv_json);
|
JsonRecyclerView mRecyclerView = getView().findViewById(R.id.rv_json);
|
||||||
// bind json
|
// bind json
|
||||||
mRecyclerView.bindJson(new Gson().toJson(app.appConfig));
|
mRecyclerView.bindJson(new Gson().toJson(app.getConfig()));
|
||||||
mRecyclerView.setTextSize(20);
|
mRecyclerView.setTextSize(20);
|
||||||
});
|
});
|
||||||
getView().findViewById(R.id.debugAppprofile).setOnClickListener(v -> {
|
getView().findViewById(R.id.debugAppprofile).setOnClickListener(v -> {
|
||||||
JsonRecyclerView mRecyclerView = getView().findViewById(R.id.rv_json);
|
JsonRecyclerView mRecyclerView = getView().findViewById(R.id.rv_json);
|
||||||
// bind json
|
// bind json
|
||||||
mRecyclerView.bindJson(new Gson().toJson(app.profile));
|
mRecyclerView.bindJson(new Gson().toJson(app.getProfile()));
|
||||||
mRecyclerView.setTextSize(20);
|
mRecyclerView.setTextSize(20);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,6 @@ public class BehaviourFragment extends Fragment {
|
|||||||
return null;
|
return null;
|
||||||
app = (App) activity.getApplication();
|
app = (App) activity.getApplication();
|
||||||
getContext().getTheme().applyStyle(Themes.INSTANCE.getAppTheme(), true);
|
getContext().getTheme().applyStyle(Themes.INSTANCE.getAppTheme(), true);
|
||||||
if (app.profile == null)
|
|
||||||
return inflater.inflate(R.layout.fragment_loading, container, false);
|
|
||||||
// activity, context and profile is valid
|
// activity, context and profile is valid
|
||||||
b = DataBindingUtil.inflate(inflater, R.layout.fragment_behaviour, container, false);
|
b = DataBindingUtil.inflate(inflater, R.layout.fragment_behaviour, container, false);
|
||||||
b.refreshLayout.setParent(activity.getSwipeRefreshLayout());
|
b.refreshLayout.setParent(activity.getSwipeRefreshLayout());
|
||||||
@ -63,7 +61,7 @@ public class BehaviourFragment extends Fragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
if (app == null || app.profile == null || activity == null || b == null || !isAdded())
|
if (app == null || activity == null || b == null || !isAdded())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
activity.getBottomSheet().prependItems(
|
activity.getBottomSheet().prependItems(
|
||||||
@ -72,7 +70,7 @@ public class BehaviourFragment extends Fragment {
|
|||||||
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
||||||
.withOnClickListener(v3 -> {
|
.withOnClickListener(v3 -> {
|
||||||
activity.getBottomSheet().close();
|
activity.getBottomSheet().close();
|
||||||
AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_NOTICE, true));
|
AsyncTask.execute(() -> App.db.metadataDao().setAllSeen(App.Companion.getProfileId(), TYPE_NOTICE, true));
|
||||||
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show();
|
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -99,8 +97,8 @@ public class BehaviourFragment extends Fragment {
|
|||||||
b.noticesView.setHasFixedSize(true);
|
b.noticesView.setHasFixedSize(true);
|
||||||
b.noticesView.setLayoutManager(linearLayoutManager);
|
b.noticesView.setLayoutManager(linearLayoutManager);
|
||||||
|
|
||||||
app.db.noticeDao().getAll(App.profileId).observe(this, notices -> {
|
app.db.noticeDao().getAll(App.Companion.getProfileId()).observe(this, notices -> {
|
||||||
if (app == null || app.profile == null || activity == null || b == null || !isAdded())
|
if (app == null || activity == null || b == null || !isAdded())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (notices == null) {
|
if (notices == null) {
|
||||||
|
@ -1,18 +1,5 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.modules.feedback;
|
package pl.szczodrzynski.edziennik.ui.modules.feedback;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.databinding.DataBindingUtil;
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.App;
|
|
||||||
import pl.szczodrzynski.edziennik.R;
|
|
||||||
import pl.szczodrzynski.edziennik.databinding.ActivityFeedbackBinding;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.FeedbackMessageWithCount;
|
|
||||||
import pl.szczodrzynski.edziennik.network.ServerRequest;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Anim;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -28,6 +15,9 @@ import android.view.animation.Animation;
|
|||||||
import android.widget.PopupMenu;
|
import android.widget.PopupMenu;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
import com.github.bassaer.chatmessageview.model.IChatUser;
|
import com.github.bassaer.chatmessageview.model.IChatUser;
|
||||||
import com.github.bassaer.chatmessageview.model.Message;
|
import com.github.bassaer.chatmessageview.model.Message;
|
||||||
@ -36,7 +26,16 @@ import com.github.bassaer.chatmessageview.view.ChatView;
|
|||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static pl.szczodrzynski.edziennik.App.APP_URL;
|
import pl.szczodrzynski.edziennik.App;
|
||||||
|
import pl.szczodrzynski.edziennik.R;
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage;
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.FeedbackMessageWithCount;
|
||||||
|
import pl.szczodrzynski.edziennik.databinding.ActivityFeedbackBinding;
|
||||||
|
import pl.szczodrzynski.edziennik.network.ServerRequest;
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Anim;
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Themes;
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils;
|
||||||
|
|
||||||
import static pl.szczodrzynski.edziennik.utils.Utils.crc16;
|
import static pl.szczodrzynski.edziennik.utils.Utils.crc16;
|
||||||
import static pl.szczodrzynski.edziennik.utils.Utils.openUrl;
|
import static pl.szczodrzynski.edziennik.utils.Utils.openUrl;
|
||||||
|
|
||||||
@ -101,7 +100,7 @@ public class FeedbackActivity extends AppCompatActivity {
|
|||||||
.content(R.string.sending_message)
|
.content(R.string.sending_message)
|
||||||
.negativeText(R.string.cancel)
|
.negativeText(R.string.cancel)
|
||||||
.show();
|
.show();
|
||||||
new ServerRequest(app, app.requestScheme + APP_URL + "main.php?feedback_message", "FeedbackSend")
|
new ServerRequest(app, "https://edziennik.szczodrzynski.pl/app/main.php?feedback_message", "FeedbackSend")
|
||||||
.setBodyParameter("message_text", text)
|
.setBodyParameter("message_text", text)
|
||||||
.setBodyParameter("target_device", deviceToSend == null ? "null" : deviceToSend)
|
.setBodyParameter("target_device", deviceToSend == null ? "null" : deviceToSend)
|
||||||
.run(((e, result) -> {
|
.run(((e, result) -> {
|
||||||
@ -199,7 +198,7 @@ public class FeedbackActivity extends AppCompatActivity {
|
|||||||
receiver = new BroadcastReceiver() {
|
receiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
FeedbackMessage message = app.gson.fromJson(intent.getStringExtra("message"), FeedbackMessage.class);
|
FeedbackMessage message = app.getGson().fromJson(intent.getStringExtra("message"), FeedbackMessage.class);
|
||||||
Calendar c = Calendar.getInstance();
|
Calendar c = Calendar.getInstance();
|
||||||
c.setTimeInMillis(message.sentTime);
|
c.setTimeInMillis(message.sentTime);
|
||||||
Message chatMessage = new Message.Builder()
|
Message chatMessage = new Message.Builder()
|
||||||
@ -238,7 +237,7 @@ public class FeedbackActivity extends AppCompatActivity {
|
|||||||
mChatView.setMessageMarginTop(5);
|
mChatView.setMessageMarginTop(5);
|
||||||
mChatView.setMessageMarginBottom(5);
|
mChatView.setMessageMarginBottom(5);
|
||||||
|
|
||||||
if (App.devMode && app.deviceId.equals("f054761fbdb6a238")) {
|
if (App.Companion.getDevMode() && app.getDeviceId().equals("f054761fbdb6a238")) {
|
||||||
b.targetDeviceLayout.setVisibility(View.VISIBLE);
|
b.targetDeviceLayout.setVisibility(View.VISIBLE);
|
||||||
b.targetDeviceDropDown.setOnClickListener((v -> {
|
b.targetDeviceDropDown.setOnClickListener((v -> {
|
||||||
AsyncTask.execute(() -> {
|
AsyncTask.execute(() -> {
|
||||||
|
@ -21,11 +21,10 @@ import com.github.bassaer.chatmessageview.model.IChatUser
|
|||||||
import com.github.bassaer.chatmessageview.model.Message
|
import com.github.bassaer.chatmessageview.model.Message
|
||||||
import com.github.bassaer.chatmessageview.view.ChatView
|
import com.github.bassaer.chatmessageview.view.ChatView
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.App.APP_URL
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.databinding.FragmentFeedbackBinding
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage
|
import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage
|
||||||
|
import pl.szczodrzynski.edziennik.databinding.FragmentFeedbackBinding
|
||||||
import pl.szczodrzynski.edziennik.network.ServerRequest
|
import pl.szczodrzynski.edziennik.network.ServerRequest
|
||||||
import pl.szczodrzynski.edziennik.utils.Anim
|
import pl.szczodrzynski.edziennik.utils.Anim
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes
|
import pl.szczodrzynski.edziennik.utils.Themes
|
||||||
@ -248,7 +247,7 @@ class FeedbackFragment : Fragment() {
|
|||||||
.content(R.string.sending_message)
|
.content(R.string.sending_message)
|
||||||
.negativeText(R.string.cancel)
|
.negativeText(R.string.cancel)
|
||||||
.show()
|
.show()
|
||||||
ServerRequest(app, app.requestScheme + APP_URL + "main.php?feedback_message", "FeedbackSend")
|
ServerRequest(app, "https://edziennik.szczodrzynski.pl/app/main.php?feedback_message", "FeedbackSend")
|
||||||
.setBodyParameter("message_text", text)
|
.setBodyParameter("message_text", text)
|
||||||
.setBodyParameter("target_device", if (deviceToSend == null) "null" else deviceToSend)
|
.setBodyParameter("target_device", if (deviceToSend == null) "null" else deviceToSend)
|
||||||
.run { e, result ->
|
.run { e, result ->
|
||||||
|
@ -16,7 +16,6 @@ import androidx.fragment.app.Fragment;
|
|||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial;
|
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -25,8 +24,8 @@ import pl.szczodrzynski.edziennik.MainActivity;
|
|||||||
import pl.szczodrzynski.edziennik.R;
|
import pl.szczodrzynski.edziennik.R;
|
||||||
import pl.szczodrzynski.edziennik.config.ProfileConfigGrades;
|
import pl.szczodrzynski.edziennik.config.ProfileConfigGrades;
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade;
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade;
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Subject;
|
import pl.szczodrzynski.edziennik.data.db.entity.Subject;
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.GradeFull;
|
||||||
import pl.szczodrzynski.edziennik.databinding.FragmentGradesBinding;
|
import pl.szczodrzynski.edziennik.databinding.FragmentGradesBinding;
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes;
|
import pl.szczodrzynski.edziennik.utils.Themes;
|
||||||
import pl.szczodrzynski.edziennik.utils.models.ItemGradesSubjectModel;
|
import pl.szczodrzynski.edziennik.utils.models.ItemGradesSubjectModel;
|
||||||
@ -56,8 +55,6 @@ public class GradesFragment extends Fragment {
|
|||||||
return null;
|
return null;
|
||||||
app = (App) activity.getApplication();
|
app = (App) activity.getApplication();
|
||||||
getContext().getTheme().applyStyle(Themes.INSTANCE.getAppTheme(), true);
|
getContext().getTheme().applyStyle(Themes.INSTANCE.getAppTheme(), true);
|
||||||
if (app.profile == null)
|
|
||||||
return inflater.inflate(R.layout.fragment_loading, container, false);
|
|
||||||
// activity, context and profile is valid
|
// activity, context and profile is valid
|
||||||
b = DataBindingUtil.inflate(inflater, R.layout.fragment_grades, container, false);
|
b = DataBindingUtil.inflate(inflater, R.layout.fragment_grades, container, false);
|
||||||
b.refreshLayout.setParent(activity.getSwipeRefreshLayout());
|
b.refreshLayout.setParent(activity.getSwipeRefreshLayout());
|
||||||
@ -68,10 +65,8 @@ public class GradesFragment extends Fragment {
|
|||||||
ListView listView;
|
ListView listView;
|
||||||
List<ItemGradesSubjectModel> subjectList;
|
List<ItemGradesSubjectModel> subjectList;
|
||||||
|
|
||||||
private boolean sortModeChanged = false;
|
|
||||||
|
|
||||||
private String getRegisterCardAverageModeSubText() {
|
private String getRegisterCardAverageModeSubText() {
|
||||||
switch (App.getConfig().forProfile().getGrades().getYearAverageMode()) {
|
switch (App.Companion.getConfig().forProfile().getGrades().getYearAverageMode()) {
|
||||||
default:
|
default:
|
||||||
case YEAR_1_AVG_2_AVG:
|
case YEAR_1_AVG_2_AVG:
|
||||||
return getString(R.string.settings_register_avg_mode_0_short);
|
return getString(R.string.settings_register_avg_mode_0_short);
|
||||||
@ -88,7 +83,7 @@ public class GradesFragment extends Fragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
if (app == null || app.profile == null || activity == null || b == null || !isAdded())
|
if (app == null || activity == null || b == null || !isAdded())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*activity.getBottomSheet().setToggleGroupEnabled(true);
|
/*activity.getBottomSheet().setToggleGroupEnabled(true);
|
||||||
@ -136,7 +131,7 @@ public class GradesFragment extends Fragment {
|
|||||||
.withIcon(CommunityMaterial.Icon2.cmd_palette_outline)
|
.withIcon(CommunityMaterial.Icon2.cmd_palette_outline)
|
||||||
.withOnClickListener(v3 -> {
|
.withOnClickListener(v3 -> {
|
||||||
activity.getBottomSheet().close();
|
activity.getBottomSheet().close();
|
||||||
ProfileConfigGrades config = app.config.getFor(App.profileId).getGrades();
|
ProfileConfigGrades config = app.getConfig().getFor(App.Companion.getProfileId()).getGrades();
|
||||||
new MaterialDialog.Builder(activity)
|
new MaterialDialog.Builder(activity)
|
||||||
.title(R.string.dialog_grades_color_mode_title)
|
.title(R.string.dialog_grades_color_mode_title)
|
||||||
.items(R.array.dialog_grades_color_modes)
|
.items(R.array.dialog_grades_color_modes)
|
||||||
@ -155,8 +150,8 @@ public class GradesFragment extends Fragment {
|
|||||||
new MaterialDialog.Builder(activity)
|
new MaterialDialog.Builder(activity)
|
||||||
.title(R.string.dialog_grades_sort_title)
|
.title(R.string.dialog_grades_sort_title)
|
||||||
.items(R.array.dialog_grades_sort_modes)
|
.items(R.array.dialog_grades_sort_modes)
|
||||||
.itemsCallbackSingleChoice(app.config.getGrades().getOrderBy(), (dialog, view1, which, text) -> {
|
.itemsCallbackSingleChoice(app.getConfig().getGrades().getOrderBy(), (dialog, view1, which, text) -> {
|
||||||
app.config.getGrades().setOrderBy(which);
|
app.getConfig().getGrades().setOrderBy(which);
|
||||||
activity.reloadTarget();
|
activity.reloadTarget();
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
@ -184,8 +179,8 @@ public class GradesFragment extends Fragment {
|
|||||||
.title(getString(R.string.settings_register_avg_mode_dialog_title))
|
.title(getString(R.string.settings_register_avg_mode_dialog_title))
|
||||||
.content(getString(R.string.settings_register_avg_mode_dialog_text))
|
.content(getString(R.string.settings_register_avg_mode_dialog_text))
|
||||||
.items(modeNames)
|
.items(modeNames)
|
||||||
.itemsCallbackSingleChoice(modeIds.indexOf(App.getConfig().forProfile().getGrades().getYearAverageMode()), (dialog, itemView, which, text) -> {
|
.itemsCallbackSingleChoice(modeIds.indexOf(App.Companion.getConfig().forProfile().getGrades().getYearAverageMode()), (dialog, itemView, which, text) -> {
|
||||||
App.getConfig().forProfile().getGrades().setYearAverageMode(modeIds.get(which));
|
App.Companion.getConfig().forProfile().getGrades().setYearAverageMode(modeIds.get(which));
|
||||||
activity.reloadTarget();
|
activity.reloadTarget();
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
@ -197,7 +192,7 @@ public class GradesFragment extends Fragment {
|
|||||||
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
||||||
.withOnClickListener(v3 -> {
|
.withOnClickListener(v3 -> {
|
||||||
activity.getBottomSheet().close();
|
activity.getBottomSheet().close();
|
||||||
AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_GRADE, true));
|
AsyncTask.execute(() -> App.db.metadataDao().setAllSeen(App.Companion.getProfileId(), TYPE_GRADE, true));
|
||||||
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show();
|
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -227,41 +222,41 @@ public class GradesFragment extends Fragment {
|
|||||||
|
|
||||||
long finalExpandSubjectId = expandSubjectId;
|
long finalExpandSubjectId = expandSubjectId;
|
||||||
String orderBy;
|
String orderBy;
|
||||||
if (app.config.getGrades().getOrderBy() == ORDER_BY_SUBJECT_ASC) {
|
if (app.getConfig().getGrades().getOrderBy() == ORDER_BY_SUBJECT_ASC) {
|
||||||
orderBy = "subjectLongName ASC, addedDate DESC";
|
orderBy = "subjectLongName ASC, addedDate DESC";
|
||||||
}
|
}
|
||||||
else if (app.config.getGrades().getOrderBy() == ORDER_BY_DATE_DESC) {
|
else if (app.getConfig().getGrades().getOrderBy() == ORDER_BY_DATE_DESC) {
|
||||||
orderBy = "addedDate DESC";
|
orderBy = "addedDate DESC";
|
||||||
}
|
}
|
||||||
else if (app.config.getGrades().getOrderBy() == ORDER_BY_DATE_ASC) {
|
else if (app.getConfig().getGrades().getOrderBy() == ORDER_BY_DATE_ASC) {
|
||||||
orderBy = "addedDate ASC";
|
orderBy = "addedDate ASC";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
orderBy = "subjectLongName DESC, addedDate DESC";
|
orderBy = "subjectLongName DESC, addedDate DESC";
|
||||||
}
|
}
|
||||||
|
|
||||||
app.db.gradeDao().getAllOrderBy(App.profileId, orderBy).observe(this, grades -> {
|
App.db.gradeDao().getAllOrderBy(App.Companion.getProfileId(), orderBy).observe(this, grades -> {
|
||||||
if (app == null || app.profile == null || activity == null || b == null || !isAdded())
|
if (app == null || activity == null || b == null || !isAdded())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
subjectList = new ArrayList<>();
|
subjectList = new ArrayList<>();
|
||||||
|
|
||||||
ProfileConfigGrades config = app.config.getFor(App.profileId).getGrades();
|
ProfileConfigGrades config = app.getConfig().getFor(App.Companion.getProfileId()).getGrades();
|
||||||
|
|
||||||
// now we have all grades from the newest to the oldest
|
// now we have all grades from the newest to the oldest
|
||||||
for (GradeFull grade: grades) {
|
for (GradeFull grade: grades) {
|
||||||
ItemGradesSubjectModel model = ItemGradesSubjectModel.searchModelBySubjectId(subjectList, grade.subjectId);
|
ItemGradesSubjectModel model = ItemGradesSubjectModel.searchModelBySubjectId(subjectList, grade.subjectId);
|
||||||
if (model == null) {
|
if (model == null) {
|
||||||
model = new ItemGradesSubjectModel(app.profile,
|
model = new ItemGradesSubjectModel(app.getProfile(),
|
||||||
new Subject(App.profileId, grade.subjectId, grade.subjectLongName, grade.subjectShortName),
|
new Subject(App.Companion.getProfileId(), grade.subjectId, grade.subjectLongName, grade.subjectShortName),
|
||||||
new ArrayList<>(),
|
new ArrayList<>(),
|
||||||
new ArrayList<>());
|
new ArrayList<>());
|
||||||
subjectList.add(model);
|
subjectList.add(model);
|
||||||
if (model.subject != null && model.subject.id == finalExpandSubjectId) {
|
if (model.subject != null && model.subject.id == finalExpandSubjectId) {
|
||||||
model.expandView = true;
|
model.expandView = true;
|
||||||
}
|
}
|
||||||
model.colorMode = App.getConfig().forProfile().getGrades().getColorMode();
|
model.colorMode = App.Companion.getConfig().forProfile().getGrades().getColorMode();
|
||||||
model.yearAverageMode = App.getConfig().forProfile().getGrades().getYearAverageMode();
|
model.yearAverageMode = App.Companion.getConfig().forProfile().getGrades().getYearAverageMode();
|
||||||
}
|
}
|
||||||
if (!grade.seen && grade.semester == 1) {
|
if (!grade.seen && grade.semester == 1) {
|
||||||
model.semester1Unread++;
|
model.semester1Unread++;
|
||||||
@ -380,7 +375,7 @@ public class GradesFragment extends Fragment {
|
|||||||
else if (!model.isBehaviourSubject && model.isNormalSubject) {
|
else if (!model.isBehaviourSubject && model.isNormalSubject) {
|
||||||
// applies for normal grades & normal+descriptive grades
|
// applies for normal grades & normal+descriptive grades
|
||||||
// calculate the normal grade average based on the user's setting
|
// calculate the normal grade average based on the user's setting
|
||||||
switch (App.getConfig().forProfile().getGrades().getYearAverageMode()) {
|
switch (App.Companion.getConfig().forProfile().getGrades().getYearAverageMode()) {
|
||||||
case YEAR_1_AVG_2_AVG:
|
case YEAR_1_AVG_2_AVG:
|
||||||
model.yearAverage = (model.semester1Average + model.semester2Average) / 2;
|
model.yearAverage = (model.semester1Average + model.semester2Average) / 2;
|
||||||
break;
|
break;
|
||||||
@ -433,7 +428,7 @@ public class GradesFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void showAverages() {
|
public void showAverages() {
|
||||||
if (app == null || app.profile == null || activity == null || b == null || !isAdded() || subjectList == null)
|
if (app == null || activity == null || b == null || !isAdded() || subjectList == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float semester1Sum = 0;
|
float semester1Sum = 0;
|
||||||
@ -529,8 +524,6 @@ public class GradesFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DecimalFormat df = new DecimalFormat("0.00");
|
|
||||||
|
|
||||||
String semester1ExpectedAverageStr = semester1Count > semester1ProposedCount || semester1Count > semester1FinalCount ? getString(R.string.dialog_averages_expected_format, 1, semester1Sum / semester1Count) : "";
|
String semester1ExpectedAverageStr = semester1Count > semester1ProposedCount || semester1Count > semester1FinalCount ? getString(R.string.dialog_averages_expected_format, 1, semester1Sum / semester1Count) : "";
|
||||||
String semester1ProposedAverageStr = semester1ProposedCount > 0 ? getString(R.string.dialog_averages_proposed_format, 1, semester1ProposedSum / semester1ProposedCount) : "";
|
String semester1ProposedAverageStr = semester1ProposedCount > 0 ? getString(R.string.dialog_averages_proposed_format, 1, semester1ProposedSum / semester1ProposedCount) : "";
|
||||||
String semester1FinalAverageStr = semester1FinalCount > 0 ? getString(R.string.dialog_averages_final_format, 1, semester1FinalSum / semester1FinalCount) : "";
|
String semester1FinalAverageStr = semester1FinalCount > 0 ? getString(R.string.dialog_averages_final_format, 1, semester1FinalSum / semester1FinalCount) : "";
|
||||||
|
@ -52,11 +52,11 @@ public class GradesListAdapter extends RecyclerView.Adapter<GradesListAdapter.Vi
|
|||||||
GradeFull grade = gradeList.get(position);
|
GradeFull grade = gradeList.get(position);
|
||||||
|
|
||||||
holder.root.setOnClickListener((v -> {
|
holder.root.setOnClickListener((v -> {
|
||||||
new GradeDetailsDialog(v.getContext(), App.profileId).show(app, grade);
|
new GradeDetailsDialog(v.getContext(), App.Companion.getProfileId()).show(app, grade);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
int gradeColor;
|
int gradeColor;
|
||||||
if (App.getConfig().forProfile().getGrades().getColorMode() == COLOR_MODE_DEFAULT) {
|
if (App.Companion.getConfig().forProfile().getGrades().getColorMode() == COLOR_MODE_DEFAULT) {
|
||||||
gradeColor = grade.color;
|
gradeColor = grade.color;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -31,8 +31,8 @@ import pl.szczodrzynski.edziennik.App;
|
|||||||
import pl.szczodrzynski.edziennik.MainActivity;
|
import pl.szczodrzynski.edziennik.MainActivity;
|
||||||
import pl.szczodrzynski.edziennik.R;
|
import pl.szczodrzynski.edziennik.R;
|
||||||
import pl.szczodrzynski.edziennik.data.db.AppDb;
|
import pl.szczodrzynski.edziennik.data.db.AppDb;
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Subject;
|
import pl.szczodrzynski.edziennik.data.db.entity.Subject;
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.GradeFull;
|
||||||
import pl.szczodrzynski.edziennik.utils.Anim;
|
import pl.szczodrzynski.edziennik.utils.Anim;
|
||||||
import pl.szczodrzynski.edziennik.utils.Colors;
|
import pl.szczodrzynski.edziennik.utils.Colors;
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils;
|
import pl.szczodrzynski.edziennik.utils.Utils;
|
||||||
@ -86,34 +86,34 @@ public class GradesSubjectAdapter extends ArrayAdapter<ItemGradesSubjectModel> i
|
|||||||
|
|
||||||
private boolean gradesSetAsRead(ViewHolder holder, ItemGradesSubjectModel model, int semester) {
|
private boolean gradesSetAsRead(ViewHolder holder, ItemGradesSubjectModel model, int semester) {
|
||||||
boolean somethingChanged = false;
|
boolean somethingChanged = false;
|
||||||
AppDb db = AppDb.getDatabase(null);
|
AppDb db = App.Companion.getDb();
|
||||||
if (semester == 1) {
|
if (semester == 1) {
|
||||||
model.semester1Unread = 0;
|
model.semester1Unread = 0;
|
||||||
for (GradeFull grade : model.grades1) {
|
for (GradeFull grade : model.grades1) {
|
||||||
if (!grade.seen) {
|
if (!grade.seen) {
|
||||||
db.metadataDao().setSeen(App.profileId, grade, somethingChanged = true);
|
db.metadataDao().setSeen(App.Companion.getProfileId(), grade, somethingChanged = true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (model.semester1Proposed != null && !model.semester1Proposed.seen)
|
if (model.semester1Proposed != null && !model.semester1Proposed.seen)
|
||||||
db.metadataDao().setSeen(App.profileId, model.semester1Proposed, somethingChanged = true);
|
db.metadataDao().setSeen(App.Companion.getProfileId(), model.semester1Proposed, somethingChanged = true);
|
||||||
if (model.semester1Final != null && !model.semester1Final.seen)
|
if (model.semester1Final != null && !model.semester1Final.seen)
|
||||||
db.metadataDao().setSeen(App.profileId, model.semester1Final, somethingChanged = true);
|
db.metadataDao().setSeen(App.Companion.getProfileId(), model.semester1Final, somethingChanged = true);
|
||||||
}
|
}
|
||||||
else if (semester == 2) {
|
else if (semester == 2) {
|
||||||
model.semester2Unread = 0;
|
model.semester2Unread = 0;
|
||||||
for (GradeFull grade : model.grades2) {
|
for (GradeFull grade : model.grades2) {
|
||||||
if (!grade.seen) {
|
if (!grade.seen) {
|
||||||
db.metadataDao().setSeen(App.profileId, grade, somethingChanged = true);
|
db.metadataDao().setSeen(App.Companion.getProfileId(), grade, somethingChanged = true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (model.semester2Proposed != null && !model.semester2Proposed.seen)
|
if (model.semester2Proposed != null && !model.semester2Proposed.seen)
|
||||||
db.metadataDao().setSeen(App.profileId, model.semester2Proposed, somethingChanged = true);
|
db.metadataDao().setSeen(App.Companion.getProfileId(), model.semester2Proposed, somethingChanged = true);
|
||||||
if (model.semester2Final != null && !model.semester2Final.seen)
|
if (model.semester2Final != null && !model.semester2Final.seen)
|
||||||
db.metadataDao().setSeen(App.profileId, model.semester2Final, somethingChanged = true);
|
db.metadataDao().setSeen(App.Companion.getProfileId(), model.semester2Final, somethingChanged = true);
|
||||||
if (model.yearProposed != null && !model.yearProposed.seen)
|
if (model.yearProposed != null && !model.yearProposed.seen)
|
||||||
db.metadataDao().setSeen(App.profileId, model.yearProposed, somethingChanged = true);
|
db.metadataDao().setSeen(App.Companion.getProfileId(), model.yearProposed, somethingChanged = true);
|
||||||
if (model.yearFinal != null && !model.yearFinal.seen)
|
if (model.yearFinal != null && !model.yearFinal.seen)
|
||||||
db.metadataDao().setSeen(App.profileId, model.yearFinal, somethingChanged = true);
|
db.metadataDao().setSeen(App.Companion.getProfileId(), model.yearFinal, somethingChanged = true);
|
||||||
}
|
}
|
||||||
if (somethingChanged) updateSubjectSemesterBadges(holder, model);
|
if (somethingChanged) updateSubjectSemesterBadges(holder, model);
|
||||||
return somethingChanged;
|
return somethingChanged;
|
||||||
@ -219,7 +219,7 @@ public class GradesSubjectAdapter extends ArrayAdapter<ItemGradesSubjectModel> i
|
|||||||
layoutParams.setMargins(0, 0, _5dp, 0);
|
layoutParams.setMargins(0, 0, _5dp, 0);
|
||||||
|
|
||||||
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
|
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
|
||||||
int maxWidthPx = displayMetrics.widthPixels - Utils.dpToPx((app.config.getUi().getMiniMenuVisible() ? 72 : 0)/*miniDrawer size*/ + 8 + 8/*left and right offsets*/ + 24/*ellipsize width*/);
|
int maxWidthPx = displayMetrics.widthPixels - Utils.dpToPx((app.getConfig().getUi().getMiniMenuVisible() ? 72 : 0)/*miniDrawer size*/ + 8 + 8/*left and right offsets*/ + 24/*ellipsize width*/);
|
||||||
int totalWidthPx = 0;
|
int totalWidthPx = 0;
|
||||||
boolean ellipsized = false;
|
boolean ellipsized = false;
|
||||||
|
|
||||||
|
@ -40,11 +40,11 @@ class HomeFragment : Fragment(), CoroutineScope {
|
|||||||
private const val TAG = "HomeFragment"
|
private const val TAG = "HomeFragment"
|
||||||
|
|
||||||
fun swapCards(fromPosition: Int, toPosition: Int, cardAdapter: HomeCardAdapter) {
|
fun swapCards(fromPosition: Int, toPosition: Int, cardAdapter: HomeCardAdapter) {
|
||||||
val homeCards = App.getConfig().ui.homeCards.toMutableList()
|
val homeCards = App.config.ui.homeCards.toMutableList()
|
||||||
val fromPair = homeCards[fromPosition]
|
val fromPair = homeCards[fromPosition]
|
||||||
homeCards[fromPosition] = homeCards[toPosition]
|
homeCards[fromPosition] = homeCards[toPosition]
|
||||||
homeCards[toPosition] = fromPair
|
homeCards[toPosition] = fromPair
|
||||||
App.getConfig().ui.homeCards = homeCards
|
App.config.ui.homeCards = homeCards
|
||||||
|
|
||||||
val fromCard = cardAdapter.items[fromPosition]
|
val fromCard = cardAdapter.items[fromPosition]
|
||||||
cardAdapter.items[fromPosition] = cardAdapter.items[toPosition]
|
cardAdapter.items[fromPosition] = cardAdapter.items[toPosition]
|
||||||
|
@ -20,7 +20,7 @@ import kotlinx.coroutines.Job
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.databinding.CardHomeDebugBinding
|
import pl.szczodrzynski.edziennik.databinding.CardHomeDebugBinding
|
||||||
import pl.szczodrzynski.edziennik.dp
|
import pl.szczodrzynski.edziennik.dp
|
||||||
|
@ -29,9 +29,9 @@ import pl.szczodrzynski.edziennik.App
|
|||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.*
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Subject
|
import pl.szczodrzynski.edziennik.data.db.entity.Subject
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||||
import pl.szczodrzynski.edziennik.databinding.CardHomeGradesBinding
|
import pl.szczodrzynski.edziennik.databinding.CardHomeGradesBinding
|
||||||
import pl.szczodrzynski.edziennik.dp
|
import pl.szczodrzynski.edziennik.dp
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCard
|
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCard
|
||||||
@ -121,7 +121,7 @@ class HomeGradesCard(
|
|||||||
16 /*ellipsize width*/)) / 1.5f
|
16 /*ellipsize width*/)) / 1.5f
|
||||||
|
|
||||||
subject.grades1.onEach { grade ->
|
subject.grades1.onEach { grade ->
|
||||||
val gradeColor = when (App.getConfig().forProfile().grades.colorMode) {
|
val gradeColor = when (App.config.forProfile().grades.colorMode) {
|
||||||
Profile.COLOR_MODE_DEFAULT -> grade.color
|
Profile.COLOR_MODE_DEFAULT -> grade.color
|
||||||
else -> Colors.gradeToColor(grade)
|
else -> Colors.gradeToColor(grade)
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ class HomeLuckyNumberCard(
|
|||||||
|
|
||||||
holder.root.onClick {
|
holder.root.onClick {
|
||||||
StudentNumberDialog(activity, profile, onDismissListener = {
|
StudentNumberDialog(activity, profile, onDismissListener = {
|
||||||
app.profileSaveAsync(profile)
|
app.profileSave(profile)
|
||||||
val newSubTextRes = if (profile.studentNumber == -1)
|
val newSubTextRes = if (profile.studentNumber == -1)
|
||||||
R.string.home_lucky_number_details_click_to_set
|
R.string.home_lucky_number_details_click_to_set
|
||||||
else
|
else
|
||||||
|
@ -22,11 +22,11 @@ import org.greenrobot.eventbus.EventBus
|
|||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.ApiTaskAllFinishedEvent
|
import pl.szczodrzynski.edziennik.data.api.events.ApiTaskAllFinishedEvent
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.LessonFull
|
import pl.szczodrzynski.edziennik.data.db.full.LessonFull
|
||||||
import pl.szczodrzynski.edziennik.databinding.CardHomeTimetableBinding
|
import pl.szczodrzynski.edziennik.databinding.CardHomeTimetableBinding
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.bell.BellSyncTimeChooseDialog
|
import pl.szczodrzynski.edziennik.ui.dialogs.bell.BellSyncTimeChooseDialog
|
||||||
|
@ -85,7 +85,7 @@ public class HomeworkAdapter extends RecyclerView.Adapter<HomeworkAdapter.ViewHo
|
|||||||
holder.homeworkItemTopic.getBackground().setColorFilter(new PorterDuffColorFilter(0x692196f3, PorterDuff.Mode.MULTIPLY));
|
holder.homeworkItemTopic.getBackground().setColorFilter(new PorterDuffColorFilter(0x692196f3, PorterDuff.Mode.MULTIPLY));
|
||||||
homework.seen = true;
|
homework.seen = true;
|
||||||
AsyncTask.execute(() -> {
|
AsyncTask.execute(() -> {
|
||||||
app.db.metadataDao().setSeen(App.profileId, homework, true);
|
App.db.metadataDao().setSeen(App.Companion.getProfileId(), homework, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -78,6 +78,6 @@ public class ChangelogIntroActivity extends IntroActivity {
|
|||||||
.build());
|
.build());
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
app.config.setAppVersion(BuildConfig.VERSION_CODE);
|
app.getConfig().setAppVersion(BuildConfig.VERSION_CODE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user