forked from github/wulkanowy-mirror
Refactor exam module (#157)
This commit is contained in:
parent
b617957891
commit
a1f64baca4
@ -8,8 +8,8 @@ apply from: 'sonarqube.gradle'
|
|||||||
apply plugin: 'com.github.triplet.play'
|
apply plugin: 'com.github.triplet.play'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 27
|
compileSdkVersion 28
|
||||||
buildToolsVersion '27.0.3'
|
buildToolsVersion '28.0.2'
|
||||||
|
|
||||||
playAccountConfigs {
|
playAccountConfigs {
|
||||||
defaultAccountConfig {
|
defaultAccountConfig {
|
||||||
@ -22,7 +22,7 @@ android {
|
|||||||
applicationId "io.github.wulkanowy"
|
applicationId "io.github.wulkanowy"
|
||||||
testApplicationId "io.github.tests.wulkanowy"
|
testApplicationId "io.github.tests.wulkanowy"
|
||||||
minSdkVersion 15
|
minSdkVersion 15
|
||||||
targetSdkVersion 27
|
targetSdkVersion 28
|
||||||
versionCode 16
|
versionCode 16
|
||||||
versionName "0.5.2"
|
versionName "0.5.2"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
@ -68,11 +68,11 @@ play {
|
|||||||
uploadImages = true
|
uploadImages = true
|
||||||
}
|
}
|
||||||
|
|
||||||
ext.supportVersion = "27.1.1"
|
ext.supportVersion = "28.0.0-rc02"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
implementation 'com.github.wulkanowy:api:88ede83149'
|
implementation 'com.github.wulkanowy:api:ad57669'
|
||||||
|
|
||||||
implementation "com.android.support:support-v4:$supportVersion"
|
implementation "com.android.support:support-v4:$supportVersion"
|
||||||
implementation "com.android.support:design:$supportVersion"
|
implementation "com.android.support:design:$supportVersion"
|
||||||
@ -98,7 +98,7 @@ dependencies {
|
|||||||
|
|
||||||
implementation 'com.github.pwittchen:reactivenetwork-rx2:2.1.0'
|
implementation 'com.github.pwittchen:reactivenetwork-rx2:2.1.0'
|
||||||
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
|
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
|
||||||
implementation "io.reactivex.rxjava2:rxjava:2.2.0"
|
implementation "io.reactivex.rxjava2:rxjava:2.2.1"
|
||||||
|
|
||||||
implementation "org.apache.commons:commons-lang3:3.8"
|
implementation "org.apache.commons:commons-lang3:3.8"
|
||||||
implementation "org.apache.commons:commons-collections4:4.2"
|
implementation "org.apache.commons:commons-collections4:4.2"
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
package io.github.wulkanowy.data.repositories.local
|
||||||
|
|
||||||
|
import android.arch.persistence.room.Room
|
||||||
|
import android.support.test.InstrumentationRegistry
|
||||||
|
import android.support.test.runner.AndroidJUnit4
|
||||||
|
import io.github.wulkanowy.data.db.AppDatabase
|
||||||
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.threeten.bp.LocalDate
|
||||||
|
import java.sql.Date
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class ExamLocalTest {
|
||||||
|
|
||||||
|
private lateinit var examLocal: ExamLocal
|
||||||
|
|
||||||
|
private lateinit var testDb: AppDatabase
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun createDb() {
|
||||||
|
testDb = Room.inMemoryDatabaseBuilder(InstrumentationRegistry.getContext(), AppDatabase::class.java).build()
|
||||||
|
examLocal = ExamLocal(testDb.examsDao())
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun closeDb() {
|
||||||
|
testDb.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun saveAndReadTest() {
|
||||||
|
examLocal.saveExams(listOf(
|
||||||
|
Exam(studentId = "1", diaryId = "2", date = Date.valueOf("2018-09-10")),
|
||||||
|
Exam(studentId = "1", diaryId = "2", date = Date.valueOf("2018-09-14")),
|
||||||
|
Exam(studentId = "1", diaryId = "2", date = Date.valueOf("2018-09-17")) // in next week
|
||||||
|
))
|
||||||
|
|
||||||
|
val exams = examLocal
|
||||||
|
.getExams(Semester(studentId = "1", diaryId = "2", semesterId = "3"), LocalDate.of(2018, 9, 10))
|
||||||
|
.blockingGet()
|
||||||
|
assertEquals(2, exams.size)
|
||||||
|
assertEquals(exams[0].date, Date.valueOf("2018-09-10"))
|
||||||
|
assertEquals(exams[1].date, Date.valueOf("2018-09-14"))
|
||||||
|
}
|
||||||
|
}
|
@ -14,9 +14,9 @@ import org.junit.runner.RunWith
|
|||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
class StudentLocalTest {
|
class SessionLocalTest {
|
||||||
|
|
||||||
private lateinit var studentLocal: StudentLocal
|
private lateinit var studentLocal: SessionLocal
|
||||||
|
|
||||||
private lateinit var testDb: AppDatabase
|
private lateinit var testDb: AppDatabase
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ class StudentLocalTest {
|
|||||||
testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
|
testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
|
||||||
.build()
|
.build()
|
||||||
sharedHelper = SharedPrefHelper(context.getSharedPreferences("TEST", Context.MODE_PRIVATE))
|
sharedHelper = SharedPrefHelper(context.getSharedPreferences("TEST", Context.MODE_PRIVATE))
|
||||||
studentLocal = StudentLocal(testDb.studentDao(), sharedHelper, context)
|
studentLocal = SessionLocal(testDb.studentDao(), testDb.semesterDao(), sharedHelper, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@ -38,12 +38,12 @@ class StudentLocalTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun saveAndReadTest() {
|
fun saveAndReadTest() {
|
||||||
studentLocal.save(Student(email = "test", password = "test123", schoolId = "23")).blockingAwait()
|
studentLocal.saveStudent(Student(email = "test", password = "test123", schoolId = "23")).blockingAwait()
|
||||||
assert(sharedHelper.getLong(StudentLocal.CURRENT_USER_KEY, 0) == 1L)
|
assert(sharedHelper.getLong(SessionLocal.LAST_USER_KEY, 0) == 1L)
|
||||||
|
|
||||||
assert(studentLocal.isStudentLoggedIn)
|
assert(studentLocal.isSessionSaved)
|
||||||
|
|
||||||
val student = studentLocal.getCurrentStudent().blockingGet()
|
val student = studentLocal.getLastStudent().blockingGet()
|
||||||
assertEquals("23", student.schoolId)
|
assertEquals("23", student.schoolId)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
package="io.github.wulkanowy"
|
package="io.github.wulkanowy"
|
||||||
android:installLocation="internalOnly">
|
android:installLocation="internalOnly">
|
||||||
|
|
||||||
@ -13,7 +14,9 @@
|
|||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:theme="@style/WulkanowyTheme">
|
android:theme="@style/WulkanowyTheme"
|
||||||
|
android:usesCleartextTraffic="true"
|
||||||
|
tools:targetApi="m">
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.splash.SplashActivity"
|
android:name=".ui.splash.SplashActivity"
|
||||||
android:configChanges="orientation|screenSize"
|
android:configChanges="orientation|screenSize"
|
||||||
|
@ -32,6 +32,9 @@ internal class RepositoryModule {
|
|||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun provideErrorHandler(context: Context) = ErrorHandler(context.resources)
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
fun provideSharedPref(context: Context): SharedPreferences {
|
fun provideSharedPref(context: Context): SharedPreferences {
|
||||||
@ -41,4 +44,12 @@ internal class RepositoryModule {
|
|||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
fun provideStudentDao(database: AppDatabase) = database.studentDao()
|
fun provideStudentDao(database: AppDatabase) = database.studentDao()
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
fun provideSemesterDao(database: AppDatabase) = database.semesterDao()
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
fun provideExamDao(database: AppDatabase) = database.examsDao()
|
||||||
}
|
}
|
||||||
|
@ -2,21 +2,31 @@ package io.github.wulkanowy.data.db
|
|||||||
|
|
||||||
import android.arch.persistence.room.Database
|
import android.arch.persistence.room.Database
|
||||||
import android.arch.persistence.room.RoomDatabase
|
import android.arch.persistence.room.RoomDatabase
|
||||||
|
import android.arch.persistence.room.TypeConverters
|
||||||
|
import io.github.wulkanowy.data.db.dao.ExamDao
|
||||||
import io.github.wulkanowy.data.db.dao.SemesterDao
|
import io.github.wulkanowy.data.db.dao.SemesterDao
|
||||||
import io.github.wulkanowy.data.db.dao.StudentDao
|
import io.github.wulkanowy.data.db.dao.StudentDao
|
||||||
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Database(
|
@Database(
|
||||||
entities = [Student::class, Semester::class],
|
entities = [
|
||||||
|
Student::class,
|
||||||
|
Semester::class,
|
||||||
|
Exam::class
|
||||||
|
],
|
||||||
version = 1,
|
version = 1,
|
||||||
exportSchema = false
|
exportSchema = false
|
||||||
)
|
)
|
||||||
|
@TypeConverters(Converters::class)
|
||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
|
||||||
abstract fun studentDao(): StudentDao
|
abstract fun studentDao(): StudentDao
|
||||||
|
|
||||||
abstract fun semesterDao(): SemesterDao
|
abstract fun semesterDao(): SemesterDao
|
||||||
|
|
||||||
|
abstract fun examsDao(): ExamDao
|
||||||
}
|
}
|
||||||
|
14
app/src/main/java/io/github/wulkanowy/data/db/Converters.kt
Normal file
14
app/src/main/java/io/github/wulkanowy/data/db/Converters.kt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package io.github.wulkanowy.data.db
|
||||||
|
|
||||||
|
import android.arch.persistence.room.TypeConverter
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class Converters {
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun fromTimestamp(value: Long?): Date? = value?.run { Date(value) }
|
||||||
|
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun dateToTimestamp(date: Date?): Long? = date?.time
|
||||||
|
}
|
22
app/src/main/java/io/github/wulkanowy/data/db/dao/ExamDao.kt
Normal file
22
app/src/main/java/io/github/wulkanowy/data/db/dao/ExamDao.kt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package io.github.wulkanowy.data.db.dao
|
||||||
|
|
||||||
|
import android.arch.persistence.room.Dao
|
||||||
|
import android.arch.persistence.room.Delete
|
||||||
|
import android.arch.persistence.room.Insert
|
||||||
|
import android.arch.persistence.room.Query
|
||||||
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
|
import io.reactivex.Maybe
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface ExamDao {
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
fun insertAll(exams: List<Exam>): List<Long>
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
fun deleteAll(exams: List<Exam>)
|
||||||
|
|
||||||
|
@Query("SELECT * FROM Exams WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
|
||||||
|
fun getExams(diaryId: String, studentId: String, from: Date, end: Date): Maybe<List<Exam>>
|
||||||
|
}
|
@ -3,11 +3,16 @@ package io.github.wulkanowy.data.db.dao
|
|||||||
import android.arch.persistence.room.Dao
|
import android.arch.persistence.room.Dao
|
||||||
import android.arch.persistence.room.Insert
|
import android.arch.persistence.room.Insert
|
||||||
import android.arch.persistence.room.OnConflictStrategy.REPLACE
|
import android.arch.persistence.room.OnConflictStrategy.REPLACE
|
||||||
|
import android.arch.persistence.room.Query
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.reactivex.Single
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface SemesterDao {
|
interface SemesterDao {
|
||||||
|
|
||||||
@Insert(onConflict = REPLACE)
|
@Insert(onConflict = REPLACE)
|
||||||
fun insert(semester: Semester): Long
|
fun insertAll(semester: List<Semester>)
|
||||||
|
|
||||||
|
@Query("SELECT * FROM Semesters WHERE student_id = :studentId")
|
||||||
|
fun getSemester(studentId: String): Single<List<Semester>>
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import android.arch.persistence.room.Insert
|
|||||||
import android.arch.persistence.room.OnConflictStrategy.REPLACE
|
import android.arch.persistence.room.OnConflictStrategy.REPLACE
|
||||||
import android.arch.persistence.room.Query
|
import android.arch.persistence.room.Query
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.reactivex.Single
|
import io.reactivex.Maybe
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface StudentDao {
|
interface StudentDao {
|
||||||
@ -14,5 +14,5 @@ interface StudentDao {
|
|||||||
fun insert(student: Student): Long
|
fun insert(student: Student): Long
|
||||||
|
|
||||||
@Query("SELECT * FROM Students WHERE id = :id")
|
@Query("SELECT * FROM Students WHERE id = :id")
|
||||||
fun load(id: Long): Single<Student>
|
fun load(id: Long): Maybe<Student>
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package io.github.wulkanowy.data.db.entities
|
||||||
|
|
||||||
|
import android.arch.persistence.room.ColumnInfo
|
||||||
|
import android.arch.persistence.room.Entity
|
||||||
|
import android.arch.persistence.room.PrimaryKey
|
||||||
|
import java.io.Serializable
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
@Entity(tableName = "Exams")
|
||||||
|
data class Exam(
|
||||||
|
|
||||||
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
var id: Long = 0,
|
||||||
|
|
||||||
|
@ColumnInfo(name = "student_id")
|
||||||
|
var studentId: String = "",
|
||||||
|
|
||||||
|
@ColumnInfo(name = "diary_id")
|
||||||
|
var diaryId: String = "",
|
||||||
|
|
||||||
|
var date: Date,
|
||||||
|
|
||||||
|
@ColumnInfo(name = "entry_date")
|
||||||
|
var entryDate: Date = Date(),
|
||||||
|
|
||||||
|
var subject: String = "",
|
||||||
|
|
||||||
|
var group: String = "",
|
||||||
|
|
||||||
|
var type: String = "",
|
||||||
|
|
||||||
|
var description: String = "",
|
||||||
|
|
||||||
|
var teacher: String = "",
|
||||||
|
|
||||||
|
@ColumnInfo(name = "teacher_symbol")
|
||||||
|
var teacherSymbol: String = ""
|
||||||
|
) : Serializable
|
@ -6,12 +6,15 @@ import android.arch.persistence.room.Index
|
|||||||
import android.arch.persistence.room.PrimaryKey
|
import android.arch.persistence.room.PrimaryKey
|
||||||
|
|
||||||
@Entity(tableName = "Semesters",
|
@Entity(tableName = "Semesters",
|
||||||
indices = [Index(value = ["diary_id", "semester_id"], unique = true)])
|
indices = [Index(value = ["semester_id", "diary_id", "student_id"], unique = true)])
|
||||||
data class Semester(
|
data class Semester(
|
||||||
|
|
||||||
@PrimaryKey
|
@PrimaryKey(autoGenerate = true)
|
||||||
var id: Long = 0,
|
var id: Long = 0,
|
||||||
|
|
||||||
|
@ColumnInfo(name = "student_id")
|
||||||
|
var studentId: String,
|
||||||
|
|
||||||
@ColumnInfo(name = "diary_id")
|
@ColumnInfo(name = "diary_id")
|
||||||
var diaryId: String,
|
var diaryId: String,
|
||||||
|
|
||||||
@ -22,5 +25,8 @@ data class Semester(
|
|||||||
var semesterId: String,
|
var semesterId: String,
|
||||||
|
|
||||||
@ColumnInfo(name = "semester_name")
|
@ColumnInfo(name = "semester_name")
|
||||||
var semesterName: String = ""
|
var semesterName: Int = 0,
|
||||||
|
|
||||||
|
@ColumnInfo(name = "is_current")
|
||||||
|
var current: Boolean = false
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
package io.github.wulkanowy.data.repositories
|
||||||
|
|
||||||
|
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.Exam
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.repositories.local.ExamLocal
|
||||||
|
import io.github.wulkanowy.data.repositories.remote.ExamRemote
|
||||||
|
import io.reactivex.Single
|
||||||
|
import org.threeten.bp.LocalDate
|
||||||
|
import java.net.UnknownHostException
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class ExamRepository @Inject constructor(
|
||||||
|
private val settings: InternetObservingSettings,
|
||||||
|
private val local: ExamLocal,
|
||||||
|
private val remote: ExamRemote
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun getExams(semester: Semester, date: LocalDate, forceRefresh: Boolean = false): Single<List<Exam>> {
|
||||||
|
return local.getExams(semester, date).filter { !forceRefresh }
|
||||||
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
|
.flatMap {
|
||||||
|
if (it) remote.getExams(semester, date)
|
||||||
|
else Single.error(UnknownHostException())
|
||||||
|
}.flatMap { newExams ->
|
||||||
|
local.getExams(semester, date).toSingle(emptyList())
|
||||||
|
.map {
|
||||||
|
local.deleteExams(it - newExams)
|
||||||
|
local.saveExams(newExams - it)
|
||||||
|
|
||||||
|
newExams
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -2,9 +2,10 @@ package io.github.wulkanowy.data.repositories
|
|||||||
|
|
||||||
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
|
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
|
||||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.local.StudentLocal
|
import io.github.wulkanowy.data.repositories.local.SessionLocal
|
||||||
import io.github.wulkanowy.data.repositories.remote.StudentRemote
|
import io.github.wulkanowy.data.repositories.remote.SessionRemote
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import java.net.UnknownHostException
|
import java.net.UnknownHostException
|
||||||
@ -12,17 +13,17 @@ import javax.inject.Inject
|
|||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class StudentRepository @Inject constructor(
|
class SessionRepository @Inject constructor(
|
||||||
private val local: StudentLocal,
|
private val local: SessionLocal,
|
||||||
private val remote: StudentRemote,
|
private val remote: SessionRemote,
|
||||||
private val settings: InternetObservingSettings) {
|
private val settings: InternetObservingSettings) {
|
||||||
|
|
||||||
|
val isSessionSaved
|
||||||
|
get() = local.isSessionSaved
|
||||||
|
|
||||||
lateinit var cachedStudents: Single<List<Student>>
|
lateinit var cachedStudents: Single<List<Student>>
|
||||||
private set
|
private set
|
||||||
|
|
||||||
val isStudentLoggedIn: Boolean
|
|
||||||
get() = local.isStudentLoggedIn
|
|
||||||
|
|
||||||
fun getConnectedStudents(email: String, password: String, symbol: String): Single<List<Student>> {
|
fun getConnectedStudents(email: String, password: String, symbol: String): Single<List<Student>> {
|
||||||
cachedStudents = ReactiveNetwork.checkInternetConnectivity(settings)
|
cachedStudents = ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap { isConnected ->
|
.flatMap { isConnected ->
|
||||||
@ -32,9 +33,19 @@ class StudentRepository @Inject constructor(
|
|||||||
return cachedStudents
|
return cachedStudents
|
||||||
}
|
}
|
||||||
|
|
||||||
fun save(student: Student): Completable = local.save(student)
|
fun getSemesters(): Single<List<Semester>> {
|
||||||
|
return local.getLastStudent()
|
||||||
|
.flatMapSingle {
|
||||||
|
remote.initApi(it, true)
|
||||||
|
local.getSemesters(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getCurrentStudent(): Single<Student> = local.getCurrentStudent()
|
fun saveStudent(student: Student): Completable {
|
||||||
|
return remote.getSemesters(student).flatMapCompletable {
|
||||||
|
local.saveSemesters(it)
|
||||||
|
}.concatWith(local.saveStudent(student))
|
||||||
|
}
|
||||||
|
|
||||||
fun clearCache() {
|
fun clearCache() {
|
||||||
cachedStudents = Single.just(emptyList())
|
cachedStudents = Single.just(emptyList())
|
@ -0,0 +1,28 @@
|
|||||||
|
package io.github.wulkanowy.data.repositories.local
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.dao.ExamDao
|
||||||
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.utils.extension.toDate
|
||||||
|
import io.reactivex.Maybe
|
||||||
|
import org.threeten.bp.DayOfWeek
|
||||||
|
import org.threeten.bp.LocalDate
|
||||||
|
import org.threeten.bp.temporal.TemporalAdjusters
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class ExamLocal @Inject constructor(private val examDb: ExamDao) {
|
||||||
|
|
||||||
|
fun getExams(semester: Semester, startDate: LocalDate): Maybe<List<Exam>> {
|
||||||
|
return examDb.getExams(semester.diaryId, semester.studentId, startDate.toDate(),
|
||||||
|
startDate.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)).toDate()
|
||||||
|
).filter { !it.isEmpty() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun saveExams(exams: List<Exam>) {
|
||||||
|
examDb.insertAll(exams)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteExams(exams: List<Exam>) {
|
||||||
|
examDb.deleteAll(exams)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package io.github.wulkanowy.data.repositories.local
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import io.github.wulkanowy.data.db.SharedPrefHelper
|
||||||
|
import io.github.wulkanowy.data.db.dao.SemesterDao
|
||||||
|
import io.github.wulkanowy.data.db.dao.StudentDao
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.utils.security.Scrambler.decrypt
|
||||||
|
import io.github.wulkanowy.utils.security.Scrambler.encrypt
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import io.reactivex.Maybe
|
||||||
|
import io.reactivex.Single
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class SessionLocal @Inject constructor(
|
||||||
|
private val studentDb: StudentDao,
|
||||||
|
private val semesterDb: SemesterDao,
|
||||||
|
private val sharedPref: SharedPrefHelper,
|
||||||
|
private val context: Context) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val LAST_USER_KEY: String = "last_user_id"
|
||||||
|
}
|
||||||
|
|
||||||
|
val isSessionSaved
|
||||||
|
get() = sharedPref.getLong(LAST_USER_KEY, defaultValue = 0L) != 0L
|
||||||
|
|
||||||
|
fun saveStudent(student: Student): Completable {
|
||||||
|
return Single.fromCallable { studentDb.insert(student.copy(password = encrypt(student.password, context))) }
|
||||||
|
.map { sharedPref.putLong(LAST_USER_KEY, it) }
|
||||||
|
.ignoreElement()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLastStudent(): Maybe<Student> {
|
||||||
|
return studentDb.load(sharedPref.getLong(LAST_USER_KEY, defaultValue = 0))
|
||||||
|
.map { it.apply { password = decrypt(password) } }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun saveSemesters(semesters: List<Semester>): Completable {
|
||||||
|
return Single.fromCallable { semesterDb.insertAll(semesters) }.ignoreElement()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSemesters(student: Student): Single<List<Semester>> {
|
||||||
|
return semesterDb.getSemester(student.studentId)
|
||||||
|
}
|
||||||
|
}
|
@ -1,37 +0,0 @@
|
|||||||
package io.github.wulkanowy.data.repositories.local
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import io.github.wulkanowy.data.db.SharedPrefHelper
|
|
||||||
import io.github.wulkanowy.data.db.dao.StudentDao
|
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
|
||||||
import io.github.wulkanowy.utils.security.Scrambler.decrypt
|
|
||||||
import io.github.wulkanowy.utils.security.Scrambler.encrypt
|
|
||||||
import io.reactivex.Completable
|
|
||||||
import io.reactivex.Single
|
|
||||||
import javax.inject.Inject
|
|
||||||
import javax.inject.Singleton
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
class StudentLocal @Inject constructor(
|
|
||||||
private val studentDb: StudentDao,
|
|
||||||
private val sharedPref: SharedPrefHelper,
|
|
||||||
private val context: Context) {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val CURRENT_USER_KEY: String = "current_user_id"
|
|
||||||
}
|
|
||||||
|
|
||||||
val isStudentLoggedIn: Boolean
|
|
||||||
get() = sharedPref.getLong(CURRENT_USER_KEY, 0) != 0L
|
|
||||||
|
|
||||||
fun save(student: Student): Completable {
|
|
||||||
return Single.fromCallable { studentDb.insert(student.copy(password = encrypt(student.password, context))) }
|
|
||||||
.map { sharedPref.putLong(CURRENT_USER_KEY, it) }
|
|
||||||
.ignoreElement()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getCurrentStudent(): Single<Student> {
|
|
||||||
return studentDb.load(sharedPref.getLong(CURRENT_USER_KEY, defaultValue = 0))
|
|
||||||
.map { it.apply { password = decrypt(password) } }
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,37 @@
|
|||||||
|
package io.github.wulkanowy.data.repositories.remote
|
||||||
|
|
||||||
|
import io.github.wulkanowy.api.Api
|
||||||
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.utils.extension.toDate
|
||||||
|
import io.reactivex.Single
|
||||||
|
import org.threeten.bp.LocalDate
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class ExamRemote @Inject constructor(private val api: Api) {
|
||||||
|
|
||||||
|
fun getExams(semester: Semester, startDate: LocalDate): Single<List<Exam>> {
|
||||||
|
return Single.just(api.run {
|
||||||
|
if (diaryId != semester.diaryId) {
|
||||||
|
diaryId = semester.diaryId
|
||||||
|
notifyDataChanged()
|
||||||
|
}
|
||||||
|
}).flatMap { api.getExams(startDate.toDate()) }
|
||||||
|
.map { exams ->
|
||||||
|
exams.map {
|
||||||
|
Exam(
|
||||||
|
studentId = semester.studentId,
|
||||||
|
diaryId = semester.diaryId,
|
||||||
|
date = it.date,
|
||||||
|
entryDate = it.entryDate,
|
||||||
|
subject = it.subject,
|
||||||
|
group = it.group,
|
||||||
|
type = it.type,
|
||||||
|
description = it.description,
|
||||||
|
teacher = it.teacher,
|
||||||
|
teacherSymbol = it.teacherSymbol
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package io.github.wulkanowy.data.repositories.remote
|
||||||
|
|
||||||
|
import io.github.wulkanowy.api.Api
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.reactivex.Single
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class SessionRemote @Inject constructor(private val api: Api) {
|
||||||
|
|
||||||
|
fun getConnectedStudents(email: String, password: String, symbol: String): Single<List<Student>> {
|
||||||
|
return Single.just(initApi(Student(email = email, password = password, symbol = symbol)))
|
||||||
|
.flatMap { _ ->
|
||||||
|
api.getPupils().map { students ->
|
||||||
|
students.map {
|
||||||
|
Student(email = email,
|
||||||
|
password = password,
|
||||||
|
symbol = it.symbol,
|
||||||
|
studentId = it.studentId,
|
||||||
|
studentName = it.studentName,
|
||||||
|
schoolId = it.schoolId,
|
||||||
|
schoolName = it.schoolName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSemesters(student: Student): Single<List<Semester>> {
|
||||||
|
return Single.just(initApi(student)).flatMap { _ ->
|
||||||
|
api.getSemesters().map { semesters ->
|
||||||
|
semesters.map {
|
||||||
|
Semester(studentId = student.studentId,
|
||||||
|
diaryId = it.diaryId,
|
||||||
|
diaryName = it.diaryName,
|
||||||
|
semesterId = it.semesterId.toString(),
|
||||||
|
semesterName = it.semesterNumber,
|
||||||
|
current = it.current)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun initApi(student: Student, checkInit: Boolean = false) {
|
||||||
|
if (if (checkInit) api.studentId.isEmpty() else true) {
|
||||||
|
api.run {
|
||||||
|
email = student.email
|
||||||
|
password = student.password
|
||||||
|
symbol = student.symbol
|
||||||
|
host = "vulcan.net.pl"
|
||||||
|
schoolId = student.schoolId
|
||||||
|
studentId = student.studentId
|
||||||
|
notifyDataChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,32 +0,0 @@
|
|||||||
package io.github.wulkanowy.data.repositories.remote
|
|
||||||
|
|
||||||
import io.github.wulkanowy.api.Api
|
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
|
||||||
import io.reactivex.Single
|
|
||||||
import javax.inject.Inject
|
|
||||||
import javax.inject.Singleton
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
class StudentRemote @Inject constructor(private val api: Api) {
|
|
||||||
|
|
||||||
fun getConnectedStudents(email: String, password: String, symbol: String): Single<List<Student>> {
|
|
||||||
api.let {
|
|
||||||
it.email = email
|
|
||||||
it.password = password
|
|
||||||
it.symbol = symbol
|
|
||||||
it.host = "vulcan.net.pl"
|
|
||||||
it.onConfigChange()
|
|
||||||
}
|
|
||||||
return api.getPupils().map { students ->
|
|
||||||
students.map {
|
|
||||||
Student(email = email,
|
|
||||||
password = password,
|
|
||||||
symbol = it.symbol,
|
|
||||||
studentId = it.studentId,
|
|
||||||
studentName = it.studentName,
|
|
||||||
schoolId = it.schoolId,
|
|
||||||
schoolName = it.schoolName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,8 +3,9 @@ package io.github.wulkanowy.di
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.WulkanowyApp
|
import io.github.wulkanowy.WulkanowyApp
|
||||||
import io.github.wulkanowy.data.ErrorHandler
|
|
||||||
import io.github.wulkanowy.utils.schedulers.SchedulersManager
|
import io.github.wulkanowy.utils.schedulers.SchedulersManager
|
||||||
import io.github.wulkanowy.utils.schedulers.SchedulersProvider
|
import io.github.wulkanowy.utils.schedulers.SchedulersProvider
|
||||||
|
|
||||||
@ -18,5 +19,5 @@ internal class AppModule {
|
|||||||
fun provideSchedulers(): SchedulersManager = SchedulersProvider()
|
fun provideSchedulers(): SchedulersManager = SchedulersProvider()
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
fun provideErrorHandler(context: Context): ErrorHandler = ErrorHandler(context.resources)
|
fun provideFlexibleAdapter() = FlexibleAdapter<AbstractFlexibleItem<*>>(null, null, true)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.login.form
|
package io.github.wulkanowy.ui.login.form
|
||||||
|
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.login.LoginErrorHandler
|
import io.github.wulkanowy.ui.login.LoginErrorHandler
|
||||||
import io.github.wulkanowy.utils.DEFAULT_SYMBOL
|
import io.github.wulkanowy.utils.DEFAULT_SYMBOL
|
||||||
@ -10,7 +10,7 @@ import javax.inject.Inject
|
|||||||
class LoginFormPresenter @Inject constructor(
|
class LoginFormPresenter @Inject constructor(
|
||||||
private val schedulers: SchedulersManager,
|
private val schedulers: SchedulersManager,
|
||||||
private val errorHandler: LoginErrorHandler,
|
private val errorHandler: LoginErrorHandler,
|
||||||
private val studentRepository: StudentRepository)
|
private val sessionRepository: SessionRepository)
|
||||||
: BasePresenter<LoginFormView>(errorHandler) {
|
: BasePresenter<LoginFormView>(errorHandler) {
|
||||||
|
|
||||||
private var wasEmpty = false
|
private var wasEmpty = false
|
||||||
@ -22,7 +22,7 @@ class LoginFormPresenter @Inject constructor(
|
|||||||
|
|
||||||
fun attemptLogin(email: String, password: String, symbol: String) {
|
fun attemptLogin(email: String, password: String, symbol: String) {
|
||||||
if (!validateCredentials(email, password, symbol)) return
|
if (!validateCredentials(email, password, symbol)) return
|
||||||
disposable.add(studentRepository.getConnectedStudents(email, password, normalizeSymbol(symbol))
|
disposable.add(sessionRepository.getConnectedStudents(email, password, normalizeSymbol(symbol))
|
||||||
.observeOn(schedulers.mainThread())
|
.observeOn(schedulers.mainThread())
|
||||||
.subscribeOn(schedulers.backgroundThread())
|
.subscribeOn(schedulers.backgroundThread())
|
||||||
.doOnSubscribe {
|
.doOnSubscribe {
|
||||||
@ -34,7 +34,7 @@ class LoginFormPresenter @Inject constructor(
|
|||||||
showSoftKeyboard()
|
showSoftKeyboard()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
studentRepository.clearCache()
|
sessionRepository.clearCache()
|
||||||
}
|
}
|
||||||
.doFinally { view?.showLoginProgress(false) }
|
.doFinally { view?.showLoginProgress(false) }
|
||||||
.subscribe({
|
.subscribe({
|
||||||
|
@ -9,6 +9,7 @@ import android.view.View.VISIBLE
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||||
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.main.MainActivity
|
import io.github.wulkanowy.ui.main.MainActivity
|
||||||
@ -22,7 +23,11 @@ class LoginOptionsFragment : BaseFragment(), LoginOptionsView {
|
|||||||
lateinit var presenter: LoginOptionsPresenter
|
lateinit var presenter: LoginOptionsPresenter
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var loginAdapter: FlexibleAdapter<LoginOptionsItem>
|
lateinit var loginAdapter: FlexibleAdapter<AbstractFlexibleItem<*>>
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newInstance() = LoginOptionsFragment()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
return inflater.inflate(R.layout.fragment_login_options, container, false)
|
return inflater.inflate(R.layout.fragment_login_options, container, false)
|
||||||
@ -34,7 +39,13 @@ class LoginOptionsFragment : BaseFragment(), LoginOptionsView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun initRecycler() {
|
override fun initRecycler() {
|
||||||
loginAdapter.setOnItemClickListener { item -> item?.let { presenter.onSelectStudent(it.student) } }
|
loginAdapter.run {
|
||||||
|
setOnItemClickListener { position ->
|
||||||
|
(getItem(position) as? LoginOptionsItem)?.let {
|
||||||
|
presenter.onSelectStudent(it.student)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
loginOptionsRecycler.run {
|
loginOptionsRecycler.run {
|
||||||
adapter = loginAdapter
|
adapter = loginAdapter
|
||||||
layoutManager = SmoothScrollLinearLayoutManager(context)
|
layoutManager = SmoothScrollLinearLayoutManager(context)
|
||||||
@ -47,7 +58,7 @@ class LoginOptionsFragment : BaseFragment(), LoginOptionsView {
|
|||||||
|
|
||||||
override fun updateData(data: List<LoginOptionsItem>) {
|
override fun updateData(data: List<LoginOptionsItem>) {
|
||||||
loginAdapter.run {
|
loginAdapter.run {
|
||||||
updateDataSet(data)
|
updateDataSet(data, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,4 +77,9 @@ class LoginOptionsFragment : BaseFragment(), LoginOptionsView {
|
|||||||
override fun showActionBar(show: Boolean) {
|
override fun showActionBar(show: Boolean) {
|
||||||
(activity as AppCompatActivity?)?.supportActionBar?.run { if (show) show() else hide() }
|
(activity as AppCompatActivity?)?.supportActionBar?.run { if (show) show() else hide() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
presenter.detachView()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,14 @@ package io.github.wulkanowy.ui.login.options
|
|||||||
|
|
||||||
import io.github.wulkanowy.data.ErrorHandler
|
import io.github.wulkanowy.data.ErrorHandler
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.utils.schedulers.SchedulersManager
|
import io.github.wulkanowy.utils.schedulers.SchedulersManager
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LoginOptionsPresenter @Inject constructor(
|
class LoginOptionsPresenter @Inject constructor(
|
||||||
private val errorHandler: ErrorHandler,
|
private val errorHandler: ErrorHandler,
|
||||||
private val repository: StudentRepository,
|
private val repository: SessionRepository,
|
||||||
private val schedulers: SchedulersManager)
|
private val schedulers: SchedulersManager)
|
||||||
: BasePresenter<LoginOptionsView>(errorHandler) {
|
: BasePresenter<LoginOptionsView>(errorHandler) {
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ class LoginOptionsPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onSelectStudent(student: Student) {
|
fun onSelectStudent(student: Student) {
|
||||||
disposable.add(repository.save(student)
|
disposable.add(repository.saveStudent(student)
|
||||||
.subscribeOn(schedulers.backgroundThread())
|
.subscribeOn(schedulers.backgroundThread())
|
||||||
.observeOn(schedulers.mainThread())
|
.observeOn(schedulers.mainThread())
|
||||||
.doOnSubscribe { _ ->
|
.doOnSubscribe { _ ->
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
package io.github.wulkanowy.ui.main.exam
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.support.v4.app.DialogFragment
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
|
import io.github.wulkanowy.utils.extension.toFormat
|
||||||
|
import kotlinx.android.synthetic.main.dialog_exam.*
|
||||||
|
|
||||||
|
class ExamDialog : DialogFragment() {
|
||||||
|
|
||||||
|
private lateinit var exam: Exam
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val ARGUMENT_KEY = "Item"
|
||||||
|
|
||||||
|
fun newInstance(exam: Exam): ExamDialog {
|
||||||
|
return ExamDialog().apply {
|
||||||
|
arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setStyle(DialogFragment.STYLE_NORMAL, R.style.DialogFragmentTheme)
|
||||||
|
arguments?.run {
|
||||||
|
exam = getSerializable(ARGUMENT_KEY) as Exam
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
dialog.setTitle(getString(R.string.all_details))
|
||||||
|
return inflater.inflate(R.layout.dialog_exam, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
|
||||||
|
examDialogSubjectValue.text = exam.subject
|
||||||
|
examDialogTypeValue.text = exam.type
|
||||||
|
examDialogTeacherValue.text = exam.teacher
|
||||||
|
examDialogDateValue.text = exam.entryDate.toFormat()
|
||||||
|
examDialogDescriptionValue.text = exam.description
|
||||||
|
|
||||||
|
examDialogClose.setOnClickListener { dismiss() }
|
||||||
|
}
|
||||||
|
}
|
@ -3,17 +3,104 @@ package io.github.wulkanowy.ui.main.exam
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.View.*
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
|
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||||
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
|
import io.github.wulkanowy.utils.extension.setOnItemClickListener
|
||||||
|
import kotlinx.android.synthetic.main.fragment_exam.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ExamFragment : BaseFragment() {
|
class ExamFragment : BaseFragment(), ExamView {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var presenter: ExamPresenter
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var examAdapter: FlexibleAdapter<AbstractFlexibleItem<*>>
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private const val SAVED_DATE_KEY = "CURRENT_DATE"
|
||||||
fun newInstance() = ExamFragment()
|
fun newInstance() = ExamFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
return inflater.inflate(R.layout.fragment_exam, container, false)
|
return inflater.inflate(R.layout.fragment_exam, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
presenter.run {
|
||||||
|
attachView(this@ExamFragment)
|
||||||
|
loadData(date = savedInstanceState?.getLong(SAVED_DATE_KEY))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initView() {
|
||||||
|
examAdapter.run {
|
||||||
|
setOnItemClickListener { presenter.onExamItemSelected(getItem(it)) }
|
||||||
|
}
|
||||||
|
examRecycler.run {
|
||||||
|
layoutManager = SmoothScrollLinearLayoutManager(context)
|
||||||
|
adapter = examAdapter
|
||||||
|
}
|
||||||
|
examSwipe.setOnRefreshListener { presenter.loadData(date = null, forceRefresh = true) }
|
||||||
|
examPreviousButton.setOnClickListener { presenter.loadExamsForPreviousWeek() }
|
||||||
|
examNextButton.setOnClickListener { presenter.loadExamsForNextWeek()}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateData(data: List<ExamItem>) {
|
||||||
|
examAdapter.updateDataSet(data, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateNavigationWeek(date: String) {
|
||||||
|
examNavDate.text = date
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showEmpty(show: Boolean) {
|
||||||
|
examEmpty.visibility = if (show) VISIBLE else GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showProgress(show: Boolean) {
|
||||||
|
examProgress.visibility = if (show) VISIBLE else GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showContent(show: Boolean) {
|
||||||
|
examRecycler.visibility = if (show) VISIBLE else GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showRefresh(show: Boolean) {
|
||||||
|
examSwipe.isRefreshing = show
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showPreButton(show: Boolean) {
|
||||||
|
examPreviousButton.visibility = if (show) VISIBLE else INVISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showNextButton(show: Boolean) {
|
||||||
|
examNextButton.visibility = if (show) VISIBLE else INVISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showExamDialog(exam: Exam) {
|
||||||
|
ExamDialog.newInstance(exam).show(fragmentManager, exam.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
|
super.onSaveInstanceState(outState)
|
||||||
|
outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewStateRestored(savedInstanceState: Bundle?) {
|
||||||
|
super.onViewStateRestored(savedInstanceState)
|
||||||
|
presenter.loadData(date = savedInstanceState?.getLong(SAVED_DATE_KEY))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
presenter.detachView()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
package io.github.wulkanowy.ui.main.exam
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
|
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
||||||
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
|
import eu.davidea.viewholders.ExpandableViewHolder
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.utils.extension.getWeekDayName
|
||||||
|
import io.github.wulkanowy.utils.extension.toFormat
|
||||||
|
import kotlinx.android.extensions.LayoutContainer
|
||||||
|
import kotlinx.android.synthetic.main.header_exam.*
|
||||||
|
import org.apache.commons.lang3.StringUtils
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class ExamHeader : AbstractHeaderItem<ExamHeader.ViewHolder>() {
|
||||||
|
|
||||||
|
lateinit var date: Date
|
||||||
|
|
||||||
|
override fun createViewHolder(view: View?, adapter: FlexibleAdapter<IFlexible<*>>?): ViewHolder {
|
||||||
|
return ViewHolder(view, adapter)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLayoutRes() = R.layout.header_exam
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as ExamHeader
|
||||||
|
|
||||||
|
if (date != other.date) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return date.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>?, holder: ViewHolder,
|
||||||
|
position: Int, payloads: MutableList<Any>?) {
|
||||||
|
holder.run {
|
||||||
|
examHeaderDay.text = StringUtils.capitalize(date.getWeekDayName())
|
||||||
|
examHeaderDate.text = date.toFormat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewHolder(view: View?, adapter: FlexibleAdapter<IFlexible<*>>?) : ExpandableViewHolder(view, adapter),
|
||||||
|
LayoutContainer {
|
||||||
|
|
||||||
|
init {
|
||||||
|
contentView.setOnClickListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val containerView: View
|
||||||
|
get() = contentView
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package io.github.wulkanowy.ui.main.exam
|
||||||
|
|
||||||
|
import android.support.v7.widget.RecyclerView
|
||||||
|
import android.view.View
|
||||||
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
|
import eu.davidea.flexibleadapter.items.AbstractSectionableItem
|
||||||
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
|
import eu.davidea.viewholders.FlexibleViewHolder
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
|
import kotlinx.android.extensions.LayoutContainer
|
||||||
|
import kotlinx.android.synthetic.main.item_exam.*
|
||||||
|
|
||||||
|
class ExamItem(header: ExamHeader, val exam: Exam) : AbstractSectionableItem<ExamItem.ViewHolder, ExamHeader>(header) {
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as ExamItem
|
||||||
|
|
||||||
|
if (exam != other.exam) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return exam.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLayoutRes() = R.layout.item_exam
|
||||||
|
|
||||||
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): ViewHolder {
|
||||||
|
return ViewHolder(view, adapter)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, holder: ViewHolder,
|
||||||
|
position: Int, payloads: MutableList<Any>?) {
|
||||||
|
holder.run {
|
||||||
|
examItemSubject.text = exam.subject
|
||||||
|
examItemTeacher.text = exam.teacher
|
||||||
|
examItemType.text = exam.type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewHolder(view: View, adapter: FlexibleAdapter<*>) : FlexibleViewHolder(view, adapter),
|
||||||
|
LayoutContainer {
|
||||||
|
|
||||||
|
override val containerView: View
|
||||||
|
get() = contentView
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
package io.github.wulkanowy.ui.main.exam
|
||||||
|
|
||||||
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
|
import io.github.wulkanowy.data.ErrorHandler
|
||||||
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.repositories.ExamRepository
|
||||||
|
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||||
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
|
import io.github.wulkanowy.utils.extension.isHolidays
|
||||||
|
import io.github.wulkanowy.utils.extension.toFormat
|
||||||
|
import io.github.wulkanowy.utils.getNearMonday
|
||||||
|
import io.github.wulkanowy.utils.schedulers.SchedulersManager
|
||||||
|
import org.threeten.bp.LocalDate
|
||||||
|
import java.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class ExamPresenter @Inject constructor(
|
||||||
|
private val errorHandler: ErrorHandler,
|
||||||
|
private val schedulers: SchedulersManager,
|
||||||
|
private val examRepository: ExamRepository,
|
||||||
|
private val sessionRepository: SessionRepository
|
||||||
|
) : BasePresenter<ExamView>(errorHandler) {
|
||||||
|
|
||||||
|
var currentDate: LocalDate = getNearMonday(LocalDate.now())
|
||||||
|
private set
|
||||||
|
|
||||||
|
override fun attachView(view: ExamView) {
|
||||||
|
super.attachView(view)
|
||||||
|
view.initView()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadExamsForPreviousWeek() = loadData(currentDate.minusDays(7).toEpochDay())
|
||||||
|
|
||||||
|
fun loadExamsForNextWeek() = loadData(currentDate.plusDays(7).toEpochDay())
|
||||||
|
|
||||||
|
fun loadData(date: Long?, forceRefresh: Boolean = false) {
|
||||||
|
this.currentDate = LocalDate.ofEpochDay(date ?: getNearMonday(currentDate).toEpochDay())
|
||||||
|
if (currentDate.isHolidays()) return
|
||||||
|
|
||||||
|
disposable.clear()
|
||||||
|
disposable.add(sessionRepository.getSemesters()
|
||||||
|
.map { selectSemester(it, -1) }
|
||||||
|
.flatMap { examRepository.getExams(it, currentDate, forceRefresh) }
|
||||||
|
.map { it.groupBy { exam -> exam.date }.toSortedMap() }
|
||||||
|
.map { createExamItems(it) }
|
||||||
|
.subscribeOn(schedulers.backgroundThread())
|
||||||
|
.observeOn(schedulers.mainThread())
|
||||||
|
.doOnSubscribe {
|
||||||
|
view?.run {
|
||||||
|
showRefresh(forceRefresh)
|
||||||
|
showProgress(!forceRefresh)
|
||||||
|
if (!forceRefresh) showEmpty(false)
|
||||||
|
showContent(null == date && forceRefresh)
|
||||||
|
showPreButton(!currentDate.minusDays(7).isHolidays())
|
||||||
|
showNextButton(!currentDate.plusDays(7).isHolidays())
|
||||||
|
updateNavigationWeek("${currentDate.toFormat("dd.MM")}-${currentDate.plusDays(4).toFormat("dd.MM")}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.doAfterSuccess {
|
||||||
|
view?.run {
|
||||||
|
showEmpty(it.isEmpty())
|
||||||
|
showContent(it.isNotEmpty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.doFinally {
|
||||||
|
view?.run {
|
||||||
|
showRefresh(false)
|
||||||
|
showProgress(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.subscribe({ view?.updateData(it) }) { errorHandler.proceed(it) })
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createExamItems(items: Map<Date, List<Exam>>): List<ExamItem> {
|
||||||
|
return items.flatMap {
|
||||||
|
val header = ExamHeader().apply { date = it.key }
|
||||||
|
it.value.reversed().map { item ->
|
||||||
|
ExamItem(header, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onExamItemSelected(item: AbstractFlexibleItem<*>?) {
|
||||||
|
if (item is ExamItem) view?.showExamDialog(item.exam)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun selectSemester(semesters: List<Semester>, index: Int): Semester {
|
||||||
|
return semesters.single { it.current }.let { currentSemester ->
|
||||||
|
if (index == -1) currentSemester
|
||||||
|
else semesters.single { semester ->
|
||||||
|
semester.run {
|
||||||
|
semesterName - 1 == index && diaryId == currentSemester.diaryId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package io.github.wulkanowy.ui.main.exam
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
import org.threeten.bp.LocalDate
|
||||||
|
|
||||||
|
interface ExamView : BaseView {
|
||||||
|
|
||||||
|
fun initView()
|
||||||
|
|
||||||
|
fun updateData(data: List<ExamItem>)
|
||||||
|
|
||||||
|
fun showEmpty(show: Boolean)
|
||||||
|
|
||||||
|
fun showProgress(show: Boolean)
|
||||||
|
|
||||||
|
fun showContent(show: Boolean)
|
||||||
|
|
||||||
|
fun showRefresh(show: Boolean)
|
||||||
|
|
||||||
|
fun showNextButton(show: Boolean)
|
||||||
|
|
||||||
|
fun showPreButton(show: Boolean)
|
||||||
|
|
||||||
|
fun showExamDialog(exam: Exam)
|
||||||
|
|
||||||
|
fun updateNavigationWeek(date: String)
|
||||||
|
}
|
@ -21,12 +21,12 @@ class SplashActivity : BaseActivity(), SplashView {
|
|||||||
presenter.detachView()
|
presenter.detachView()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openLoginActivity() {
|
override fun openLoginView() {
|
||||||
startActivity(LoginActivity.getStartIntent(this))
|
startActivity(LoginActivity.getStartIntent(this))
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openMainActivity() {
|
override fun openMainView() {
|
||||||
startActivity(MainActivity.getStartIntent(this))
|
startActivity(MainActivity.getStartIntent(this))
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
package io.github.wulkanowy.ui.splash
|
package io.github.wulkanowy.ui.splash
|
||||||
|
|
||||||
import io.github.wulkanowy.data.ErrorHandler
|
import io.github.wulkanowy.data.ErrorHandler
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class SplashPresenter @Inject constructor(private val studentRepository: StudentRepository,
|
class SplashPresenter @Inject constructor(private val sessionRepository: SessionRepository,
|
||||||
errorHandler: ErrorHandler)
|
errorHandler: ErrorHandler)
|
||||||
: BasePresenter<SplashView>(errorHandler) {
|
: BasePresenter<SplashView>(errorHandler) {
|
||||||
|
|
||||||
override fun attachView(view: SplashView) {
|
override fun attachView(view: SplashView) {
|
||||||
super.attachView(view)
|
super.attachView(view)
|
||||||
view.run { if (studentRepository.isStudentLoggedIn) openMainActivity() else openLoginActivity() }
|
view.run { if (sessionRepository.isSessionSaved) openMainView() else openLoginView() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import io.github.wulkanowy.ui.base.BaseView
|
|||||||
|
|
||||||
interface SplashView : BaseView {
|
interface SplashView : BaseView {
|
||||||
|
|
||||||
fun openLoginActivity()
|
fun openLoginView()
|
||||||
|
|
||||||
fun openMainActivity()
|
fun openMainView()
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import org.threeten.bp.DayOfWeek.*
|
|||||||
import org.threeten.bp.LocalDate
|
import org.threeten.bp.LocalDate
|
||||||
import org.threeten.bp.Year
|
import org.threeten.bp.Year
|
||||||
import org.threeten.bp.format.DateTimeFormatter
|
import org.threeten.bp.format.DateTimeFormatter
|
||||||
|
import org.threeten.bp.temporal.TemporalAdjuster
|
||||||
import org.threeten.bp.temporal.TemporalAdjusters
|
import org.threeten.bp.temporal.TemporalAdjusters
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@ -68,29 +69,35 @@ fun isDateInWeek(firstWeekDay: LocalDate, date: LocalDate): Boolean {
|
|||||||
return date.isAfter(firstWeekDay.minusDays(1)) && date.isBefore(firstWeekDay.plusDays(5))
|
return date.isAfter(firstWeekDay.minusDays(1)) && date.isBefore(firstWeekDay.plusDays(5))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getNearMonday(date: LocalDate): LocalDate {
|
||||||
|
return when(date.dayOfWeek) {
|
||||||
|
MONDAY -> date
|
||||||
|
SATURDAY, SUNDAY -> date.with(TemporalAdjusters.next(MONDAY))
|
||||||
|
else -> date.with(TemporalAdjusters.previous(MONDAY))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Dz.U. 2016 poz. 1335](http://prawo.sejm.gov.pl/isap.nsf/DocDetails.xsp?id=WDU20160001335)
|
* [Dz.U. 2016 poz. 1335](http://prawo.sejm.gov.pl/isap.nsf/DocDetails.xsp?id=WDU20160001335)
|
||||||
*/
|
*/
|
||||||
fun isHolidays(): Boolean = isHolidays(LocalDate.now(), Year.now().value)
|
fun isHolidays(): Boolean = isHolidays(LocalDate.now())
|
||||||
|
|
||||||
fun isHolidays(day: LocalDate, year: Int): Boolean {
|
fun isHolidays(day: LocalDate): Boolean {
|
||||||
return day.isAfter(getLastSchoolDay(year)) && day.isBefore(getFirstSchoolDay(year))
|
return day.isAfter(getLastSchoolDay(day.year)) && day.isBefore(getFirstSchoolDay(day.year))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFirstSchoolDay(year: Int): LocalDate? {
|
fun getFirstSchoolDay(year: Int): LocalDate {
|
||||||
val firstSeptember = LocalDate.of(year, 9, 1)
|
val firstSeptember = LocalDate.of(year, 9, 1)
|
||||||
|
|
||||||
return when (firstSeptember.dayOfWeek) {
|
return when (firstSeptember.dayOfWeek) {
|
||||||
FRIDAY,
|
FRIDAY,
|
||||||
SATURDAY,
|
SATURDAY,
|
||||||
SUNDAY -> firstSeptember.with(TemporalAdjusters.firstInMonth(MONDAY))
|
SUNDAY -> firstSeptember.with(TemporalAdjusters.firstInMonth(MONDAY))
|
||||||
else -> {
|
else -> firstSeptember
|
||||||
firstSeptember
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLastSchoolDay(year: Int): LocalDate? {
|
fun getLastSchoolDay(year: Int): LocalDate {
|
||||||
return LocalDate
|
return LocalDate
|
||||||
.of(year, 6, 20)
|
.of(year, 6, 20)
|
||||||
.with(TemporalAdjusters.next(FRIDAY))
|
.with(TemporalAdjusters.next(FRIDAY))
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package io.github.wulkanowy.utils.extension
|
||||||
|
|
||||||
|
import io.github.wulkanowy.utils.DATE_PATTERN
|
||||||
|
import io.github.wulkanowy.utils.isHolidays
|
||||||
|
import org.threeten.bp.Instant
|
||||||
|
import org.threeten.bp.LocalDate
|
||||||
|
import org.threeten.bp.ZoneId
|
||||||
|
import org.threeten.bp.format.DateTimeFormatter
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
private val formatter = DateTimeFormatter.ofPattern(DATE_PATTERN)
|
||||||
|
|
||||||
|
fun LocalDate.toDate(): Date = java.sql.Date.valueOf(this.format(formatter))
|
||||||
|
|
||||||
|
fun LocalDate.toFormat(format: String): String = this.format(DateTimeFormatter.ofPattern(format))
|
||||||
|
|
||||||
|
fun LocalDate.toFormat(): String = this.toFormat(DATE_PATTERN)
|
||||||
|
|
||||||
|
fun LocalDate.isHolidays(): Boolean = isHolidays(this)
|
||||||
|
|
||||||
|
fun Date.toLocalDate(): LocalDate = Instant.ofEpochMilli(this.time).atZone(ZoneId.systemDefault()).toLocalDate()
|
||||||
|
|
||||||
|
fun Date.getWeekDayName(): String = this.toLocalDate().format(DateTimeFormatter.ofPattern("EEEE", Locale.getDefault()))
|
||||||
|
|
||||||
|
fun Date.toFormat(): String = this.toLocalDate().toFormat()
|
@ -3,9 +3,13 @@ package io.github.wulkanowy.utils.extension
|
|||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
|
|
||||||
fun <K : AbstractFlexibleItem<*>, T : FlexibleAdapter<K>> T.setOnItemClickListener(listener: (K?) -> Unit) {
|
fun FlexibleAdapter<*>.setOnItemClickListener(listener: (position: Int) -> Unit) {
|
||||||
addListener(FlexibleAdapter.OnItemClickListener { _, position ->
|
addListener(FlexibleAdapter.OnItemClickListener { _, position ->
|
||||||
listener(getItem(position))
|
listener(position)
|
||||||
true
|
true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FlexibleAdapter<*>.setOnUpdateListener(listener: (size: Int) -> Unit) {
|
||||||
|
addListener(FlexibleAdapter.OnUpdateListener { listener(it) })
|
||||||
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
@ -8,171 +7,106 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minWidth="300dp"
|
android:minWidth="300dp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
android:padding="20dp">
|
||||||
|
|
||||||
<RelativeLayout
|
<TextView
|
||||||
android:id="@+id/timetable_dialog_relative_layout"
|
android:id="@+id/examDialogSubject"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingBottom="20dp"
|
android:text="@string/all_subject"
|
||||||
android:paddingEnd="20dp"
|
android:textIsSelectable="true"
|
||||||
android:paddingLeft="20dp"
|
android:textSize="17sp" />
|
||||||
android:paddingRight="20dp"
|
|
||||||
android:paddingStart="20dp"
|
|
||||||
android:paddingTop="10dp"
|
|
||||||
tools:ignore="UselessParent">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/exams_dialog_details"
|
android:id="@+id/examDialogSubjectValue"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_marginTop="3dp"
|
||||||
android:layout_alignParentStart="true"
|
android:text="@string/all_no_data"
|
||||||
android:layout_alignParentTop="true"
|
android:textIsSelectable="true"
|
||||||
android:layout_gravity="start"
|
android:textSize="12sp" />
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:maxLines="5"
|
|
||||||
android:minHeight="60dp"
|
|
||||||
android:minLines="2"
|
|
||||||
android:paddingTop="10dp"
|
|
||||||
android:text="@string/all_details"
|
|
||||||
android:textIsSelectable="true"
|
|
||||||
android:textSize="20sp" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/exams_dialog_subject"
|
android:id="@+id/examDialogType"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_marginTop="10dp"
|
||||||
android:layout_alignParentStart="true"
|
android:text="@string/exam_type"
|
||||||
android:layout_below="@+id/exams_dialog_details"
|
android:textIsSelectable="true"
|
||||||
android:layout_marginTop="10dp"
|
android:textSize="17sp" />
|
||||||
android:text="@string/all_subject"
|
|
||||||
android:textIsSelectable="true"
|
|
||||||
android:textSize="17sp" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/exams_dialog_subject_value"
|
android:id="@+id/examDialogTypeValue"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_marginTop="3dp"
|
||||||
android:layout_alignParentStart="true"
|
android:text="@string/all_no_data"
|
||||||
android:layout_below="@+id/exams_dialog_subject"
|
android:textIsSelectable="true"
|
||||||
android:layout_marginTop="3dp"
|
android:textSize="12sp" />
|
||||||
android:text="@string/all_no_data"
|
|
||||||
android:textIsSelectable="true"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/exams_dialog_type"
|
android:id="@+id/examDialogTeacher"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_marginTop="10dp"
|
||||||
android:layout_alignParentStart="true"
|
android:text="@string/all_teacher"
|
||||||
android:layout_below="@+id/exams_dialog_subject_value"
|
android:textSize="17sp" />
|
||||||
android:layout_marginTop="10dp"
|
|
||||||
android:text="@string/exam_type"
|
|
||||||
android:textIsSelectable="true"
|
|
||||||
android:textSize="17sp" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/exams_dialog_type_value"
|
android:id="@+id/examDialogTeacherValue"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_marginTop="3dp"
|
||||||
android:layout_alignParentStart="true"
|
android:text="@string/all_no_data"
|
||||||
android:layout_below="@+id/exams_dialog_type"
|
android:textIsSelectable="true"
|
||||||
android:layout_marginTop="3dp"
|
android:textSize="12sp" />
|
||||||
android:text="@string/all_no_data"
|
|
||||||
android:textIsSelectable="true"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/exams_dialog_teacher"
|
android:id="@+id/examDialogDate"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_marginTop="10dp"
|
||||||
android:layout_alignParentStart="true"
|
android:text="@string/exam_entry_date"
|
||||||
android:layout_below="@+id/exams_dialog_type_value"
|
android:textSize="17sp" />
|
||||||
android:layout_marginTop="10dp"
|
|
||||||
android:text="@string/all_teacher"
|
|
||||||
android:textSize="17sp" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/exams_dialog_teacher_value"
|
android:id="@+id/examDialogDateValue"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_marginTop="3dp"
|
||||||
android:layout_alignParentStart="true"
|
android:text="@string/all_no_data"
|
||||||
android:layout_below="@+id/exams_dialog_teacher"
|
android:textIsSelectable="true"
|
||||||
android:layout_marginTop="3dp"
|
android:textSize="12sp" />
|
||||||
android:text="@string/all_no_data"
|
|
||||||
android:textIsSelectable="true"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/exams_dialog_date"
|
android:id="@+id/examDialogDescription"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_marginTop="10dp"
|
||||||
android:layout_alignParentStart="true"
|
android:text="@string/all_description"
|
||||||
android:layout_below="@+id/exams_dialog_teacher_value"
|
android:textSize="17sp" />
|
||||||
android:layout_marginTop="10dp"
|
|
||||||
android:text="@string/exam_entry_date"
|
|
||||||
android:textSize="17sp" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/exams_dialog_date_value"
|
android:id="@+id/examDialogDescriptionValue"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_marginTop="3dp"
|
||||||
android:layout_alignParentStart="true"
|
android:text="@string/all_no_data"
|
||||||
android:layout_below="@+id/exams_dialog_date"
|
android:textIsSelectable="true"
|
||||||
android:layout_marginTop="3dp"
|
android:textSize="12sp" />
|
||||||
android:text="@string/all_no_data"
|
|
||||||
android:textIsSelectable="true"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
|
|
||||||
<TextView
|
<Button
|
||||||
android:id="@+id/exams_dialog_description"
|
android:id="@+id/examDialogClose"
|
||||||
android:layout_width="wrap_content"
|
style="@style/Widget.AppCompat.Button.Borderless"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_gravity="end"
|
||||||
android:layout_below="@+id/exams_dialog_date_value"
|
android:layout_marginTop="15dp"
|
||||||
android:layout_marginTop="10dp"
|
android:padding="0dp"
|
||||||
android:text="@string/all_description"
|
android:text="@string/all_close"
|
||||||
android:textSize="17sp" />
|
android:textAllCaps="true"
|
||||||
|
android:textSize="15sp" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/exams_dialog_description_value"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_below="@+id/exams_dialog_description"
|
|
||||||
android:layout_marginTop="3dp"
|
|
||||||
android:text="@string/all_no_data"
|
|
||||||
android:textIsSelectable="true"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/exams_dialog_close"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_alignTop="@+id/exams_dialog_description_value"
|
|
||||||
android:layout_marginTop="25dp"
|
|
||||||
android:background="?attr/selectableItemBackground"
|
|
||||||
android:focusable="true"
|
|
||||||
android:text="@string/all_close"
|
|
||||||
android:textColor="?android:attr/android:textColorSecondary"
|
|
||||||
android:textAllCaps="true"
|
|
||||||
android:textSize="15sp" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
@ -1,30 +1,99 @@
|
|||||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/examContainer"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_alignParentBottom="true">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<FrameLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="0dp"
|
||||||
android:gravity="center"
|
android:layout_weight="1"
|
||||||
android:text="Exam" />
|
android:orientation="vertical">
|
||||||
|
|
||||||
<!--<RelativeLayout
|
<ProgressBar
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/examProgress"
|
||||||
android:layout_height="match_parent">
|
android:layout_width="wrap_content"
|
||||||
|
|
||||||
<android.support.design.widget.TabLayout
|
|
||||||
android:id="@+id/exams_fragment_tab_layout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:tabMinWidth="125dp"
|
android:layout_gravity="center"
|
||||||
app:tabMode="scrollable" />
|
android:indeterminate="true" />
|
||||||
|
|
||||||
<android.support.v4.view.ViewPager
|
<android.support.v4.widget.SwipeRefreshLayout
|
||||||
android:id="@+id/exams_fragment_viewpager"
|
android:id="@+id/examSwipe"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<android.support.v7.widget.RecyclerView
|
||||||
|
android:id="@+id/examRecycler"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
</android.support.v4.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/examEmpty"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_below="@id/exams_fragment_tab_layout" />
|
android:gravity="center"
|
||||||
</RelativeLayout>-->
|
android:orientation="vertical"
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
android:padding="10dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<android.support.v7.widget.AppCompatImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="100dp"
|
||||||
|
android:minWidth="100dp"
|
||||||
|
app:srcCompat="@drawable/ic_menu_main_exam_24dp"
|
||||||
|
app:tint="?android:attr/textColorPrimary"
|
||||||
|
tools:ignore="contentDescription" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/exam_no_items"
|
||||||
|
android:textSize="20sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/examPreviousButton"
|
||||||
|
style="@style/Widget.AppCompat.Button.Borderless"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:drawablePadding="4dp"
|
||||||
|
android:gravity="start|center"
|
||||||
|
android:text="@string/prev"
|
||||||
|
android:textAlignment="gravity" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/examNavDate"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/app_name" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/examNextButton"
|
||||||
|
style="@style/Widget.AppCompat.Button.Borderless"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:drawablePadding="4dp"
|
||||||
|
android:gravity="end|center"
|
||||||
|
android:text="@string/next"
|
||||||
|
android:textAlignment="gravity" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/exams_tab_fragment_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context="io.github.wulkanowy.ui.main.grades.GradesFragment">
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:id="@+id/exams_tab_fragment_progress_bar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:indeterminate="true" />
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:id="@+id/exams_tab_fragment_no_item_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center">
|
|
||||||
|
|
||||||
<android.support.v7.widget.AppCompatImageView
|
|
||||||
android:id="@+id/exams_tab_fragment_no_item_image"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@+id/exams_tab_fragment_no_item_text"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_marginTop="40dp"
|
|
||||||
android:minHeight="100dp"
|
|
||||||
android:minWidth="100dp"
|
|
||||||
app:srcCompat="@drawable/ic_menu_main_exam_24dp"
|
|
||||||
app:tint="?android:attr/textColorPrimary"
|
|
||||||
tools:ignore="contentDescription" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/exams_tab_fragment_no_item_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="46dp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="@string/exam_no_items"
|
|
||||||
android:textSize="20sp" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<android.support.v4.widget.SwipeRefreshLayout
|
|
||||||
android:id="@+id/exams_tab_fragment_swipe_refresh"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
|
||||||
android:id="@+id/exams_tab_fragment_recycler"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
</android.support.v4.widget.SwipeRefreshLayout>
|
|
||||||
|
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
|
@ -10,7 +10,7 @@
|
|||||||
android:paddingTop="10dp">
|
android:paddingTop="10dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/exams_header_name"
|
android:id="@+id/examHeaderDay"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
@ -18,7 +18,7 @@
|
|||||||
android:textSize="18sp" />
|
android:textSize="18sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/exams_header_date"
|
android:id="@+id/examHeaderDate"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
@ -26,8 +26,8 @@
|
|||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_marginLeft="10dp"
|
android:layout_marginLeft="10dp"
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
android:layout_toEndOf="@id/exams_header_name"
|
android:layout_toEndOf="@id/examHeaderDay"
|
||||||
android:layout_toRightOf="@id/exams_header_name"
|
android:layout_toRightOf="@id/examHeaderDay"
|
||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
android:text="@string/app_name"
|
android:text="@string/app_name"
|
||||||
android:textSize="13sp" />
|
android:textSize="13sp" />
|
||||||
|
@ -1,56 +1,47 @@
|
|||||||
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:id="@+id/exams_subitem_container"
|
android:id="@+id/exams_subitem_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minHeight="60dp"
|
android:foreground="?attr/selectableItemBackgroundBorderless">
|
||||||
card_view:cardElevation="0dp">
|
|
||||||
|
|
||||||
<RelativeLayout
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/examItemSubject"
|
||||||
android:layout_height="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:background="@drawable/ic_all_divider"
|
android:layout_height="wrap_content"
|
||||||
android:foreground="?attr/selectableItemBackgroundBorderless">
|
android:layout_marginLeft="20dp"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:text="@string/app_name"
|
||||||
|
android:textSize="15sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/exams_subitem_subject"
|
android:id="@+id/examItemType"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="20dp"
|
android:layout_alignLeft="@id/examItemSubject"
|
||||||
android:layout_marginStart="20dp"
|
android:layout_alignStart="@id/examItemSubject"
|
||||||
android:layout_marginTop="10dp"
|
android:layout_below="@id/examItemSubject"
|
||||||
android:text="@string/app_name"
|
android:layout_marginBottom="5dp"
|
||||||
android:textSize="15sp" />
|
android:layout_marginTop="5dp"
|
||||||
|
android:text="@string/app_name"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/exams_subitems_type"
|
android:id="@+id/examItemTeacher"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignLeft="@id/exams_subitem_subject"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_alignStart="@id/exams_subitem_subject"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_below="@id/exams_subitem_subject"
|
android:layout_below="@id/examItemSubject"
|
||||||
android:layout_marginBottom="5dp"
|
android:layout_marginBottom="10dp"
|
||||||
android:layout_marginTop="5dp"
|
android:layout_marginEnd="20dp"
|
||||||
android:text="@string/app_name"
|
android:layout_marginLeft="10dp"
|
||||||
android:textSize="13sp" />
|
android:layout_marginRight="20dp"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
<TextView
|
android:layout_marginTop="5dp"
|
||||||
android:id="@+id/exams_subitems_teacher"
|
android:layout_toEndOf="@id/examItemType"
|
||||||
android:layout_width="wrap_content"
|
android:layout_toRightOf="@id/examItemType"
|
||||||
android:layout_height="wrap_content"
|
android:gravity="end"
|
||||||
android:layout_alignParentEnd="true"
|
android:text="@string/app_name"
|
||||||
android:layout_alignParentRight="true"
|
android:textSize="13sp" />
|
||||||
android:layout_below="@id/exams_subitem_subject"
|
</RelativeLayout>
|
||||||
android:layout_marginBottom="10dp"
|
|
||||||
android:layout_marginEnd="20dp"
|
|
||||||
android:layout_marginLeft="10dp"
|
|
||||||
android:layout_marginRight="20dp"
|
|
||||||
android:layout_marginStart="10dp"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
android:layout_toEndOf="@id/exams_subitems_type"
|
|
||||||
android:layout_toRightOf="@id/exams_subitems_type"
|
|
||||||
android:gravity="end"
|
|
||||||
android:text="@string/app_name"
|
|
||||||
android:textSize="13sp" />
|
|
||||||
</RelativeLayout>
|
|
||||||
</android.support.v7.widget.CardView>
|
|
||||||
|
@ -163,4 +163,7 @@
|
|||||||
<string name="all_sync_fail">Podczas synchronizacji wystąpił błąd</string>
|
<string name="all_sync_fail">Podczas synchronizacji wystąpił błąd</string>
|
||||||
<string name="all_timeout">Zbyt długie oczekiwanie na połączenie</string>
|
<string name="all_timeout">Zbyt długie oczekiwanie na połączenie</string>
|
||||||
<string name="all_login_failed">Logowanie nie powiodło się. Spróbuj ponownie lub zrestartuj aplikację</string>
|
<string name="all_login_failed">Logowanie nie powiodło się. Spróbuj ponownie lub zrestartuj aplikację</string>
|
||||||
|
|
||||||
|
<string name="prev">Poprzedni</string>
|
||||||
|
<string name="next">Następny</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -156,4 +156,6 @@
|
|||||||
<string name="all_sync_fail">There was an error during synchronization</string>
|
<string name="all_sync_fail">There was an error during synchronization</string>
|
||||||
<string name="all_timeout">Too long wait for connection</string>
|
<string name="all_timeout">Too long wait for connection</string>
|
||||||
<string name="all_login_failed">Login is failed. Try again or restart the app</string>
|
<string name="all_login_failed">Login is failed. Try again or restart the app</string>
|
||||||
|
<string name="prev">Prev</string>
|
||||||
|
<string name="next">Next</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -36,4 +36,12 @@
|
|||||||
<item name="android:windowBackground">@drawable/layer_splash_background</item>
|
<item name="android:windowBackground">@drawable/layer_splash_background</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="DialogFragmentTheme" parent="Theme.AppCompat.DayNight.Dialog.Alert">
|
||||||
|
<item name="android:textColorTertiary">@android:color/primary_text_light</item>
|
||||||
|
<item name="windowActionBar">false</item>
|
||||||
|
<item name="windowNoTitle">false</item>
|
||||||
|
<item name="android:windowActionBar">false</item>
|
||||||
|
<item name="android:windowNoTitle">false</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
package io.github.wulkanowy.data.repositories.remote
|
||||||
|
|
||||||
|
import io.github.wulkanowy.api.Api
|
||||||
|
import io.github.wulkanowy.api.exams.Exam
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.reactivex.Single
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.mockito.ArgumentMatchers.any
|
||||||
|
import org.mockito.Mock
|
||||||
|
import org.mockito.Mockito.doReturn
|
||||||
|
import org.mockito.MockitoAnnotations
|
||||||
|
import org.threeten.bp.LocalDate
|
||||||
|
import java.sql.Date
|
||||||
|
|
||||||
|
class ExamRemoteTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private lateinit var mockApi: Api
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private lateinit var semesterMock: Semester
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun initApi() {
|
||||||
|
MockitoAnnotations.initMocks(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getExamsTest() {
|
||||||
|
doReturn(Single.just(listOf(
|
||||||
|
getExam("2018-09-10"),
|
||||||
|
getExam("2018-09-17")
|
||||||
|
))).`when`(mockApi).getExams(any())
|
||||||
|
|
||||||
|
doReturn("1").`when`(semesterMock).studentId
|
||||||
|
doReturn("1").`when`(semesterMock).diaryId
|
||||||
|
|
||||||
|
val exams = ExamRemote(mockApi).getExams(semesterMock, LocalDate.of(2018, 9, 10)).blockingGet()
|
||||||
|
assertEquals(2, exams.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getExam(dateString: String): Exam {
|
||||||
|
return Exam().apply {
|
||||||
|
subject = ""
|
||||||
|
group = ""
|
||||||
|
type = ""
|
||||||
|
description = ""
|
||||||
|
teacher = ""
|
||||||
|
teacherSymbol = ""
|
||||||
|
date = Date.valueOf(dateString)
|
||||||
|
entryDate = Date.valueOf(dateString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,7 @@ class StudentRemoteTest {
|
|||||||
doReturn(Single.just(listOf(Pupil("", "", "", "test", "", ""))))
|
doReturn(Single.just(listOf(Pupil("", "", "", "test", "", ""))))
|
||||||
.`when`(mockApi).getPupils()
|
.`when`(mockApi).getPupils()
|
||||||
|
|
||||||
val students = StudentRemote(mockApi).getConnectedStudents("", "", "").blockingGet()
|
val students = SessionRemote(mockApi).getConnectedStudents("", "", "").blockingGet()
|
||||||
assertEquals(1, students.size)
|
assertEquals(1, students.size)
|
||||||
assertEquals("test", students.first().studentName)
|
assertEquals("test", students.first().studentName)
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package io.github.wulkanowy.ui.login.form
|
|||||||
|
|
||||||
import io.github.wulkanowy.TestSchedulers
|
import io.github.wulkanowy.TestSchedulers
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||||
import io.github.wulkanowy.ui.login.LoginErrorHandler
|
import io.github.wulkanowy.ui.login.LoginErrorHandler
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@ -18,7 +18,7 @@ class LoginFormPresenterTest {
|
|||||||
lateinit var loginFormView: LoginFormView
|
lateinit var loginFormView: LoginFormView
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var repository: StudentRepository
|
lateinit var repository: SessionRepository
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var errorHandler: LoginErrorHandler
|
lateinit var errorHandler: LoginErrorHandler
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.ui.login.options
|
|||||||
import io.github.wulkanowy.TestSchedulers
|
import io.github.wulkanowy.TestSchedulers
|
||||||
import io.github.wulkanowy.data.ErrorHandler
|
import io.github.wulkanowy.data.ErrorHandler
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@ -21,7 +21,7 @@ class LoginOptionsPresenterTest {
|
|||||||
lateinit var loginOptionsView: LoginOptionsView
|
lateinit var loginOptionsView: LoginOptionsView
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var repository: StudentRepository
|
lateinit var repository: SessionRepository
|
||||||
|
|
||||||
private lateinit var presenter: LoginOptionsPresenter
|
private lateinit var presenter: LoginOptionsPresenter
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ class LoginOptionsPresenterTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun onSelectedStudentTest() {
|
fun onSelectedStudentTest() {
|
||||||
doReturn(Completable.complete()).`when`(repository).save(testStudent)
|
doReturn(Completable.complete()).`when`(repository).saveStudent(testStudent)
|
||||||
presenter.onSelectStudent(testStudent)
|
presenter.onSelectStudent(testStudent)
|
||||||
verify(loginOptionsView).showLoginProgress(true)
|
verify(loginOptionsView).showLoginProgress(true)
|
||||||
verify(loginOptionsView).openMainView()
|
verify(loginOptionsView).openMainView()
|
||||||
@ -71,9 +71,9 @@ class LoginOptionsPresenterTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun onSelectedStudentErrorTest() {
|
fun onSelectedStudentErrorTest() {
|
||||||
doReturn(Completable.error(testException)).`when`(repository).save(testStudent)
|
doReturn(Completable.error(testException)).`when`(repository).saveStudent(testStudent)
|
||||||
presenter.onSelectStudent(testStudent)
|
presenter.onSelectStudent(testStudent)
|
||||||
verify(loginOptionsView).showLoginProgress(true)
|
verify(loginOptionsView).showLoginProgress(true)
|
||||||
verify(errorHandler).proceed(testException)
|
verify(errorHandler).proceed(testException)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package io.github.wulkanowy.ui.splash
|
package io.github.wulkanowy.ui.splash
|
||||||
|
|
||||||
import io.github.wulkanowy.data.ErrorHandler
|
import io.github.wulkanowy.data.ErrorHandler
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
@ -15,7 +15,7 @@ class SplashPresenterTest {
|
|||||||
lateinit var splashView: SplashView
|
lateinit var splashView: SplashView
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var studentRepository: StudentRepository
|
lateinit var studentRepository: SessionRepository
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var errorHandler: ErrorHandler
|
lateinit var errorHandler: ErrorHandler
|
||||||
@ -30,15 +30,15 @@ class SplashPresenterTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testOpenLoginView() {
|
fun testOpenLoginView() {
|
||||||
doReturn(false).`when`(studentRepository).isStudentLoggedIn
|
doReturn(false).`when`(studentRepository).isSessionSaved
|
||||||
presenter.attachView(splashView)
|
presenter.attachView(splashView)
|
||||||
verify(splashView).openLoginActivity()
|
verify(splashView).openLoginView()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testMainMainView() {
|
fun testMainMainView() {
|
||||||
doReturn(true).`when`(studentRepository).isStudentLoggedIn
|
doReturn(true).`when`(studentRepository).isSessionSaved
|
||||||
presenter.attachView(splashView)
|
presenter.attachView(splashView)
|
||||||
verify(splashView).openMainActivity()
|
verify(splashView).openMainView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,55 +86,55 @@ class TimeUtilsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test fun isHolidaysInSchoolEndTest() {
|
@Test fun isHolidaysInSchoolEndTest() {
|
||||||
assertFalse(isHolidays(LocalDate.of(2017, 6, 23), 2017))
|
assertFalse(isHolidays(LocalDate.of(2017, 6, 23)))
|
||||||
assertFalse(isHolidays(LocalDate.of(2018, 6, 22), 2018))
|
assertFalse(isHolidays(LocalDate.of(2018, 6, 22)))
|
||||||
assertFalse(isHolidays(LocalDate.of(2019, 6, 21), 2019))
|
assertFalse(isHolidays(LocalDate.of(2019, 6, 21)))
|
||||||
assertFalse(isHolidays(LocalDate.of(2020, 6, 26), 2020))
|
assertFalse(isHolidays(LocalDate.of(2020, 6, 26)))
|
||||||
assertFalse(isHolidays(LocalDate.of(2021, 6, 25), 2021))
|
assertFalse(isHolidays(LocalDate.of(2021, 6, 25)))
|
||||||
assertFalse(isHolidays(LocalDate.of(2022, 6, 24), 2022))
|
assertFalse(isHolidays(LocalDate.of(2022, 6, 24)))
|
||||||
assertFalse(isHolidays(LocalDate.of(2023, 6, 23), 2023))
|
assertFalse(isHolidays(LocalDate.of(2023, 6, 23)))
|
||||||
assertFalse(isHolidays(LocalDate.of(2024, 6, 21), 2024))
|
assertFalse(isHolidays(LocalDate.of(2024, 6, 21)))
|
||||||
assertFalse(isHolidays(LocalDate.of(2025, 6, 27), 2025))
|
assertFalse(isHolidays(LocalDate.of(2025, 6, 27)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun isHolidaysInHolidaysStartTest() {
|
@Test fun isHolidaysInHolidaysStartTest() {
|
||||||
assertTrue(isHolidays(LocalDate.of(2017, 6, 24), 2017))
|
assertTrue(isHolidays(LocalDate.of(2017, 6, 24)))
|
||||||
assertTrue(isHolidays(LocalDate.of(2018, 6, 23), 2018))
|
assertTrue(isHolidays(LocalDate.of(2018, 6, 23)))
|
||||||
assertTrue(isHolidays(LocalDate.of(2019, 6, 22), 2019))
|
assertTrue(isHolidays(LocalDate.of(2019, 6, 22)))
|
||||||
assertTrue(isHolidays(LocalDate.of(2020, 6, 27), 2020))
|
assertTrue(isHolidays(LocalDate.of(2020, 6, 27)))
|
||||||
assertTrue(isHolidays(LocalDate.of(2021, 6, 26), 2021))
|
assertTrue(isHolidays(LocalDate.of(2021, 6, 26)))
|
||||||
assertTrue(isHolidays(LocalDate.of(2022, 6, 25), 2022))
|
assertTrue(isHolidays(LocalDate.of(2022, 6, 25)))
|
||||||
assertTrue(isHolidays(LocalDate.of(2023, 6, 24), 2023))
|
assertTrue(isHolidays(LocalDate.of(2023, 6, 24)))
|
||||||
assertTrue(isHolidays(LocalDate.of(2024, 6, 22), 2024))
|
assertTrue(isHolidays(LocalDate.of(2024, 6, 22)))
|
||||||
assertTrue(isHolidays(LocalDate.of(2025, 6, 28), 2025))
|
assertTrue(isHolidays(LocalDate.of(2025, 6, 28)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun isHolidaysInHolidaysEndTest() {
|
@Test fun isHolidaysInHolidaysEndTest() {
|
||||||
assertTrue(isHolidays(LocalDate.of(2017, 9, 1), 2017)) // friday
|
assertTrue(isHolidays(LocalDate.of(2017, 9, 1))) // friday
|
||||||
assertTrue(isHolidays(LocalDate.of(2017, 9, 2), 2017)) // saturday
|
assertTrue(isHolidays(LocalDate.of(2017, 9, 2))) // saturday
|
||||||
assertTrue(isHolidays(LocalDate.of(2017, 9, 3), 2017)) // sunday
|
assertTrue(isHolidays(LocalDate.of(2017, 9, 3))) // sunday
|
||||||
assertTrue(isHolidays(LocalDate.of(2018, 9, 1), 2018)) // saturday
|
assertTrue(isHolidays(LocalDate.of(2018, 9, 1))) // saturday
|
||||||
assertTrue(isHolidays(LocalDate.of(2018, 9, 2), 2018)) // sunday
|
assertTrue(isHolidays(LocalDate.of(2018, 9, 2))) // sunday
|
||||||
assertTrue(isHolidays(LocalDate.of(2019, 9, 1), 2019)) // sunday
|
assertTrue(isHolidays(LocalDate.of(2019, 9, 1))) // sunday
|
||||||
assertTrue(isHolidays(LocalDate.of(2020, 8, 31), 2020)) // monday
|
assertTrue(isHolidays(LocalDate.of(2020, 8, 31))) // monday
|
||||||
assertTrue(isHolidays(LocalDate.of(2021, 8, 31), 2021)) // tuesday
|
assertTrue(isHolidays(LocalDate.of(2021, 8, 31))) // tuesday
|
||||||
assertTrue(isHolidays(LocalDate.of(2022, 8, 31), 2022)) // wednesday
|
assertTrue(isHolidays(LocalDate.of(2022, 8, 31))) // wednesday
|
||||||
assertTrue(isHolidays(LocalDate.of(2023, 9, 1), 2023)) // friday
|
assertTrue(isHolidays(LocalDate.of(2023, 9, 1))) // friday
|
||||||
assertTrue(isHolidays(LocalDate.of(2023, 9, 2), 2023)) // saturday
|
assertTrue(isHolidays(LocalDate.of(2023, 9, 2))) // saturday
|
||||||
assertTrue(isHolidays(LocalDate.of(2023, 9, 3), 2023)) // sunday
|
assertTrue(isHolidays(LocalDate.of(2023, 9, 3))) // sunday
|
||||||
assertTrue(isHolidays(LocalDate.of(2024, 9, 1), 2024)) // sunday
|
assertTrue(isHolidays(LocalDate.of(2024, 9, 1))) // sunday
|
||||||
assertTrue(isHolidays(LocalDate.of(2025, 8, 31), 2025)) // sunday
|
assertTrue(isHolidays(LocalDate.of(2025, 8, 31))) // sunday
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun isHolidaysInSchoolStartTest() {
|
@Test fun isHolidaysInSchoolStartTest() {
|
||||||
assertFalse(isHolidays(LocalDate.of(2017, 9, 4), 2017)) // monday
|
assertFalse(isHolidays(LocalDate.of(2017, 9, 4))) // monday
|
||||||
assertFalse(isHolidays(LocalDate.of(2018, 9, 3), 2018)) // monday
|
assertFalse(isHolidays(LocalDate.of(2018, 9, 3))) // monday
|
||||||
assertFalse(isHolidays(LocalDate.of(2019, 9, 2), 2019)) // monday
|
assertFalse(isHolidays(LocalDate.of(2019, 9, 2))) // monday
|
||||||
assertFalse(isHolidays(LocalDate.of(2020, 9, 1), 2020)) // tuesday
|
assertFalse(isHolidays(LocalDate.of(2020, 9, 1))) // tuesday
|
||||||
assertFalse(isHolidays(LocalDate.of(2021, 9, 1), 2021)) // wednesday
|
assertFalse(isHolidays(LocalDate.of(2021, 9, 1))) // wednesday
|
||||||
assertFalse(isHolidays(LocalDate.of(2022, 9, 1), 2022)) // thursday
|
assertFalse(isHolidays(LocalDate.of(2022, 9, 1))) // thursday
|
||||||
assertFalse(isHolidays(LocalDate.of(2023, 9, 4), 2023)) // monday
|
assertFalse(isHolidays(LocalDate.of(2023, 9, 4))) // monday
|
||||||
assertFalse(isHolidays(LocalDate.of(2024, 9, 2), 2024)) // monday
|
assertFalse(isHolidays(LocalDate.of(2024, 9, 2))) // monday
|
||||||
assertFalse(isHolidays(LocalDate.of(2025, 9, 1), 2025)) // monday
|
assertFalse(isHolidays(LocalDate.of(2025, 9, 1))) // monday
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.2.61'
|
ext.kotlin_version = '1.2.70'
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
google()
|
google()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user