mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2025-01-18 13:26:44 -06: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_IF_CONDITIONS" value="false" />
|
||||
<option name="CONTINUATION_INDENT_IN_ELVIS" value="false" />
|
||||
<option name="WRAP_ELVIS_EXPRESSIONS" value="0" />
|
||||
</JetCodeStyleSettings>
|
||||
<Objective-C-extensions>
|
||||
<file>
|
||||
|
@ -82,7 +82,12 @@ dependencies {
|
||||
implementation 'androidx.multidex:multidex:2.0.1'
|
||||
|
||||
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"
|
||||
kapt "com.google.dagger:dagger-compiler:2.21"
|
||||
|
@ -42,13 +42,6 @@
|
||||
android:label="@string/main_title"
|
||||
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
|
||||
android:name=".services.widgets.TimetableWidgetService"
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||
@ -64,6 +57,12 @@
|
||||
android:resource="@xml/provider_widget_timetable" />
|
||||
</receiver>
|
||||
|
||||
<provider
|
||||
android:name="androidx.work.impl.WorkManagerInitializer"
|
||||
android:authorities="${applicationId}.workmanager-init"
|
||||
android:exported="false"
|
||||
tools:node="remove" />
|
||||
|
||||
<meta-data
|
||||
android:name="io.fabric.ApiKey"
|
||||
android:value="${fabric_api_key}" />
|
||||
|
@ -3,6 +3,8 @@ package io.github.wulkanowy
|
||||
import android.content.Context
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.multidex.MultiDex
|
||||
import androidx.work.Configuration
|
||||
import androidx.work.WorkManager
|
||||
import com.crashlytics.android.Crashlytics
|
||||
import com.crashlytics.android.core.CrashlyticsCore
|
||||
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.data.repositories.preferences.PreferencesRepository
|
||||
import io.github.wulkanowy.di.DaggerAppComponent
|
||||
import io.github.wulkanowy.services.sync.SyncWorkerFactory
|
||||
import io.github.wulkanowy.utils.CrashlyticsTree
|
||||
import io.github.wulkanowy.utils.DebugLogTree
|
||||
import timber.log.Timber
|
||||
@ -24,6 +27,9 @@ class WulkanowyApp : DaggerApplication() {
|
||||
@Inject
|
||||
lateinit var prefRepository: PreferencesRepository
|
||||
|
||||
@Inject
|
||||
lateinit var workerFactory: SyncWorkerFactory
|
||||
|
||||
override fun attachBaseContext(base: Context?) {
|
||||
super.attachBaseContext(base)
|
||||
MultiDex.install(this)
|
||||
@ -35,6 +41,7 @@ class WulkanowyApp : DaggerApplication() {
|
||||
initializeFabric()
|
||||
if (DEBUG) enableDebugLog()
|
||||
AppCompatDelegate.setDefaultNightMode(prefRepository.currentTheme)
|
||||
WorkManager.initialize(this, Configuration.Builder().setWorkerFactory(workerFactory).build())
|
||||
}
|
||||
|
||||
private fun enableDebugLog() {
|
||||
|
@ -14,7 +14,7 @@ import javax.inject.Singleton
|
||||
interface CompletedLessonsDao {
|
||||
|
||||
@Insert
|
||||
fun insertAll(exams: List<CompletedLesson>): List<Long>
|
||||
fun insertAll(exams: List<CompletedLesson>)
|
||||
|
||||
@Delete
|
||||
fun deleteAll(exams: List<CompletedLesson>)
|
||||
|
@ -16,9 +16,6 @@ interface GradeDao {
|
||||
@Insert
|
||||
fun insertAll(grades: List<Grade>)
|
||||
|
||||
@Update
|
||||
fun update(grade: Grade)
|
||||
|
||||
@Update
|
||||
fun updateAll(grade: List<Grade>)
|
||||
|
||||
@ -28,6 +25,4 @@ interface GradeDao {
|
||||
@Query("SELECT * FROM Grades WHERE semester_id = :semesterId AND student_id = :studentId")
|
||||
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)
|
||||
|
||||
@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 {
|
||||
|
||||
@Insert
|
||||
fun insertAll(messages: List<Message>): List<Long>
|
||||
fun insertAll(messages: List<Message>)
|
||||
|
||||
@Delete
|
||||
fun deleteAll(messages: List<Message>)
|
||||
|
||||
@Update
|
||||
fun update(message: Message)
|
||||
|
||||
@Update
|
||||
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")
|
||||
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")
|
||||
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
|
||||
fun insertAll(notes: List<Note>)
|
||||
|
||||
@Update
|
||||
fun update(note: Note)
|
||||
|
||||
@Update
|
||||
fun updateAll(notes: List<Note>)
|
||||
|
||||
@ -28,6 +25,4 @@ interface NoteDao {
|
||||
@Query("SELECT * FROM Notes WHERE student_id = :studentId")
|
||||
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
|
||||
|
||||
@ColumnInfo(name = "is_read")
|
||||
var isRead: Boolean = false
|
||||
var isRead: Boolean = true
|
||||
|
||||
@ColumnInfo(name = "is_notified")
|
||||
var isNotified: Boolean = true
|
||||
|
@ -11,11 +11,6 @@ import javax.inject.Singleton
|
||||
@Singleton
|
||||
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>) {
|
||||
attendanceDb.insertAll(attendance)
|
||||
}
|
||||
@ -23,4 +18,8 @@ class AttendanceLocal @Inject constructor(private val attendanceDb: AttendanceDa
|
||||
fun deleteAttendance(attendance: List<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
|
||||
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>) {
|
||||
attendanceDb.insertAll(attendance)
|
||||
}
|
||||
@ -21,4 +17,8 @@ class AttendanceSummaryLocal @Inject constructor(private val attendanceDb: Atten
|
||||
fun deleteAttendanceSummary(attendance: List<AttendanceSummary>) {
|
||||
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
|
||||
) {
|
||||
|
||||
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 }
|
||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||
.flatMap {
|
||||
|
@ -11,10 +11,6 @@ import javax.inject.Singleton
|
||||
@Singleton
|
||||
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>) {
|
||||
completedLessonsDb.insertAll(completedLessons)
|
||||
}
|
||||
@ -22,4 +18,8 @@ class CompletedLessonsLocal @Inject constructor(private val completedLessonsDb:
|
||||
fun deleteCompleteLessons(completedLessons: List<CompletedLesson>) {
|
||||
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.entities.Grade
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Maybe
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
@ -11,27 +10,19 @@ import javax.inject.Singleton
|
||||
@Singleton
|
||||
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>) {
|
||||
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>) {
|
||||
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.saveGrades((newGrades - oldGrades)
|
||||
.onEach {
|
||||
if (it.date >= notifyBreakDate) {
|
||||
if (notify) it.isNotified = false
|
||||
it.isRead = false
|
||||
if (it.date >= notifyBreakDate) it.apply {
|
||||
isRead = false
|
||||
if (notify) isNotified = false
|
||||
}
|
||||
})
|
||||
}
|
||||
}.flatMap { local.getGrades(semester).toSingle(emptyList()) })
|
||||
}
|
||||
|
||||
fun getNewGrades(semester: Semester): Single<List<Grade>> {
|
||||
return local.getNewGrades(semester).toSingle(emptyList())
|
||||
fun getUnreadGrades(semester: Semester): Single<List<Grade>> {
|
||||
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 {
|
||||
return local.updateGrade(grade)
|
||||
return Completable.fromCallable { local.updateGrades(listOf(grade)) }
|
||||
}
|
||||
|
||||
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
|
||||
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>) {
|
||||
gradeSummaryDb.insertAll(gradesSummary)
|
||||
}
|
||||
@ -22,4 +17,8 @@ class GradeSummaryLocal @Inject constructor(private val gradeSummaryDb: GradeSum
|
||||
fun deleteGradesSummary(gradesSummary: List<GradeSummary>) {
|
||||
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
|
||||
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>) {
|
||||
homeworkDb.insertAll(homework)
|
||||
}
|
||||
@ -22,4 +18,8 @@ class HomeworkLocal @Inject constructor(private val homeworkDb: HomeworkDao) {
|
||||
fun deleteHomework(homework: List<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.entities.LuckyNumber
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Maybe
|
||||
import org.threeten.bp.LocalDate
|
||||
import javax.inject.Inject
|
||||
@ -12,19 +11,19 @@ import javax.inject.Singleton
|
||||
@Singleton
|
||||
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) {
|
||||
luckyNumberDb.insert(luckyNumber)
|
||||
}
|
||||
|
||||
fun updateLuckyNumber(luckyNumber: LuckyNumber): Completable {
|
||||
return Completable.fromCallable { luckyNumberDb.update(luckyNumber) }
|
||||
fun updateLuckyNumber(luckyNumber: LuckyNumber) {
|
||||
luckyNumberDb.update(luckyNumber)
|
||||
}
|
||||
|
||||
fun deleteLuckyNumber(luckyNumber: 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 {
|
||||
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.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.repositories.message.MessageFolder.TRASHED
|
||||
import io.reactivex.Maybe
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
@ -10,34 +11,26 @@ import javax.inject.Singleton
|
||||
@Singleton
|
||||
class MessageLocal @Inject constructor(private val messagesDb: MessagesDao) {
|
||||
|
||||
fun getMessage(studentId: Int, id: Int): Maybe<Message> {
|
||||
return messagesDb.loadOne(studentId, id)
|
||||
}
|
||||
|
||||
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 saveMessages(messages: List<Message>) {
|
||||
messagesDb.insertAll(messages)
|
||||
}
|
||||
|
||||
fun updateMessages(messages: List<Message>) {
|
||||
return messagesDb.updateAll(messages)
|
||||
messagesDb.updateAll(messages)
|
||||
}
|
||||
|
||||
fun deleteMessages(messages: List<Message>) {
|
||||
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
|
||||
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 ->
|
||||
messages.map {
|
||||
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.Recipient
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Single
|
||||
import java.net.UnknownHostException
|
||||
@ -21,22 +22,16 @@ class MessageRepository @Inject constructor(
|
||||
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>> {
|
||||
return Single.just(apiHelper.initApi(student))
|
||||
.flatMap { _ ->
|
||||
local.getMessages(student.studentId, folder).filter { !forceRefresh }
|
||||
local.getMessages(student, folder).filter { !forceRefresh }
|
||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||
.flatMap {
|
||||
if (it) remote.getMessages(student.studentId, folder)
|
||||
else Single.error(UnknownHostException())
|
||||
}.flatMap { new ->
|
||||
local.getMessages(student.studentId, folder).toSingle(emptyList())
|
||||
local.getMessages(student, folder).toSingle(emptyList())
|
||||
.doOnSuccess { old ->
|
||||
local.deleteMessages(old - new)
|
||||
local.saveMessages((new - old)
|
||||
@ -44,7 +39,7 @@ class MessageRepository @Inject constructor(
|
||||
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> {
|
||||
return Single.just(apiHelper.initApi(student))
|
||||
.flatMap { _ ->
|
||||
local.getMessage(student.studentId, messageId)
|
||||
local.getMessage(student, messageId)
|
||||
.filter { !it.content.isNullOrEmpty() }
|
||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||
.flatMap {
|
||||
if (it) local.getMessage(student.studentId, messageId).toSingle()
|
||||
if (it) local.getMessage(student, messageId).toSingle()
|
||||
else Single.error(UnknownHostException())
|
||||
}
|
||||
.flatMap { dbMessage ->
|
||||
remote.getMessagesContent(dbMessage, markAsRead).doOnSuccess {
|
||||
local.updateMessage(dbMessage.copy(unread = false).apply {
|
||||
local.updateMessages(listOf(dbMessage.copy(unread = false).apply {
|
||||
id = dbMessage.id
|
||||
content = it
|
||||
})
|
||||
}))
|
||||
}
|
||||
}.flatMap {
|
||||
local.getMessage(student.studentId, messageId).toSingle()
|
||||
local.getMessage(student, messageId).toSingle()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun getNewMessages(student: Student): Single<List<Message>> {
|
||||
return local.getNewMessages(student).toSingle(emptyList())
|
||||
fun getNotNotifiedMessages(student: Student): Single<List<Message>> {
|
||||
return local.getMessages(student, RECEIVED)
|
||||
.map { it.filter { message -> !message.isNotified && message.unread } }
|
||||
.toSingle(emptyList())
|
||||
}
|
||||
|
||||
fun updateMessage(message: Message): Completable {
|
||||
return Completable.fromCallable { local.updateMessage(message) }
|
||||
return Completable.fromCallable { local.updateMessages(listOf(message)) }
|
||||
}
|
||||
|
||||
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.entities.Note
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Maybe
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
@ -11,27 +10,19 @@ import javax.inject.Singleton
|
||||
@Singleton
|
||||
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>) {
|
||||
noteDb.insertAll(notes)
|
||||
}
|
||||
|
||||
fun updateNote(note: Note): Completable {
|
||||
return Completable.fromCallable { noteDb.update(note) }
|
||||
}
|
||||
|
||||
fun updateNotes(notes: List<Note>): Completable {
|
||||
return Completable.fromCallable { noteDb.updateAll(notes) }
|
||||
fun updateNotes(notes: List<Note>) {
|
||||
noteDb.updateAll(notes)
|
||||
}
|
||||
|
||||
fun deleteNotes(notes: List<Note>) {
|
||||
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.saveNotes((new - old)
|
||||
.onEach {
|
||||
if (student.registrationDate <= it.date.atStartOfDay()) {
|
||||
if (notify) it.isNotified = false
|
||||
it.isRead = false
|
||||
if (it.date >= student.registrationDate.toLocalDate()) it.apply {
|
||||
isRead = false
|
||||
if (notify) isNotified = false
|
||||
}
|
||||
})
|
||||
}
|
||||
}.flatMap { local.getNotes(student).toSingle(emptyList()) })
|
||||
}
|
||||
|
||||
fun getNewNotes(student: Student): Single<List<Note>> {
|
||||
return local.getNewNotes(student).toSingle(emptyList())
|
||||
fun getNotNotifiedNotes(student: Student): Single<List<Note>> {
|
||||
return local.getNotes(student).map { it.filter { note -> !note.isNotified } }.toSingle(emptyList())
|
||||
}
|
||||
|
||||
fun updateNote(note: Note): Completable {
|
||||
return local.updateNote(note)
|
||||
return Completable.fromCallable { local.updateNotes(listOf(note)) }
|
||||
}
|
||||
|
||||
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 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
|
||||
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 currentTheme: Int
|
||||
get() = sharedPref.getString(currentThemeKey, "1")?.toInt() ?: 1
|
||||
get() = sharedPref.getString(currentThemeKey, "1")?.toIntOrNull() ?: 1
|
||||
|
||||
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
|
||||
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
|
||||
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_color_scheme), "vulcan") ?: "vulcan"
|
||||
|
||||
|
||||
val serviceEnablesKey: String = context.getString(R.string.pref_key_services_enable)
|
||||
val serviceEnableKey: String = context.getString(R.string.pref_key_services_enable)
|
||||
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 servicesInterval: Int
|
||||
get() = sharedPref.getString(servicesIntervalKey, "60")?.toInt() ?: 60
|
||||
val servicesInterval: Long
|
||||
get() = sharedPref.getString(servicesIntervalKey, "60")?.toLongOrNull() ?: 60
|
||||
|
||||
val servicesOnlyWifiKey: String = context.getString(R.string.pref_key_services_wifi_only)
|
||||
val isServicesOnlyWifi: Boolean
|
||||
|
@ -11,11 +11,6 @@ import javax.inject.Singleton
|
||||
@Singleton
|
||||
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>) {
|
||||
timetableDb.insertAll(timetables)
|
||||
}
|
||||
@ -23,4 +18,8 @@ class TimetableLocal @Inject constructor(private val timetableDb: TimetableDao)
|
||||
fun deleteTimetable(timetables: List<Timetable>) {
|
||||
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 io.github.wulkanowy.WulkanowyApp
|
||||
import io.github.wulkanowy.data.RepositoryModule
|
||||
import io.github.wulkanowy.services.ServicesModule
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
@ -12,6 +13,7 @@ import javax.inject.Singleton
|
||||
AndroidSupportInjectionModule::class,
|
||||
AppModule::class,
|
||||
RepositoryModule::class,
|
||||
ServicesModule::class,
|
||||
BuilderModule::class])
|
||||
interface AppComponent : AndroidInjector<WulkanowyApp> {
|
||||
|
||||
|
@ -2,8 +2,6 @@ package io.github.wulkanowy.di
|
||||
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.Context
|
||||
import com.firebase.jobdispatcher.FirebaseJobDispatcher
|
||||
import com.firebase.jobdispatcher.GooglePlayDriver
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
@ -30,10 +28,6 @@ internal class AppModule {
|
||||
@Provides
|
||||
fun provideFlexibleAdapter() = FlexibleAdapter<AbstractFlexibleItem<*>>(null, null, true)
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideJobDispatcher(context: Context) = FirebaseJobDispatcher(GooglePlayDriver(context))
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideFirebaseAnalyticsHelper(context: Context) = FirebaseAnalyticsHelper(FirebaseAnalytics.getInstance(context))
|
||||
|
@ -3,7 +3,6 @@ package io.github.wulkanowy.di
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
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.ui.modules.login.LoginActivity
|
||||
import io.github.wulkanowy.ui.modules.login.LoginModule
|
||||
@ -32,7 +31,4 @@ internal abstract class BuilderModule {
|
||||
|
||||
@ContributesAndroidInjector
|
||||
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 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.ErrorHandler
|
||||
import io.github.wulkanowy.utils.SchedulersProvider
|
||||
@ -12,6 +13,7 @@ import javax.inject.Inject
|
||||
class AccountPresenter @Inject constructor(
|
||||
private val errorHandler: ErrorHandler,
|
||||
private val studentRepository: StudentRepository,
|
||||
private val syncManager: SyncManager,
|
||||
private val schedulers: SchedulersProvider
|
||||
) : BasePresenter<AccountView>(errorHandler) {
|
||||
|
||||
@ -48,6 +50,7 @@ class AccountPresenter @Inject constructor(
|
||||
view?.apply {
|
||||
if (it.isEmpty()) {
|
||||
Timber.i("Logout result: Open login view")
|
||||
syncManager.stopSyncWorker()
|
||||
openClearLoginView()
|
||||
} else {
|
||||
Timber.i("Logout result: Switch to another student")
|
||||
|
@ -62,7 +62,7 @@ class GradeDetailsPresenter @Inject constructor(
|
||||
Timber.i("Select mark grades as read")
|
||||
disposable.add(studentRepository.getCurrentStudent()
|
||||
.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 } } }
|
||||
.flatMapCompletable {
|
||||
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.Companion.HIDE
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.services.notification.GradeNotification
|
||||
import io.github.wulkanowy.ui.base.BaseActivity
|
||||
import io.github.wulkanowy.ui.modules.account.AccountDialog
|
||||
import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment
|
||||
@ -164,10 +163,6 @@ class MainActivity : BaseActivity(), MainView {
|
||||
presenter.onBackPressed { super.onBackPressed() }
|
||||
}
|
||||
|
||||
override fun cancelNotifications() {
|
||||
GradeNotification(applicationContext).cancelAll()
|
||||
}
|
||||
|
||||
override fun openLoginView() {
|
||||
startActivity(LoginActivity.getStartIntent(this)
|
||||
.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 io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||
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.ErrorHandler
|
||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||
@ -17,8 +17,8 @@ class MainPresenter @Inject constructor(
|
||||
private val errorHandler: ErrorHandler,
|
||||
private val studentRepository: StudentRepository,
|
||||
private val prefRepository: PreferencesRepository,
|
||||
private val syncManager: SyncManager,
|
||||
private val schedulers: SchedulersProvider,
|
||||
private val serviceHelper: ServiceHelper,
|
||||
private val analytics: FirebaseAnalyticsHelper
|
||||
) : BasePresenter<MainView>(errorHandler) {
|
||||
|
||||
@ -26,11 +26,11 @@ class MainPresenter @Inject constructor(
|
||||
super.onAttachView(view)
|
||||
Timber.i("Main view is attached with $initMenuIndex menu index")
|
||||
view.run {
|
||||
cancelNotifications()
|
||||
startMenuIndex = if (initMenuIndex != -1) initMenuIndex else prefRepository.startMenuIndex
|
||||
initView()
|
||||
}
|
||||
serviceHelper.startFullSyncService()
|
||||
|
||||
syncManager.startSyncWorker()
|
||||
|
||||
analytics.logEvent(APP_OPEN, DESTINATION to when (initMenuIndex) {
|
||||
1 -> "Grades"
|
||||
@ -92,8 +92,7 @@ class MainPresenter @Inject constructor(
|
||||
if (it.isNotEmpty()) {
|
||||
Timber.i("Switching current student")
|
||||
studentRepository.switchStudent(it[0])
|
||||
}
|
||||
else Completable.complete()
|
||||
} else Completable.complete()
|
||||
}
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.observeOn(schedulers.mainThread)
|
||||
|
@ -26,8 +26,6 @@ interface MainView : BaseView {
|
||||
|
||||
fun popView()
|
||||
|
||||
fun cancelNotifications()
|
||||
|
||||
fun openLoginView()
|
||||
|
||||
interface MainChildView {
|
||||
|
@ -7,9 +7,9 @@ import android.view.View.INVISIBLE
|
||||
import android.view.View.VISIBLE
|
||||
import android.view.ViewGroup
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.repositories.message.MessageRepository.MessageFolder.RECEIVED
|
||||
import io.github.wulkanowy.data.repositories.message.MessageRepository.MessageFolder.SENT
|
||||
import io.github.wulkanowy.data.repositories.message.MessageRepository.MessageFolder.TRASHED
|
||||
import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED
|
||||
import io.github.wulkanowy.data.repositories.message.MessageFolder.SENT
|
||||
import io.github.wulkanowy.data.repositories.message.MessageFolder.TRASHED
|
||||
import io.github.wulkanowy.ui.base.BaseFragment
|
||||
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
||||
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.items.AbstractFlexibleItem
|
||||
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.modules.main.MainActivity
|
||||
import io.github.wulkanowy.ui.modules.message.MessageFragment
|
||||
@ -34,7 +34,7 @@ class MessageTabFragment : BaseSessionFragment(), MessageTabView, MessageView.Me
|
||||
companion object {
|
||||
const val MESSAGE_TAB_FOLDER_ID = "message_tab_folder_id"
|
||||
|
||||
fun newInstance(folder: MessageRepository.MessageFolder): MessageTabFragment {
|
||||
fun newInstance(folder: MessageFolder): MessageTabFragment {
|
||||
return MessageTabFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putString(MESSAGE_TAB_FOLDER_ID, folder.name)
|
||||
@ -56,7 +56,7 @@ class MessageTabFragment : BaseSessionFragment(), MessageTabView, MessageView.Me
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
messageContainer = messageTabRecycler
|
||||
presenter.onAttachView(this, MessageRepository.MessageFolder.valueOf(
|
||||
presenter.onAttachView(this, MessageFolder.valueOf(
|
||||
(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 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.student.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.session.BaseSessionPresenter
|
||||
@ -20,9 +21,9 @@ class MessageTabPresenter @Inject constructor(
|
||||
private val analytics: FirebaseAnalyticsHelper
|
||||
) : 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)
|
||||
view.initView()
|
||||
this.folder = folder
|
||||
|
@ -2,7 +2,7 @@ package io.github.wulkanowy.ui.modules.settings
|
||||
|
||||
import com.readystatesoftware.chuck.api.ChuckCollector
|
||||
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.ErrorHandler
|
||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||
@ -14,36 +14,25 @@ import javax.inject.Inject
|
||||
class SettingsPresenter @Inject constructor(
|
||||
errorHandler: ErrorHandler,
|
||||
private val preferencesRepository: PreferencesRepository,
|
||||
private val serviceHelper: ServiceHelper,
|
||||
private val analytics: FirebaseAnalyticsHelper,
|
||||
private val syncManager: SyncManager,
|
||||
private val chuckCollector: ChuckCollector
|
||||
) : BasePresenter<SettingsView>(errorHandler) {
|
||||
|
||||
override fun onAttachView(view: SettingsView) {
|
||||
super.onAttachView(view)
|
||||
Timber.i("Settings view is attached")
|
||||
|
||||
view.run {
|
||||
setServicesSuspended(preferencesRepository.serviceEnablesKey, now().isHolidays)
|
||||
}
|
||||
view.setServicesSuspended(preferencesRepository.serviceEnableKey, now().isHolidays)
|
||||
}
|
||||
|
||||
fun onSharedPreferenceChanged(key: String) {
|
||||
Timber.i("Change settings $key")
|
||||
when (key) {
|
||||
preferencesRepository.serviceEnablesKey -> {
|
||||
if (preferencesRepository.isServiceEnabled) serviceHelper.startFullSyncService()
|
||||
else serviceHelper.stopFullSyncService()
|
||||
}
|
||||
preferencesRepository.servicesIntervalKey,
|
||||
preferencesRepository.servicesOnlyWifiKey -> {
|
||||
serviceHelper.reloadFullSyncService()
|
||||
}
|
||||
preferencesRepository.currentThemeKey -> {
|
||||
view?.setTheme(preferencesRepository.currentTheme)
|
||||
}
|
||||
preferencesRepository.isShowChuckerNotificationKey -> {
|
||||
chuckCollector.showNotification(preferencesRepository.isShowChuckerNotification)
|
||||
preferencesRepository.apply {
|
||||
when (key) {
|
||||
serviceEnableKey -> syncManager.run { if (isServiceEnabled) startSyncWorker() else stopSyncWorker() }
|
||||
servicesIntervalKey, servicesOnlyWifiKey -> syncManager.startSyncWorker(true)
|
||||
currentThemeKey -> view?.setTheme(currentTheme)
|
||||
isShowChuckerNotificationKey -> chuckCollector.showNotification(isShowChuckerNotification)
|
||||
}
|
||||
}
|
||||
analytics.logEvent("setting_changed", "name" to key)
|
||||
|
@ -3,13 +3,18 @@ package io.github.wulkanowy.utils
|
||||
import android.content.Context
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.core.content.ContextCompat
|
||||
|
||||
@ColorInt
|
||||
fun Context.getThemeAttrColor(@AttrRes colorAttr: Int): Int {
|
||||
val array = this.obtainStyledAttributes(null, intArrayOf(colorAttr))
|
||||
try {
|
||||
return array.getColor(0, 0)
|
||||
val array = obtainStyledAttributes(null, intArrayOf(colorAttr))
|
||||
return try {
|
||||
array.getColor(0, 0)
|
||||
} finally {
|
||||
array.recycle()
|
||||
}
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
fun Context.getCompatColor(@ColorRes colorRes: Int) = ContextCompat.getColor(this, colorRes)
|
||||
|
@ -16,8 +16,8 @@
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginEnd="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
|
||||
android:id="@+id/loginItemName"
|
||||
|
@ -1,6 +1,7 @@
|
||||
<resources>
|
||||
<string name="app_name">Wulkanowy</string>
|
||||
|
||||
|
||||
<!--Activity/Fragment title-->
|
||||
<string name="login_title">Wybierz ucznia</string>
|
||||
<string name="main_title">Wulkanowy</string>
|
||||
@ -70,17 +71,12 @@
|
||||
<item quantity="many">%d ocen</item>
|
||||
<item quantity="other">%d ocen</item>
|
||||
</plurals>
|
||||
|
||||
<plurals name="grade_new_items">
|
||||
<item quantity="one">Nowa ocena</item>
|
||||
<item quantity="few">Nowe oceny</item>
|
||||
<item quantity="many">Nowe oceny</item>
|
||||
</plurals>
|
||||
|
||||
|
||||
<!--Grade notify-->
|
||||
<string name="notify_grade_channel">Nowe oceny</string>
|
||||
<plurals name="notify_grade_new_items">
|
||||
<plurals name="grade_notify_new_items">
|
||||
<item quantity="one">Dostałeś %1$d ocenę</item>
|
||||
<item quantity="few">"Dostałeś %1$d oceny</item>
|
||||
<item quantity="many">Dostałeś %1$d ocen</item>
|
||||
@ -88,16 +84,6 @@
|
||||
</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-->
|
||||
<string name="timetable_lesson">Lekcja</string>
|
||||
<string name="timetable_room">Sala</string>
|
||||
@ -106,6 +92,7 @@
|
||||
<string name="timetable_changes">Zmiany</string>
|
||||
<string name="timetable_no_items">Brak lekcji w tym dniu</string>
|
||||
|
||||
|
||||
<!--CompletedLesson-->
|
||||
<string name="completed_lessons_title">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_resources">Zasoby</string>
|
||||
|
||||
|
||||
<!--Attendance-->
|
||||
<string name="attendance_summary_button">Podsumowanie frekwencji</string>
|
||||
<string name="attendance_absence_school">Nieobecny z przyczyn szkolnych</string>
|
||||
@ -131,9 +119,11 @@
|
||||
<item quantity="many">%1$d nieobecności</item>
|
||||
</plurals>
|
||||
|
||||
|
||||
<!--Attendance summary-->
|
||||
<string name="attendance_summary_final">Frekwencja</string>
|
||||
|
||||
|
||||
<!--Exam-->
|
||||
<string name="exam_no_items">Brak sprawdzianów w tym tygodniu</string>
|
||||
<string name="exam_type">Typ</string>
|
||||
@ -155,17 +145,12 @@
|
||||
<item quantity="few">%d wiadomości</item>
|
||||
<item quantity="many">%d wiadomości</item>
|
||||
</plurals>
|
||||
|
||||
<plurals name="message_new_items">
|
||||
<item quantity="one">Nowa wiadomość</item>
|
||||
<item quantity="few">Nowe wiadomości</item>
|
||||
<item quantity="many">Nowe wiadomości</item>
|
||||
</plurals>
|
||||
|
||||
|
||||
<!--Message notify-->
|
||||
<string name="notify_message_channel">Nowe wiadomości</string>
|
||||
<plurals name="notify_message_new_items">
|
||||
<plurals name="message_notify_new_items">
|
||||
<item quantity="one">Dostałeś %1$d wiadomość</item>
|
||||
<item quantity="few">"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_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-->
|
||||
<string name="note_no_items">Brak informacji o uwagach</string>
|
||||
@ -193,27 +175,31 @@
|
||||
<item quantity="many">%d uwag</item>
|
||||
<item quantity="other">%d uwag</item>
|
||||
</plurals>
|
||||
|
||||
<plurals name="note_new_items">
|
||||
<item quantity="one">Nowa uwaga</item>
|
||||
<item quantity="few">Nowe uwagi</item>
|
||||
<item quantity="many">Nowych uwag</item>
|
||||
<item quantity="other">Nowych uwag</item>
|
||||
</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-->
|
||||
<string name="homework_no_items">Brak zadań domowych</string>
|
||||
|
||||
|
||||
<!--Lucky number-->
|
||||
<string name="lucky_number_title">Szczęśliwy numerek</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_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-->
|
||||
<string name="account_add_new">Dodaj konto</string>
|
||||
@ -222,6 +208,11 @@
|
||||
<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-->
|
||||
<string name="all_content">Treść</string>
|
||||
<string name="all_description">Opis</string>
|
||||
@ -267,6 +258,10 @@
|
||||
<string name="pref_services_wifi">Tylko WiFi</string>
|
||||
|
||||
|
||||
<!--Notification Channels-->
|
||||
<string name="channel_new_entries">Nowe wpisy w dzienniku</string>
|
||||
|
||||
|
||||
<!--Colors-->
|
||||
<string name="all_black">Czarny</string>
|
||||
<string name="all_red">Czerwony</string>
|
||||
@ -279,6 +274,7 @@
|
||||
<!--Others-->
|
||||
<string name="all_copied">Skopiowano</string>
|
||||
|
||||
|
||||
<!--Errors-->
|
||||
<string name="error_no_internet">Brak połączenia z internetem</string>
|
||||
<string name="error_timeout">Zbyt długie oczekiwanie na połączenie</string>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<resources>
|
||||
<string name="app_name">Wulkanowy</string>
|
||||
|
||||
|
||||
<!--Activity/Fragment title-->
|
||||
<string name="login_title">Select student</string>
|
||||
<string name="main_title">Wulkanowy</string>
|
||||
@ -68,26 +69,15 @@
|
||||
<item quantity="one">%d grade</item>
|
||||
<item quantity="other">%d grades</item>
|
||||
</plurals>
|
||||
|
||||
<plurals name="grade_new_items">
|
||||
<item quantity="one">New grade</item>
|
||||
<item quantity="other">New grades</item>
|
||||
</plurals>
|
||||
|
||||
<!--Grade notify-->
|
||||
<string name="notify_grade_channel">New grades</string>
|
||||
<plurals name="notify_grade_new_items">
|
||||
<plurals name="grade_notify_new_items">
|
||||
<item quantity="one">You received %1$d grade</item>
|
||||
<item quantity="other">You received %1$d grades</item>
|
||||
</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-->
|
||||
<string name="timetable_lesson">Lesson</string>
|
||||
@ -97,6 +87,7 @@
|
||||
<string name="timetable_changes">Changes</string>
|
||||
<string name="timetable_no_items">No lessons this day</string>
|
||||
|
||||
|
||||
<!--Completed lessons-->
|
||||
<string name="completed_lessons_title">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_resources">Resources</string>
|
||||
|
||||
|
||||
<!--Attendance-->
|
||||
<string name="attendance_summary_button">Attendance summary</string>
|
||||
<string name="attendance_absence_school">Absent for school reasons</string>
|
||||
@ -121,6 +113,7 @@
|
||||
<item quantity="other">%1$d absences</item>
|
||||
</plurals>
|
||||
|
||||
|
||||
<!--Attendance summary-->
|
||||
<string name="attendance_summary_final">Attendance</string>
|
||||
|
||||
@ -145,15 +138,11 @@
|
||||
<item quantity="one">%d message</item>
|
||||
<item quantity="other">%d messages</item>
|
||||
</plurals>
|
||||
|
||||
<plurals name="message_new_items">
|
||||
<item quantity="one">New message</item>
|
||||
<item quantity="other">New messages</item>
|
||||
</plurals>
|
||||
|
||||
<!--Message notify-->
|
||||
<string name="notify_message_channel">New messages</string>
|
||||
<plurals name="notify_message_new_items">
|
||||
<plurals name="message_notify_new_items">
|
||||
<item quantity="one">You received %1$d message</item>
|
||||
<item quantity="other">You received %1$d messages</item>
|
||||
</plurals>
|
||||
@ -168,9 +157,6 @@
|
||||
<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>
|
||||
|
||||
<!--About-->
|
||||
<string name="about_source_code">Source code</string>
|
||||
<string name="about_feedback">Report a bug</string>
|
||||
|
||||
<!--Note-->
|
||||
<string name="note_no_items">No info about notes</string>
|
||||
@ -178,25 +164,27 @@
|
||||
<item quantity="one">%d note</item>
|
||||
<item quantity="other">%d notes</item>
|
||||
</plurals>
|
||||
|
||||
<plurals name="note_new_items">
|
||||
<item quantity="one">New note</item>
|
||||
<item quantity="other">New notes</item>
|
||||
</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-->
|
||||
<string name="homework_no_items">No info about homework</string>
|
||||
|
||||
|
||||
<!--Lucky number-->
|
||||
<string name="lucky_number_title">Lucky number</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_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-->
|
||||
<string name="account_add_new">Add account</string>
|
||||
@ -205,6 +193,11 @@
|
||||
<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-->
|
||||
<string name="all_content">Content</string>
|
||||
<string name="all_description">Description</string>
|
||||
@ -250,6 +243,10 @@
|
||||
<string name="pref_services_wifi">Wi-Fi only</string>
|
||||
|
||||
|
||||
<!--Notification Channels-->
|
||||
<string name="channel_new_entries">New entries in register</string>
|
||||
|
||||
|
||||
<!--Colors-->
|
||||
<string name="all_black">Black</string>
|
||||
<string name="all_red">Red</string>
|
||||
@ -262,6 +259,7 @@
|
||||
<!--Others-->
|
||||
<string name="all_copied">Copied</string>
|
||||
|
||||
|
||||
<!--Errors-->
|
||||
<string name="error_no_internet">No internet 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.data.repositories.preferences.PreferencesRepository
|
||||
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.utils.FirebaseAnalyticsHelper
|
||||
import org.junit.Before
|
||||
@ -25,7 +25,7 @@ class MainPresenterTest {
|
||||
lateinit var prefRepository: PreferencesRepository
|
||||
|
||||
@Mock
|
||||
lateinit var serviceHelper: ServiceHelper
|
||||
lateinit var syncManager: SyncManager
|
||||
|
||||
@Mock
|
||||
lateinit var mainView: MainView
|
||||
@ -40,7 +40,7 @@ class MainPresenterTest {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
clearInvocations(mainView)
|
||||
|
||||
presenter = MainPresenter(errorHandler, studentRepository, prefRepository, TestSchedulersProvider(), serviceHelper, analytics)
|
||||
presenter = MainPresenter(errorHandler, studentRepository, prefRepository, syncManager, TestSchedulersProvider(), analytics)
|
||||
presenter.onAttachView(mainView, -1)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user