mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2025-01-31 10:28:21 +01:00
parent
722f8d691a
commit
919680c766
1
.idea/codeStyles/Project.xml
generated
1
.idea/codeStyles/Project.xml
generated
@ -19,6 +19,7 @@
|
|||||||
<option name="CONTINUATION_INDENT_IN_SUPERTYPE_LISTS" value="false" />
|
<option name="CONTINUATION_INDENT_IN_SUPERTYPE_LISTS" value="false" />
|
||||||
<option name="CONTINUATION_INDENT_IN_IF_CONDITIONS" value="false" />
|
<option name="CONTINUATION_INDENT_IN_IF_CONDITIONS" value="false" />
|
||||||
<option name="CONTINUATION_INDENT_IN_ELVIS" value="false" />
|
<option name="CONTINUATION_INDENT_IN_ELVIS" value="false" />
|
||||||
|
<option name="WRAP_ELVIS_EXPRESSIONS" value="0" />
|
||||||
</JetCodeStyleSettings>
|
</JetCodeStyleSettings>
|
||||||
<Objective-C-extensions>
|
<Objective-C-extensions>
|
||||||
<file>
|
<file>
|
||||||
|
@ -82,7 +82,12 @@ dependencies {
|
|||||||
implementation 'androidx.multidex:multidex:2.0.1'
|
implementation 'androidx.multidex:multidex:2.0.1'
|
||||||
|
|
||||||
implementation 'com.takisoft.preferencex:preferencex:1.0.0'
|
implementation 'com.takisoft.preferencex:preferencex:1.0.0'
|
||||||
implementation "com.firebase:firebase-jobdispatcher:0.8.5"
|
|
||||||
|
implementation "android.arch.work:work-rxjava2:1.0.0"
|
||||||
|
implementation "android.arch.work:work-runtime:1.0.0"
|
||||||
|
|
||||||
|
implementation 'com.squareup.inject:assisted-inject-annotations-dagger2:0.3.2'
|
||||||
|
kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.3.2'
|
||||||
|
|
||||||
implementation "com.google.dagger:dagger-android-support:2.21"
|
implementation "com.google.dagger:dagger-android-support:2.21"
|
||||||
kapt "com.google.dagger:dagger-compiler:2.21"
|
kapt "com.google.dagger:dagger-compiler:2.21"
|
||||||
|
@ -42,13 +42,6 @@
|
|||||||
android:label="@string/main_title"
|
android:label="@string/main_title"
|
||||||
android:theme="@style/WulkanowyTheme.NoActionBar" />
|
android:theme="@style/WulkanowyTheme.NoActionBar" />
|
||||||
|
|
||||||
<service
|
|
||||||
android:name=".services.job.SyncWorker"
|
|
||||||
android:exported="false">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
|
|
||||||
</intent-filter>
|
|
||||||
</service>
|
|
||||||
<service
|
<service
|
||||||
android:name=".services.widgets.TimetableWidgetService"
|
android:name=".services.widgets.TimetableWidgetService"
|
||||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||||
@ -64,6 +57,12 @@
|
|||||||
android:resource="@xml/provider_widget_timetable" />
|
android:resource="@xml/provider_widget_timetable" />
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name="androidx.work.impl.WorkManagerInitializer"
|
||||||
|
android:authorities="${applicationId}.workmanager-init"
|
||||||
|
android:exported="false"
|
||||||
|
tools:node="remove" />
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="io.fabric.ApiKey"
|
android:name="io.fabric.ApiKey"
|
||||||
android:value="${fabric_api_key}" />
|
android:value="${fabric_api_key}" />
|
||||||
|
@ -3,6 +3,8 @@ package io.github.wulkanowy
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.multidex.MultiDex
|
import androidx.multidex.MultiDex
|
||||||
|
import androidx.work.Configuration
|
||||||
|
import androidx.work.WorkManager
|
||||||
import com.crashlytics.android.Crashlytics
|
import com.crashlytics.android.Crashlytics
|
||||||
import com.crashlytics.android.core.CrashlyticsCore
|
import com.crashlytics.android.core.CrashlyticsCore
|
||||||
import com.jakewharton.threetenabp.AndroidThreeTen
|
import com.jakewharton.threetenabp.AndroidThreeTen
|
||||||
@ -14,6 +16,7 @@ import io.fabric.sdk.android.Fabric
|
|||||||
import io.github.wulkanowy.BuildConfig.DEBUG
|
import io.github.wulkanowy.BuildConfig.DEBUG
|
||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.di.DaggerAppComponent
|
import io.github.wulkanowy.di.DaggerAppComponent
|
||||||
|
import io.github.wulkanowy.services.sync.SyncWorkerFactory
|
||||||
import io.github.wulkanowy.utils.CrashlyticsTree
|
import io.github.wulkanowy.utils.CrashlyticsTree
|
||||||
import io.github.wulkanowy.utils.DebugLogTree
|
import io.github.wulkanowy.utils.DebugLogTree
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -24,6 +27,9 @@ class WulkanowyApp : DaggerApplication() {
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var prefRepository: PreferencesRepository
|
lateinit var prefRepository: PreferencesRepository
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var workerFactory: SyncWorkerFactory
|
||||||
|
|
||||||
override fun attachBaseContext(base: Context?) {
|
override fun attachBaseContext(base: Context?) {
|
||||||
super.attachBaseContext(base)
|
super.attachBaseContext(base)
|
||||||
MultiDex.install(this)
|
MultiDex.install(this)
|
||||||
@ -35,6 +41,7 @@ class WulkanowyApp : DaggerApplication() {
|
|||||||
initializeFabric()
|
initializeFabric()
|
||||||
if (DEBUG) enableDebugLog()
|
if (DEBUG) enableDebugLog()
|
||||||
AppCompatDelegate.setDefaultNightMode(prefRepository.currentTheme)
|
AppCompatDelegate.setDefaultNightMode(prefRepository.currentTheme)
|
||||||
|
WorkManager.initialize(this, Configuration.Builder().setWorkerFactory(workerFactory).build())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun enableDebugLog() {
|
private fun enableDebugLog() {
|
||||||
|
@ -14,7 +14,7 @@ import javax.inject.Singleton
|
|||||||
interface CompletedLessonsDao {
|
interface CompletedLessonsDao {
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
fun insertAll(exams: List<CompletedLesson>): List<Long>
|
fun insertAll(exams: List<CompletedLesson>)
|
||||||
|
|
||||||
@Delete
|
@Delete
|
||||||
fun deleteAll(exams: List<CompletedLesson>)
|
fun deleteAll(exams: List<CompletedLesson>)
|
||||||
|
@ -16,9 +16,6 @@ interface GradeDao {
|
|||||||
@Insert
|
@Insert
|
||||||
fun insertAll(grades: List<Grade>)
|
fun insertAll(grades: List<Grade>)
|
||||||
|
|
||||||
@Update
|
|
||||||
fun update(grade: Grade)
|
|
||||||
|
|
||||||
@Update
|
@Update
|
||||||
fun updateAll(grade: List<Grade>)
|
fun updateAll(grade: List<Grade>)
|
||||||
|
|
||||||
@ -28,6 +25,4 @@ interface GradeDao {
|
|||||||
@Query("SELECT * FROM Grades WHERE semester_id = :semesterId AND student_id = :studentId")
|
@Query("SELECT * FROM Grades WHERE semester_id = :semesterId AND student_id = :studentId")
|
||||||
fun loadAll(semesterId: Int, studentId: Int): Maybe<List<Grade>>
|
fun loadAll(semesterId: Int, studentId: Int): Maybe<List<Grade>>
|
||||||
|
|
||||||
@Query("SELECT * FROM Grades WHERE is_read = 0 AND semester_id = :semesterId AND student_id = :studentId")
|
|
||||||
fun loadAllNew(semesterId: Int, studentId: Int): Maybe<List<Grade>>
|
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,6 @@ interface LuckyNumberDao {
|
|||||||
fun delete(luckyNumber: LuckyNumber)
|
fun delete(luckyNumber: LuckyNumber)
|
||||||
|
|
||||||
@Query("SELECT * FROM LuckyNumbers WHERE student_id = :studentId AND date = :date")
|
@Query("SELECT * FROM LuckyNumbers WHERE student_id = :studentId AND date = :date")
|
||||||
fun loadFromDate(studentId: Int, date: LocalDate): Maybe<LuckyNumber>
|
fun load(studentId: Int, date: LocalDate): Maybe<LuckyNumber>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,26 +12,20 @@ import io.reactivex.Maybe
|
|||||||
interface MessagesDao {
|
interface MessagesDao {
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
fun insertAll(messages: List<Message>): List<Long>
|
fun insertAll(messages: List<Message>)
|
||||||
|
|
||||||
@Delete
|
@Delete
|
||||||
fun deleteAll(messages: List<Message>)
|
fun deleteAll(messages: List<Message>)
|
||||||
|
|
||||||
@Update
|
|
||||||
fun update(message: Message)
|
|
||||||
|
|
||||||
@Update
|
@Update
|
||||||
fun updateAll(messages: List<Message>)
|
fun updateAll(messages: List<Message>)
|
||||||
|
|
||||||
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND real_id = :id")
|
|
||||||
fun loadOne(studentId: Int, id: Int): Maybe<Message>
|
|
||||||
|
|
||||||
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND folder_id = :folder ORDER BY date DESC")
|
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND folder_id = :folder ORDER BY date DESC")
|
||||||
fun load(studentId: Int, folder: Int): Maybe<List<Message>>
|
fun loadAll(studentId: Int, folder: Int): Maybe<List<Message>>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND real_id = :id")
|
||||||
|
fun load(studentId: Int, id: Int): Maybe<Message>
|
||||||
|
|
||||||
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND removed = 1 ORDER BY date DESC")
|
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND removed = 1 ORDER BY date DESC")
|
||||||
fun loadDeleted(studentId: Int): Maybe<List<Message>>
|
fun loadDeleted(studentId: Int): Maybe<List<Message>>
|
||||||
|
|
||||||
@Query("SELECT * FROM Messages WHERE unread = 1 AND student_id = :studentId")
|
|
||||||
fun loadNewMessages(studentId: Int): Maybe<List<Message>>
|
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,6 @@ interface NoteDao {
|
|||||||
@Insert
|
@Insert
|
||||||
fun insertAll(notes: List<Note>)
|
fun insertAll(notes: List<Note>)
|
||||||
|
|
||||||
@Update
|
|
||||||
fun update(note: Note)
|
|
||||||
|
|
||||||
@Update
|
@Update
|
||||||
fun updateAll(notes: List<Note>)
|
fun updateAll(notes: List<Note>)
|
||||||
|
|
||||||
@ -28,6 +25,4 @@ interface NoteDao {
|
|||||||
@Query("SELECT * FROM Notes WHERE student_id = :studentId")
|
@Query("SELECT * FROM Notes WHERE student_id = :studentId")
|
||||||
fun loadAll(studentId: Int): Maybe<List<Note>>
|
fun loadAll(studentId: Int): Maybe<List<Note>>
|
||||||
|
|
||||||
@Query("SELECT * FROM Notes WHERE is_read = 0 AND student_id = :studentId")
|
|
||||||
fun loadNew(studentId: Int): Maybe<List<Note>>
|
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ data class Note(
|
|||||||
var id: Long = 0
|
var id: Long = 0
|
||||||
|
|
||||||
@ColumnInfo(name = "is_read")
|
@ColumnInfo(name = "is_read")
|
||||||
var isRead: Boolean = false
|
var isRead: Boolean = true
|
||||||
|
|
||||||
@ColumnInfo(name = "is_notified")
|
@ColumnInfo(name = "is_notified")
|
||||||
var isNotified: Boolean = true
|
var isNotified: Boolean = true
|
||||||
|
@ -11,11 +11,6 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class AttendanceLocal @Inject constructor(private val attendanceDb: AttendanceDao) {
|
class AttendanceLocal @Inject constructor(private val attendanceDb: AttendanceDao) {
|
||||||
|
|
||||||
fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe<List<Attendance>> {
|
|
||||||
return attendanceDb.loadAll(semester.diaryId, semester.studentId, startDate, endDate)
|
|
||||||
.filter { !it.isEmpty() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun saveAttendance(attendance: List<Attendance>) {
|
fun saveAttendance(attendance: List<Attendance>) {
|
||||||
attendanceDb.insertAll(attendance)
|
attendanceDb.insertAll(attendance)
|
||||||
}
|
}
|
||||||
@ -23,4 +18,8 @@ class AttendanceLocal @Inject constructor(private val attendanceDb: AttendanceDa
|
|||||||
fun deleteAttendance(attendance: List<Attendance>) {
|
fun deleteAttendance(attendance: List<Attendance>) {
|
||||||
attendanceDb.deleteAll(attendance)
|
attendanceDb.deleteAll(attendance)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe<List<Attendance>> {
|
||||||
|
return attendanceDb.loadAll(semester.diaryId, semester.studentId, startDate, endDate).filter { it.isNotEmpty() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,6 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class AttendanceSummaryLocal @Inject constructor(private val attendanceDb: AttendanceSummaryDao) {
|
class AttendanceSummaryLocal @Inject constructor(private val attendanceDb: AttendanceSummaryDao) {
|
||||||
|
|
||||||
fun getAttendanceSummary(semester: Semester, subjectId: Int): Maybe<List<AttendanceSummary>> {
|
|
||||||
return attendanceDb.loadAll(semester.diaryId, semester.studentId, subjectId).filter { !it.isEmpty() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun saveAttendanceSummary(attendance: List<AttendanceSummary>) {
|
fun saveAttendanceSummary(attendance: List<AttendanceSummary>) {
|
||||||
attendanceDb.insertAll(attendance)
|
attendanceDb.insertAll(attendance)
|
||||||
}
|
}
|
||||||
@ -21,4 +17,8 @@ class AttendanceSummaryLocal @Inject constructor(private val attendanceDb: Atten
|
|||||||
fun deleteAttendanceSummary(attendance: List<AttendanceSummary>) {
|
fun deleteAttendanceSummary(attendance: List<AttendanceSummary>) {
|
||||||
attendanceDb.deleteAll(attendance)
|
attendanceDb.deleteAll(attendance)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getAttendanceSummary(semester: Semester, subjectId: Int): Maybe<List<AttendanceSummary>> {
|
||||||
|
return attendanceDb.loadAll(semester.diaryId, semester.studentId, subjectId).filter { it.isNotEmpty() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ class AttendanceSummaryRepository @Inject constructor(
|
|||||||
private val remote: AttendanceSummaryRemote
|
private val remote: AttendanceSummaryRemote
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getAttendanceSummary(semester: Semester, subjectId: Int, forceRefresh: Boolean = false): Single<List<AttendanceSummary>>? {
|
fun getAttendanceSummary(semester: Semester, subjectId: Int, forceRefresh: Boolean = false): Single<List<AttendanceSummary>> {
|
||||||
return local.getAttendanceSummary(semester, subjectId).filter { !forceRefresh }
|
return local.getAttendanceSummary(semester, subjectId).filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
|
@ -11,10 +11,6 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class CompletedLessonsLocal @Inject constructor(private val completedLessonsDb: CompletedLessonsDao) {
|
class CompletedLessonsLocal @Inject constructor(private val completedLessonsDb: CompletedLessonsDao) {
|
||||||
|
|
||||||
fun getCompletedLessons(semester: Semester, start: LocalDate, end: LocalDate): Maybe<List<CompletedLesson>> {
|
|
||||||
return completedLessonsDb.loadAll(semester.diaryId, semester.studentId, start, end).filter { !it.isEmpty() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun saveCompletedLessons(completedLessons: List<CompletedLesson>) {
|
fun saveCompletedLessons(completedLessons: List<CompletedLesson>) {
|
||||||
completedLessonsDb.insertAll(completedLessons)
|
completedLessonsDb.insertAll(completedLessons)
|
||||||
}
|
}
|
||||||
@ -22,4 +18,8 @@ class CompletedLessonsLocal @Inject constructor(private val completedLessonsDb:
|
|||||||
fun deleteCompleteLessons(completedLessons: List<CompletedLesson>) {
|
fun deleteCompleteLessons(completedLessons: List<CompletedLesson>) {
|
||||||
completedLessonsDb.deleteAll(completedLessons)
|
completedLessonsDb.deleteAll(completedLessons)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getCompletedLessons(semester: Semester, start: LocalDate, end: LocalDate): Maybe<List<CompletedLesson>> {
|
||||||
|
return completedLessonsDb.loadAll(semester.diaryId, semester.studentId, start, end).filter { it.isNotEmpty() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package io.github.wulkanowy.data.repositories.grade
|
|||||||
import io.github.wulkanowy.data.db.dao.GradeDao
|
import io.github.wulkanowy.data.db.dao.GradeDao
|
||||||
import io.github.wulkanowy.data.db.entities.Grade
|
import io.github.wulkanowy.data.db.entities.Grade
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.reactivex.Completable
|
|
||||||
import io.reactivex.Maybe
|
import io.reactivex.Maybe
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -11,27 +10,19 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class GradeLocal @Inject constructor(private val gradeDb: GradeDao) {
|
class GradeLocal @Inject constructor(private val gradeDb: GradeDao) {
|
||||||
|
|
||||||
fun getGrades(semester: Semester): Maybe<List<Grade>> {
|
|
||||||
return gradeDb.loadAll(semester.semesterId, semester.studentId).filter { !it.isEmpty() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getNewGrades(semester: Semester): Maybe<List<Grade>> {
|
|
||||||
return gradeDb.loadAllNew(semester.semesterId, semester.studentId)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun saveGrades(grades: List<Grade>) {
|
fun saveGrades(grades: List<Grade>) {
|
||||||
gradeDb.insertAll(grades)
|
gradeDb.insertAll(grades)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateGrade(grade: Grade): Completable {
|
|
||||||
return Completable.fromCallable { gradeDb.update(grade) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateGrades(grades: List<Grade>): Completable {
|
|
||||||
return Completable.fromCallable { gradeDb.updateAll(grades) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun deleteGrades(grades: List<Grade>) {
|
fun deleteGrades(grades: List<Grade>) {
|
||||||
gradeDb.deleteAll(grades)
|
gradeDb.deleteAll(grades)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateGrades(grades: List<Grade>) {
|
||||||
|
gradeDb.updateAll(grades)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getGrades(semester: Semester): Maybe<List<Grade>> {
|
||||||
|
return gradeDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,24 +31,28 @@ class GradeRepository @Inject constructor(
|
|||||||
local.deleteGrades(oldGrades - newGrades)
|
local.deleteGrades(oldGrades - newGrades)
|
||||||
local.saveGrades((newGrades - oldGrades)
|
local.saveGrades((newGrades - oldGrades)
|
||||||
.onEach {
|
.onEach {
|
||||||
if (it.date >= notifyBreakDate) {
|
if (it.date >= notifyBreakDate) it.apply {
|
||||||
if (notify) it.isNotified = false
|
isRead = false
|
||||||
it.isRead = false
|
if (notify) isNotified = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}.flatMap { local.getGrades(semester).toSingle(emptyList()) })
|
}.flatMap { local.getGrades(semester).toSingle(emptyList()) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getNewGrades(semester: Semester): Single<List<Grade>> {
|
fun getUnreadGrades(semester: Semester): Single<List<Grade>> {
|
||||||
return local.getNewGrades(semester).toSingle(emptyList())
|
return local.getGrades(semester).map { it.filter { grade -> !grade.isRead } }.toSingle(emptyList())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getNotNotifiedGrades(semester: Semester): Single<List<Grade>> {
|
||||||
|
return local.getGrades(semester).map { it.filter { grade -> !grade.isNotified } }.toSingle(emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateGrade(grade: Grade): Completable {
|
fun updateGrade(grade: Grade): Completable {
|
||||||
return local.updateGrade(grade)
|
return Completable.fromCallable { local.updateGrades(listOf(grade)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateGrades(grades: List<Grade>): Completable {
|
fun updateGrades(grades: List<Grade>): Completable {
|
||||||
return local.updateGrades(grades)
|
return Completable.fromCallable { local.updateGrades(grades) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,6 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class GradeSummaryLocal @Inject constructor(private val gradeSummaryDb: GradeSummaryDao) {
|
class GradeSummaryLocal @Inject constructor(private val gradeSummaryDb: GradeSummaryDao) {
|
||||||
|
|
||||||
fun getGradesSummary(semester: Semester): Maybe<List<GradeSummary>> {
|
|
||||||
return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId)
|
|
||||||
.filter { !it.isEmpty() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun saveGradesSummary(gradesSummary: List<GradeSummary>) {
|
fun saveGradesSummary(gradesSummary: List<GradeSummary>) {
|
||||||
gradeSummaryDb.insertAll(gradesSummary)
|
gradeSummaryDb.insertAll(gradesSummary)
|
||||||
}
|
}
|
||||||
@ -22,4 +17,8 @@ class GradeSummaryLocal @Inject constructor(private val gradeSummaryDb: GradeSum
|
|||||||
fun deleteGradesSummary(gradesSummary: List<GradeSummary>) {
|
fun deleteGradesSummary(gradesSummary: List<GradeSummary>) {
|
||||||
gradeSummaryDb.deleteAll(gradesSummary)
|
gradeSummaryDb.deleteAll(gradesSummary)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getGradesSummary(semester: Semester): Maybe<List<GradeSummary>> {
|
||||||
|
return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,6 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class HomeworkLocal @Inject constructor(private val homeworkDb: HomeworkDao) {
|
class HomeworkLocal @Inject constructor(private val homeworkDb: HomeworkDao) {
|
||||||
|
|
||||||
fun getHomework(semester: Semester, date: LocalDate): Maybe<List<Homework>> {
|
|
||||||
return homeworkDb.loadAll(semester.semesterId, semester.studentId, date).filter { !it.isEmpty() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun saveHomework(homework: List<Homework>) {
|
fun saveHomework(homework: List<Homework>) {
|
||||||
homeworkDb.insertAll(homework)
|
homeworkDb.insertAll(homework)
|
||||||
}
|
}
|
||||||
@ -22,4 +18,8 @@ class HomeworkLocal @Inject constructor(private val homeworkDb: HomeworkDao) {
|
|||||||
fun deleteHomework(homework: List<Homework>) {
|
fun deleteHomework(homework: List<Homework>) {
|
||||||
homeworkDb.deleteAll(homework)
|
homeworkDb.deleteAll(homework)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getHomework(semester: Semester, date: LocalDate): Maybe<List<Homework>> {
|
||||||
|
return homeworkDb.loadAll(semester.semesterId, semester.studentId, date).filter { it.isNotEmpty() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package io.github.wulkanowy.data.repositories.luckynumber
|
|||||||
import io.github.wulkanowy.data.db.dao.LuckyNumberDao
|
import io.github.wulkanowy.data.db.dao.LuckyNumberDao
|
||||||
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.reactivex.Completable
|
|
||||||
import io.reactivex.Maybe
|
import io.reactivex.Maybe
|
||||||
import org.threeten.bp.LocalDate
|
import org.threeten.bp.LocalDate
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -12,19 +11,19 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class LuckyNumberLocal @Inject constructor(private val luckyNumberDb: LuckyNumberDao) {
|
class LuckyNumberLocal @Inject constructor(private val luckyNumberDb: LuckyNumberDao) {
|
||||||
|
|
||||||
fun getLuckyNumber(semester: Semester, date: LocalDate): Maybe<LuckyNumber> {
|
|
||||||
return luckyNumberDb.loadFromDate(semester.studentId, date)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun saveLuckyNumber(luckyNumber: LuckyNumber) {
|
fun saveLuckyNumber(luckyNumber: LuckyNumber) {
|
||||||
luckyNumberDb.insert(luckyNumber)
|
luckyNumberDb.insert(luckyNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateLuckyNumber(luckyNumber: LuckyNumber): Completable {
|
fun updateLuckyNumber(luckyNumber: LuckyNumber) {
|
||||||
return Completable.fromCallable { luckyNumberDb.update(luckyNumber) }
|
luckyNumberDb.update(luckyNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteLuckyNumber(luckyNumber: LuckyNumber) {
|
fun deleteLuckyNumber(luckyNumber: LuckyNumber) {
|
||||||
luckyNumberDb.delete(luckyNumber)
|
luckyNumberDb.delete(luckyNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getLuckyNumber(semester: Semester, date: LocalDate): Maybe<LuckyNumber> {
|
||||||
|
return luckyNumberDb.load(semester.studentId, date)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,11 @@ class LuckyNumberRepository @Inject constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getNotNotifiedLuckyNumber(semester: Semester): Maybe<LuckyNumber> {
|
||||||
|
return local.getLuckyNumber(semester, LocalDate.now()).filter { !it.isNotified }
|
||||||
|
}
|
||||||
|
|
||||||
fun updateLuckyNumber(luckyNumber: LuckyNumber): Completable {
|
fun updateLuckyNumber(luckyNumber: LuckyNumber): Completable {
|
||||||
return local.updateLuckyNumber(luckyNumber)
|
return Completable.fromCallable { local.updateLuckyNumber(luckyNumber) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package io.github.wulkanowy.data.repositories.message
|
||||||
|
|
||||||
|
enum class MessageFolder(val id: Int = 1) {
|
||||||
|
RECEIVED(1),
|
||||||
|
SENT(2),
|
||||||
|
TRASHED(3)
|
||||||
|
}
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.message
|
|||||||
import io.github.wulkanowy.data.db.dao.MessagesDao
|
import io.github.wulkanowy.data.db.dao.MessagesDao
|
||||||
import io.github.wulkanowy.data.db.entities.Message
|
import io.github.wulkanowy.data.db.entities.Message
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.message.MessageFolder.TRASHED
|
||||||
import io.reactivex.Maybe
|
import io.reactivex.Maybe
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -10,34 +11,26 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class MessageLocal @Inject constructor(private val messagesDb: MessagesDao) {
|
class MessageLocal @Inject constructor(private val messagesDb: MessagesDao) {
|
||||||
|
|
||||||
fun getMessage(studentId: Int, id: Int): Maybe<Message> {
|
fun saveMessages(messages: List<Message>) {
|
||||||
return messagesDb.loadOne(studentId, id)
|
messagesDb.insertAll(messages)
|
||||||
}
|
|
||||||
|
|
||||||
fun getMessages(studentId: Int, folder: MessageRepository.MessageFolder): Maybe<List<Message>> {
|
|
||||||
return when (folder) {
|
|
||||||
MessageRepository.MessageFolder.TRASHED -> messagesDb.loadDeleted(studentId)
|
|
||||||
else -> messagesDb.load(studentId, folder.id)
|
|
||||||
}.filter { !it.isEmpty() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getNewMessages(student: Student): Maybe<List<Message>> {
|
|
||||||
return messagesDb.loadNewMessages(student.studentId)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun saveMessages(messages: List<Message>): List<Long> {
|
|
||||||
return messagesDb.insertAll(messages)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateMessage(message: Message) {
|
|
||||||
return messagesDb.update(message)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateMessages(messages: List<Message>) {
|
fun updateMessages(messages: List<Message>) {
|
||||||
return messagesDb.updateAll(messages)
|
messagesDb.updateAll(messages)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteMessages(messages: List<Message>) {
|
fun deleteMessages(messages: List<Message>) {
|
||||||
messagesDb.deleteAll(messages)
|
messagesDb.deleteAll(messages)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getMessage(student: Student, id: Int): Maybe<Message> {
|
||||||
|
return messagesDb.load(student.studentId, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getMessages(student: Student, folder: MessageFolder): Maybe<List<Message>> {
|
||||||
|
return when (folder) {
|
||||||
|
TRASHED -> messagesDb.loadDeleted(student.studentId)
|
||||||
|
else -> messagesDb.loadAll(student.studentId, folder.id)
|
||||||
|
}.filter { it.isNotEmpty() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ import io.github.wulkanowy.api.messages.Recipient as ApiRecipient
|
|||||||
@Singleton
|
@Singleton
|
||||||
class MessageRemote @Inject constructor(private val api: Api) {
|
class MessageRemote @Inject constructor(private val api: Api) {
|
||||||
|
|
||||||
fun getMessages(studentId: Int, folder: MessageRepository.MessageFolder): Single<List<Message>> {
|
fun getMessages(studentId: Int, folder: MessageFolder): Single<List<Message>> {
|
||||||
return api.getMessages(Folder.valueOf(folder.name)).map { messages ->
|
return api.getMessages(Folder.valueOf(folder.name)).map { messages ->
|
||||||
messages.map {
|
messages.map {
|
||||||
Message(
|
Message(
|
||||||
|
@ -7,6 +7,7 @@ import io.github.wulkanowy.data.ApiHelper
|
|||||||
import io.github.wulkanowy.data.db.entities.Message
|
import io.github.wulkanowy.data.db.entities.Message
|
||||||
import io.github.wulkanowy.data.db.entities.Recipient
|
import io.github.wulkanowy.data.db.entities.Recipient
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import java.net.UnknownHostException
|
import java.net.UnknownHostException
|
||||||
@ -21,22 +22,16 @@ class MessageRepository @Inject constructor(
|
|||||||
private val apiHelper: ApiHelper
|
private val apiHelper: ApiHelper
|
||||||
) {
|
) {
|
||||||
|
|
||||||
enum class MessageFolder(val id: Int = 1) {
|
|
||||||
RECEIVED(1),
|
|
||||||
SENT(2),
|
|
||||||
TRASHED(3)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getMessages(student: Student, folder: MessageFolder, forceRefresh: Boolean = false, notify: Boolean = false): Single<List<Message>> {
|
fun getMessages(student: Student, folder: MessageFolder, forceRefresh: Boolean = false, notify: Boolean = false): Single<List<Message>> {
|
||||||
return Single.just(apiHelper.initApi(student))
|
return Single.just(apiHelper.initApi(student))
|
||||||
.flatMap { _ ->
|
.flatMap { _ ->
|
||||||
local.getMessages(student.studentId, folder).filter { !forceRefresh }
|
local.getMessages(student, folder).filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.getMessages(student.studentId, folder)
|
if (it) remote.getMessages(student.studentId, folder)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMap { new ->
|
}.flatMap { new ->
|
||||||
local.getMessages(student.studentId, folder).toSingle(emptyList())
|
local.getMessages(student, folder).toSingle(emptyList())
|
||||||
.doOnSuccess { old ->
|
.doOnSuccess { old ->
|
||||||
local.deleteMessages(old - new)
|
local.deleteMessages(old - new)
|
||||||
local.saveMessages((new - old)
|
local.saveMessages((new - old)
|
||||||
@ -44,7 +39,7 @@ class MessageRepository @Inject constructor(
|
|||||||
it.isNotified = !notify
|
it.isNotified = !notify
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}.flatMap { local.getMessages(student.studentId, folder).toSingle(emptyList()) }
|
}.flatMap { local.getMessages(student, folder).toSingle(emptyList()) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,33 +47,35 @@ class MessageRepository @Inject constructor(
|
|||||||
fun getMessage(student: Student, messageId: Int, markAsRead: Boolean = false): Single<Message> {
|
fun getMessage(student: Student, messageId: Int, markAsRead: Boolean = false): Single<Message> {
|
||||||
return Single.just(apiHelper.initApi(student))
|
return Single.just(apiHelper.initApi(student))
|
||||||
.flatMap { _ ->
|
.flatMap { _ ->
|
||||||
local.getMessage(student.studentId, messageId)
|
local.getMessage(student, messageId)
|
||||||
.filter { !it.content.isNullOrEmpty() }
|
.filter { !it.content.isNullOrEmpty() }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) local.getMessage(student.studentId, messageId).toSingle()
|
if (it) local.getMessage(student, messageId).toSingle()
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}
|
}
|
||||||
.flatMap { dbMessage ->
|
.flatMap { dbMessage ->
|
||||||
remote.getMessagesContent(dbMessage, markAsRead).doOnSuccess {
|
remote.getMessagesContent(dbMessage, markAsRead).doOnSuccess {
|
||||||
local.updateMessage(dbMessage.copy(unread = false).apply {
|
local.updateMessages(listOf(dbMessage.copy(unread = false).apply {
|
||||||
id = dbMessage.id
|
id = dbMessage.id
|
||||||
content = it
|
content = it
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
}.flatMap {
|
}.flatMap {
|
||||||
local.getMessage(student.studentId, messageId).toSingle()
|
local.getMessage(student, messageId).toSingle()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getNewMessages(student: Student): Single<List<Message>> {
|
fun getNotNotifiedMessages(student: Student): Single<List<Message>> {
|
||||||
return local.getNewMessages(student).toSingle(emptyList())
|
return local.getMessages(student, RECEIVED)
|
||||||
|
.map { it.filter { message -> !message.isNotified && message.unread } }
|
||||||
|
.toSingle(emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateMessage(message: Message): Completable {
|
fun updateMessage(message: Message): Completable {
|
||||||
return Completable.fromCallable { local.updateMessage(message) }
|
return Completable.fromCallable { local.updateMessages(listOf(message)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateMessages(messages: List<Message>): Completable {
|
fun updateMessages(messages: List<Message>): Completable {
|
||||||
|
@ -3,7 +3,6 @@ package io.github.wulkanowy.data.repositories.note
|
|||||||
import io.github.wulkanowy.data.db.dao.NoteDao
|
import io.github.wulkanowy.data.db.dao.NoteDao
|
||||||
import io.github.wulkanowy.data.db.entities.Note
|
import io.github.wulkanowy.data.db.entities.Note
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.reactivex.Completable
|
|
||||||
import io.reactivex.Maybe
|
import io.reactivex.Maybe
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -11,27 +10,19 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class NoteLocal @Inject constructor(private val noteDb: NoteDao) {
|
class NoteLocal @Inject constructor(private val noteDb: NoteDao) {
|
||||||
|
|
||||||
fun getNotes(student: Student): Maybe<List<Note>> {
|
|
||||||
return noteDb.loadAll(student.studentId).filter { !it.isEmpty() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getNewNotes(student: Student): Maybe<List<Note>> {
|
|
||||||
return noteDb.loadNew(student.studentId)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun saveNotes(notes: List<Note>) {
|
fun saveNotes(notes: List<Note>) {
|
||||||
noteDb.insertAll(notes)
|
noteDb.insertAll(notes)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateNote(note: Note): Completable {
|
fun updateNotes(notes: List<Note>) {
|
||||||
return Completable.fromCallable { noteDb.update(note) }
|
noteDb.updateAll(notes)
|
||||||
}
|
|
||||||
|
|
||||||
fun updateNotes(notes: List<Note>): Completable {
|
|
||||||
return Completable.fromCallable { noteDb.updateAll(notes) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteNotes(notes: List<Note>) {
|
fun deleteNotes(notes: List<Note>) {
|
||||||
noteDb.deleteAll(notes)
|
noteDb.deleteAll(notes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getNotes(student: Student): Maybe<List<Note>> {
|
||||||
|
return noteDb.loadAll(student.studentId).filter { it.isNotEmpty() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,24 +30,24 @@ class NoteRepository @Inject constructor(
|
|||||||
local.deleteNotes(old - new)
|
local.deleteNotes(old - new)
|
||||||
local.saveNotes((new - old)
|
local.saveNotes((new - old)
|
||||||
.onEach {
|
.onEach {
|
||||||
if (student.registrationDate <= it.date.atStartOfDay()) {
|
if (it.date >= student.registrationDate.toLocalDate()) it.apply {
|
||||||
if (notify) it.isNotified = false
|
isRead = false
|
||||||
it.isRead = false
|
if (notify) isNotified = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}.flatMap { local.getNotes(student).toSingle(emptyList()) })
|
}.flatMap { local.getNotes(student).toSingle(emptyList()) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getNewNotes(student: Student): Single<List<Note>> {
|
fun getNotNotifiedNotes(student: Student): Single<List<Note>> {
|
||||||
return local.getNewNotes(student).toSingle(emptyList())
|
return local.getNotes(student).map { it.filter { note -> !note.isNotified } }.toSingle(emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateNote(note: Note): Completable {
|
fun updateNote(note: Note): Completable {
|
||||||
return local.updateNote(note)
|
return Completable.fromCallable { local.updateNotes(listOf(note)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateNotes(notes: List<Note>): Completable {
|
fun updateNotes(notes: List<Note>): Completable {
|
||||||
return local.updateNotes(notes)
|
return Completable.fromCallable { local.updateNotes(notes) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ class PreferencesRepository @Inject constructor(
|
|||||||
val context: Context
|
val context: Context
|
||||||
) {
|
) {
|
||||||
val startMenuIndex: Int
|
val startMenuIndex: Int
|
||||||
get() = sharedPref.getString(context.getString(R.string.pref_key_start_menu), "0")?.toInt() ?: 0
|
get() = sharedPref.getString(context.getString(R.string.pref_key_start_menu), "0")?.toIntOrNull() ?: 0
|
||||||
|
|
||||||
val isShowPresent: Boolean
|
val isShowPresent: Boolean
|
||||||
get() = sharedPref.getBoolean(context.getString(R.string.pref_key_attendance_present), true)
|
get() = sharedPref.getBoolean(context.getString(R.string.pref_key_attendance_present), true)
|
||||||
@ -22,25 +22,24 @@ class PreferencesRepository @Inject constructor(
|
|||||||
|
|
||||||
val currentThemeKey: String = context.getString(R.string.pref_key_theme)
|
val currentThemeKey: String = context.getString(R.string.pref_key_theme)
|
||||||
val currentTheme: Int
|
val currentTheme: Int
|
||||||
get() = sharedPref.getString(currentThemeKey, "1")?.toInt() ?: 1
|
get() = sharedPref.getString(currentThemeKey, "1")?.toIntOrNull() ?: 1
|
||||||
|
|
||||||
val gradePlusModifier: Double
|
val gradePlusModifier: Double
|
||||||
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_modifier_plus), "0.0")?.toDouble() ?: 0.0
|
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_modifier_plus), "0.0")?.toDoubleOrNull() ?: 0.0
|
||||||
|
|
||||||
val gradeMinusModifier: Double
|
val gradeMinusModifier: Double
|
||||||
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_modifier_minus), "0.0")?.toDouble() ?: 0.0
|
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_modifier_minus), "0.0")?.toDoubleOrNull() ?: 0.0
|
||||||
|
|
||||||
val gradeColorTheme: String
|
val gradeColorTheme: String
|
||||||
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_color_scheme), "vulcan") ?: "vulcan"
|
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_color_scheme), "vulcan") ?: "vulcan"
|
||||||
|
|
||||||
|
val serviceEnableKey: String = context.getString(R.string.pref_key_services_enable)
|
||||||
val serviceEnablesKey: String = context.getString(R.string.pref_key_services_enable)
|
|
||||||
val isServiceEnabled: Boolean
|
val isServiceEnabled: Boolean
|
||||||
get() = sharedPref.getBoolean(serviceEnablesKey, true)
|
get() = sharedPref.getBoolean(serviceEnableKey, true)
|
||||||
|
|
||||||
val servicesIntervalKey: String = context.getString(R.string.pref_key_services_interval)
|
val servicesIntervalKey: String = context.getString(R.string.pref_key_services_interval)
|
||||||
val servicesInterval: Int
|
val servicesInterval: Long
|
||||||
get() = sharedPref.getString(servicesIntervalKey, "60")?.toInt() ?: 60
|
get() = sharedPref.getString(servicesIntervalKey, "60")?.toLongOrNull() ?: 60
|
||||||
|
|
||||||
val servicesOnlyWifiKey: String = context.getString(R.string.pref_key_services_wifi_only)
|
val servicesOnlyWifiKey: String = context.getString(R.string.pref_key_services_wifi_only)
|
||||||
val isServicesOnlyWifi: Boolean
|
val isServicesOnlyWifi: Boolean
|
||||||
|
@ -11,11 +11,6 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class TimetableLocal @Inject constructor(private val timetableDb: TimetableDao) {
|
class TimetableLocal @Inject constructor(private val timetableDb: TimetableDao) {
|
||||||
|
|
||||||
fun getTimetable(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe<List<Timetable>> {
|
|
||||||
return timetableDb.loadAll(semester.diaryId, semester.studentId, startDate, endDate)
|
|
||||||
.filter { !it.isEmpty() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun saveTimetable(timetables: List<Timetable>) {
|
fun saveTimetable(timetables: List<Timetable>) {
|
||||||
timetableDb.insertAll(timetables)
|
timetableDb.insertAll(timetables)
|
||||||
}
|
}
|
||||||
@ -23,4 +18,8 @@ class TimetableLocal @Inject constructor(private val timetableDb: TimetableDao)
|
|||||||
fun deleteTimetable(timetables: List<Timetable>) {
|
fun deleteTimetable(timetables: List<Timetable>) {
|
||||||
timetableDb.deleteAll(timetables)
|
timetableDb.deleteAll(timetables)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getTimetable(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe<List<Timetable>> {
|
||||||
|
return timetableDb.loadAll(semester.diaryId, semester.studentId, startDate, endDate).filter { it.isNotEmpty() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import dagger.android.AndroidInjector
|
|||||||
import dagger.android.support.AndroidSupportInjectionModule
|
import dagger.android.support.AndroidSupportInjectionModule
|
||||||
import io.github.wulkanowy.WulkanowyApp
|
import io.github.wulkanowy.WulkanowyApp
|
||||||
import io.github.wulkanowy.data.RepositoryModule
|
import io.github.wulkanowy.data.RepositoryModule
|
||||||
|
import io.github.wulkanowy.services.ServicesModule
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@ -12,6 +13,7 @@ import javax.inject.Singleton
|
|||||||
AndroidSupportInjectionModule::class,
|
AndroidSupportInjectionModule::class,
|
||||||
AppModule::class,
|
AppModule::class,
|
||||||
RepositoryModule::class,
|
RepositoryModule::class,
|
||||||
|
ServicesModule::class,
|
||||||
BuilderModule::class])
|
BuilderModule::class])
|
||||||
interface AppComponent : AndroidInjector<WulkanowyApp> {
|
interface AppComponent : AndroidInjector<WulkanowyApp> {
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@ package io.github.wulkanowy.di
|
|||||||
|
|
||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.firebase.jobdispatcher.FirebaseJobDispatcher
|
|
||||||
import com.firebase.jobdispatcher.GooglePlayDriver
|
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics
|
import com.google.firebase.analytics.FirebaseAnalytics
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
@ -30,10 +28,6 @@ internal class AppModule {
|
|||||||
@Provides
|
@Provides
|
||||||
fun provideFlexibleAdapter() = FlexibleAdapter<AbstractFlexibleItem<*>>(null, null, true)
|
fun provideFlexibleAdapter() = FlexibleAdapter<AbstractFlexibleItem<*>>(null, null, true)
|
||||||
|
|
||||||
@Singleton
|
|
||||||
@Provides
|
|
||||||
fun provideJobDispatcher(context: Context) = FirebaseJobDispatcher(GooglePlayDriver(context))
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
fun provideFirebaseAnalyticsHelper(context: Context) = FirebaseAnalyticsHelper(FirebaseAnalytics.getInstance(context))
|
fun provideFirebaseAnalyticsHelper(context: Context) = FirebaseAnalyticsHelper(FirebaseAnalytics.getInstance(context))
|
||||||
|
@ -3,7 +3,6 @@ package io.github.wulkanowy.di
|
|||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.android.ContributesAndroidInjector
|
import dagger.android.ContributesAndroidInjector
|
||||||
import io.github.wulkanowy.di.scopes.PerActivity
|
import io.github.wulkanowy.di.scopes.PerActivity
|
||||||
import io.github.wulkanowy.services.job.SyncWorker
|
|
||||||
import io.github.wulkanowy.services.widgets.TimetableWidgetService
|
import io.github.wulkanowy.services.widgets.TimetableWidgetService
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginModule
|
import io.github.wulkanowy.ui.modules.login.LoginModule
|
||||||
@ -32,7 +31,4 @@ internal abstract class BuilderModule {
|
|||||||
|
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract fun bindTimetableWidgetProvider(): TimetableWidgetProvider
|
abstract fun bindTimetableWidgetProvider(): TimetableWidgetProvider
|
||||||
|
|
||||||
@ContributesAndroidInjector
|
|
||||||
abstract fun bindSyncJob(): SyncWorker
|
|
||||||
}
|
}
|
||||||
|
102
app/src/main/java/io/github/wulkanowy/services/ServicesModule.kt
Normal file
102
app/src/main/java/io/github/wulkanowy/services/ServicesModule.kt
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package io.github.wulkanowy.services
|
||||||
|
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Context.NOTIFICATION_SERVICE
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import androidx.work.WorkManager
|
||||||
|
import com.squareup.inject.assisted.dagger2.AssistedModule
|
||||||
|
import dagger.Binds
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.multibindings.IntoSet
|
||||||
|
import io.github.wulkanowy.services.sync.works.AttendanceSummaryWork
|
||||||
|
import io.github.wulkanowy.services.sync.works.AttendanceWork
|
||||||
|
import io.github.wulkanowy.services.sync.works.CompletedLessonWork
|
||||||
|
import io.github.wulkanowy.services.sync.works.ExamWork
|
||||||
|
import io.github.wulkanowy.services.sync.works.GradeStatisticsWork
|
||||||
|
import io.github.wulkanowy.services.sync.works.GradeSummaryWork
|
||||||
|
import io.github.wulkanowy.services.sync.works.GradeWork
|
||||||
|
import io.github.wulkanowy.services.sync.works.HomeworkWork
|
||||||
|
import io.github.wulkanowy.services.sync.works.LuckyNumberWork
|
||||||
|
import io.github.wulkanowy.services.sync.works.MessageWork
|
||||||
|
import io.github.wulkanowy.services.sync.works.NoteWork
|
||||||
|
import io.github.wulkanowy.services.sync.works.RecipientWork
|
||||||
|
import io.github.wulkanowy.services.sync.works.TimetableWork
|
||||||
|
import io.github.wulkanowy.services.sync.works.Work
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@AssistedModule
|
||||||
|
@Module(includes = [AssistedInject_ServicesModule::class])
|
||||||
|
abstract class ServicesModule {
|
||||||
|
|
||||||
|
@Module
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@Provides
|
||||||
|
fun provideWorkManager() = WorkManager.getInstance()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
fun provideNotificationManagerCompat(context: Context) = NotificationManagerCompat.from(context)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
fun provideNotificationManager(context: Context) = context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
||||||
|
}
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideGradeWork(work: GradeWork): Work
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideNoteWork(work: NoteWork): Work
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideAttendanceWork(work: AttendanceWork): Work
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideGradeSummaryWork(work: GradeSummaryWork): Work
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideExamWork(work: ExamWork): Work
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideAttendanceSummaryWork(work: AttendanceSummaryWork): Work
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideTimetableWork(work: TimetableWork): Work
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideLuckyNumberWork(work: LuckyNumberWork): Work
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideCompletedLessonWork(work: CompletedLessonWork): Work
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideHomeworkWork(work: HomeworkWork): Work
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideMessageWork(work: MessageWork): Work
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideRecipientWork(work: RecipientWork): Work
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideGradeStatistics(work: GradeStatisticsWork): Work
|
||||||
|
}
|
@ -1,57 +0,0 @@
|
|||||||
package io.github.wulkanowy.services.job
|
|
||||||
|
|
||||||
import com.firebase.jobdispatcher.Constraint.ON_ANY_NETWORK
|
|
||||||
import com.firebase.jobdispatcher.Constraint.ON_UNMETERED_NETWORK
|
|
||||||
import com.firebase.jobdispatcher.FirebaseJobDispatcher
|
|
||||||
import com.firebase.jobdispatcher.Lifetime.FOREVER
|
|
||||||
import com.firebase.jobdispatcher.RetryStrategy.DEFAULT_EXPONENTIAL
|
|
||||||
import com.firebase.jobdispatcher.Trigger.executionWindow
|
|
||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
|
||||||
import io.github.wulkanowy.utils.isHolidays
|
|
||||||
import org.threeten.bp.LocalDate
|
|
||||||
import timber.log.Timber
|
|
||||||
import javax.inject.Inject
|
|
||||||
import javax.inject.Singleton
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
class ServiceHelper @Inject constructor(
|
|
||||||
private val prefRepository: PreferencesRepository,
|
|
||||||
private val dispatcher: FirebaseJobDispatcher
|
|
||||||
) {
|
|
||||||
|
|
||||||
fun reloadFullSyncService() {
|
|
||||||
startFullSyncService(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun startFullSyncService(replaceCurrent: Boolean = false) {
|
|
||||||
if (LocalDate.now().isHolidays || !prefRepository.isServiceEnabled) {
|
|
||||||
Timber.d("Services disabled or it's holidays")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatcher.mustSchedule(
|
|
||||||
dispatcher.newJobBuilder()
|
|
||||||
.setLifetime(FOREVER)
|
|
||||||
.setRecurring(true)
|
|
||||||
.setService(SyncWorker::class.java)
|
|
||||||
.setTag(SyncWorker.WORK_TAG)
|
|
||||||
.setTrigger(
|
|
||||||
executionWindow(
|
|
||||||
prefRepository.servicesInterval * 60,
|
|
||||||
(prefRepository.servicesInterval + 10) * 60
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setConstraints(if (prefRepository.isServicesOnlyWifi) ON_UNMETERED_NETWORK else ON_ANY_NETWORK)
|
|
||||||
.setReplaceCurrent(replaceCurrent)
|
|
||||||
.setRetryStrategy(DEFAULT_EXPONENTIAL)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
|
|
||||||
Timber.d("Services started")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun stopFullSyncService() {
|
|
||||||
dispatcher.cancel(SyncWorker.WORK_TAG)
|
|
||||||
Timber.d("Services stopped")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,214 +0,0 @@
|
|||||||
package io.github.wulkanowy.services.job
|
|
||||||
|
|
||||||
import com.firebase.jobdispatcher.JobParameters
|
|
||||||
import com.firebase.jobdispatcher.SimpleJobService
|
|
||||||
import dagger.android.AndroidInjection
|
|
||||||
import io.github.wulkanowy.data.repositories.attendance.AttendanceRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.completedlessons.CompletedLessonsRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.exam.ExamRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.grade.GradeRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.gradessummary.GradeSummaryRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.homework.HomeworkRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.luckynumber.LuckyNumberRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.message.MessageRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.message.MessageRepository.MessageFolder.RECEIVED
|
|
||||||
import io.github.wulkanowy.data.repositories.note.NoteRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.recipient.RecipientRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.reportingunit.ReportingUnitRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.timetable.TimetableRepository
|
|
||||||
import io.github.wulkanowy.services.notification.GradeNotification
|
|
||||||
import io.github.wulkanowy.services.notification.LuckyNumberNotification
|
|
||||||
import io.github.wulkanowy.services.notification.MessageNotification
|
|
||||||
import io.github.wulkanowy.services.notification.NoteNotification
|
|
||||||
import io.github.wulkanowy.utils.friday
|
|
||||||
import io.github.wulkanowy.utils.isHolidays
|
|
||||||
import io.github.wulkanowy.utils.monday
|
|
||||||
import io.reactivex.Completable
|
|
||||||
import io.reactivex.Maybe
|
|
||||||
import io.reactivex.Single
|
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
|
||||||
import org.threeten.bp.LocalDate
|
|
||||||
import timber.log.Timber
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
class SyncWorker : SimpleJobService() {
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var student: StudentRepository
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var semester: SemesterRepository
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var gradesDetails: GradeRepository
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var gradesSummary: GradeSummaryRepository
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var attendance: AttendanceRepository
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var exam: ExamRepository
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var timetable: TimetableRepository
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var message: MessageRepository
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var note: NoteRepository
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var homework: HomeworkRepository
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var luckyNumber: LuckyNumberRepository
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var completedLessons: CompletedLessonsRepository
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var reportingUnitRepository: ReportingUnitRepository
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var recipientRepository: RecipientRepository
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var prefRepository: PreferencesRepository
|
|
||||||
|
|
||||||
private val disposable = CompositeDisposable()
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val WORK_TAG = "FULL_SYNC"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate() {
|
|
||||||
super.onCreate()
|
|
||||||
AndroidInjection.inject(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onRunJob(job: JobParameters?): Int {
|
|
||||||
Timber.d("Synchronization started")
|
|
||||||
|
|
||||||
val start = LocalDate.now().monday
|
|
||||||
val end = LocalDate.now().friday
|
|
||||||
|
|
||||||
if (start.isHolidays) return RESULT_FAIL_NORETRY
|
|
||||||
|
|
||||||
var error: Throwable? = null
|
|
||||||
|
|
||||||
val notify = prefRepository.isNotificationsEnable
|
|
||||||
|
|
||||||
disposable.add(student.isStudentSaved()
|
|
||||||
.flatMapMaybe { if (it) student.getCurrentStudent().toMaybe() else Maybe.empty() }
|
|
||||||
.flatMap { semester.getCurrentSemester(it, true).map { semester -> semester to it }.toMaybe() }
|
|
||||||
.flatMapCompletable { c ->
|
|
||||||
Completable.merge(
|
|
||||||
listOf(
|
|
||||||
gradesDetails.getGrades(c.second, c.first, true, notify).ignoreElement(),
|
|
||||||
gradesSummary.getGradesSummary(c.first, true).ignoreElement(),
|
|
||||||
attendance.getAttendance(c.first, start, end, true).ignoreElement(),
|
|
||||||
exam.getExams(c.first, start, end, true).ignoreElement(),
|
|
||||||
timetable.getTimetable(c.first, start, end, true).ignoreElement(),
|
|
||||||
message.getMessages(c.second, RECEIVED, true, notify).ignoreElement(),
|
|
||||||
note.getNotes(c.second, c.first, true, notify).ignoreElement(),
|
|
||||||
homework.getHomework(c.first, LocalDate.now(), true).ignoreElement(),
|
|
||||||
homework.getHomework(c.first, LocalDate.now().plusDays(1), true).ignoreElement(),
|
|
||||||
luckyNumber.getLuckyNumber(c.first, true, notify).ignoreElement(),
|
|
||||||
completedLessons.getCompletedLessons(c.first, start, end, true).ignoreElement()
|
|
||||||
) + reportingUnitRepository.getReportingUnits(c.second, true)
|
|
||||||
.flatMapPublisher { reportingUnits ->
|
|
||||||
Single.merge(reportingUnits.map { recipientRepository.getRecipients(c.second, 2, it, true) })
|
|
||||||
}.ignoreElements()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.subscribe({}, { error = it }))
|
|
||||||
|
|
||||||
return if (null === error) {
|
|
||||||
if (notify) sendNotifications()
|
|
||||||
Timber.d("Synchronization successful")
|
|
||||||
RESULT_SUCCESS
|
|
||||||
} else {
|
|
||||||
Timber.e(error, "Synchronization failed")
|
|
||||||
RESULT_FAIL_RETRY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun sendNotifications() {
|
|
||||||
sendGradeNotifications()
|
|
||||||
sendMessageNotification()
|
|
||||||
sendNoteNotification()
|
|
||||||
sendLuckyNumberNotification()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun sendGradeNotifications() {
|
|
||||||
disposable.add(student.getCurrentStudent()
|
|
||||||
.flatMap { semester.getCurrentSemester(it) }
|
|
||||||
.flatMap { gradesDetails.getNewGrades(it) }
|
|
||||||
.map { it.filter { grade -> !grade.isNotified } }
|
|
||||||
.doOnSuccess {
|
|
||||||
if (it.isNotEmpty()) {
|
|
||||||
Timber.d("Found ${it.size} unread grades")
|
|
||||||
GradeNotification(applicationContext).sendNotification(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.map { it.map { grade -> grade.apply { isNotified = true } } }
|
|
||||||
.flatMapCompletable { gradesDetails.updateGrades(it) }
|
|
||||||
.subscribe({}, { Timber.e(it, "Grade notifications sending failed") }))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun sendMessageNotification() {
|
|
||||||
disposable.add(student.getCurrentStudent()
|
|
||||||
.flatMap { message.getNewMessages(it) }
|
|
||||||
.map { it.filter { message -> !message.isNotified } }
|
|
||||||
.doOnSuccess {
|
|
||||||
if (it.isNotEmpty()) {
|
|
||||||
Timber.d("Found ${it.size} unread messages")
|
|
||||||
MessageNotification(applicationContext).sendNotification(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.map { it.map { message -> message.apply { isNotified = true } } }
|
|
||||||
.flatMapCompletable { message.updateMessages(it) }
|
|
||||||
.subscribe({}, { Timber.e(it, "Message notifications sending failed") })
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun sendNoteNotification() {
|
|
||||||
disposable.add(student.getCurrentStudent()
|
|
||||||
.flatMap { note.getNewNotes(it) }
|
|
||||||
.map { it.filter { note -> !note.isNotified } }
|
|
||||||
.doOnSuccess {
|
|
||||||
if (it.isNotEmpty()) {
|
|
||||||
Timber.d("Found ${it.size} unread notes")
|
|
||||||
NoteNotification(applicationContext).sendNotification(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.map { it.map { note -> note.apply { isNotified = true } } }
|
|
||||||
.flatMapCompletable { note.updateNotes(it) }
|
|
||||||
.subscribe({}, { Timber.e("Notifications sending failed") })
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun sendLuckyNumberNotification() {
|
|
||||||
disposable.add(student.getCurrentStudent()
|
|
||||||
.flatMap { semester.getCurrentSemester(it) }
|
|
||||||
.flatMapMaybe { luckyNumber.getLuckyNumber(it) }
|
|
||||||
.filter { !it.isNotified }
|
|
||||||
.doOnSuccess {
|
|
||||||
LuckyNumberNotification(applicationContext).sendNotification(it)
|
|
||||||
}
|
|
||||||
.map { it.apply { isNotified = true } }
|
|
||||||
.flatMapCompletable { luckyNumber.updateLuckyNumber(it) }
|
|
||||||
.subscribe({}, { Timber.e("Lucky number notification sending failed") }))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
disposable.clear()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package io.github.wulkanowy.services.notification
|
|
||||||
|
|
||||||
import android.app.Notification
|
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Context.NOTIFICATION_SERVICE
|
|
||||||
import android.os.Build.VERSION.SDK_INT
|
|
||||||
import android.os.Build.VERSION_CODES.O
|
|
||||||
import androidx.core.app.NotificationCompat
|
|
||||||
import timber.log.Timber
|
|
||||||
import kotlin.random.Random
|
|
||||||
|
|
||||||
abstract class BaseNotification(protected val context: Context) {
|
|
||||||
|
|
||||||
protected val notificationManager: NotificationManager by lazy {
|
|
||||||
context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
|
||||||
}
|
|
||||||
|
|
||||||
fun notify(notification: Notification) {
|
|
||||||
notificationManager.notify(Random.nextInt(1000), notification)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun notificationBuilder(channelId: String): NotificationCompat.Builder {
|
|
||||||
if (SDK_INT >= O) createChannel(channelId)
|
|
||||||
return NotificationCompat.Builder(context, channelId)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun cancelAll() {
|
|
||||||
notificationManager.cancelAll()
|
|
||||||
Timber.d("Notifications canceled")
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract fun createChannel(channelId: String)
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
package io.github.wulkanowy.services.notification
|
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
|
||||||
import android.app.Notification.VISIBILITY_PUBLIC
|
|
||||||
import android.app.NotificationChannel
|
|
||||||
import android.app.NotificationManager.IMPORTANCE_HIGH
|
|
||||||
import android.app.PendingIntent
|
|
||||||
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.core.app.NotificationCompat
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import io.github.wulkanowy.R
|
|
||||||
import io.github.wulkanowy.data.db.entities.Grade
|
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity.Companion.EXTRA_START_MENU_INDEX
|
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
class GradeNotification(context: Context) : BaseNotification(context) {
|
|
||||||
|
|
||||||
private val channelId = "Grade_Notify"
|
|
||||||
|
|
||||||
@TargetApi(26)
|
|
||||||
override fun createChannel(channelId: String) {
|
|
||||||
notificationManager.createNotificationChannel(NotificationChannel(
|
|
||||||
channelId, context.getString(R.string.notify_grade_channel), IMPORTANCE_HIGH
|
|
||||||
).apply {
|
|
||||||
enableLights(true)
|
|
||||||
enableVibration(true)
|
|
||||||
lockscreenVisibility = VISIBILITY_PUBLIC
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fun sendNotification(items: List<Grade>) {
|
|
||||||
notify(notificationBuilder(channelId)
|
|
||||||
.setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items, items.size, items.size))
|
|
||||||
.setContentText(context.resources.getQuantityString(R.plurals.notify_grade_new_items, items.size, items.size))
|
|
||||||
.setSmallIcon(R.drawable.ic_stat_notify_grade)
|
|
||||||
.setAutoCancel(true)
|
|
||||||
.setDefaults(NotificationCompat.DEFAULT_ALL)
|
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
|
||||||
.setColor(ContextCompat.getColor(context, R.color.colorPrimary))
|
|
||||||
.setContentIntent(
|
|
||||||
PendingIntent.getActivity(context, 0,
|
|
||||||
MainActivity.getStartIntent(context).putExtra(EXTRA_START_MENU_INDEX, 0),
|
|
||||||
FLAG_UPDATE_CURRENT
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setStyle(NotificationCompat.InboxStyle().run {
|
|
||||||
setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, items.size, items.size))
|
|
||||||
items.forEach {
|
|
||||||
addLine("${it.subject}: ${it.entry}")
|
|
||||||
}
|
|
||||||
this
|
|
||||||
})
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
|
|
||||||
Timber.d("Notification sent")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package io.github.wulkanowy.services.notification
|
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
|
||||||
import android.app.Notification
|
|
||||||
import android.app.NotificationChannel
|
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.app.PendingIntent
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.core.app.NotificationCompat
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import io.github.wulkanowy.R
|
|
||||||
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
|
||||||
|
|
||||||
class LuckyNumberNotification(context: Context) : BaseNotification(context) {
|
|
||||||
|
|
||||||
private val channelId = "Lucky_Number_Notify"
|
|
||||||
|
|
||||||
@TargetApi(26)
|
|
||||||
override fun createChannel(channelId: String) {
|
|
||||||
notificationManager.createNotificationChannel(NotificationChannel(
|
|
||||||
channelId, context.getString(R.string.notify_lucky_number_channel), NotificationManager.IMPORTANCE_HIGH
|
|
||||||
).apply {
|
|
||||||
enableLights(true)
|
|
||||||
enableVibration(true)
|
|
||||||
lockscreenVisibility = Notification.VISIBILITY_PUBLIC
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fun sendNotification(luckyNumber: LuckyNumber) {
|
|
||||||
notify(notificationBuilder(channelId)
|
|
||||||
.setContentTitle(context.getString(R.string.notify_lucky_number_new_item_title))
|
|
||||||
.setContentText(context.getString(R.string.notify_lucky_number_new_item, luckyNumber.luckyNumber))
|
|
||||||
.setSmallIcon(R.drawable.ic_stat_notify_lucky_number)
|
|
||||||
.setAutoCancel(true)
|
|
||||||
.setDefaults(NotificationCompat.DEFAULT_ALL)
|
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
|
||||||
.setColor(ContextCompat.getColor(context, R.color.colorPrimary))
|
|
||||||
.setContentIntent(
|
|
||||||
PendingIntent.getActivity(context, 0,
|
|
||||||
MainActivity.getStartIntent(context).putExtra(MainActivity.EXTRA_START_MENU_INDEX, 4),
|
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
package io.github.wulkanowy.services.notification
|
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
|
||||||
import android.app.Notification
|
|
||||||
import android.app.NotificationChannel
|
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.app.PendingIntent
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.core.app.NotificationCompat
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import io.github.wulkanowy.R
|
|
||||||
import io.github.wulkanowy.data.db.entities.Message
|
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
class MessageNotification(context: Context) : BaseNotification(context) {
|
|
||||||
|
|
||||||
private val channelId = "Message_Notify"
|
|
||||||
|
|
||||||
@TargetApi(26)
|
|
||||||
override fun createChannel(channelId: String) {
|
|
||||||
notificationManager.createNotificationChannel(NotificationChannel(
|
|
||||||
channelId, context.getString(R.string.notify_message_channel), NotificationManager.IMPORTANCE_HIGH
|
|
||||||
).apply {
|
|
||||||
enableLights(true)
|
|
||||||
enableVibration(true)
|
|
||||||
lockscreenVisibility = Notification.VISIBILITY_PUBLIC
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fun sendNotification(items: List<Message>) {
|
|
||||||
notify(notificationBuilder(channelId)
|
|
||||||
.setContentTitle(context.resources.getQuantityString(R.plurals.message_new_items, items.size, items.size))
|
|
||||||
.setContentText(context.resources.getQuantityString(R.plurals.notify_message_new_items, items.size, items.size))
|
|
||||||
.setSmallIcon(R.drawable.ic_stat_notify_message)
|
|
||||||
.setAutoCancel(true)
|
|
||||||
.setDefaults(NotificationCompat.DEFAULT_ALL)
|
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
|
||||||
.setColor(ContextCompat.getColor(context, R.color.colorPrimary))
|
|
||||||
.setContentIntent(
|
|
||||||
PendingIntent.getActivity(context, 0,
|
|
||||||
MainActivity.getStartIntent(context).putExtra(MainActivity.EXTRA_START_MENU_INDEX, 4),
|
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setStyle(NotificationCompat.InboxStyle().run {
|
|
||||||
setSummaryText(context.resources.getQuantityString(R.plurals.message_number_item, items.size, items.size))
|
|
||||||
items.forEach {
|
|
||||||
addLine("${it.sender}: ${it.subject}")
|
|
||||||
}
|
|
||||||
this
|
|
||||||
})
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
|
|
||||||
Timber.d("Notification sent")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
package io.github.wulkanowy.services.notification
|
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
|
||||||
import android.app.Notification
|
|
||||||
import android.app.NotificationChannel
|
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.app.PendingIntent
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.core.app.NotificationCompat
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import io.github.wulkanowy.R
|
|
||||||
import io.github.wulkanowy.data.db.entities.Note
|
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
class NoteNotification(context: Context) : BaseNotification(context) {
|
|
||||||
|
|
||||||
private val channelId = "Note_Notify"
|
|
||||||
|
|
||||||
@TargetApi(26)
|
|
||||||
override fun createChannel(channelId: String) {
|
|
||||||
notificationManager.createNotificationChannel(NotificationChannel(
|
|
||||||
channelId, context.getString(R.string.notify_note_channel), NotificationManager.IMPORTANCE_HIGH
|
|
||||||
).apply {
|
|
||||||
enableLights(true)
|
|
||||||
enableVibration(true)
|
|
||||||
lockscreenVisibility = Notification.VISIBILITY_PUBLIC
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fun sendNotification(items: List<Note>) {
|
|
||||||
notify(notificationBuilder(channelId)
|
|
||||||
.setContentTitle(context.resources.getQuantityString(R.plurals.note_new_items, items.size, items.size))
|
|
||||||
.setContentText(context.resources.getQuantityString(R.plurals.notify_note_new_items, items.size, items.size))
|
|
||||||
.setSmallIcon(R.drawable.ic_stat_notify_note)
|
|
||||||
.setAutoCancel(true)
|
|
||||||
.setDefaults(NotificationCompat.DEFAULT_ALL)
|
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
|
||||||
.setColor(ContextCompat.getColor(context, R.color.colorPrimary))
|
|
||||||
.setContentIntent(
|
|
||||||
PendingIntent.getActivity(context, 0,
|
|
||||||
MainActivity.getStartIntent(context).putExtra(MainActivity.EXTRA_START_MENU_INDEX, 4),
|
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setStyle(NotificationCompat.InboxStyle().run {
|
|
||||||
setSummaryText(context.resources.getQuantityString(R.plurals.note_number_item, items.size, items.size))
|
|
||||||
items.forEach {
|
|
||||||
addLine("${it.teacher}: ${it.category}")
|
|
||||||
}
|
|
||||||
this
|
|
||||||
})
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
|
|
||||||
Timber.d("Notification sent")
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,50 @@
|
|||||||
|
package io.github.wulkanowy.services.sync
|
||||||
|
|
||||||
|
import android.os.Build.VERSION.SDK_INT
|
||||||
|
import android.os.Build.VERSION_CODES.O
|
||||||
|
import androidx.work.BackoffPolicy.EXPONENTIAL
|
||||||
|
import androidx.work.Constraints
|
||||||
|
import androidx.work.ExistingPeriodicWorkPolicy.KEEP
|
||||||
|
import androidx.work.ExistingPeriodicWorkPolicy.REPLACE
|
||||||
|
import androidx.work.NetworkType.METERED
|
||||||
|
import androidx.work.NetworkType.UNMETERED
|
||||||
|
import androidx.work.PeriodicWorkRequest
|
||||||
|
import androidx.work.WorkManager
|
||||||
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
|
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
||||||
|
import io.github.wulkanowy.utils.isHolidays
|
||||||
|
import org.threeten.bp.LocalDate.now
|
||||||
|
import timber.log.Timber
|
||||||
|
import java.util.concurrent.TimeUnit.MINUTES
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class SyncManager @Inject constructor(
|
||||||
|
private val workManager: WorkManager,
|
||||||
|
private val preferencesRepository: PreferencesRepository,
|
||||||
|
newEntriesChannel: NewEntriesChannel
|
||||||
|
) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (SDK_INT >= O) newEntriesChannel.create()
|
||||||
|
if (now().isHolidays) stopSyncWorker()
|
||||||
|
Timber.i("SyncManager was initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun startSyncWorker(restart: Boolean = false) {
|
||||||
|
if (preferencesRepository.isServiceEnabled && !now().isHolidays) {
|
||||||
|
workManager.enqueueUniquePeriodicWork(SyncWorker::class.java.simpleName, if (restart) REPLACE else KEEP,
|
||||||
|
PeriodicWorkRequest.Builder(SyncWorker::class.java, preferencesRepository.servicesInterval, MINUTES, 10, MINUTES)
|
||||||
|
.setBackoffCriteria(EXPONENTIAL, 30, MINUTES)
|
||||||
|
.setConstraints(Constraints.Builder()
|
||||||
|
.setRequiredNetworkType(if (preferencesRepository.isServicesOnlyWifi) METERED else UNMETERED)
|
||||||
|
.build())
|
||||||
|
.build())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stopSyncWorker() {
|
||||||
|
workManager.cancelUniqueWork(SyncWorker::class.java.simpleName)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package io.github.wulkanowy.services.sync
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.work.ListenableWorker
|
||||||
|
import androidx.work.RxWorker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import com.squareup.inject.assisted.Assisted
|
||||||
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
|
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||||
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
|
import io.github.wulkanowy.services.sync.works.Work
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import io.reactivex.Single
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
class SyncWorker @AssistedInject constructor(
|
||||||
|
@Assisted appContext: Context,
|
||||||
|
@Assisted workerParameters: WorkerParameters,
|
||||||
|
private val studentRepository: StudentRepository,
|
||||||
|
private val semesterRepository: SemesterRepository,
|
||||||
|
private val works: Set<@JvmSuppressWildcards Work>
|
||||||
|
) : RxWorker(appContext, workerParameters) {
|
||||||
|
|
||||||
|
override fun createWork(): Single<Result> {
|
||||||
|
return studentRepository.getCurrentStudent()
|
||||||
|
.flatMapCompletable { student ->
|
||||||
|
semesterRepository.getCurrentSemester(student, true)
|
||||||
|
.flatMapCompletable { semester ->
|
||||||
|
Completable.mergeDelayError(works.map { it.create(student, semester) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.toSingleDefault(Result.success())
|
||||||
|
.onErrorReturn {
|
||||||
|
Timber.e(it, "There was an error during synchronization")
|
||||||
|
Result.retry()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
|
||||||
|
fun create(appContext: Context, workerParameters: WorkerParameters): ListenableWorker
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
|||||||
|
package io.github.wulkanowy.services.sync
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.work.ListenableWorker
|
||||||
|
import androidx.work.WorkerFactory
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class SyncWorkerFactory @Inject constructor(private val syncWorkerFactory: SyncWorker.Factory) : WorkerFactory() {
|
||||||
|
|
||||||
|
override fun createWorker(appContext: Context, workerClassName: String, workerParameters: WorkerParameters): ListenableWorker? {
|
||||||
|
return if (workerClassName == SyncWorker::class.java.name) {
|
||||||
|
syncWorkerFactory.create(appContext, workerParameters)
|
||||||
|
} else {
|
||||||
|
Timber.e(IllegalArgumentException("Unknown worker class name: $workerClassName"))
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.channels
|
||||||
|
|
||||||
|
import android.annotation.TargetApi
|
||||||
|
import android.app.Notification.VISIBILITY_PUBLIC
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.app.NotificationManager.IMPORTANCE_HIGH
|
||||||
|
import android.content.Context
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@TargetApi(26)
|
||||||
|
class NewEntriesChannel @Inject constructor(
|
||||||
|
private val notificationManager: NotificationManager,
|
||||||
|
private val context: Context
|
||||||
|
) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val CHANNEL_ID = "new_entries_channel"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun create() {
|
||||||
|
notificationManager.createNotificationChannel(
|
||||||
|
NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_new_entries), IMPORTANCE_HIGH).apply {
|
||||||
|
enableLights(true)
|
||||||
|
enableVibration(true)
|
||||||
|
lockscreenVisibility = VISIBILITY_PUBLIC
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.attendancesummary.AttendanceSummaryRepository
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class AttendanceSummaryWork @Inject constructor(
|
||||||
|
private val attendanceSummaryRepository: AttendanceSummaryRepository
|
||||||
|
) : Work {
|
||||||
|
|
||||||
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
|
return attendanceSummaryRepository.getAttendanceSummary(semester, -1, true).ignoreElement()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.attendance.AttendanceRepository
|
||||||
|
import io.github.wulkanowy.utils.friday
|
||||||
|
import io.github.wulkanowy.utils.monday
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import org.threeten.bp.LocalDate.now
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class AttendanceWork @Inject constructor(private val attendanceRepository: AttendanceRepository) : Work {
|
||||||
|
|
||||||
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
|
return attendanceRepository.getAttendance(semester, now().monday, now().friday, true)
|
||||||
|
.ignoreElement()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.completedlessons.CompletedLessonsRepository
|
||||||
|
import io.github.wulkanowy.utils.friday
|
||||||
|
import io.github.wulkanowy.utils.monday
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import org.threeten.bp.LocalDate.now
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class CompletedLessonWork @Inject constructor(
|
||||||
|
private val completedLessonsRepository: CompletedLessonsRepository
|
||||||
|
) : Work {
|
||||||
|
|
||||||
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
|
return completedLessonsRepository.getCompletedLessons(semester, now().monday, now().friday, true)
|
||||||
|
.ignoreElement()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.exam.ExamRepository
|
||||||
|
import io.github.wulkanowy.utils.friday
|
||||||
|
import io.github.wulkanowy.utils.monday
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import org.threeten.bp.LocalDate.now
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class ExamWork @Inject constructor(private val examRepository: ExamRepository) : Work {
|
||||||
|
|
||||||
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
|
return examRepository.getExams(semester, now().monday, now().friday, true).ignoreElement()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.gradestatistics.GradeStatisticsRepository
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class GradeStatisticsWork @Inject constructor(private val gradeStatisticsRepository: GradeStatisticsRepository) : Work {
|
||||||
|
|
||||||
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
|
return gradeStatisticsRepository.getGradesStatistics(semester, "Wszystkie", false, true)
|
||||||
|
.ignoreElement()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.gradessummary.GradeSummaryRepository
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class GradeSummaryWork @Inject constructor(private val gradeSummaryRepository: GradeSummaryRepository) : Work {
|
||||||
|
|
||||||
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
|
return gradeSummaryRepository.getGradesSummary(semester, true).ignoreElement()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.NotificationCompat.DEFAULT_ALL
|
||||||
|
import androidx.core.app.NotificationCompat.PRIORITY_HIGH
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.data.db.entities.Grade
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.grade.GradeRepository
|
||||||
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
|
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainActivity.Companion.EXTRA_START_MENU_INDEX
|
||||||
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
class GradeWork @Inject constructor(
|
||||||
|
private val context: Context,
|
||||||
|
private val notificationManager: NotificationManagerCompat,
|
||||||
|
private val gradeRepository: GradeRepository,
|
||||||
|
private val preferencesRepository: PreferencesRepository
|
||||||
|
) : Work {
|
||||||
|
|
||||||
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
|
return gradeRepository.getGrades(student, semester, true, preferencesRepository.isNotificationsEnable)
|
||||||
|
.flatMap { gradeRepository.getNotNotifiedGrades(semester) }
|
||||||
|
.flatMapCompletable {
|
||||||
|
if (it.isNotEmpty()) notify(it)
|
||||||
|
gradeRepository.updateGrades(it.onEach { grade -> grade.isNotified = true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun notify(grades: List<Grade>) {
|
||||||
|
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewEntriesChannel.CHANNEL_ID)
|
||||||
|
.setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items, grades.size, grades.size))
|
||||||
|
.setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items, grades.size, grades.size))
|
||||||
|
.setSmallIcon(R.drawable.ic_stat_notify_grade)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setPriority(PRIORITY_HIGH)
|
||||||
|
.setDefaults(DEFAULT_ALL)
|
||||||
|
.setColor(context.getCompatColor(R.color.colorPrimary))
|
||||||
|
.setContentIntent(
|
||||||
|
PendingIntent.getActivity(context, 0,
|
||||||
|
MainActivity.getStartIntent(context).putExtra(EXTRA_START_MENU_INDEX, 0), FLAG_UPDATE_CURRENT))
|
||||||
|
.setStyle(NotificationCompat.InboxStyle().run {
|
||||||
|
setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, grades.size, grades.size))
|
||||||
|
grades.forEach { addLine("${it.subject}: ${it.entry}") }
|
||||||
|
this
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.homework.HomeworkRepository
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import org.threeten.bp.LocalDate.now
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class HomeworkWork @Inject constructor(private val homeworkRepository: HomeworkRepository) : Work {
|
||||||
|
|
||||||
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
|
return homeworkRepository.getHomework(semester, now(), true).ignoreElement()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.NotificationCompat.DEFAULT_ALL
|
||||||
|
import androidx.core.app.NotificationCompat.PRIORITY_HIGH
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.luckynumber.LuckyNumberRepository
|
||||||
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
|
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainActivity.Companion.EXTRA_START_MENU_INDEX
|
||||||
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
class LuckyNumberWork @Inject constructor(
|
||||||
|
private val context: Context,
|
||||||
|
private val notificationManager: NotificationManagerCompat,
|
||||||
|
private val luckyNumberRepository: LuckyNumberRepository,
|
||||||
|
private val preferencesRepository: PreferencesRepository
|
||||||
|
) : Work {
|
||||||
|
|
||||||
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
|
return luckyNumberRepository.getLuckyNumber(semester, true, preferencesRepository.isNotificationsEnable)
|
||||||
|
.flatMap { luckyNumberRepository.getNotNotifiedLuckyNumber(semester) }
|
||||||
|
.flatMapCompletable {
|
||||||
|
notify(it)
|
||||||
|
luckyNumberRepository.updateLuckyNumber(it.apply { isNotified = true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun notify(luckyNumber: LuckyNumber) {
|
||||||
|
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewEntriesChannel.CHANNEL_ID)
|
||||||
|
.setContentTitle(context.getString(R.string.lucky_number_notify_new_item_title))
|
||||||
|
.setContentText(context.getString(R.string.lucky_number_notify_new_item, luckyNumber.luckyNumber))
|
||||||
|
.setSmallIcon(R.drawable.ic_stat_notify_lucky_number)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setDefaults(DEFAULT_ALL)
|
||||||
|
.setPriority(PRIORITY_HIGH)
|
||||||
|
.setColor(context.getCompatColor(R.color.colorPrimary))
|
||||||
|
.setContentIntent(
|
||||||
|
PendingIntent.getActivity(context, 0,
|
||||||
|
MainActivity.getStartIntent(context).putExtra(EXTRA_START_MENU_INDEX, 4), FLAG_UPDATE_CURRENT)
|
||||||
|
)
|
||||||
|
.build())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.NotificationCompat.DEFAULT_ALL
|
||||||
|
import androidx.core.app.NotificationCompat.PRIORITY_HIGH
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.data.db.entities.Message
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED
|
||||||
|
import io.github.wulkanowy.data.repositories.message.MessageRepository
|
||||||
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
|
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainActivity.Companion.EXTRA_START_MENU_INDEX
|
||||||
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
class MessageWork @Inject constructor(
|
||||||
|
private val context: Context,
|
||||||
|
private val notificationManager: NotificationManagerCompat,
|
||||||
|
private val messageRepository: MessageRepository,
|
||||||
|
private val preferencesRepository: PreferencesRepository
|
||||||
|
) : Work {
|
||||||
|
|
||||||
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
|
return messageRepository.getMessages(student, RECEIVED, true, preferencesRepository.isNotificationsEnable)
|
||||||
|
.flatMap { messageRepository.getNotNotifiedMessages(student) }
|
||||||
|
.flatMapCompletable {
|
||||||
|
if (it.isNotEmpty()) notify(it)
|
||||||
|
messageRepository.updateMessages(it.onEach { message -> message.isNotified = true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun notify(messages: List<Message>) {
|
||||||
|
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewEntriesChannel.CHANNEL_ID)
|
||||||
|
.setContentTitle(context.resources.getQuantityString(R.plurals.message_new_items, messages.size, messages.size))
|
||||||
|
.setContentText(context.resources.getQuantityString(R.plurals.message_notify_new_items, messages.size, messages.size))
|
||||||
|
.setSmallIcon(R.drawable.ic_stat_notify_message)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setDefaults(DEFAULT_ALL)
|
||||||
|
.setPriority(PRIORITY_HIGH)
|
||||||
|
.setColor(context.getCompatColor(R.color.colorPrimary))
|
||||||
|
.setContentIntent(
|
||||||
|
PendingIntent.getActivity(context, 0,
|
||||||
|
MainActivity.getStartIntent(context).putExtra(EXTRA_START_MENU_INDEX, 4), FLAG_UPDATE_CURRENT)
|
||||||
|
)
|
||||||
|
.setStyle(NotificationCompat.InboxStyle().run {
|
||||||
|
setSummaryText(context.resources.getQuantityString(R.plurals.message_number_item, messages.size, messages.size))
|
||||||
|
messages.forEach { addLine("${it.sender}: ${it.subject}") }
|
||||||
|
this
|
||||||
|
})
|
||||||
|
.build())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.NotificationCompat.DEFAULT_ALL
|
||||||
|
import androidx.core.app.NotificationCompat.PRIORITY_HIGH
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.data.db.entities.Note
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.note.NoteRepository
|
||||||
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
|
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainActivity.Companion.EXTRA_START_MENU_INDEX
|
||||||
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
class NoteWork @Inject constructor(
|
||||||
|
private val context: Context,
|
||||||
|
private val notificationManager: NotificationManagerCompat,
|
||||||
|
private val noteRepository: NoteRepository,
|
||||||
|
private val preferencesRepository: PreferencesRepository
|
||||||
|
) : Work {
|
||||||
|
|
||||||
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
|
return noteRepository.getNotes(student, semester, true, preferencesRepository.isNotificationsEnable)
|
||||||
|
.flatMap { noteRepository.getNotNotifiedNotes(student) }
|
||||||
|
.flatMapCompletable {
|
||||||
|
if (it.isNotEmpty()) notify(it)
|
||||||
|
noteRepository.updateNotes(it.onEach { note -> note.isNotified = true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun notify(notes: List<Note>) {
|
||||||
|
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewEntriesChannel.CHANNEL_ID)
|
||||||
|
.setContentTitle(context.resources.getQuantityString(R.plurals.note_new_items, notes.size, notes.size))
|
||||||
|
.setContentText(context.resources.getQuantityString(R.plurals.note_notify_new_items, notes.size, notes.size))
|
||||||
|
.setSmallIcon(R.drawable.ic_stat_notify_note)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setDefaults(DEFAULT_ALL)
|
||||||
|
.setPriority(PRIORITY_HIGH)
|
||||||
|
.setColor(context.getCompatColor(R.color.colorPrimary))
|
||||||
|
.setContentIntent(
|
||||||
|
PendingIntent.getActivity(context, 0,
|
||||||
|
MainActivity.getStartIntent(context).putExtra(EXTRA_START_MENU_INDEX, 4), FLAG_UPDATE_CURRENT)
|
||||||
|
)
|
||||||
|
.setStyle(NotificationCompat.InboxStyle().run {
|
||||||
|
setSummaryText(context.resources.getQuantityString(R.plurals.note_number_item, notes.size, notes.size))
|
||||||
|
notes.forEach { addLine("${it.teacher}: ${it.category}") }
|
||||||
|
this
|
||||||
|
})
|
||||||
|
.build())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.recipient.RecipientRepository
|
||||||
|
import io.github.wulkanowy.data.repositories.reportingunit.ReportingUnitRepository
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class RecipientWork @Inject constructor(
|
||||||
|
private val reportingUnitRepository: ReportingUnitRepository,
|
||||||
|
private val recipientRepository: RecipientRepository
|
||||||
|
) : Work {
|
||||||
|
|
||||||
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
|
return reportingUnitRepository.getReportingUnits(student)
|
||||||
|
.flatMapCompletable { units ->
|
||||||
|
Completable.mergeDelayError(units.map {
|
||||||
|
recipientRepository.getRecipients(student, 2, it).ignoreElement()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.timetable.TimetableRepository
|
||||||
|
import io.github.wulkanowy.utils.friday
|
||||||
|
import io.github.wulkanowy.utils.monday
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import org.threeten.bp.LocalDate.now
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class TimetableWork @Inject constructor(private val timetableRepository: TimetableRepository) : Work {
|
||||||
|
|
||||||
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
|
return timetableRepository.getTimetable(semester, now().monday, now().friday, true)
|
||||||
|
.ignoreElement()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.reactivex.Completable
|
||||||
|
|
||||||
|
interface Work {
|
||||||
|
|
||||||
|
fun create(student: Student, semester: Semester): Completable
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ package io.github.wulkanowy.ui.modules.account
|
|||||||
|
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
|
import io.github.wulkanowy.services.sync.SyncManager
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
@ -12,6 +13,7 @@ import javax.inject.Inject
|
|||||||
class AccountPresenter @Inject constructor(
|
class AccountPresenter @Inject constructor(
|
||||||
private val errorHandler: ErrorHandler,
|
private val errorHandler: ErrorHandler,
|
||||||
private val studentRepository: StudentRepository,
|
private val studentRepository: StudentRepository,
|
||||||
|
private val syncManager: SyncManager,
|
||||||
private val schedulers: SchedulersProvider
|
private val schedulers: SchedulersProvider
|
||||||
) : BasePresenter<AccountView>(errorHandler) {
|
) : BasePresenter<AccountView>(errorHandler) {
|
||||||
|
|
||||||
@ -48,6 +50,7 @@ class AccountPresenter @Inject constructor(
|
|||||||
view?.apply {
|
view?.apply {
|
||||||
if (it.isEmpty()) {
|
if (it.isEmpty()) {
|
||||||
Timber.i("Logout result: Open login view")
|
Timber.i("Logout result: Open login view")
|
||||||
|
syncManager.stopSyncWorker()
|
||||||
openClearLoginView()
|
openClearLoginView()
|
||||||
} else {
|
} else {
|
||||||
Timber.i("Logout result: Switch to another student")
|
Timber.i("Logout result: Switch to another student")
|
||||||
|
@ -62,7 +62,7 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
Timber.i("Select mark grades as read")
|
Timber.i("Select mark grades as read")
|
||||||
disposable.add(studentRepository.getCurrentStudent()
|
disposable.add(studentRepository.getCurrentStudent()
|
||||||
.flatMap { semesterRepository.getSemesters(it) }
|
.flatMap { semesterRepository.getSemesters(it) }
|
||||||
.flatMap { gradeRepository.getNewGrades(it.first { item -> item.semesterId == currentSemesterId }) }
|
.flatMap { gradeRepository.getUnreadGrades(it.first { item -> item.semesterId == currentSemesterId }) }
|
||||||
.map { it.map { grade -> grade.apply { isRead = true } } }
|
.map { it.map { grade -> grade.apply { isRead = true } } }
|
||||||
.flatMapCompletable {
|
.flatMapCompletable {
|
||||||
Timber.i("Mark as read ${it.size} grades")
|
Timber.i("Mark as read ${it.size} grades")
|
||||||
|
@ -14,7 +14,6 @@ import com.aurelhubert.ahbottomnavigation.AHBottomNavigationItem
|
|||||||
import com.ncapdevi.fragnav.FragNavController
|
import com.ncapdevi.fragnav.FragNavController
|
||||||
import com.ncapdevi.fragnav.FragNavController.Companion.HIDE
|
import com.ncapdevi.fragnav.FragNavController.Companion.HIDE
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.services.notification.GradeNotification
|
|
||||||
import io.github.wulkanowy.ui.base.BaseActivity
|
import io.github.wulkanowy.ui.base.BaseActivity
|
||||||
import io.github.wulkanowy.ui.modules.account.AccountDialog
|
import io.github.wulkanowy.ui.modules.account.AccountDialog
|
||||||
import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment
|
import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment
|
||||||
@ -164,10 +163,6 @@ class MainActivity : BaseActivity(), MainView {
|
|||||||
presenter.onBackPressed { super.onBackPressed() }
|
presenter.onBackPressed { super.onBackPressed() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cancelNotifications() {
|
|
||||||
GradeNotification(applicationContext).cancelAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun openLoginView() {
|
override fun openLoginView() {
|
||||||
startActivity(LoginActivity.getStartIntent(this)
|
startActivity(LoginActivity.getStartIntent(this)
|
||||||
.apply { addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) })
|
.apply { addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) })
|
||||||
|
@ -4,7 +4,7 @@ import com.google.firebase.analytics.FirebaseAnalytics.Event.APP_OPEN
|
|||||||
import com.google.firebase.analytics.FirebaseAnalytics.Param.DESTINATION
|
import com.google.firebase.analytics.FirebaseAnalytics.Param.DESTINATION
|
||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.services.job.ServiceHelper
|
import io.github.wulkanowy.services.sync.SyncManager
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
@ -17,8 +17,8 @@ class MainPresenter @Inject constructor(
|
|||||||
private val errorHandler: ErrorHandler,
|
private val errorHandler: ErrorHandler,
|
||||||
private val studentRepository: StudentRepository,
|
private val studentRepository: StudentRepository,
|
||||||
private val prefRepository: PreferencesRepository,
|
private val prefRepository: PreferencesRepository,
|
||||||
|
private val syncManager: SyncManager,
|
||||||
private val schedulers: SchedulersProvider,
|
private val schedulers: SchedulersProvider,
|
||||||
private val serviceHelper: ServiceHelper,
|
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BasePresenter<MainView>(errorHandler) {
|
) : BasePresenter<MainView>(errorHandler) {
|
||||||
|
|
||||||
@ -26,11 +26,11 @@ class MainPresenter @Inject constructor(
|
|||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
Timber.i("Main view is attached with $initMenuIndex menu index")
|
Timber.i("Main view is attached with $initMenuIndex menu index")
|
||||||
view.run {
|
view.run {
|
||||||
cancelNotifications()
|
|
||||||
startMenuIndex = if (initMenuIndex != -1) initMenuIndex else prefRepository.startMenuIndex
|
startMenuIndex = if (initMenuIndex != -1) initMenuIndex else prefRepository.startMenuIndex
|
||||||
initView()
|
initView()
|
||||||
}
|
}
|
||||||
serviceHelper.startFullSyncService()
|
|
||||||
|
syncManager.startSyncWorker()
|
||||||
|
|
||||||
analytics.logEvent(APP_OPEN, DESTINATION to when (initMenuIndex) {
|
analytics.logEvent(APP_OPEN, DESTINATION to when (initMenuIndex) {
|
||||||
1 -> "Grades"
|
1 -> "Grades"
|
||||||
@ -92,8 +92,7 @@ class MainPresenter @Inject constructor(
|
|||||||
if (it.isNotEmpty()) {
|
if (it.isNotEmpty()) {
|
||||||
Timber.i("Switching current student")
|
Timber.i("Switching current student")
|
||||||
studentRepository.switchStudent(it[0])
|
studentRepository.switchStudent(it[0])
|
||||||
}
|
} else Completable.complete()
|
||||||
else Completable.complete()
|
|
||||||
}
|
}
|
||||||
.subscribeOn(schedulers.backgroundThread)
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
.observeOn(schedulers.mainThread)
|
.observeOn(schedulers.mainThread)
|
||||||
|
@ -26,8 +26,6 @@ interface MainView : BaseView {
|
|||||||
|
|
||||||
fun popView()
|
fun popView()
|
||||||
|
|
||||||
fun cancelNotifications()
|
|
||||||
|
|
||||||
fun openLoginView()
|
fun openLoginView()
|
||||||
|
|
||||||
interface MainChildView {
|
interface MainChildView {
|
||||||
|
@ -7,9 +7,9 @@ import android.view.View.INVISIBLE
|
|||||||
import android.view.View.VISIBLE
|
import android.view.View.VISIBLE
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.repositories.message.MessageRepository.MessageFolder.RECEIVED
|
import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED
|
||||||
import io.github.wulkanowy.data.repositories.message.MessageRepository.MessageFolder.SENT
|
import io.github.wulkanowy.data.repositories.message.MessageFolder.SENT
|
||||||
import io.github.wulkanowy.data.repositories.message.MessageRepository.MessageFolder.TRASHED
|
import io.github.wulkanowy.data.repositories.message.MessageFolder.TRASHED
|
||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
|
@ -12,7 +12,7 @@ import eu.davidea.flexibleadapter.common.FlexibleItemDecoration
|
|||||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.repositories.message.MessageRepository
|
import io.github.wulkanowy.data.repositories.message.MessageFolder
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionFragment
|
import io.github.wulkanowy.ui.base.session.BaseSessionFragment
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.message.MessageFragment
|
import io.github.wulkanowy.ui.modules.message.MessageFragment
|
||||||
@ -34,7 +34,7 @@ class MessageTabFragment : BaseSessionFragment(), MessageTabView, MessageView.Me
|
|||||||
companion object {
|
companion object {
|
||||||
const val MESSAGE_TAB_FOLDER_ID = "message_tab_folder_id"
|
const val MESSAGE_TAB_FOLDER_ID = "message_tab_folder_id"
|
||||||
|
|
||||||
fun newInstance(folder: MessageRepository.MessageFolder): MessageTabFragment {
|
fun newInstance(folder: MessageFolder): MessageTabFragment {
|
||||||
return MessageTabFragment().apply {
|
return MessageTabFragment().apply {
|
||||||
arguments = Bundle().apply {
|
arguments = Bundle().apply {
|
||||||
putString(MESSAGE_TAB_FOLDER_ID, folder.name)
|
putString(MESSAGE_TAB_FOLDER_ID, folder.name)
|
||||||
@ -56,7 +56,7 @@ class MessageTabFragment : BaseSessionFragment(), MessageTabView, MessageView.Me
|
|||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
messageContainer = messageTabRecycler
|
messageContainer = messageTabRecycler
|
||||||
presenter.onAttachView(this, MessageRepository.MessageFolder.valueOf(
|
presenter.onAttachView(this, MessageFolder.valueOf(
|
||||||
(savedInstanceState ?: arguments)?.getString(MessageTabFragment.MESSAGE_TAB_FOLDER_ID) ?: ""
|
(savedInstanceState ?: arguments)?.getString(MessageTabFragment.MESSAGE_TAB_FOLDER_ID) ?: ""
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package io.github.wulkanowy.ui.modules.message.tab
|
|||||||
|
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.data.db.entities.Message
|
import io.github.wulkanowy.data.db.entities.Message
|
||||||
|
import io.github.wulkanowy.data.repositories.message.MessageFolder
|
||||||
import io.github.wulkanowy.data.repositories.message.MessageRepository
|
import io.github.wulkanowy.data.repositories.message.MessageRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionPresenter
|
import io.github.wulkanowy.ui.base.session.BaseSessionPresenter
|
||||||
@ -20,9 +21,9 @@ class MessageTabPresenter @Inject constructor(
|
|||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BaseSessionPresenter<MessageTabView>(errorHandler) {
|
) : BaseSessionPresenter<MessageTabView>(errorHandler) {
|
||||||
|
|
||||||
lateinit var folder: MessageRepository.MessageFolder
|
lateinit var folder: MessageFolder
|
||||||
|
|
||||||
fun onAttachView(view: MessageTabView, folder: MessageRepository.MessageFolder) {
|
fun onAttachView(view: MessageTabView, folder: MessageFolder) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
view.initView()
|
view.initView()
|
||||||
this.folder = folder
|
this.folder = folder
|
||||||
|
@ -2,7 +2,7 @@ package io.github.wulkanowy.ui.modules.settings
|
|||||||
|
|
||||||
import com.readystatesoftware.chuck.api.ChuckCollector
|
import com.readystatesoftware.chuck.api.ChuckCollector
|
||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.services.job.ServiceHelper
|
import io.github.wulkanowy.services.sync.SyncManager
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
@ -14,36 +14,25 @@ import javax.inject.Inject
|
|||||||
class SettingsPresenter @Inject constructor(
|
class SettingsPresenter @Inject constructor(
|
||||||
errorHandler: ErrorHandler,
|
errorHandler: ErrorHandler,
|
||||||
private val preferencesRepository: PreferencesRepository,
|
private val preferencesRepository: PreferencesRepository,
|
||||||
private val serviceHelper: ServiceHelper,
|
|
||||||
private val analytics: FirebaseAnalyticsHelper,
|
private val analytics: FirebaseAnalyticsHelper,
|
||||||
|
private val syncManager: SyncManager,
|
||||||
private val chuckCollector: ChuckCollector
|
private val chuckCollector: ChuckCollector
|
||||||
) : BasePresenter<SettingsView>(errorHandler) {
|
) : BasePresenter<SettingsView>(errorHandler) {
|
||||||
|
|
||||||
override fun onAttachView(view: SettingsView) {
|
override fun onAttachView(view: SettingsView) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
Timber.i("Settings view is attached")
|
Timber.i("Settings view is attached")
|
||||||
|
view.setServicesSuspended(preferencesRepository.serviceEnableKey, now().isHolidays)
|
||||||
view.run {
|
|
||||||
setServicesSuspended(preferencesRepository.serviceEnablesKey, now().isHolidays)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onSharedPreferenceChanged(key: String) {
|
fun onSharedPreferenceChanged(key: String) {
|
||||||
Timber.i("Change settings $key")
|
Timber.i("Change settings $key")
|
||||||
when (key) {
|
preferencesRepository.apply {
|
||||||
preferencesRepository.serviceEnablesKey -> {
|
when (key) {
|
||||||
if (preferencesRepository.isServiceEnabled) serviceHelper.startFullSyncService()
|
serviceEnableKey -> syncManager.run { if (isServiceEnabled) startSyncWorker() else stopSyncWorker() }
|
||||||
else serviceHelper.stopFullSyncService()
|
servicesIntervalKey, servicesOnlyWifiKey -> syncManager.startSyncWorker(true)
|
||||||
}
|
currentThemeKey -> view?.setTheme(currentTheme)
|
||||||
preferencesRepository.servicesIntervalKey,
|
isShowChuckerNotificationKey -> chuckCollector.showNotification(isShowChuckerNotification)
|
||||||
preferencesRepository.servicesOnlyWifiKey -> {
|
|
||||||
serviceHelper.reloadFullSyncService()
|
|
||||||
}
|
|
||||||
preferencesRepository.currentThemeKey -> {
|
|
||||||
view?.setTheme(preferencesRepository.currentTheme)
|
|
||||||
}
|
|
||||||
preferencesRepository.isShowChuckerNotificationKey -> {
|
|
||||||
chuckCollector.showNotification(preferencesRepository.isShowChuckerNotification)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
analytics.logEvent("setting_changed", "name" to key)
|
analytics.logEvent("setting_changed", "name" to key)
|
||||||
|
@ -3,13 +3,18 @@ package io.github.wulkanowy.utils
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.annotation.AttrRes
|
import androidx.annotation.AttrRes
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
|
import androidx.annotation.ColorRes
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
|
||||||
@ColorInt
|
@ColorInt
|
||||||
fun Context.getThemeAttrColor(@AttrRes colorAttr: Int): Int {
|
fun Context.getThemeAttrColor(@AttrRes colorAttr: Int): Int {
|
||||||
val array = this.obtainStyledAttributes(null, intArrayOf(colorAttr))
|
val array = obtainStyledAttributes(null, intArrayOf(colorAttr))
|
||||||
try {
|
return try {
|
||||||
return array.getColor(0, 0)
|
array.getColor(0, 0)
|
||||||
} finally {
|
} finally {
|
||||||
array.recycle()
|
array.recycle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ColorInt
|
||||||
|
fun Context.getCompatColor(@ColorRes colorRes: Int) = ContextCompat.getColor(this, colorRes)
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
android:layout_height="40dp"
|
android:layout_height="40dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="16dp"
|
||||||
android:tint="@android:color/black"
|
app:srcCompat="@drawable/ic_all_account_24dp"
|
||||||
app:srcCompat="@drawable/ic_all_account_24dp" />
|
app:tint="?android:textColorPrimary" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/loginItemName"
|
android:id="@+id/loginItemName"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Wulkanowy</string>
|
<string name="app_name">Wulkanowy</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Activity/Fragment title-->
|
<!--Activity/Fragment title-->
|
||||||
<string name="login_title">Wybierz ucznia</string>
|
<string name="login_title">Wybierz ucznia</string>
|
||||||
<string name="main_title">Wulkanowy</string>
|
<string name="main_title">Wulkanowy</string>
|
||||||
@ -70,17 +71,12 @@
|
|||||||
<item quantity="many">%d ocen</item>
|
<item quantity="many">%d ocen</item>
|
||||||
<item quantity="other">%d ocen</item>
|
<item quantity="other">%d ocen</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
<plurals name="grade_new_items">
|
<plurals name="grade_new_items">
|
||||||
<item quantity="one">Nowa ocena</item>
|
<item quantity="one">Nowa ocena</item>
|
||||||
<item quantity="few">Nowe oceny</item>
|
<item quantity="few">Nowe oceny</item>
|
||||||
<item quantity="many">Nowe oceny</item>
|
<item quantity="many">Nowe oceny</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
<plurals name="grade_notify_new_items">
|
||||||
|
|
||||||
<!--Grade notify-->
|
|
||||||
<string name="notify_grade_channel">Nowe oceny</string>
|
|
||||||
<plurals name="notify_grade_new_items">
|
|
||||||
<item quantity="one">Dostałeś %1$d ocenę</item>
|
<item quantity="one">Dostałeś %1$d ocenę</item>
|
||||||
<item quantity="few">"Dostałeś %1$d oceny</item>
|
<item quantity="few">"Dostałeś %1$d oceny</item>
|
||||||
<item quantity="many">Dostałeś %1$d ocen</item>
|
<item quantity="many">Dostałeś %1$d ocen</item>
|
||||||
@ -88,16 +84,6 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
|
|
||||||
<!--Note notify-->
|
|
||||||
<string name="notify_note_channel">Nowe uwagi</string>
|
|
||||||
<plurals name="notify_note_new_items">
|
|
||||||
<item quantity="one">Dostałeś %1$d uwagę</item>
|
|
||||||
<item quantity="few">"Dostałeś %1$d uwagi</item>
|
|
||||||
<item quantity="many">Dostałeś %1$d uwag</item>
|
|
||||||
<item quantity="other">Dostałeś %1$d uwag</item>
|
|
||||||
</plurals>
|
|
||||||
|
|
||||||
|
|
||||||
<!--Timetable-->
|
<!--Timetable-->
|
||||||
<string name="timetable_lesson">Lekcja</string>
|
<string name="timetable_lesson">Lekcja</string>
|
||||||
<string name="timetable_room">Sala</string>
|
<string name="timetable_room">Sala</string>
|
||||||
@ -106,6 +92,7 @@
|
|||||||
<string name="timetable_changes">Zmiany</string>
|
<string name="timetable_changes">Zmiany</string>
|
||||||
<string name="timetable_no_items">Brak lekcji w tym dniu</string>
|
<string name="timetable_no_items">Brak lekcji w tym dniu</string>
|
||||||
|
|
||||||
|
|
||||||
<!--CompletedLesson-->
|
<!--CompletedLesson-->
|
||||||
<string name="completed_lessons_title">Lekcje zrealizowane</string>
|
<string name="completed_lessons_title">Lekcje zrealizowane</string>
|
||||||
<string name="completed_lessons_button">Zobacz lekcje zrealizowane</string>
|
<string name="completed_lessons_button">Zobacz lekcje zrealizowane</string>
|
||||||
@ -114,6 +101,7 @@
|
|||||||
<string name="completed_lessons_absence">Nieobecność</string>
|
<string name="completed_lessons_absence">Nieobecność</string>
|
||||||
<string name="completed_lessons_resources">Zasoby</string>
|
<string name="completed_lessons_resources">Zasoby</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Attendance-->
|
<!--Attendance-->
|
||||||
<string name="attendance_summary_button">Podsumowanie frekwencji</string>
|
<string name="attendance_summary_button">Podsumowanie frekwencji</string>
|
||||||
<string name="attendance_absence_school">Nieobecny z przyczyn szkolnych</string>
|
<string name="attendance_absence_school">Nieobecny z przyczyn szkolnych</string>
|
||||||
@ -131,9 +119,11 @@
|
|||||||
<item quantity="many">%1$d nieobecności</item>
|
<item quantity="many">%1$d nieobecności</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
|
|
||||||
<!--Attendance summary-->
|
<!--Attendance summary-->
|
||||||
<string name="attendance_summary_final">Frekwencja</string>
|
<string name="attendance_summary_final">Frekwencja</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Exam-->
|
<!--Exam-->
|
||||||
<string name="exam_no_items">Brak sprawdzianów w tym tygodniu</string>
|
<string name="exam_no_items">Brak sprawdzianów w tym tygodniu</string>
|
||||||
<string name="exam_type">Typ</string>
|
<string name="exam_type">Typ</string>
|
||||||
@ -155,17 +145,12 @@
|
|||||||
<item quantity="few">%d wiadomości</item>
|
<item quantity="few">%d wiadomości</item>
|
||||||
<item quantity="many">%d wiadomości</item>
|
<item quantity="many">%d wiadomości</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
<plurals name="message_new_items">
|
<plurals name="message_new_items">
|
||||||
<item quantity="one">Nowa wiadomość</item>
|
<item quantity="one">Nowa wiadomość</item>
|
||||||
<item quantity="few">Nowe wiadomości</item>
|
<item quantity="few">Nowe wiadomości</item>
|
||||||
<item quantity="many">Nowe wiadomości</item>
|
<item quantity="many">Nowe wiadomości</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
<plurals name="message_notify_new_items">
|
||||||
|
|
||||||
<!--Message notify-->
|
|
||||||
<string name="notify_message_channel">Nowe wiadomości</string>
|
|
||||||
<plurals name="notify_message_new_items">
|
|
||||||
<item quantity="one">Dostałeś %1$d wiadomość</item>
|
<item quantity="one">Dostałeś %1$d wiadomość</item>
|
||||||
<item quantity="few">"Dostałeś %1$d wiadomości</item>
|
<item quantity="few">"Dostałeś %1$d wiadomości</item>
|
||||||
<item quantity="many">Dostałeś %1$d wiadomości</item>
|
<item quantity="many">Dostałeś %1$d wiadomości</item>
|
||||||
@ -181,9 +166,6 @@
|
|||||||
<string name="send_message_required_recipients">Musisz wybrać co najmniej 1 adresata</string>
|
<string name="send_message_required_recipients">Musisz wybrać co najmniej 1 adresata</string>
|
||||||
<string name="send_message_content_min_length">Treść wiadomości musi zawierać co najmniej 3 znaki</string>
|
<string name="send_message_content_min_length">Treść wiadomości musi zawierać co najmniej 3 znaki</string>
|
||||||
|
|
||||||
<!--About-->
|
|
||||||
<string name="about_source_code">Kod źródłowy</string>
|
|
||||||
<string name="about_feedback">Zgłoś błąd</string>
|
|
||||||
|
|
||||||
<!--Note-->
|
<!--Note-->
|
||||||
<string name="note_no_items">Brak informacji o uwagach</string>
|
<string name="note_no_items">Brak informacji o uwagach</string>
|
||||||
@ -193,27 +175,31 @@
|
|||||||
<item quantity="many">%d uwag</item>
|
<item quantity="many">%d uwag</item>
|
||||||
<item quantity="other">%d uwag</item>
|
<item quantity="other">%d uwag</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
<plurals name="note_new_items">
|
<plurals name="note_new_items">
|
||||||
<item quantity="one">Nowa uwaga</item>
|
<item quantity="one">Nowa uwaga</item>
|
||||||
<item quantity="few">Nowe uwagi</item>
|
<item quantity="few">Nowe uwagi</item>
|
||||||
<item quantity="many">Nowych uwag</item>
|
<item quantity="many">Nowych uwag</item>
|
||||||
<item quantity="other">Nowych uwag</item>
|
<item quantity="other">Nowych uwag</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
<plurals name="note_notify_new_items">
|
||||||
|
<item quantity="one">Dostałeś %1$d uwagę</item>
|
||||||
|
<item quantity="few">"Dostałeś %1$d uwagi</item>
|
||||||
|
<item quantity="many">Dostałeś %1$d uwag</item>
|
||||||
|
<item quantity="other">Dostałeś %1$d uwag</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
|
|
||||||
<!--Homework-->
|
<!--Homework-->
|
||||||
<string name="homework_no_items">Brak zadań domowych</string>
|
<string name="homework_no_items">Brak zadań domowych</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Lucky number-->
|
<!--Lucky number-->
|
||||||
<string name="lucky_number_title">Szczęśliwy numerek</string>
|
<string name="lucky_number_title">Szczęśliwy numerek</string>
|
||||||
<string name="lucky_number_header">Dzisiejszym szczęśliwym numerkiem jest</string>
|
<string name="lucky_number_header">Dzisiejszym szczęśliwym numerkiem jest</string>
|
||||||
<string name="lucky_number_empty">Brak informacji o szczęśliwym numerku</string>
|
<string name="lucky_number_empty">Brak informacji o szczęśliwym numerku</string>
|
||||||
|
<string name="lucky_number_notify_new_item_title">Szczęśliwy numerek na dzisiaj</string>
|
||||||
|
<string name="lucky_number_notify_new_item">Dziś szczęśliwym numerkiem jest: %d</string>
|
||||||
|
|
||||||
<!--Lucky number notify-->
|
|
||||||
<string name="notify_lucky_number_channel">Nowe szczęśliwe numerki</string>
|
|
||||||
<string name="notify_lucky_number_new_item_title">Szczęśliwy numerek na dzisiaj</string>
|
|
||||||
<string name="notify_lucky_number_new_item">Dziś szczęśliwym numerkiem jest: %d</string>
|
|
||||||
|
|
||||||
<!--Account-->
|
<!--Account-->
|
||||||
<string name="account_add_new">Dodaj konto</string>
|
<string name="account_add_new">Dodaj konto</string>
|
||||||
@ -222,6 +208,11 @@
|
|||||||
<string name="account_logout_student">Wylogowanie ucznia</string>
|
<string name="account_logout_student">Wylogowanie ucznia</string>
|
||||||
|
|
||||||
|
|
||||||
|
<!--About-->
|
||||||
|
<string name="about_source_code">Kod źródłowy</string>
|
||||||
|
<string name="about_feedback">Zgłoś błąd</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Generic-->
|
<!--Generic-->
|
||||||
<string name="all_content">Treść</string>
|
<string name="all_content">Treść</string>
|
||||||
<string name="all_description">Opis</string>
|
<string name="all_description">Opis</string>
|
||||||
@ -267,6 +258,10 @@
|
|||||||
<string name="pref_services_wifi">Tylko WiFi</string>
|
<string name="pref_services_wifi">Tylko WiFi</string>
|
||||||
|
|
||||||
|
|
||||||
|
<!--Notification Channels-->
|
||||||
|
<string name="channel_new_entries">Nowe wpisy w dzienniku</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Colors-->
|
<!--Colors-->
|
||||||
<string name="all_black">Czarny</string>
|
<string name="all_black">Czarny</string>
|
||||||
<string name="all_red">Czerwony</string>
|
<string name="all_red">Czerwony</string>
|
||||||
@ -279,6 +274,7 @@
|
|||||||
<!--Others-->
|
<!--Others-->
|
||||||
<string name="all_copied">Skopiowano</string>
|
<string name="all_copied">Skopiowano</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Errors-->
|
<!--Errors-->
|
||||||
<string name="error_no_internet">Brak połączenia z internetem</string>
|
<string name="error_no_internet">Brak połączenia z internetem</string>
|
||||||
<string name="error_timeout">Zbyt długie oczekiwanie na połączenie</string>
|
<string name="error_timeout">Zbyt długie oczekiwanie na połączenie</string>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Wulkanowy</string>
|
<string name="app_name">Wulkanowy</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Activity/Fragment title-->
|
<!--Activity/Fragment title-->
|
||||||
<string name="login_title">Select student</string>
|
<string name="login_title">Select student</string>
|
||||||
<string name="main_title">Wulkanowy</string>
|
<string name="main_title">Wulkanowy</string>
|
||||||
@ -68,26 +69,15 @@
|
|||||||
<item quantity="one">%d grade</item>
|
<item quantity="one">%d grade</item>
|
||||||
<item quantity="other">%d grades</item>
|
<item quantity="other">%d grades</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
<plurals name="grade_new_items">
|
<plurals name="grade_new_items">
|
||||||
<item quantity="one">New grade</item>
|
<item quantity="one">New grade</item>
|
||||||
<item quantity="other">New grades</item>
|
<item quantity="other">New grades</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
<plurals name="grade_notify_new_items">
|
||||||
<!--Grade notify-->
|
|
||||||
<string name="notify_grade_channel">New grades</string>
|
|
||||||
<plurals name="notify_grade_new_items">
|
|
||||||
<item quantity="one">You received %1$d grade</item>
|
<item quantity="one">You received %1$d grade</item>
|
||||||
<item quantity="other">You received %1$d grades</item>
|
<item quantity="other">You received %1$d grades</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
<!--Note notify-->
|
|
||||||
<string name="notify_note_channel">New notes</string>
|
|
||||||
<plurals name="notify_note_new_items">
|
|
||||||
<item quantity="one">You received %1$d note</item>
|
|
||||||
<item quantity="other">You received %1$d notes</item>
|
|
||||||
</plurals>
|
|
||||||
|
|
||||||
|
|
||||||
<!--Timetable-->
|
<!--Timetable-->
|
||||||
<string name="timetable_lesson">Lesson</string>
|
<string name="timetable_lesson">Lesson</string>
|
||||||
@ -97,6 +87,7 @@
|
|||||||
<string name="timetable_changes">Changes</string>
|
<string name="timetable_changes">Changes</string>
|
||||||
<string name="timetable_no_items">No lessons this day</string>
|
<string name="timetable_no_items">No lessons this day</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Completed lessons-->
|
<!--Completed lessons-->
|
||||||
<string name="completed_lessons_title">Completed lessons</string>
|
<string name="completed_lessons_title">Completed lessons</string>
|
||||||
<string name="completed_lessons_button">Show completed lessons</string>
|
<string name="completed_lessons_button">Show completed lessons</string>
|
||||||
@ -105,6 +96,7 @@
|
|||||||
<string name="completed_lessons_absence">Absence</string>
|
<string name="completed_lessons_absence">Absence</string>
|
||||||
<string name="completed_lessons_resources">Resources</string>
|
<string name="completed_lessons_resources">Resources</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Attendance-->
|
<!--Attendance-->
|
||||||
<string name="attendance_summary_button">Attendance summary</string>
|
<string name="attendance_summary_button">Attendance summary</string>
|
||||||
<string name="attendance_absence_school">Absent for school reasons</string>
|
<string name="attendance_absence_school">Absent for school reasons</string>
|
||||||
@ -121,6 +113,7 @@
|
|||||||
<item quantity="other">%1$d absences</item>
|
<item quantity="other">%1$d absences</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
|
|
||||||
<!--Attendance summary-->
|
<!--Attendance summary-->
|
||||||
<string name="attendance_summary_final">Attendance</string>
|
<string name="attendance_summary_final">Attendance</string>
|
||||||
|
|
||||||
@ -145,15 +138,11 @@
|
|||||||
<item quantity="one">%d message</item>
|
<item quantity="one">%d message</item>
|
||||||
<item quantity="other">%d messages</item>
|
<item quantity="other">%d messages</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
<plurals name="message_new_items">
|
<plurals name="message_new_items">
|
||||||
<item quantity="one">New message</item>
|
<item quantity="one">New message</item>
|
||||||
<item quantity="other">New messages</item>
|
<item quantity="other">New messages</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
<plurals name="message_notify_new_items">
|
||||||
<!--Message notify-->
|
|
||||||
<string name="notify_message_channel">New messages</string>
|
|
||||||
<plurals name="notify_message_new_items">
|
|
||||||
<item quantity="one">You received %1$d message</item>
|
<item quantity="one">You received %1$d message</item>
|
||||||
<item quantity="other">You received %1$d messages</item>
|
<item quantity="other">You received %1$d messages</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
@ -168,9 +157,6 @@
|
|||||||
<string name="send_message_required_recipients">You need to choose at least 1 recipient</string>
|
<string name="send_message_required_recipients">You need to choose at least 1 recipient</string>
|
||||||
<string name="send_message_content_min_length">The message content must be at least 3 characters</string>
|
<string name="send_message_content_min_length">The message content must be at least 3 characters</string>
|
||||||
|
|
||||||
<!--About-->
|
|
||||||
<string name="about_source_code">Source code</string>
|
|
||||||
<string name="about_feedback">Report a bug</string>
|
|
||||||
|
|
||||||
<!--Note-->
|
<!--Note-->
|
||||||
<string name="note_no_items">No info about notes</string>
|
<string name="note_no_items">No info about notes</string>
|
||||||
@ -178,25 +164,27 @@
|
|||||||
<item quantity="one">%d note</item>
|
<item quantity="one">%d note</item>
|
||||||
<item quantity="other">%d notes</item>
|
<item quantity="other">%d notes</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
<plurals name="note_new_items">
|
<plurals name="note_new_items">
|
||||||
<item quantity="one">New note</item>
|
<item quantity="one">New note</item>
|
||||||
<item quantity="other">New notes</item>
|
<item quantity="other">New notes</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
<plurals name="note_notify_new_items">
|
||||||
|
<item quantity="one">You received %1$d note</item>
|
||||||
|
<item quantity="other">You received %1$d notes</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
|
|
||||||
<!--Homework-->
|
<!--Homework-->
|
||||||
<string name="homework_no_items">No info about homework</string>
|
<string name="homework_no_items">No info about homework</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Lucky number-->
|
<!--Lucky number-->
|
||||||
<string name="lucky_number_title">Lucky number</string>
|
<string name="lucky_number_title">Lucky number</string>
|
||||||
<string name="lucky_number_header">Today\'s lucky number is</string>
|
<string name="lucky_number_header">Today\'s lucky number is</string>
|
||||||
<string name="lucky_number_empty">No info about the lucky number</string>
|
<string name="lucky_number_empty">No info about the lucky number</string>
|
||||||
|
<string name="lucky_number_notify_new_item_title">Lucky number for today</string>
|
||||||
|
<string name="lucky_number_notify_new_item">Today\'s lucky number is: %d</string>
|
||||||
|
|
||||||
<!--Lucky number notify-->
|
|
||||||
<string name="notify_lucky_number_channel">New lucky numbers</string>
|
|
||||||
<string name="notify_lucky_number_new_item_title">Lucky number for today</string>
|
|
||||||
<string name="notify_lucky_number_new_item">Today\'s lucky number is: %d</string>
|
|
||||||
|
|
||||||
<!--Account-->
|
<!--Account-->
|
||||||
<string name="account_add_new">Add account</string>
|
<string name="account_add_new">Add account</string>
|
||||||
@ -205,6 +193,11 @@
|
|||||||
<string name="account_logout_student">Student logout</string>
|
<string name="account_logout_student">Student logout</string>
|
||||||
|
|
||||||
|
|
||||||
|
<!--About-->
|
||||||
|
<string name="about_source_code">Source code</string>
|
||||||
|
<string name="about_feedback">Report a bug</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Generic-->
|
<!--Generic-->
|
||||||
<string name="all_content">Content</string>
|
<string name="all_content">Content</string>
|
||||||
<string name="all_description">Description</string>
|
<string name="all_description">Description</string>
|
||||||
@ -250,6 +243,10 @@
|
|||||||
<string name="pref_services_wifi">Wi-Fi only</string>
|
<string name="pref_services_wifi">Wi-Fi only</string>
|
||||||
|
|
||||||
|
|
||||||
|
<!--Notification Channels-->
|
||||||
|
<string name="channel_new_entries">New entries in register</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Colors-->
|
<!--Colors-->
|
||||||
<string name="all_black">Black</string>
|
<string name="all_black">Black</string>
|
||||||
<string name="all_red">Red</string>
|
<string name="all_red">Red</string>
|
||||||
@ -262,6 +259,7 @@
|
|||||||
<!--Others-->
|
<!--Others-->
|
||||||
<string name="all_copied">Copied</string>
|
<string name="all_copied">Copied</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Errors-->
|
<!--Errors-->
|
||||||
<string name="error_no_internet">No internet connection</string>
|
<string name="error_no_internet">No internet connection</string>
|
||||||
<string name="error_timeout">Too long wait for connection</string>
|
<string name="error_timeout">Too long wait for connection</string>
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.ui.modules.main
|
|||||||
import io.github.wulkanowy.TestSchedulersProvider
|
import io.github.wulkanowy.TestSchedulersProvider
|
||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.services.job.ServiceHelper
|
import io.github.wulkanowy.services.sync.SyncManager
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@ -25,7 +25,7 @@ class MainPresenterTest {
|
|||||||
lateinit var prefRepository: PreferencesRepository
|
lateinit var prefRepository: PreferencesRepository
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var serviceHelper: ServiceHelper
|
lateinit var syncManager: SyncManager
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var mainView: MainView
|
lateinit var mainView: MainView
|
||||||
@ -40,7 +40,7 @@ class MainPresenterTest {
|
|||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
clearInvocations(mainView)
|
clearInvocations(mainView)
|
||||||
|
|
||||||
presenter = MainPresenter(errorHandler, studentRepository, prefRepository, TestSchedulersProvider(), serviceHelper, analytics)
|
presenter = MainPresenter(errorHandler, studentRepository, prefRepository, syncManager, TestSchedulersProvider(), analytics)
|
||||||
presenter.onAttachView(mainView, -1)
|
presenter.onAttachView(mainView, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user