mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2025-01-31 13:18:20 +01:00
Mark as read items older than student registration date (#253)
This commit is contained in:
parent
c365564a77
commit
82d7cf94e8
@ -12,6 +12,7 @@ import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.threeten.bp.LocalDateTime.now
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@ -39,7 +40,7 @@ class StudentLocalTest {
|
||||
|
||||
@Test
|
||||
fun saveAndReadTest() {
|
||||
studentLocal.saveStudent(Student(email = "test", password = "test123", schoolSymbol = "23", endpoint = "fakelog.cf", loginType = "AUTO", isCurrent = true, studentName = "", schoolName = "", studentId = 0, symbol = ""))
|
||||
studentLocal.saveStudent(Student(email = "test", password = "test123", schoolSymbol = "23", endpoint = "fakelog.cf", loginType = "AUTO", isCurrent = true, studentName = "", schoolName = "", studentId = 0, symbol = "", registrationDate = now()))
|
||||
.blockingGet()
|
||||
|
||||
val student = studentLocal.getCurrentStudent(true).blockingGet()
|
||||
|
@ -8,6 +8,7 @@ import androidx.room.RoomDatabase.JournalMode.TRUNCATE
|
||||
import androidx.room.TypeConverters
|
||||
import io.github.wulkanowy.data.db.dao.AttendanceDao
|
||||
import io.github.wulkanowy.data.db.dao.AttendanceSummaryDao
|
||||
import io.github.wulkanowy.data.db.dao.CompletedLessonsDao
|
||||
import io.github.wulkanowy.data.db.dao.ExamDao
|
||||
import io.github.wulkanowy.data.db.dao.GradeDao
|
||||
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
|
||||
@ -15,13 +16,13 @@ import io.github.wulkanowy.data.db.dao.HomeworkDao
|
||||
import io.github.wulkanowy.data.db.dao.LuckyNumberDao
|
||||
import io.github.wulkanowy.data.db.dao.MessagesDao
|
||||
import io.github.wulkanowy.data.db.dao.NoteDao
|
||||
import io.github.wulkanowy.data.db.dao.CompletedLessonsDao
|
||||
import io.github.wulkanowy.data.db.dao.SemesterDao
|
||||
import io.github.wulkanowy.data.db.dao.StudentDao
|
||||
import io.github.wulkanowy.data.db.dao.SubjectDao
|
||||
import io.github.wulkanowy.data.db.dao.TimetableDao
|
||||
import io.github.wulkanowy.data.db.entities.Attendance
|
||||
import io.github.wulkanowy.data.db.entities.AttendanceSummary
|
||||
import io.github.wulkanowy.data.db.entities.CompletedLesson
|
||||
import io.github.wulkanowy.data.db.entities.Exam
|
||||
import io.github.wulkanowy.data.db.entities.Grade
|
||||
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||
@ -29,7 +30,6 @@ import io.github.wulkanowy.data.db.entities.Homework
|
||||
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.Note
|
||||
import io.github.wulkanowy.data.db.entities.CompletedLesson
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.db.entities.Subject
|
||||
@ -37,6 +37,7 @@ import io.github.wulkanowy.data.db.entities.Timetable
|
||||
import io.github.wulkanowy.data.db.migrations.Migration2
|
||||
import io.github.wulkanowy.data.db.migrations.Migration3
|
||||
import io.github.wulkanowy.data.db.migrations.Migration4
|
||||
import io.github.wulkanowy.data.db.migrations.Migration5
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
@ -57,22 +58,25 @@ import javax.inject.Singleton
|
||||
LuckyNumber::class,
|
||||
CompletedLesson::class
|
||||
],
|
||||
version = 4,
|
||||
version = AppDatabase.VERSION_SCHEMA,
|
||||
exportSchema = false
|
||||
)
|
||||
@TypeConverters(Converters::class)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
companion object {
|
||||
const val VERSION_SCHEMA = 5
|
||||
|
||||
fun newInstance(context: Context): AppDatabase {
|
||||
return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database")
|
||||
.setJournalMode(TRUNCATE)
|
||||
.fallbackToDestructiveMigrationFrom(5)
|
||||
.fallbackToDestructiveMigrationFrom(VERSION_SCHEMA + 1)
|
||||
.fallbackToDestructiveMigrationOnDowngrade()
|
||||
.addMigrations(
|
||||
Migration2(),
|
||||
Migration3(),
|
||||
Migration4()
|
||||
Migration4(),
|
||||
Migration5()
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
@ -25,9 +25,9 @@ interface NoteDao {
|
||||
@Delete
|
||||
fun deleteAll(notes: List<Note>)
|
||||
|
||||
@Query("SELECT * FROM Notes WHERE semester_id = :semesterId AND student_id = :studentId")
|
||||
fun loadAll(semesterId: Int, studentId: Int): Maybe<List<Note>>
|
||||
@Query("SELECT * FROM Notes WHERE student_id = :studentId")
|
||||
fun loadAll(studentId: Int): Maybe<List<Note>>
|
||||
|
||||
@Query("SELECT * FROM Notes WHERE is_read = 0 AND semester_id = :semesterId AND student_id = :studentId")
|
||||
fun loadNew(semesterId: Int, studentId: Int): Maybe<List<Note>>
|
||||
@Query("SELECT * FROM Notes WHERE is_read = 0 AND student_id = :studentId")
|
||||
fun loadNew(studentId: Int): Maybe<List<Note>>
|
||||
}
|
||||
|
@ -9,9 +9,6 @@ import java.io.Serializable
|
||||
@Entity(tableName = "Notes")
|
||||
data class Note(
|
||||
|
||||
@ColumnInfo(name = "semester_id")
|
||||
val semesterId: Int,
|
||||
|
||||
@ColumnInfo(name = "student_id")
|
||||
val studentId: Int,
|
||||
|
||||
|
@ -4,6 +4,7 @@ import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
import org.threeten.bp.LocalDateTime
|
||||
import java.io.Serializable
|
||||
|
||||
@Entity(tableName = "Students", indices = [Index(value = ["email", "symbol", "student_id", "school_id"], unique = true)])
|
||||
@ -32,7 +33,10 @@ data class Student(
|
||||
val schoolName: String,
|
||||
|
||||
@ColumnInfo(name = "is_current")
|
||||
val isCurrent: Boolean
|
||||
val isCurrent: Boolean,
|
||||
|
||||
@ColumnInfo(name = "registration_date")
|
||||
val registrationDate: LocalDateTime
|
||||
) : Serializable {
|
||||
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
|
@ -0,0 +1,24 @@
|
||||
package io.github.wulkanowy.data.db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import org.threeten.bp.LocalDateTime.now
|
||||
import org.threeten.bp.ZoneOffset
|
||||
|
||||
class Migration5 : Migration(4, 5) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE Students ADD COLUMN `registration_date` INTEGER NOT NULL DEFAULT 0")
|
||||
database.execSQL("UPDATE Students SET `registration_date` = '${now().atZone(ZoneOffset.UTC).toInstant().toEpochMilli()}'")
|
||||
database.execSQL("DROP TABLE IF EXISTS `Notes`")
|
||||
database.execSQL("CREATE TABLE IF NOT EXISTS `Notes` (" +
|
||||
"`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
|
||||
"`is_read` INTEGER NOT NULL," +
|
||||
"`is_notified` INTEGER NOT NULL," +
|
||||
"`student_id` INTEGER NOT NULL," +
|
||||
"`date` INTEGER NOT NULL," +
|
||||
"`teacher` TEXT NOT NULL," +
|
||||
"`category` TEXT NOT NULL," +
|
||||
"`content` TEXT NOT NULL)")
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||
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.reactivex.Completable
|
||||
import io.reactivex.Single
|
||||
import java.net.UnknownHostException
|
||||
@ -17,7 +18,7 @@ class GradeRepository @Inject constructor(
|
||||
private val remote: GradeRemote
|
||||
) {
|
||||
|
||||
fun getGrades(semester: Semester, forceRefresh: Boolean = false, notify: Boolean = false): Single<List<Grade>> {
|
||||
fun getGrades(student: Student, semester: Semester, forceRefresh: Boolean = false, notify: Boolean = false): Single<List<Grade>> {
|
||||
return local.getGrades(semester).filter { !forceRefresh }
|
||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||
.flatMap {
|
||||
@ -29,8 +30,10 @@ class GradeRepository @Inject constructor(
|
||||
local.deleteGrades(oldGrades - newGrades)
|
||||
local.saveGrades((newGrades - oldGrades)
|
||||
.onEach {
|
||||
if (oldGrades.isNotEmpty()) it.isRead = false
|
||||
if (notify) it.isNotified = false
|
||||
if (student.registrationDate <= it.date.atStartOfDay()) {
|
||||
if (notify) it.isNotified = false
|
||||
it.isRead = false
|
||||
}
|
||||
})
|
||||
}
|
||||
}.flatMap { local.getGrades(semester).toSingle(emptyList()) })
|
||||
|
@ -2,7 +2,7 @@ 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.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Maybe
|
||||
import javax.inject.Inject
|
||||
@ -11,12 +11,12 @@ import javax.inject.Singleton
|
||||
@Singleton
|
||||
class NoteLocal @Inject constructor(private val noteDb: NoteDao) {
|
||||
|
||||
fun getNotes(semester: Semester): Maybe<List<Note>> {
|
||||
return noteDb.loadAll(semester.semesterId, semester.studentId).filter { !it.isEmpty() }
|
||||
fun getNotes(student: Student): Maybe<List<Note>> {
|
||||
return noteDb.loadAll(student.studentId).filter { !it.isEmpty() }
|
||||
}
|
||||
|
||||
fun getNewNotes(semester: Semester): Maybe<List<Note>> {
|
||||
return noteDb.loadNew(semester.semesterId, semester.studentId)
|
||||
fun getNewNotes(student: Student): Maybe<List<Note>> {
|
||||
return noteDb.loadNew(student.studentId)
|
||||
}
|
||||
|
||||
fun saveNotes(notes: List<Note>) {
|
||||
|
@ -17,7 +17,6 @@ class NoteRemote @Inject constructor(private val api: Api) {
|
||||
.map { notes ->
|
||||
notes.map {
|
||||
Note(
|
||||
semesterId = semester.semesterId,
|
||||
studentId = semester.studentId,
|
||||
date = it.date.toLocalDate(),
|
||||
teacher = it.teacher,
|
||||
|
@ -4,6 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||
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.reactivex.Completable
|
||||
import io.reactivex.Single
|
||||
import java.net.UnknownHostException
|
||||
@ -17,27 +18,29 @@ class NoteRepository @Inject constructor(
|
||||
private val remote: NoteRemote
|
||||
) {
|
||||
|
||||
fun getNotes(semester: Semester, forceRefresh: Boolean = false, notify: Boolean = false): Single<List<Note>> {
|
||||
return local.getNotes(semester).filter { !forceRefresh }
|
||||
fun getNotes(student: Student, semester: Semester, forceRefresh: Boolean = false, notify: Boolean = false): Single<List<Note>> {
|
||||
return local.getNotes(student).filter { !forceRefresh }
|
||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||
.flatMap {
|
||||
if (it) remote.getNotes(semester)
|
||||
else Single.error(UnknownHostException())
|
||||
}.flatMap { new ->
|
||||
local.getNotes(semester).toSingle(emptyList())
|
||||
local.getNotes(student).toSingle(emptyList())
|
||||
.doOnSuccess { old ->
|
||||
local.deleteNotes(old - new)
|
||||
local.saveNotes((new - old)
|
||||
.onEach {
|
||||
if (notify) it.isNotified = false
|
||||
if (student.registrationDate <= it.date.atStartOfDay()) {
|
||||
if (notify) it.isNotified = false
|
||||
it.isRead = false
|
||||
}
|
||||
})
|
||||
}
|
||||
}.flatMap { local.getNotes(semester).toSingle(emptyList()) }
|
||||
)
|
||||
}.flatMap { local.getNotes(student).toSingle(emptyList()) })
|
||||
}
|
||||
|
||||
fun getNewNotes(semester: Semester): Single<List<Note>> {
|
||||
return local.getNewNotes(semester).toSingle(emptyList())
|
||||
fun getNewNotes(student: Student): Single<List<Note>> {
|
||||
return local.getNewNotes(student).toSingle(emptyList())
|
||||
}
|
||||
|
||||
fun updateNote(note: Note): Completable {
|
||||
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.student
|
||||
import io.github.wulkanowy.api.Api
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.reactivex.Single
|
||||
import org.threeten.bp.LocalDateTime.now
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@ -22,7 +23,8 @@ class StudentRemote @Inject constructor(private val api: Api) {
|
||||
schoolName = student.schoolName,
|
||||
endpoint = endpoint,
|
||||
loginType = student.loginType.name,
|
||||
isCurrent = false
|
||||
isCurrent = false,
|
||||
registrationDate = now()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -101,13 +101,13 @@ class SyncWorker : SimpleJobService() {
|
||||
.flatMapCompletable {
|
||||
Completable.merge(
|
||||
listOf(
|
||||
gradesDetails.getGrades(it.first, true, notify).ignoreElement(),
|
||||
gradesDetails.getGrades(it.second, it.first, true, notify).ignoreElement(),
|
||||
gradesSummary.getGradesSummary(it.first, true).ignoreElement(),
|
||||
attendance.getAttendance(it.first, start, end, true).ignoreElement(),
|
||||
exam.getExams(it.first, start, end, true).ignoreElement(),
|
||||
timetable.getTimetable(it.first, start, end, true).ignoreElement(),
|
||||
message.getMessages(it.second, RECEIVED, true, notify).ignoreElement(),
|
||||
note.getNotes(it.first, true, notify).ignoreElement(),
|
||||
note.getNotes(it.second, it.first, true, notify).ignoreElement(),
|
||||
homework.getHomework(it.first, LocalDate.now(), true).ignoreElement(),
|
||||
homework.getHomework(it.first, LocalDate.now().plusDays(1), true).ignoreElement(),
|
||||
luckyNumber.getLuckyNumber(it.first, true, notify).ignoreElement(),
|
||||
@ -168,7 +168,6 @@ class SyncWorker : SimpleJobService() {
|
||||
|
||||
private fun sendNoteNotification() {
|
||||
disposable.add(student.getCurrentStudent()
|
||||
.flatMap { semester.getCurrentSemester(it) }
|
||||
.flatMap { note.getNewNotes(it) }
|
||||
.map { it.filter { note -> !note.isNotified } }
|
||||
.doOnSuccess {
|
||||
|
@ -108,8 +108,8 @@ class GradeDetailsPresenter @Inject constructor(
|
||||
private fun loadData(semesterId: Int, forceRefresh: Boolean) {
|
||||
Timber.i("Loading grade details data started")
|
||||
disposable.add(studentRepository.getCurrentStudent()
|
||||
.flatMap { semesterRepository.getSemesters(it) }
|
||||
.flatMap { gradeRepository.getGrades(it.first { item -> item.semesterId == semesterId }, forceRefresh) }
|
||||
.flatMap { semesterRepository.getSemesters(it).map { semester -> semester to it } }
|
||||
.flatMap { gradeRepository.getGrades(it.second, it.first.first { item -> item.semesterId == semesterId }, forceRefresh) }
|
||||
.map { it.sortedByDescending { grade -> grade.date } }
|
||||
.map { it.map { item -> item.changeModifier(preferencesRepository.gradePlusModifier, preferencesRepository.gradeMinusModifier) } }
|
||||
.map { createGradeItems(it.groupBy { grade -> grade.subject }.toSortedMap()) }
|
||||
|
@ -36,12 +36,12 @@ class GradeSummaryPresenter @Inject constructor(
|
||||
fun onParentViewLoadData(semesterId: Int, forceRefresh: Boolean) {
|
||||
Timber.i("Loading grade summary data started")
|
||||
disposable.add(studentRepository.getCurrentStudent()
|
||||
.flatMap { semesterRepository.getSemesters(it) }
|
||||
.map { semester -> semester.first { it.semesterId == semesterId } }
|
||||
.flatMap { semesterRepository.getSemesters(it).map { semester -> semester to it } }
|
||||
.map { pair -> pair.first.first { it.semesterId == semesterId } to pair.second }
|
||||
.flatMap {
|
||||
gradeSummaryRepository.getGradesSummary(it, forceRefresh)
|
||||
gradeSummaryRepository.getGradesSummary(it.first, forceRefresh)
|
||||
.flatMap { gradesSummary ->
|
||||
gradeRepository.getGrades(it, forceRefresh)
|
||||
gradeRepository.getGrades(it.second, it.first, forceRefresh)
|
||||
.map { grades ->
|
||||
grades.map { item -> item.changeModifier(preferencesRepository.gradePlusModifier, preferencesRepository.gradeMinusModifier) }
|
||||
.groupBy { grade -> grade.subject }
|
||||
|
@ -36,8 +36,8 @@ class NotePresenter @Inject constructor(
|
||||
private fun loadData(forceRefresh: Boolean = false) {
|
||||
Timber.i("Loading note data started")
|
||||
disposable.add(studentRepository.getCurrentStudent()
|
||||
.flatMap { semesterRepository.getCurrentSemester(it) }
|
||||
.flatMap { noteRepository.getNotes(it, forceRefresh) }
|
||||
.flatMap { semesterRepository.getCurrentSemester(it).map { semester -> semester to it } }
|
||||
.flatMap { noteRepository.getNotes(it.second, it.first, forceRefresh) }
|
||||
.map { items -> items.map { NoteItem(it) } }
|
||||
.map { items -> items.sortedByDescending { it.note.date } }
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
|
@ -16,6 +16,7 @@ import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.times
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.threeten.bp.LocalDateTime.now
|
||||
|
||||
class LoginFormPresenterTest {
|
||||
|
||||
@ -75,7 +76,7 @@ class LoginFormPresenterTest {
|
||||
|
||||
@Test
|
||||
fun loginTest() {
|
||||
val studentTest = Student(email = "test@", password = "123", endpoint = "https://fakelog.cf", loginType = "AUTO", studentName = "", schoolSymbol = "", schoolName = "", studentId = 0, isCurrent = false, symbol = "")
|
||||
val studentTest = Student(email = "test@", password = "123", endpoint = "https://fakelog.cf", loginType = "AUTO", studentName = "", schoolSymbol = "", schoolName = "", studentId = 0, isCurrent = false, symbol = "", registrationDate = now())
|
||||
doReturn(Single.just(listOf(studentTest)))
|
||||
.`when`(repository).getStudents(anyString(), anyString(), anyString(), anyString())
|
||||
presenter.attemptLogin("@", "123456", "https://fakelog.cf")
|
||||
|
@ -16,6 +16,7 @@ import org.mockito.Mockito.clearInvocations
|
||||
import org.mockito.Mockito.doReturn
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.threeten.bp.LocalDateTime.now
|
||||
|
||||
class LoginStudentSelectPresenterTest {
|
||||
|
||||
@ -36,7 +37,7 @@ class LoginStudentSelectPresenterTest {
|
||||
|
||||
private lateinit var presenter: LoginStudentSelectPresenter
|
||||
|
||||
private val testStudent by lazy { Student(email = "test", password = "test123", endpoint = "https://fakelog.cf", loginType = "AUTO", symbol = "", isCurrent = false, studentId = 0, schoolName = "", schoolSymbol = "", studentName = "") }
|
||||
private val testStudent by lazy { Student(email = "test", password = "test123", endpoint = "https://fakelog.cf", loginType = "AUTO", symbol = "", isCurrent = false, studentId = 0, schoolName = "", schoolSymbol = "", studentName = "", registrationDate = now()) }
|
||||
|
||||
private val testException by lazy { RuntimeException("Problem") }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user