From 7a3c0de7ad17fa2005e2503009ce05ce0786fdba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Borcz?= Date: Sat, 24 Nov 2018 18:51:41 +0100 Subject: [PATCH] Add account manager (#183) --- .travis.yml | 2 +- app/build.gradle | 18 ++-- .../repositories/local/AttendanceLocalTest.kt | 2 +- .../data/repositories/local/ExamLocalTest.kt | 2 +- ...essionLocalTest.kt => StudentLocalTest.kt} | 17 ++-- .../repositories/local/TimetableLocalTest.kt | 2 +- app/src/main/AndroidManifest.xml | 1 - .../java/io/github/wulkanowy/WulkanowyApp.kt | 2 - .../io/github/wulkanowy/data/ApiHelper.kt | 27 +++++ .../io/github/wulkanowy/data/ErrorHandler.kt | 5 +- .../github/wulkanowy/data/RepositoryModule.kt | 39 +++++--- .../github/wulkanowy/data/db/AppDatabase.kt | 18 ++-- .../wulkanowy/data/db/SharedPrefHelper.kt | 8 ++ .../wulkanowy/data/db/dao/AttendanceDao.kt | 2 +- .../github/wulkanowy/data/db/dao/ExamDao.kt | 2 +- .../github/wulkanowy/data/db/dao/GradeDao.kt | 10 +- .../wulkanowy/data/db/dao/GradeSummaryDao.kt | 3 +- .../wulkanowy/data/db/dao/HomeworkDao.kt | 2 +- .../github/wulkanowy/data/db/dao/NoteDao.kt | 4 +- .../wulkanowy/data/db/dao/SemesterDao.kt | 17 ++-- .../wulkanowy/data/db/dao/StudentDao.kt | 23 ++++- .../wulkanowy/data/db/dao/TimetableDao.kt | 2 +- .../wulkanowy/data/db/entities/Semester.kt | 31 +++--- .../wulkanowy/data/db/entities/Student.kt | 36 ++++--- .../data/repositories/SemesterRepository.kt | 42 ++++++++ .../data/repositories/SessionRepository.kt | 64 ------------ .../data/repositories/StudentRepository.kt | 58 +++++++++++ .../repositories/local/AttendanceLocal.kt | 2 +- .../data/repositories/local/ExamLocal.kt | 2 +- .../data/repositories/local/GradeLocal.kt | 4 +- .../repositories/local/GradeSummaryLocal.kt | 2 +- .../data/repositories/local/HomeworkLocal.kt | 2 +- .../data/repositories/local/NoteLocal.kt | 4 +- .../data/repositories/local/SemesterLocal.kt | 27 +++++ .../data/repositories/local/SessionLocal.kt | 55 ----------- .../data/repositories/local/StudentLocal.kt | 60 +++++++++++ .../data/repositories/local/TimetableLocal.kt | 4 +- .../repositories/remote/AttendanceRemote.kt | 16 ++- .../data/repositories/remote/ExamRemote.kt | 16 ++- .../data/repositories/remote/GradeRemote.kt | 46 ++++----- .../repositories/remote/GradeSummaryRemote.kt | 28 +++--- .../repositories/remote/HomeworkRemote.kt | 8 +- .../data/repositories/remote/NoteRemote.kt | 8 +- .../repositories/remote/SemesterRemote.kt | 30 ++++++ .../data/repositories/remote/SessionRemote.kt | 96 ------------------ .../data/repositories/remote/StudentRemote.kt | 29 ++++++ .../repositories/remote/TimetableRemote.kt | 17 ++-- .../wulkanowy/services/job/SyncWorker.kt | 20 ++-- .../widgets/TimetableWidgetService.kt | 12 ++- .../ui/modules/account/AccountDialog.kt | 99 +++++++++++++++++++ .../ui/modules/account/AccountItem.kt | 51 ++++++++++ .../ui/modules/account/AccountPresenter.kt | 70 +++++++++++++ .../ui/modules/account/AccountView.kt | 19 ++++ .../modules/attendance/AttendanceFragment.kt | 2 +- .../modules/attendance/AttendancePresenter.kt | 10 +- .../wulkanowy/ui/modules/exam/ExamFragment.kt | 6 +- .../ui/modules/exam/ExamPresenter.kt | 10 +- .../ui/modules/grade/GradeFragment.kt | 27 ++--- .../ui/modules/grade/GradePresenter.kt | 39 ++++---- .../grade/details/GradeDetailsFragment.kt | 2 +- .../grade/details/GradeDetailsPresenter.kt | 9 +- .../grade/summary/GradeSummaryFragment.kt | 6 +- .../grade/summary/GradeSummaryPresenter.kt | 11 ++- .../modules/grade/summary/GradeSummaryView.kt | 2 +- .../ui/modules/homework/HomeworkFragment.kt | 2 +- .../ui/modules/homework/HomeworkPresenter.kt | 10 +- .../ui/modules/login/LoginErrorHandler.kt | 9 +- .../modules/login/form/LoginFormPresenter.kt | 8 +- .../login/options/LoginOptionsFragment.kt | 8 +- .../login/options/LoginOptionsPresenter.kt | 30 ++++-- .../wulkanowy/ui/modules/main/MainActivity.kt | 25 ++++- .../wulkanowy/ui/modules/main/MainModule.kt | 8 ++ .../ui/modules/main/MainPresenter.kt | 5 + .../wulkanowy/ui/modules/main/MainView.kt | 2 + .../wulkanowy/ui/modules/more/MoreFragment.kt | 2 +- .../wulkanowy/ui/modules/more/MoreItem.kt | 9 +- .../wulkanowy/ui/modules/note/NoteFragment.kt | 2 +- .../ui/modules/note/NotePresenter.kt | 12 ++- .../ui/modules/splash/SplashPresenter.kt | 6 +- .../ui/modules/timetable/TimetableFragment.kt | 2 +- .../modules/timetable/TimetablePresenter.kt | 10 +- .../timetable/TimetableWidgetFactory.kt | 12 ++- .../utils/FlexibleAdapterExtension.kt | 5 +- .../main/res/drawable/ic_account_add_24dp.xml | 11 +++ .../drawable/ic_account_circular_border.xml | 8 ++ .../main/res/drawable/ic_all_account_24dp.xml | 12 +++ app/src/main/res/layout/dialog_account.xml | 50 ++++++++++ app/src/main/res/layout/dialog_attendance.xml | 1 - app/src/main/res/layout/dialog_exam.xml | 1 - app/src/main/res/layout/dialog_homework.xml | 1 - app/src/main/res/layout/dialog_note.xml | 1 - app/src/main/res/layout/dialog_timetable.xml | 1 - app/src/main/res/layout/item_account.xml | 48 +++++++++ app/src/main/res/layout/item_more.xml | 3 +- app/src/main/res/menu/action_menu_grade.xml | 6 +- app/src/main/res/menu/action_menu_main.xml | 10 ++ app/src/main/res/values-pl/strings.xml | 16 ++- app/src/main/res/values/strings.xml | 16 ++- app/src/main/res/values/styles.xml | 1 - .../remote/AttendanceRemoteTest.kt | 7 +- .../repositories/remote/ExamRemoteTest.kt | 5 +- ...sionRemoteTest.kt => StudentRemoteTest.kt} | 6 +- .../remote/TimetableRemoteTest.kt | 7 +- .../login/form/LoginFormPresenterTest.kt | 14 +-- .../options/LoginOptionsPresenterTest.kt | 33 ++++--- .../ui/modules/splash/SplashPresenterTest.kt | 10 +- 106 files changed, 1140 insertions(+), 585 deletions(-) rename app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/{SessionLocalTest.kt => StudentLocalTest.kt} (70%) create mode 100644 app/src/main/java/io/github/wulkanowy/data/ApiHelper.kt create mode 100644 app/src/main/java/io/github/wulkanowy/data/repositories/SemesterRepository.kt delete mode 100644 app/src/main/java/io/github/wulkanowy/data/repositories/SessionRepository.kt create mode 100644 app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt create mode 100644 app/src/main/java/io/github/wulkanowy/data/repositories/local/SemesterLocal.kt delete mode 100644 app/src/main/java/io/github/wulkanowy/data/repositories/local/SessionLocal.kt create mode 100644 app/src/main/java/io/github/wulkanowy/data/repositories/local/StudentLocal.kt create mode 100644 app/src/main/java/io/github/wulkanowy/data/repositories/remote/SemesterRemote.kt delete mode 100644 app/src/main/java/io/github/wulkanowy/data/repositories/remote/SessionRemote.kt create mode 100644 app/src/main/java/io/github/wulkanowy/data/repositories/remote/StudentRemote.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountDialog.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountItem.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountPresenter.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountView.kt create mode 100644 app/src/main/res/drawable/ic_account_add_24dp.xml create mode 100644 app/src/main/res/drawable/ic_account_circular_border.xml create mode 100644 app/src/main/res/drawable/ic_all_account_24dp.xml create mode 100644 app/src/main/res/layout/dialog_account.xml create mode 100644 app/src/main/res/layout/item_account.xml create mode 100644 app/src/main/res/menu/action_menu_main.xml rename app/src/test/java/io/github/wulkanowy/data/repositories/remote/{SessionRemoteTest.kt => StudentRemoteTest.kt} (79%) diff --git a/.travis.yml b/.travis.yml index efef4fee..3d2c2d5b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,7 +52,7 @@ script: - ./gradlew createDebugCoverageReport --stacktrace -PdisableCrashlytics --daemon - ./gradlew jacocoTestReport --stacktrace --daemon - if [ "$TRAVIS_PULL_REQUEST" != "false" ] || [ "$TRAVIS_BRANCH" == "master" ]; then - ./gradlew sonarqube -x test -x lint -x fabricGenerateResourcesRelease -Dsonar.host.url=$SONAR_HOST -Dsonar.organization=$SONAR_ORG -Dsonar.login=$SONAR_KEY -Dsonar.branch.name=$TRAVIS_BRANCH -PdisableCrashlytics --stacktrace --daemon; + ./gradlew sonarqube -x test -x lint -x fabricGenerateResourcesRelease -Dsonar.host.url=$SONAR_HOST -Dsonar.organization=$SONAR_ORG -Dsonar.login=$SONAR_KEY -Dsonar.branch.name=${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH} -PdisableCrashlytics --stacktrace --daemon; fi - | if [ $TRAVIS_TAG ]; then diff --git a/app/build.gradle b/app/build.gradle index 7532ba7c..bc3365a8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -31,7 +31,7 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true playAccountConfig = playAccountConfigs.defaultAccountConfig - manifestPlaceholders = [ fabricApiKey: fabricApiKey ] + manifestPlaceholders = [fabricApiKey: fabricApiKey] } signingConfigs { @@ -74,16 +74,18 @@ play { uploadImages = true } -ext.androidx_version = "1.0.0" +configurations.all { + resolutionStrategy.force "com.squareup.okhttp3:okhttp-urlconnection:3.11.0" +} dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - implementation('com.github.wulkanowy:api:a80b8e5') { exclude module: "threetenbp" } + implementation('com.github.wulkanowy:api:0ac961607b') { exclude module: "threetenbp" } - implementation "androidx.legacy:legacy-support-v4:$androidx_version" - implementation "androidx.appcompat:appcompat:$androidx_version" - implementation "androidx.cardview:cardview:$androidx_version" - implementation "com.google.android.material:material:$androidx_version" + implementation "androidx.legacy:legacy-support-v4:1.0.0" + implementation "androidx.appcompat:appcompat:1.0.2" + implementation "androidx.cardview:cardview:1.0.0" + implementation "com.google.android.material:material:1.0.0" implementation 'androidx.multidex:multidex:2.0.0' implementation 'com.takisoft.preferencex:preferencex:1.0.0' @@ -113,7 +115,6 @@ dependencies { implementation "com.jakewharton.timber:timber:4.7.1" implementation "at.favre.lib:slf4j-timber:1.0.1" - implementation 'com.akaita.java:rxjava2-debug:1.3.0' implementation("com.crashlytics.sdk.android:crashlytics:2.9.5@aar") { transitive = true } @@ -132,6 +133,5 @@ dependencies { androidTestImplementation 'androidx.test:runner:1.1.0' androidTestImplementation 'androidx.test.ext:junit:1.0.0' androidTestImplementation "org.mockito:mockito-android:2.23.0" - androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version" } diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/AttendanceLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/AttendanceLocalTest.kt index 47116483..8cbd13cd 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/AttendanceLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/AttendanceLocalTest.kt @@ -23,7 +23,7 @@ class AttendanceLocalTest { @Before fun createDb() { testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java).build() - attendanceLocal = AttendanceLocal(testDb.attendanceDao()) + attendanceLocal = AttendanceLocal(testDb.attendanceDao) } @After diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/ExamLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/ExamLocalTest.kt index 7e4217f1..c60348e3 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/ExamLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/ExamLocalTest.kt @@ -23,7 +23,7 @@ class ExamLocalTest { @Before fun createDb() { testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java).build() - examLocal = ExamLocal(testDb.examsDao()) + examLocal = ExamLocal(testDb.examsDao) } @After diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/SessionLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/StudentLocalTest.kt similarity index 70% rename from app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/SessionLocalTest.kt rename to app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/StudentLocalTest.kt index ba9273f4..85ff2319 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/SessionLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/StudentLocalTest.kt @@ -14,9 +14,9 @@ import org.junit.runner.RunWith import kotlin.test.assertEquals @RunWith(AndroidJUnit4::class) -class SessionLocalTest { +class StudentLocalTest { - private lateinit var sessionLocal: SessionLocal + private lateinit var studentLocal: StudentLocal private lateinit var testDb: AppDatabase @@ -26,9 +26,9 @@ class SessionLocalTest { fun createDb() { val context = ApplicationProvider.getApplicationContext() testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java) - .build() + .build() sharedHelper = SharedPrefHelper(context.getSharedPreferences("TEST", Context.MODE_PRIVATE)) - sessionLocal = SessionLocal(testDb.studentDao(), testDb.semesterDao(), sharedHelper, context) + studentLocal = StudentLocal(testDb.studentDao, sharedHelper, context) } @After @@ -38,12 +38,11 @@ class SessionLocalTest { @Test fun saveAndReadTest() { - sessionLocal.saveStudent(Student(email = "test", password = "test123", schoolSymbol = "23", endpoint = "fakelog.cf", loginType = "AUTO")).blockingAwait() - assert(sharedHelper.getLong(SessionLocal.LAST_USER_KEY, 0) == 1L) + studentLocal.saveStudent(Student(email = "test", password = "test123", schoolSymbol = "23", endpoint = "fakelog.cf", loginType = "AUTO", isCurrent = true)) + .blockingAwait() + assert(studentLocal.isStudentSaved) - assert(sessionLocal.isSessionSaved) - - val student = sessionLocal.getLastStudent().blockingGet() + val student = studentLocal.getCurrentStudent().blockingGet() assertEquals("23", student.schoolSymbol) } } diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/TimetableLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/TimetableLocalTest.kt index 81d822ea..df0a7994 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/TimetableLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/TimetableLocalTest.kt @@ -24,7 +24,7 @@ class TimetableLocalTest { @Before fun createDb() { testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java).build() - timetableDb = TimetableLocal(testDb.timetableDao()) + timetableDb = TimetableLocal(testDb.timetableDao) } @After diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0a7c78c8..dbbd5874 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -38,7 +38,6 @@ android:name=".ui.modules.main.MainActivity" android:configChanges="orientation|screenSize" android:label="@string/main_title" - android:launchMode="singleTop" android:theme="@style/WulkanowyTheme.NoActionBar" /> Unit = {} open fun proceed(error: Throwable) { - Timber.e(RxJava2Debug.getEnhancedStackTrace(error), "An exception occurred while the Wulkanowy was running") + Timber.e(error, "An exception occurred while the Wulkanowy was running") showErrorMessage((when (error) { is UnknownHostException -> resources.getString(R.string.all_no_internet) diff --git a/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt b/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt index 5264f444..2af26be1 100644 --- a/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt +++ b/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt @@ -9,6 +9,10 @@ import dagger.Module import dagger.Provides import io.github.wulkanowy.api.Api import io.github.wulkanowy.data.db.AppDatabase +import okhttp3.logging.HttpLoggingInterceptor +import okhttp3.logging.HttpLoggingInterceptor.Level.BASIC +import okhttp3.logging.HttpLoggingInterceptor.Level.NONE +import timber.log.Timber import javax.inject.Singleton @Module @@ -18,14 +22,19 @@ internal class RepositoryModule { @Provides fun provideInternetObservingSettings(): InternetObservingSettings { return InternetObservingSettings.builder() - .strategy(SocketInternetObservingStrategy()) - .host("www.google.com") - .build() + .strategy(SocketInternetObservingStrategy()) + .host("www.google.com") + .build() } @Singleton @Provides - fun provideApi() = Api() + fun provideApi(): Api { + return Api().apply { + logLevel = NONE + setInterceptor(HttpLoggingInterceptor(HttpLoggingInterceptor.Logger { Timber.d(it) }).setLevel(BASIC)) + } + } @Singleton @Provides @@ -36,43 +45,41 @@ internal class RepositoryModule { @Singleton @Provides - fun provideSharedPref(context: Context): SharedPreferences { - return PreferenceManager.getDefaultSharedPreferences(context) - } + fun provideSharedPref(context: Context): SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) @Singleton @Provides - fun provideStudentDao(database: AppDatabase) = database.studentDao() + fun provideStudentDao(database: AppDatabase) = database.studentDao @Singleton @Provides - fun provideSemesterDao(database: AppDatabase) = database.semesterDao() + fun provideSemesterDao(database: AppDatabase) = database.semesterDao @Singleton @Provides - fun provideGradeDao(database: AppDatabase) = database.gradeDao() + fun provideGradeDao(database: AppDatabase) = database.gradeDao @Singleton @Provides - fun provideGradeSummaryDao(database: AppDatabase) = database.gradeSummaryDao() + fun provideGradeSummaryDao(database: AppDatabase) = database.gradeSummaryDao @Singleton @Provides - fun provideExamDao(database: AppDatabase) = database.examsDao() + fun provideExamDao(database: AppDatabase) = database.examsDao @Singleton @Provides - fun provideAttendanceDao(database: AppDatabase) = database.attendanceDao() + fun provideAttendanceDao(database: AppDatabase) = database.attendanceDao @Singleton @Provides - fun provideTimetableDao(database: AppDatabase) = database.timetableDao() + fun provideTimetableDao(database: AppDatabase) = database.timetableDao @Singleton @Provides - fun provideNoteDao(database: AppDatabase) = database.noteDao() + fun provideNoteDao(database: AppDatabase) = database.noteDao @Singleton @Provides - fun provideHomeworkDao(database: AppDatabase) = database.homeworkDao() + fun provideHomeworkDao(database: AppDatabase) = database.homeworkDao } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt b/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt index 91c468b0..ca717a67 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt @@ -51,21 +51,21 @@ abstract class AppDatabase : RoomDatabase() { } } - abstract fun studentDao(): StudentDao + abstract val studentDao: StudentDao - abstract fun semesterDao(): SemesterDao + abstract val semesterDao: SemesterDao - abstract fun examsDao(): ExamDao + abstract val examsDao: ExamDao - abstract fun timetableDao(): TimetableDao + abstract val timetableDao: TimetableDao - abstract fun attendanceDao(): AttendanceDao + abstract val attendanceDao: AttendanceDao - abstract fun gradeDao(): GradeDao + abstract val gradeDao: GradeDao - abstract fun gradeSummaryDao(): GradeSummaryDao + abstract val gradeSummaryDao: GradeSummaryDao - abstract fun noteDao(): NoteDao + abstract val noteDao: NoteDao - abstract fun homeworkDao(): HomeworkDao + abstract val homeworkDao: HomeworkDao } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefHelper.kt b/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefHelper.kt index b3b6f5e3..656b39d4 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefHelper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefHelper.kt @@ -19,6 +19,14 @@ class SharedPrefHelper @Inject constructor(private val sharedPref: SharedPrefere return sharedPref.getLong(key, defaultValue) } + fun putBoolean(key: String, value: Boolean) { + sharedPref.edit().putBoolean(key, value).apply() + } + + fun getBoolean(key: String, defaultValue: Boolean): Boolean { + return sharedPref.getBoolean(key, defaultValue) + } + fun delete(key: String) { sharedPref.edit().remove(key).apply() } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceDao.kt index 7babb76e..287b7d96 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceDao.kt @@ -18,5 +18,5 @@ interface AttendanceDao { fun deleteAll(exams: List) @Query("SELECT * FROM Attendance WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end") - fun getExams(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe> + fun load(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/ExamDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/ExamDao.kt index 58c7867b..60c053c2 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/ExamDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/ExamDao.kt @@ -18,5 +18,5 @@ interface ExamDao { fun deleteAll(exams: List) @Query("SELECT * FROM Exams WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end") - fun getExams(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe> + fun load(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeDao.kt index e5a153a6..531db4ff 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeDao.kt @@ -1,6 +1,10 @@ package io.github.wulkanowy.data.db.dao -import androidx.room.* +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.Query +import androidx.room.Update import io.github.wulkanowy.data.db.entities.Grade import io.reactivex.Maybe @@ -20,8 +24,8 @@ interface GradeDao { fun deleteAll(grades: List) @Query("SELECT * FROM Grades WHERE semester_id = :semesterId AND student_id = :studentId") - fun getGrades(semesterId: Int, studentId: Int): Maybe> + fun load(semesterId: Int, studentId: Int): Maybe> @Query("SELECT * FROM Grades WHERE is_read = 0 AND semester_id = :semesterId AND student_id = :studentId") - fun getNewGrades(semesterId: Int, studentId: Int): Maybe> + fun loadNew(semesterId: Int, studentId: Int): Maybe> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeSummaryDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeSummaryDao.kt index 3a9b9d81..92748148 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeSummaryDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeSummaryDao.kt @@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert -import androidx.room.OnConflictStrategy.REPLACE import androidx.room.Query import io.github.wulkanowy.data.db.entities.GradeSummary import io.reactivex.Maybe @@ -18,5 +17,5 @@ interface GradeSummaryDao { fun deleteAll(gradesSummary: List) @Query("SELECT * FROM grades_summary WHERE student_id = :studentId AND semester_id = :semesterId") - fun getGradesSummary(semesterId: Int, studentId: Int): Maybe> + fun load(semesterId: Int, studentId: Int): Maybe> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/HomeworkDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/HomeworkDao.kt index 3961df4d..56ebf88e 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/HomeworkDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/HomeworkDao.kt @@ -18,5 +18,5 @@ interface HomeworkDao { fun deleteAll(homework: List) @Query("SELECT * FROM Homework WHERE semester_id = :semesterId AND student_id = :studentId AND date = :date") - fun getHomework(semesterId: Int, studentId: Int, date: LocalDate): Maybe> + fun load(semesterId: Int, studentId: Int, date: LocalDate): Maybe> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/NoteDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/NoteDao.kt index efba6e46..1b94d4d0 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/NoteDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/NoteDao.kt @@ -24,8 +24,8 @@ interface NoteDao { fun deleteAll(notes: List) @Query("SELECT * FROM Notes WHERE semester_id = :semesterId AND student_id = :studentId") - fun getNotes(semesterId: Int, studentId: Int): Maybe> + fun load(semesterId: Int, studentId: Int): Maybe> @Query("SELECT * FROM Notes WHERE is_read = 0 AND semester_id = :semesterId AND student_id = :studentId") - fun getNewNotes(semesterId: Int, studentId: Int): Maybe> + fun loadNew(semesterId: Int, studentId: Int): Maybe> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/SemesterDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/SemesterDao.kt index 135e65e5..eab24e85 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/SemesterDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/SemesterDao.kt @@ -2,22 +2,23 @@ package io.github.wulkanowy.data.db.dao import androidx.room.Dao import androidx.room.Insert +import androidx.room.OnConflictStrategy.IGNORE import androidx.room.Query import io.github.wulkanowy.data.db.entities.Semester -import io.reactivex.Single +import io.reactivex.Maybe @Dao interface SemesterDao { - @Insert + @Insert(onConflict = IGNORE) fun insertAll(semester: List) + @Query("UPDATE Semesters SET is_current = 1 WHERE semester_id = :semesterId AND diary_id = :diaryId") + fun update(semesterId: Int, diaryId: Int) + @Query("SELECT * FROM Semesters WHERE student_id = :studentId") - fun getSemester(studentId: Int): Single> + fun load(studentId: Int): Maybe> - @Query("UPDATE Semesters SET is_current = 0") - fun resetCurrentSemester() - - @Query("UPDATE Semesters SET is_current = 1 WHERE semester_id = :semesterId") - fun setCurrentSemester(semesterId: Int) + @Query("UPDATE Semesters SET is_current = 0 WHERE student_id = :studentId") + fun resetCurrent(studentId: Int) } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt index 41bf5da9..8fa30e90 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt @@ -1,17 +1,32 @@ package io.github.wulkanowy.data.db.dao import androidx.room.Dao +import androidx.room.Delete import androidx.room.Insert +import androidx.room.OnConflictStrategy.FAIL import androidx.room.Query +import androidx.room.Update import io.github.wulkanowy.data.db.entities.Student import io.reactivex.Maybe @Dao interface StudentDao { - @Insert - fun insert(student: Student): Long + @Insert(onConflict = FAIL) + fun insert(student: Student) - @Query("SELECT * FROM Students WHERE id = :id") - fun load(id: Long): Maybe + @Update + fun update(student: Student) + + @Delete + fun delete(student: Student) + + @Query("SELECT * FROM Students WHERE is_current = 1") + fun loadCurrent(): Maybe + + @Query("SELECT * FROM Students") + fun loadAll(): Maybe> + + @Query("UPDATE Students SET is_current = 0") + fun resetCurrent() } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableDao.kt index 2624e94a..9253993c 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableDao.kt @@ -18,5 +18,5 @@ interface TimetableDao { fun deleteAll(exams: List) @Query("SELECT * FROM Timetable WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end") - fun getTimetable(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe> + fun load(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Semester.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Semester.kt index fc776e9b..509a692e 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Semester.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Semester.kt @@ -2,29 +2,30 @@ package io.github.wulkanowy.data.db.entities import androidx.room.ColumnInfo import androidx.room.Entity +import androidx.room.Index import androidx.room.PrimaryKey -@Entity(tableName = "Semesters") +@Entity(tableName = "Semesters", indices = [Index(value = ["student_id", "diary_id", "semester_id"], unique = true)]) data class Semester( - @PrimaryKey(autoGenerate = true) - var id: Long = 0, + @PrimaryKey(autoGenerate = true) + var id: Long = 0, - @ColumnInfo(name = "student_id") - var studentId: Int, + @ColumnInfo(name = "student_id") + var studentId: Int, - @ColumnInfo(name = "diary_id") - var diaryId: Int, + @ColumnInfo(name = "diary_id") + var diaryId: Int, - @ColumnInfo(name = "diary_name") - var diaryName: String, + @ColumnInfo(name = "diary_name") + var diaryName: String, - @ColumnInfo(name = "semester_id") - var semesterId: Int, + @ColumnInfo(name = "semester_id") + var semesterId: Int, - @ColumnInfo(name = "semester_name") - var semesterName: Int, + @ColumnInfo(name = "semester_name") + var semesterName: Int, - @ColumnInfo(name = "is_current") - var current: Boolean = false + @ColumnInfo(name = "is_current") + var isCurrent: Boolean = false ) diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Student.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Student.kt index a9f405c8..1fe4cf8d 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Student.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Student.kt @@ -2,33 +2,37 @@ package io.github.wulkanowy.data.db.entities import androidx.room.ColumnInfo import androidx.room.Entity +import androidx.room.Index import androidx.room.PrimaryKey -@Entity(tableName = "Students") +@Entity(tableName = "Students", indices = [Index(value = ["email", "symbol", "student_id", "school_id"], unique = true)]) data class Student( - @PrimaryKey(autoGenerate = true) - var id: Long = 0, + @PrimaryKey(autoGenerate = true) + var id: Long = 0, - var endpoint: String, + var endpoint: String, - var loginType: String, + var loginType: String, - var email: String, + var email: String, - var password: String, + var password: String, - var symbol: String = "", + var symbol: String = "", - @ColumnInfo(name = "student_id") - var studentId: Int = 0, + @ColumnInfo(name = "student_id") + var studentId: Int = 0, - @ColumnInfo(name = "student_name") - var studentName: String = "", + @ColumnInfo(name = "student_name") + var studentName: String = "", - @ColumnInfo(name = "school_id") - var schoolSymbol: String = "", + @ColumnInfo(name = "school_id") + var schoolSymbol: String = "", - @ColumnInfo(name = "school_name") - var schoolName: String = "" + @ColumnInfo(name = "school_name") + var schoolName: String = "", + + @ColumnInfo(name = "is_current") + var isCurrent: Boolean = false ) diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/SemesterRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/SemesterRepository.kt new file mode 100644 index 00000000..b7902106 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/SemesterRepository.kt @@ -0,0 +1,42 @@ +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.ApiHelper +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.data.repositories.local.SemesterLocal +import io.github.wulkanowy.data.repositories.remote.SemesterRemote +import io.reactivex.Maybe +import io.reactivex.Single +import java.net.UnknownHostException +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SemesterRepository @Inject constructor( + private val remote: SemesterRemote, + private val local: SemesterLocal, + private val settings: InternetObservingSettings, + private val apiHelper: ApiHelper +) { + + fun getSemesters(student: Student, forceRefresh: Boolean = false): Single> { + return Maybe.just(apiHelper.initApi(student)) + .flatMap { local.getSemesters(student).filter { !forceRefresh } } + .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings) + .flatMap { + if (it) remote.getSemesters(student) else Single.error(UnknownHostException()) + }.map { newSemesters -> + local.apply { + saveSemesters(newSemesters) + setCurrentSemester(newSemesters.single { it.isCurrent }) + } + }.flatMap { local.getSemesters(student).toSingle(emptyList()) }) + } + + fun getCurrentSemester(student: Student, forceRefresh: Boolean = false): Single { + return getSemesters(student, forceRefresh).map { item -> item.single { it.isCurrent } } + } +} + diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/SessionRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/SessionRepository.kt deleted file mode 100644 index 4280fcae..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/SessionRepository.kt +++ /dev/null @@ -1,64 +0,0 @@ -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.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.local.SessionLocal -import io.github.wulkanowy.data.repositories.remote.SessionRemote -import io.reactivex.Completable -import io.reactivex.Single -import java.net.UnknownHostException -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class SessionRepository @Inject constructor( - private val local: SessionLocal, - private val remote: SessionRemote, - private val settings: InternetObservingSettings -) { - - val isSessionSaved - get() = local.isSessionSaved - - lateinit var cachedStudents: Single> - private set - - fun getConnectedStudents(email: String, password: String, symbol: String, endpoint: String): Single> { - cachedStudents = ReactiveNetwork.checkInternetConnectivity(settings) - .flatMap { isConnected -> - if (isConnected) remote.getConnectedStudents(email, password, symbol, endpoint) - else Single.error>(UnknownHostException("No internet connection")) - }.doOnSuccess { cachedStudents = Single.just(it) } - return cachedStudents - } - - fun saveStudent(student: Student): Completable { - return remote.getSemesters(student) - .flatMapCompletable { local.saveSemesters(it) } - .concatWith(local.saveStudent(student)) - } - - fun getSemesters(forceRefresh: Boolean = false): Single> { - return local.getLastStudent() - .flatMapSingle { student -> - remote.initApi(student) - local.getSemesters(student).filter { !forceRefresh } - .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap { - if (it) remote.getCurrentSemester(student) - else Single.error(UnknownHostException()) - }.flatMap { current -> - local.getSemesters(student).doOnSuccess { semesters -> - if (semesters.single { it.current }.semesterId != current.semesterId) { - local.saveSemesters(listOf(current)).andThen { - local.setCurrentSemester(current.semesterId) - } - } - } - }.flatMap { - local.getSemesters(student) - }) - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt new file mode 100644 index 00000000..04d3e621 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt @@ -0,0 +1,58 @@ +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.ApiHelper +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.data.repositories.local.StudentLocal +import io.github.wulkanowy.data.repositories.remote.StudentRemote +import io.reactivex.Completable +import io.reactivex.Single +import java.net.UnknownHostException +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class StudentRepository @Inject constructor( + private val local: StudentLocal, + private val remote: StudentRemote, + private val settings: InternetObservingSettings, + private val apiHelper: ApiHelper +) { + + val isStudentSaved + get() = local.isStudentSaved + + lateinit var cachedStudents: Single> + private set + + fun getStudents(email: String, password: String, symbol: String, endpoint: String): Single> { + cachedStudents = ReactiveNetwork.checkInternetConnectivity(settings) + .flatMap { + apiHelper.initApi(email, password, symbol, endpoint) + if (it) remote.getStudents(email, password, endpoint) + else Single.error(UnknownHostException("No internet connection")) + }.doOnSuccess { cachedStudents = Single.just(it) } + return cachedStudents + } + + fun getSavedStudents(): Single> { + return local.getStudents().toSingle(emptyList()) + } + + fun getCurrentStudent(): Single { + return local.getCurrentStudent().toSingle() + } + + fun saveStudent(student: Student): Completable { + return local.saveStudent(student) + } + + fun switchStudent(student: Student): Completable { + return local.setCurrentStudent(student) + } + + fun logoutCurrentStudent(): Completable { + return local.logoutCurrentStudent() + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/local/AttendanceLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/local/AttendanceLocal.kt index 79ab5ec0..a95ad741 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/local/AttendanceLocal.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/local/AttendanceLocal.kt @@ -10,7 +10,7 @@ import javax.inject.Inject class AttendanceLocal @Inject constructor(private val attendanceDb: AttendanceDao) { fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe> { - return attendanceDb.getExams(semester.diaryId, semester.studentId, startDate, endDate) + return attendanceDb.load(semester.diaryId, semester.studentId, startDate, endDate) .filter { !it.isEmpty() } } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/local/ExamLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/local/ExamLocal.kt index b8c3c0e2..40a3e8e7 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/local/ExamLocal.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/local/ExamLocal.kt @@ -10,7 +10,7 @@ import javax.inject.Inject class ExamLocal @Inject constructor(private val examDb: ExamDao) { fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe> { - return examDb.getExams(semester.diaryId, semester.studentId, startDate, endDate) + return examDb.load(semester.diaryId, semester.studentId, startDate, endDate) .filter { !it.isEmpty() } } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/local/GradeLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/local/GradeLocal.kt index 4110bc3a..be3ed1ef 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/local/GradeLocal.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/local/GradeLocal.kt @@ -12,11 +12,11 @@ import javax.inject.Singleton class GradeLocal @Inject constructor(private val gradeDb: GradeDao) { fun getGrades(semester: Semester): Maybe> { - return gradeDb.getGrades(semester.semesterId, semester.studentId).filter { !it.isEmpty() } + return gradeDb.load(semester.semesterId, semester.studentId).filter { !it.isEmpty() } } fun getNewGrades(semester: Semester): Maybe> { - return gradeDb.getNewGrades(semester.semesterId, semester.studentId) + return gradeDb.loadNew(semester.semesterId, semester.studentId) } fun saveGrades(grades: List) { diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/local/GradeSummaryLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/local/GradeSummaryLocal.kt index 3b7c2d7b..0a7f4679 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/local/GradeSummaryLocal.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/local/GradeSummaryLocal.kt @@ -11,7 +11,7 @@ import javax.inject.Singleton class GradeSummaryLocal @Inject constructor(private val gradeSummaryDb: GradeSummaryDao) { fun getGradesSummary(semester: Semester): Maybe> { - return gradeSummaryDb.getGradesSummary(semester.semesterId, semester.studentId) + return gradeSummaryDb.load(semester.semesterId, semester.studentId) .filter { !it.isEmpty() } } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/local/HomeworkLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/local/HomeworkLocal.kt index 68da6080..ea3818dd 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/local/HomeworkLocal.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/local/HomeworkLocal.kt @@ -12,7 +12,7 @@ import javax.inject.Singleton class HomeworkLocal @Inject constructor(private val homeworkDb: HomeworkDao) { fun getHomework(semester: Semester, date: LocalDate): Maybe> { - return homeworkDb.getHomework(semester.semesterId, semester.studentId, date).filter { !it.isEmpty() } + return homeworkDb.load(semester.semesterId, semester.studentId, date).filter { !it.isEmpty() } } fun saveHomework(homework: List) { diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/local/NoteLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/local/NoteLocal.kt index c8778125..ef4ea987 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/local/NoteLocal.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/local/NoteLocal.kt @@ -12,11 +12,11 @@ import javax.inject.Singleton class NoteLocal @Inject constructor(private val noteDb: NoteDao) { fun getNotes(semester: Semester): Maybe> { - return noteDb.getNotes(semester.semesterId, semester.studentId).filter { !it.isEmpty() } + return noteDb.load(semester.semesterId, semester.studentId).filter { !it.isEmpty() } } fun getNewNotes(semester: Semester): Maybe> { - return noteDb.getNewNotes(semester.semesterId, semester.studentId) + return noteDb.loadNew(semester.semesterId, semester.studentId) } fun saveNotes(notes: List) { diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/local/SemesterLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/local/SemesterLocal.kt new file mode 100644 index 00000000..45b4c700 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/local/SemesterLocal.kt @@ -0,0 +1,27 @@ +package io.github.wulkanowy.data.repositories.local + +import io.github.wulkanowy.data.db.dao.SemesterDao +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.reactivex.Maybe +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SemesterLocal @Inject constructor(private val semesterDb: SemesterDao) { + + fun saveSemesters(semesters: List) { + return semesterDb.insertAll(semesters) + } + + fun getSemesters(student: Student): Maybe> { + return semesterDb.load(student.studentId).filter { !it.isEmpty() } + } + + fun setCurrentSemester(semester: Semester) { + semesterDb.run { + resetCurrent(semester.studentId) + update(semester.semesterId, semester.diaryId) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/local/SessionLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/local/SessionLocal.kt deleted file mode 100644 index 008cd8e3..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/local/SessionLocal.kt +++ /dev/null @@ -1,55 +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.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.decrypt -import io.github.wulkanowy.utils.security.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 { - return studentDb.load(sharedPref.getLong(LAST_USER_KEY, defaultValue = 0)) - .map { it.apply { password = decrypt(password) } } - } - - fun saveSemesters(semesters: List): Completable { - return Single.fromCallable { semesterDb.insertAll(semesters) }.ignoreElement() - } - - fun getSemesters(student: Student): Single> { - return semesterDb.getSemester(student.studentId) - } - - fun setCurrentSemester(semesterId: Int): Completable { - return Single.fromCallable { semesterDb.resetCurrentSemester() }.ignoreElement().andThen { - semesterDb.setCurrentSemester(semesterId) - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/local/StudentLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/local/StudentLocal.kt new file mode 100644 index 00000000..1df90120 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/local/StudentLocal.kt @@ -0,0 +1,60 @@ +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.decrypt +import io.github.wulkanowy.utils.security.encrypt +import io.reactivex.Completable +import io.reactivex.Maybe +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 STUDENT_SAVED_KEY: String = "is_student_saved" + } + + val isStudentSaved + get() = sharedPref.getBoolean(STUDENT_SAVED_KEY, false) + + fun saveStudent(student: Student): Completable { + return Completable.fromCallable { + studentDb.run { + resetCurrent() + studentDb.insert(student.copy(password = encrypt(student.password, context))) + } + }.doOnComplete { sharedPref.putBoolean(STUDENT_SAVED_KEY, true) } + } + + fun getCurrentStudent(): Maybe { + return studentDb.loadCurrent().map { it.apply { password = decrypt(password) } } + } + + fun getStudents(): Maybe> { + return studentDb.loadAll() + } + + fun setCurrentStudent(student: Student): Completable { + return Completable.fromCallable { + studentDb.run { + resetCurrent() + update(student.apply { isCurrent = true }) + } + }.doOnComplete { sharedPref.putBoolean(STUDENT_SAVED_KEY, true) } + } + + fun logoutCurrentStudent(): Completable { + return studentDb.loadCurrent().doOnSuccess { + studentDb.delete(it) + sharedPref.putBoolean(STUDENT_SAVED_KEY, false) + }.ignoreElement() + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/local/TimetableLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/local/TimetableLocal.kt index de5329eb..21f9dbd2 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/local/TimetableLocal.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/local/TimetableLocal.kt @@ -10,8 +10,8 @@ import javax.inject.Inject class TimetableLocal @Inject constructor(private val timetableDb: TimetableDao) { fun getTimetable(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe> { - return timetableDb.getTimetable(semester.diaryId, semester.studentId, startDate, endDate) - .filter { !it.isEmpty() } + return timetableDb.load(semester.diaryId, semester.studentId, startDate, endDate) + .filter { !it.isEmpty() } } fun saveTimetable(timetables: List) { diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/AttendanceRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/AttendanceRemote.kt index 4d17c24c..8ce3ceda 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/AttendanceRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/AttendanceRemote.kt @@ -11,14 +11,10 @@ import javax.inject.Inject class AttendanceRemote @Inject constructor(private val api: Api) { fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single> { - return Single.just(api.run { - if (diaryId != semester.diaryId) { - diaryId = semester.diaryId - notifyDataChanged() - } - }).flatMap { api.getAttendance(startDate, endDate) }.map { attendance -> - attendance.map { - Attendance( + return Single.just(api.apply { diaryId = semester.diaryId }) + .flatMap { it.getAttendance(startDate, endDate) }.map { attendance -> + attendance.map { + Attendance( studentId = semester.studentId, diaryId = semester.diaryId, date = it.date.toLocalDate(), @@ -31,8 +27,8 @@ class AttendanceRemote @Inject constructor(private val api: Api) { lateness = it.lateness, excused = it.excused, deleted = it.deleted - ) + ) + } } - } } } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/ExamRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/ExamRemote.kt index 719d561d..3937b768 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/ExamRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/ExamRemote.kt @@ -11,14 +11,10 @@ import javax.inject.Inject class ExamRemote @Inject constructor(private val api: Api) { fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single> { - return Single.just(api.run { - if (diaryId != semester.diaryId) { - diaryId = semester.diaryId - notifyDataChanged() - } - }).flatMap { api.getExams(startDate, endDate) }.map { exams -> - exams.map { - Exam( + return Single.just(api.apply { diaryId = semester.diaryId }) + .flatMap { it.getExams(startDate, endDate) }.map { exams -> + exams.map { + Exam( studentId = semester.studentId, diaryId = semester.diaryId, date = it.date.toLocalDate(), @@ -29,8 +25,8 @@ class ExamRemote @Inject constructor(private val api: Api) { description = it.description, teacher = it.teacher, teacherSymbol = it.teacherSymbol - ) + ) + } } - } } } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/GradeRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/GradeRemote.kt index 52940231..06e4d683 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/GradeRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/GradeRemote.kt @@ -12,31 +12,27 @@ import javax.inject.Singleton class GradeRemote @Inject constructor(private val api: Api) { fun getGrades(semester: Semester): Single> { - return Single.just(api.run { - if (diaryId != semester.diaryId) { - diaryId = semester.diaryId - notifyDataChanged() - } - }).flatMap { api.getGrades(semester.semesterId) } - .map { grades -> - grades.map { - Grade( - semesterId = semester.semesterId, - studentId = semester.studentId, - subject = it.subject, - entry = it.entry, - value = it.value, - modifier = it.modifier, - comment = it.comment, - color = it.color, - gradeSymbol = it.symbol, - description = it.description, - weight = it.weight, - weightValue = it.weightValue, - date = it.date.toLocalDate(), - teacher = it.teacher - ) - } + return Single.just(api.apply { diaryId = semester.diaryId }) + .flatMap { it.getGrades(semester.semesterId) } + .map { grades -> + grades.map { + Grade( + semesterId = semester.semesterId, + studentId = semester.studentId, + subject = it.subject, + entry = it.entry, + value = it.value, + modifier = it.modifier, + comment = it.comment, + color = it.color, + gradeSymbol = it.symbol, + description = it.description, + weight = it.weight, + weightValue = it.weightValue, + date = it.date.toLocalDate(), + teacher = it.teacher + ) } + } } } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/GradeSummaryRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/GradeSummaryRemote.kt index f8cbdca4..af45ca73 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/GradeSummaryRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/GradeSummaryRemote.kt @@ -11,22 +11,18 @@ import javax.inject.Singleton class GradeSummaryRemote @Inject constructor(private val api: Api) { fun getGradeSummary(semester: Semester): Single> { - return Single.just(api.run { - if (diaryId != semester.diaryId) { - diaryId = semester.diaryId - notifyDataChanged() - } - }).flatMap { api.getGradesSummary(semester.semesterId) } - .map { gradesSummary -> - gradesSummary.map { - GradeSummary( - semesterId = semester.semesterId, - studentId = semester.studentId, - subject = it.name, - predictedGrade = it.predicted, - finalGrade = it.final - ) - } + return Single.just(api.apply { diaryId = semester.diaryId }) + .flatMap { it.getGradesSummary(semester.semesterId) } + .map { gradesSummary -> + gradesSummary.map { + GradeSummary( + semesterId = semester.semesterId, + studentId = semester.studentId, + subject = it.name, + predictedGrade = it.predicted, + finalGrade = it.final + ) } + } } } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/HomeworkRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/HomeworkRemote.kt index cb4b4a1a..0fdc0251 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/HomeworkRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/HomeworkRemote.kt @@ -13,12 +13,8 @@ import javax.inject.Singleton class HomeworkRemote @Inject constructor(private val api: Api) { fun getHomework(semester: Semester, date: LocalDate): Single> { - return Single.just(api.run { - if (diaryId != semester.diaryId) { - diaryId = semester.diaryId - notifyDataChanged() - } - }).flatMap { api.getHomework(date, date) } + return Single.just(api.apply { diaryId = semester.diaryId }) + .flatMap { it.getHomework(date, date) } .map { homework -> homework.map { Homework( diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/NoteRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/NoteRemote.kt index 288966ee..31f28e11 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/NoteRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/NoteRemote.kt @@ -12,12 +12,8 @@ import javax.inject.Singleton class NoteRemote @Inject constructor(private val api: Api) { fun getNotes(semester: Semester): Single> { - return Single.just(api.run { - if (diaryId != semester.diaryId) { - diaryId = semester.diaryId - notifyDataChanged() - } - }).flatMap { api.getNotes() } + return Single.just(api.apply { diaryId = semester.diaryId }) + .flatMap { it.getNotes() } .map { notes -> notes.map { Note( diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/SemesterRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/SemesterRemote.kt new file mode 100644 index 00000000..1cf10501 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/SemesterRemote.kt @@ -0,0 +1,30 @@ +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 SemesterRemote @Inject constructor(private val api: Api) { + + fun getSemesters(student: Student): Single> { + return api.getSemesters().map { semesters -> + semesters.map { semester -> + Semester( + studentId = student.studentId, + diaryId = semester.diaryId, + diaryName = semester.diaryName, + semesterId = semester.semesterId, + semesterName = semester.semesterNumber, + isCurrent = semester.current + ) + } + + } + } +} + + diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/SessionRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/SessionRemote.kt deleted file mode 100644 index c6757ab6..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/SessionRemote.kt +++ /dev/null @@ -1,96 +0,0 @@ -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 okhttp3.logging.HttpLoggingInterceptor -import timber.log.Timber -import java.net.URL -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, endpoint: String): Single> { - return Single.just( - initApi( - Student( - email = email, - password = password, - symbol = symbol, - endpoint = endpoint, - loginType = "AUTO" - ), true - ) - ).flatMap { - api.getPupils().map { students -> - students.map { pupil -> - Student( - email = email, - password = password, - symbol = pupil.symbol, - studentId = pupil.studentId, - studentName = pupil.studentName, - schoolSymbol = pupil.schoolSymbol, - schoolName = pupil.schoolName, - endpoint = endpoint, - loginType = pupil.loginType.name - ) - } - } - } - } - - fun getSemesters(student: Student): Single> { - return Single.just(initApi(student)).flatMap { - api.getSemesters().map { semesters -> - semesters.map { semester -> - Semester( - studentId = student.studentId, - diaryId = semester.diaryId, - diaryName = semester.diaryName, - semesterId = semester.semesterId, - semesterName = semester.semesterNumber, - current = semester.current - ) - } - - } - } - } - - fun getCurrentSemester(student: Student): Single { - return api.getCurrentSemester().map { - Semester( - studentId = student.studentId, - diaryId = it.diaryId, - diaryName = it.diaryName, - semesterId = it.semesterId, - semesterName = it.semesterNumber, - current = it.current - ) - } - } - - fun initApi(student: Student, reInitialize: Boolean = false) { - if (if (reInitialize) true else 0 == api.studentId) { - api.run { - logLevel = HttpLoggingInterceptor.Level.NONE - email = student.email - password = student.password - symbol = student.symbol - host = URL(student.endpoint).run { host + ":$port".removeSuffix(":-1") } - ssl = student.endpoint.startsWith("https") - schoolSymbol = student.schoolSymbol - studentId = student.studentId - loginType = Api.LoginType.valueOf(student.loginType) - notifyDataChanged() - setInterceptor(HttpLoggingInterceptor(HttpLoggingInterceptor.Logger { - Timber.d(it) - }).setLevel(HttpLoggingInterceptor.Level.BASIC)) - } - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/StudentRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/StudentRemote.kt new file mode 100644 index 00000000..1db18b26 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/StudentRemote.kt @@ -0,0 +1,29 @@ +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 getStudents(email: String, password: String, endpoint: String): Single> { + return api.getPupils().map { students -> + students.map { pupil -> + Student( + email = email, + password = password, + symbol = pupil.symbol, + studentId = pupil.studentId, + studentName = pupil.studentName, + schoolSymbol = pupil.schoolSymbol, + schoolName = pupil.schoolName, + endpoint = endpoint, + loginType = pupil.loginType.name + ) + } + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/TimetableRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/TimetableRemote.kt index 64386395..aa8949fd 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/remote/TimetableRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/remote/TimetableRemote.kt @@ -12,14 +12,11 @@ import javax.inject.Inject class TimetableRemote @Inject constructor(private val api: Api) { fun getTimetable(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single> { - return Single.just(api.run { - if (diaryId != semester.diaryId) { - diaryId = semester.diaryId - notifyDataChanged() - } - }).flatMap { api.getTimetable(startDate, endDate) }.map { lessons -> - lessons.map { - Timetable( + return Single.just(api.apply { diaryId = semester.diaryId }) + .flatMap { it.getTimetable(startDate, endDate) } + .map { lessons -> + lessons.map { + Timetable( studentId = semester.studentId, diaryId = semester.diaryId, number = it.number, @@ -33,8 +30,8 @@ class TimetableRemote @Inject constructor(private val api: Api) { info = it.info, changes = it.changes, canceled = it.canceled - ) + ) + } } - } } } diff --git a/app/src/main/java/io/github/wulkanowy/services/job/SyncWorker.kt b/app/src/main/java/io/github/wulkanowy/services/job/SyncWorker.kt index caa52943..2e39463f 100644 --- a/app/src/main/java/io/github/wulkanowy/services/job/SyncWorker.kt +++ b/app/src/main/java/io/github/wulkanowy/services/job/SyncWorker.kt @@ -10,7 +10,8 @@ import io.github.wulkanowy.data.repositories.GradeSummaryRepository import io.github.wulkanowy.data.repositories.HomeworkRepository import io.github.wulkanowy.data.repositories.NoteRepository import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.SemesterRepository +import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.data.repositories.TimetableRepository import io.github.wulkanowy.services.notification.GradeNotification import io.github.wulkanowy.services.notification.NoteNotification @@ -26,7 +27,10 @@ import javax.inject.Inject class SyncWorker : SimpleJobService() { @Inject - lateinit var session: SessionRepository + lateinit var student: StudentRepository + + @Inject + lateinit var semester: SemesterRepository @Inject lateinit var gradesDetails: GradeRepository @@ -73,8 +77,8 @@ class SyncWorker : SimpleJobService() { var error: Throwable? = null - disposable.add(session.getSemesters(true) - .map { it.single { semester -> semester.current } } + disposable.add(student.getCurrentStudent() + .flatMap { semester.getCurrentSemester(it, true) } .flatMapPublisher { Single.merge( listOf( @@ -107,8 +111,8 @@ class SyncWorker : SimpleJobService() { } private fun sendGradeNotifications() { - disposable.add(session.getSemesters() - .map { it.single { semester -> semester.current } } + disposable.add(student.getCurrentStudent() + .flatMap { semester.getCurrentSemester(it, true) } .flatMap { gradesDetails.getNewGrades(it) } .map { it.filter { grade -> !grade.isNotified } } .subscribe({ @@ -121,8 +125,8 @@ class SyncWorker : SimpleJobService() { } private fun sendNoteNotification() { - disposable.add(session.getSemesters() - .map { it.single { semester -> semester.current } } + disposable.add(student.getCurrentStudent() + .flatMap { semester.getCurrentSemester(it, true) } .flatMap { note.getNewNotes(it) } .map { it.filter { note -> !note.isNotified } } .subscribe({ diff --git a/app/src/main/java/io/github/wulkanowy/services/widgets/TimetableWidgetService.kt b/app/src/main/java/io/github/wulkanowy/services/widgets/TimetableWidgetService.kt index 1e5ac71f..d1e275b7 100644 --- a/app/src/main/java/io/github/wulkanowy/services/widgets/TimetableWidgetService.kt +++ b/app/src/main/java/io/github/wulkanowy/services/widgets/TimetableWidgetService.kt @@ -4,7 +4,8 @@ import android.content.Intent import android.widget.RemoteViewsService import dagger.android.AndroidInjection import io.github.wulkanowy.data.db.SharedPrefHelper -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.SemesterRepository +import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.data.repositories.TimetableRepository import io.github.wulkanowy.ui.widgets.timetable.TimetableWidgetFactory import javax.inject.Inject @@ -12,16 +13,19 @@ import javax.inject.Inject class TimetableWidgetService : RemoteViewsService() { @Inject - lateinit var timetableRepository: TimetableRepository + lateinit var timetableRepo: TimetableRepository @Inject - lateinit var sessionRepository: SessionRepository + lateinit var studentRepo: StudentRepository + + @Inject + lateinit var semesterRepo: SemesterRepository @Inject lateinit var sharedPref: SharedPrefHelper override fun onGetViewFactory(intent: Intent?): RemoteViewsFactory { AndroidInjection.inject(this) - return TimetableWidgetFactory(timetableRepository, sessionRepository, sharedPref, applicationContext, intent) + return TimetableWidgetFactory(timetableRepo, studentRepo, semesterRepo, sharedPref, applicationContext, intent) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountDialog.kt new file mode 100644 index 00000000..040bfd3a --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountDialog.kt @@ -0,0 +1,99 @@ +package io.github.wulkanowy.ui.modules.account + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import android.widget.Toast.LENGTH_LONG +import androidx.appcompat.app.AlertDialog +import dagger.android.support.DaggerAppCompatDialogFragment +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.ui.modules.login.LoginActivity +import io.github.wulkanowy.ui.modules.main.MainActivity +import io.github.wulkanowy.utils.setOnItemClickListener +import kotlinx.android.synthetic.main.dialog_account.* +import javax.inject.Inject + +class AccountDialog : DaggerAppCompatDialogFragment(), AccountView { + + @Inject + lateinit var presenter: AccountPresenter + + @Inject + lateinit var accountAdapter: FlexibleAdapter> + + companion object { + fun newInstance() = AccountDialog() + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setStyle(STYLE_NO_TITLE, 0) + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.dialog_account, container, false) + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + presenter.onAttachView(this) + } + + override fun initView() { + accountAdapter.setOnItemClickListener { presenter.onItemSelected(it) } + + accountDialogAdd.setOnClickListener { presenter.onAddSelected() } + accountDialogRemove.setOnClickListener { presenter.onRemoveSelected() } + accountDialogRecycler.apply { + layoutManager = SmoothScrollLinearLayoutManager(context) + adapter = accountAdapter + } + } + + override fun updateData(data: List) { + accountAdapter.updateDataSet(data) + } + + override fun showMessage(text: String) { + Toast.makeText(context, text, LENGTH_LONG).show() + } + + override fun dismissView() { + dismiss() + } + + override fun openLoginView() { + activity?.also { + startActivity(LoginActivity.getStartIntent(it)) + } + } + + override fun showConfirmDialog() { + context?.let { + AlertDialog.Builder(it) + .setTitle(R.string.account_logout_student) + .setMessage(R.string.account_confirm) + .setPositiveButton(R.string.account_logout) { _, _ -> presenter.onLogoutConfirm() } + .setNegativeButton(android.R.string.cancel) { _, _ -> } + .show() + } + } + + override fun recreateView() { + activity?.also { + startActivity(MainActivity.getStartIntent(it)) + it.finish() + } + } + + override fun onDestroy() { + presenter.onDetachView() + super.onDestroy() + } +} + diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountItem.kt new file mode 100644 index 00000000..a564306d --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountItem.kt @@ -0,0 +1,51 @@ +package io.github.wulkanowy.ui.modules.account + +import android.view.View +import eu.davidea.flexibleadapter.FlexibleAdapter +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem +import eu.davidea.flexibleadapter.items.IFlexible +import eu.davidea.viewholders.FlexibleViewHolder +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Student +import kotlinx.android.extensions.LayoutContainer +import kotlinx.android.synthetic.main.item_account.* + +class AccountItem(val student: Student) : AbstractFlexibleItem() { + + override fun getLayoutRes() = R.layout.item_account + + override fun createViewHolder(view: View?, adapter: FlexibleAdapter>?): ViewHolder { + return ViewHolder(view, adapter) + } + + override fun bindViewHolder(adapter: FlexibleAdapter>?, holder: ViewHolder?, position: Int, payloads: MutableList?) { + holder?.apply { + accountItemName.text = student.studentName + accountItemSchool.text = student.schoolName + accountItemImage.setBackgroundResource(if (student.isCurrent) R.drawable.ic_account_circular_border else 0) + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as AccountItem + + if (student != other.student) return false + + return true + } + + override fun hashCode(): Int { + return student.hashCode() + } + + class ViewHolder(view: View?, adapter: FlexibleAdapter>?) : FlexibleViewHolder(view, adapter), + LayoutContainer { + + override val containerView: View? + get() = contentView + } +} + diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountPresenter.kt new file mode 100644 index 00000000..8a276492 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountPresenter.kt @@ -0,0 +1,70 @@ +package io.github.wulkanowy.ui.modules.account + +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem +import io.github.wulkanowy.data.ErrorHandler +import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.utils.SchedulersProvider +import io.reactivex.Single +import javax.inject.Inject + +class AccountPresenter @Inject constructor( + private val errorHandler: ErrorHandler, + private val studentRepository: StudentRepository, + private val schedulers: SchedulersProvider +) : BasePresenter(errorHandler) { + + override fun onAttachView(view: AccountView) { + super.onAttachView(view) + view.initView() + loadData() + } + + fun onAddSelected() { + view?.openLoginView() + } + + fun onRemoveSelected() { + view?.showConfirmDialog() + } + + fun onLogoutConfirm() { + disposable.add(studentRepository.logoutCurrentStudent() + .andThen(studentRepository.getSavedStudents()) + .flatMap { + if (it.isNotEmpty()) studentRepository.switchStudent(it[0]).toSingle { it } + else Single.just(it) + } + .subscribeOn(schedulers.backgroundThread) + .observeOn(schedulers.mainThread) + .doFinally { view?.dismissView() } + .subscribe({ + view?.apply { + if (it.isEmpty()) openLoginView() + else recreateView() + } + }, { errorHandler.proceed(it) })) + } + + fun onItemSelected(item: AbstractFlexibleItem<*>) { + if (item is AccountItem) { + if (item.student.isCurrent) { + view?.dismissView() + } else { + disposable.add(studentRepository.switchStudent(item.student) + .subscribeOn(schedulers.backgroundThread) + .observeOn(schedulers.mainThread) + .subscribe({ view?.recreateView() }, { errorHandler.proceed(it) })) + } + } + } + + private fun loadData() { + disposable.add(studentRepository.getSavedStudents() + .map { it.map { item -> AccountItem(item) } } + .subscribeOn(schedulers.backgroundThread) + .observeOn(schedulers.mainThread) + .subscribe({ view?.updateData(it) }, { errorHandler.proceed(it) })) + } +} + diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountView.kt new file mode 100644 index 00000000..e5b8ed6c --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountView.kt @@ -0,0 +1,19 @@ +package io.github.wulkanowy.ui.modules.account + +import io.github.wulkanowy.ui.base.BaseView + +interface AccountView : BaseView { + + fun initView() + + fun updateData(data: List) + + fun dismissView() + + fun showConfirmDialog() + + fun openLoginView() + + fun recreateView() +} + diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt index 92226be2..2baaa6ae 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt @@ -47,7 +47,7 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie override fun initView() { attendanceAdapter.apply { - setOnItemClickListener { presenter.onAttendanceItemSelected(getItem(it)) } + setOnItemClickListener { presenter.onAttendanceItemSelected(it) } } attendanceRecycler.run { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt index e328c382..56a027dd 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt @@ -4,7 +4,8 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import io.github.wulkanowy.data.ErrorHandler import io.github.wulkanowy.data.repositories.AttendanceRepository import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.SemesterRepository +import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.isHolidays @@ -23,7 +24,8 @@ class AttendancePresenter @Inject constructor( private val errorHandler: ErrorHandler, private val schedulers: SchedulersProvider, private val attendanceRepository: AttendanceRepository, - private val sessionRepository: SessionRepository, + private val studentRepository: StudentRepository, + private val semesterRepository: SemesterRepository, private val prefRepository: PreferencesRepository ) : BasePresenter(errorHandler) { @@ -66,9 +68,9 @@ class AttendancePresenter @Inject constructor( currentDate = date disposable.apply { clear() - add(sessionRepository.getSemesters() + add(studentRepository.getCurrentStudent() .delay(200, MILLISECONDS) - .map { it.single { semester -> semester.current } } + .flatMap { semesterRepository.getCurrentSemester(it) } .flatMap { attendanceRepository.getAttendance(it, date, date, forceRefresh) } .map { list -> if (prefRepository.isShowPresent) list diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamFragment.kt index 3e1f7cad..abbc2d79 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamFragment.kt @@ -3,7 +3,9 @@ package io.github.wulkanowy.ui.modules.exam import android.os.Bundle import android.view.LayoutInflater import android.view.View -import android.view.View.* +import android.view.View.GONE +import android.view.View.INVISIBLE +import android.view.View.VISIBLE import android.view.ViewGroup import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager @@ -48,7 +50,7 @@ class ExamFragment : BaseFragment(), ExamView, MainView.MainChildView, MainView. override fun initView() { examAdapter.run { - setOnItemClickListener { presenter.onExamItemSelected(getItem(it)) } + setOnItemClickListener { presenter.onExamItemSelected(it) } } examRecycler.run { layoutManager = SmoothScrollLinearLayoutManager(context) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamPresenter.kt index f2bf7b07..da4332ab 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamPresenter.kt @@ -4,7 +4,8 @@ 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.repositories.ExamRepository -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.SemesterRepository +import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.friday @@ -23,7 +24,8 @@ class ExamPresenter @Inject constructor( private val errorHandler: ErrorHandler, private val schedulers: SchedulersProvider, private val examRepository: ExamRepository, - private val sessionRepository: SessionRepository + private val studentRepository: StudentRepository, + private val semesterRepository: SemesterRepository ) : BasePresenter(errorHandler) { lateinit var currentDate: LocalDate @@ -65,9 +67,9 @@ class ExamPresenter @Inject constructor( currentDate = date disposable.apply { clear() - add(sessionRepository.getSemesters() + add(studentRepository.getCurrentStudent() .delay(200, MILLISECONDS) - .map { it.single { semester -> semester.current } } + .flatMap { semesterRepository.getCurrentSemester(it) } .flatMap { examRepository.getExams(it, currentDate.monday, currentDate.friday, forceRefresh) }.map { it.groupBy { exam -> exam.date }.toSortedMap() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt index 57140c16..0188c041 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt @@ -1,9 +1,14 @@ package io.github.wulkanowy.ui.modules.grade import android.os.Bundle -import android.view.* +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.View import android.view.View.INVISIBLE import android.view.View.VISIBLE +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import io.github.wulkanowy.R import io.github.wulkanowy.ui.base.BaseFragment @@ -55,8 +60,8 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainVie override fun initView() { pagerAdapter.fragments.putAll(mapOf( - getString(R.string.all_details) to GradeDetailsFragment.newInstance(), - getString(R.string.grade_menu_summary) to GradeSummaryFragment.newInstance() + getString(R.string.all_details) to GradeDetailsFragment.newInstance(), + getString(R.string.grade_menu_summary) to GradeSummaryFragment.newInstance() )) gradeViewPager.run { adapter = pagerAdapter @@ -85,16 +90,16 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainVie override fun showSemesterDialog(selectedIndex: Int) { arrayOf(getString(R.string.grade_semester, 1), - getString(R.string.grade_semester, 2)).also { array -> + getString(R.string.grade_semester, 2)).also { array -> context?.let { AlertDialog.Builder(it) - .setSingleChoiceItems(array, selectedIndex) { dialog, which -> - presenter.onSemesterSelected(which) - dialog.dismiss() - } - .setTitle(R.string.grade_switch_semester) - .setNegativeButton(R.string.all_cancel) { dialog, _ -> dialog.dismiss() } - .show() + .setSingleChoiceItems(array, selectedIndex) { dialog, which -> + presenter.onSemesterSelected(which) + dialog.dismiss() + } + .setTitle(R.string.grade_switch_semester) + .setNegativeButton(android.R.string.cancel) { _, _ -> } + .show() } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradePresenter.kt index 5d678915..47412dc9 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradePresenter.kt @@ -2,19 +2,21 @@ package io.github.wulkanowy.ui.modules.grade import io.github.wulkanowy.data.ErrorHandler import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.SemesterRepository +import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.logEvent import io.reactivex.Completable -import timber.log.Timber import java.util.concurrent.TimeUnit.MILLISECONDS import javax.inject.Inject class GradePresenter @Inject constructor( - private val errorHandler: ErrorHandler, - private val schedulers: SchedulersProvider, - private val sessionRepository: SessionRepository) : BasePresenter(errorHandler) { + private val errorHandler: ErrorHandler, + private val schedulers: SchedulersProvider, + private val studentRepository: StudentRepository, + private val semesterRepository: SemesterRepository +) : BasePresenter(errorHandler) { var selectedIndex = 0 private set @@ -26,11 +28,11 @@ class GradePresenter @Inject constructor( fun onAttachView(view: GradeView, savedIndex: Int?) { super.onAttachView(view) disposable.add(Completable.timer(150, MILLISECONDS, schedulers.mainThread) - .subscribe { - selectedIndex = savedIndex ?: 0 - view.initView() - loadData() - }) + .subscribe { + selectedIndex = savedIndex ?: 0 + view.initView() + loadData() + }) } fun onViewReselected() { @@ -71,15 +73,16 @@ class GradePresenter @Inject constructor( } private fun loadData() { - disposable.add(sessionRepository.getSemesters() - .doOnSuccess { - it.first { item -> item.current }.also { current -> - selectedIndex = if (selectedIndex == 0) current.semesterName else selectedIndex - semesters = it.filter { semester -> semester.diaryId == current.diaryId } - } + disposable.add(studentRepository.getCurrentStudent() + .flatMap { semesterRepository.getSemesters(it) } + .doOnSuccess { + it.first { item -> item.isCurrent }.also { current -> + selectedIndex = if (selectedIndex == 0) current.semesterName else selectedIndex + semesters = it.filter { semester -> semester.diaryId == current.diaryId } } - .subscribeOn(schedulers.backgroundThread) - .observeOn(schedulers.mainThread) + } + .subscribeOn(schedulers.backgroundThread) + .observeOn(schedulers.mainThread) .subscribe({ view?.run { loadChild(currentPageIndex) } }) { errorHandler.proceed(it) }) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsFragment.kt index 3a508ccf..419d9e47 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsFragment.kt @@ -59,7 +59,7 @@ class GradeDetailsFragment : BaseFragment(), GradeDetailsView, GradeView.GradeCh gradeDetailsAdapter.run { isAutoCollapseOnExpand = true isAutoScrollOnExpand = true - setOnItemClickListener { presenter.onGradeItemSelected(getItem(it)) } + setOnItemClickListener { presenter.onGradeItemSelected(it) } } gradeDetailsRecycler.run { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt index 09da0ed9..974cb09f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt @@ -5,7 +5,8 @@ import io.github.wulkanowy.data.ErrorHandler import io.github.wulkanowy.data.db.entities.Grade import io.github.wulkanowy.data.repositories.GradeRepository import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.SemesterRepository +import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.calcAverage @@ -19,7 +20,8 @@ class GradeDetailsPresenter @Inject constructor( private val errorHandler: ErrorHandler, private val schedulers: SchedulersProvider, private val gradeRepository: GradeRepository, - private val sessionRepository: SessionRepository, + private val studentRepository: StudentRepository, + private val semesterRepository: SemesterRepository, private val preferencesRepository: PreferencesRepository ) : BasePresenter(errorHandler) { @@ -29,7 +31,8 @@ class GradeDetailsPresenter @Inject constructor( } fun onParentViewLoadData(semesterId: Int, forceRefresh: Boolean) { - disposable.add(sessionRepository.getSemesters() + disposable.add(studentRepository.getCurrentStudent() + .flatMap { semesterRepository.getSemesters(it) } .flatMap { gradeRepository.getGrades(it.first { item -> item.semesterId == semesterId }, forceRefresh) } .map { it.map { item -> item.changeModifier(preferencesRepository.gradeModifier) } } .map { createGradeItems(it.groupBy { grade -> grade.subject }.toSortedMap()) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryFragment.kt index 76473b40..b2993bd3 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryFragment.kt @@ -3,7 +3,9 @@ package io.github.wulkanowy.ui.modules.grade.summary import android.os.Bundle import android.view.LayoutInflater import android.view.View -import android.view.View.* +import android.view.View.GONE +import android.view.View.INVISIBLE +import android.view.View.VISIBLE import android.view.ViewGroup import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager @@ -56,7 +58,7 @@ class GradeSummaryFragment : BaseFragment(), GradeSummaryView, GradeView.GradeCh gradeSummarySwipe.setOnRefreshListener { presenter.onSwipeRefresh() } } - override fun updateDataSet(data: List, header: GradeSummaryScrollableHeader) { + override fun updateData(data: List, header: GradeSummaryScrollableHeader) { gradeSummaryAdapter.apply { updateDataSet(data, true) removeAllScrollableHeaders() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt index 874e3247..84099a1d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt @@ -5,7 +5,8 @@ import io.github.wulkanowy.data.db.entities.GradeSummary import io.github.wulkanowy.data.repositories.GradeRepository import io.github.wulkanowy.data.repositories.GradeSummaryRepository import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.SemesterRepository +import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.calcAverage @@ -19,7 +20,8 @@ class GradeSummaryPresenter @Inject constructor( private val errorHandler: ErrorHandler, private val gradeSummaryRepository: GradeSummaryRepository, private val gradeRepository: GradeRepository, - private val sessionRepository: SessionRepository, + private val studentRepository: StudentRepository, + private val semesterRepository: SemesterRepository, private val preferencesRepository: PreferencesRepository, private val schedulers: SchedulersProvider ) : BasePresenter(errorHandler) { @@ -30,7 +32,8 @@ class GradeSummaryPresenter @Inject constructor( } fun onParentViewLoadData(semesterId: Int, forceRefresh: Boolean) { - disposable.add(sessionRepository.getSemesters() + disposable.add(studentRepository.getCurrentStudent() + .flatMap { semesterRepository.getSemesters(it) } .map { semester -> semester.first { it.semesterId == semesterId } } .flatMap { gradeSummaryRepository.getGradesSummary(it, forceRefresh) @@ -63,7 +66,7 @@ class GradeSummaryPresenter @Inject constructor( view?.run { showEmpty(it.first.isEmpty()) showContent(it.first.isNotEmpty()) - updateDataSet(it.first, it.second) + updateData(it.first, it.second) } logEvent("Grade summary load", mapOf("items" to it.first.size, "forceRefresh" to forceRefresh)) }) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryView.kt index f7035abc..7aa609f4 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryView.kt @@ -12,7 +12,7 @@ interface GradeSummaryView : BaseView { fun initView() - fun updateDataSet(data: List, header: GradeSummaryScrollableHeader) + fun updateData(data: List, header: GradeSummaryScrollableHeader) fun resetView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkFragment.kt index 8a8faf50..ac1f397f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkFragment.kt @@ -44,7 +44,7 @@ class HomeworkFragment : BaseFragment(), HomeworkView, MainView.TitledView { override fun initView() { homeworkAdapter.run { - setOnItemClickListener { presenter.onHomeworkItemSelected(getItem(it)) } + setOnItemClickListener { presenter.onHomeworkItemSelected(it) } } homeworkRecycler.run { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkPresenter.kt index 8f0ef485..e3a3b4fc 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkPresenter.kt @@ -3,7 +3,8 @@ package io.github.wulkanowy.ui.modules.homework import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import io.github.wulkanowy.data.ErrorHandler import io.github.wulkanowy.data.repositories.HomeworkRepository -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.SemesterRepository +import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.isHolidays @@ -20,7 +21,8 @@ class HomeworkPresenter @Inject constructor( private val errorHandler: ErrorHandler, private val schedulers: SchedulersProvider, private val homeworkRepository: HomeworkRepository, - private val sessionRepository: SessionRepository + private val studentRepository: StudentRepository, + private val semesterRepository: SemesterRepository ) : BasePresenter(errorHandler) { lateinit var currentDate: LocalDate @@ -57,9 +59,9 @@ class HomeworkPresenter @Inject constructor( currentDate = date disposable.apply { clear() - add(sessionRepository.getSemesters() + add(studentRepository.getCurrentStudent() .delay(200, TimeUnit.MILLISECONDS) - .map { it.single { semester -> semester.current } } + .flatMap { semesterRepository.getCurrentSemester(it) } .flatMap { homeworkRepository.getHomework(it, currentDate, forceRefresh) } .map { items -> items.map { HomeworkItem(it) } } .subscribeOn(schedulers.backgroundThread) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginErrorHandler.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginErrorHandler.kt index 418dbed9..1763f8d4 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginErrorHandler.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginErrorHandler.kt @@ -1,22 +1,25 @@ package io.github.wulkanowy.ui.modules.login import android.content.res.Resources +import android.database.sqlite.SQLiteConstraintException +import io.github.wulkanowy.R import io.github.wulkanowy.api.login.BadCredentialsException import io.github.wulkanowy.data.ErrorHandler class LoginErrorHandler(resources: Resources) : ErrorHandler(resources) { - var doOnBadCredentials: () -> Unit = {} + var onBadCredentials: () -> Unit = {} override fun proceed(error: Throwable) { when (error) { - is BadCredentialsException -> doOnBadCredentials() + is BadCredentialsException -> onBadCredentials() + is SQLiteConstraintException -> showErrorMessage(resources.getString(R.string.login_duplicate_student)) else -> super.proceed(error) } } override fun clear() { super.clear() - doOnBadCredentials = {} + onBadCredentials = {} } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt index 2e7c726c..41d1fc5e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt @@ -1,6 +1,6 @@ package io.github.wulkanowy.ui.modules.login.form -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.modules.login.LoginErrorHandler import io.github.wulkanowy.utils.SchedulersProvider @@ -12,7 +12,7 @@ import javax.inject.Inject class LoginFormPresenter @Inject constructor( private val schedulers: SchedulersProvider, private val errorHandler: LoginErrorHandler, - private val sessionRepository: SessionRepository + private val studentRepository: StudentRepository ) : BasePresenter(errorHandler) { private var wasEmpty = false @@ -21,7 +21,7 @@ class LoginFormPresenter @Inject constructor( super.onAttachView(view) view.run { initView() - errorHandler.doOnBadCredentials = { + errorHandler.onBadCredentials = { setErrorPassIncorrect() showSoftKeyboard() Timber.i("Entered wrong username or password") @@ -32,7 +32,7 @@ class LoginFormPresenter @Inject constructor( fun attemptLogin(email: String, password: String, symbol: String, endpoint: String) { if (!validateCredentials(email, password, symbol)) return - disposable.add(sessionRepository.getConnectedStudents(email, password, symbol, endpoint) + disposable.add(studentRepository.getStudents(email, password, symbol, endpoint) .subscribeOn(schedulers.backgroundThread) .observeOn(schedulers.mainThread) .doOnSubscribe { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsFragment.kt index e242aba3..3e306b19 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsFragment.kt @@ -1,5 +1,7 @@ package io.github.wulkanowy.ui.modules.login.options +import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK +import android.content.Intent.FLAG_ACTIVITY_NEW_TASK import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -39,7 +41,7 @@ class LoginOptionsFragment : BaseFragment(), LoginOptionsView { } override fun initView() { - loginAdapter.apply { setOnItemClickListener { presenter.onSelectItem(getItem(it)) } } + loginAdapter.apply { setOnItemClickListener { presenter.onItemSelected(it) } } loginOptionsRecycler.apply { adapter = loginAdapter @@ -57,8 +59,8 @@ class LoginOptionsFragment : BaseFragment(), LoginOptionsView { override fun openMainView() { activity?.let { - startActivity(MainActivity.getStartIntent(it)) - it.finish() + startActivity(MainActivity.getStartIntent(it) + .apply { addFlags(FLAG_ACTIVITY_CLEAR_TASK or FLAG_ACTIVITY_NEW_TASK) }) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenter.kt index 85dfbfd4..ba16072d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenter.kt @@ -1,17 +1,20 @@ package io.github.wulkanowy.ui.modules.login.options import eu.davidea.flexibleadapter.items.AbstractFlexibleItem -import io.github.wulkanowy.data.ErrorHandler import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.SemesterRepository +import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.ui.modules.login.LoginErrorHandler import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.logRegister +import io.reactivex.Single import javax.inject.Inject class LoginOptionsPresenter @Inject constructor( - private val errorHandler: ErrorHandler, - private val repository: SessionRepository, + private val errorHandler: LoginErrorHandler, + private val studentRepository: StudentRepository, + private val semesterRepository: SemesterRepository, private val schedulers: SchedulersProvider ) : BasePresenter(errorHandler) { @@ -21,25 +24,27 @@ class LoginOptionsPresenter @Inject constructor( } fun onParentViewLoadData() { - disposable.add(repository.cachedStudents + disposable.add(studentRepository.cachedStudents .observeOn(schedulers.mainThread) .subscribeOn(schedulers.backgroundThread) .doOnSubscribe { view?.showActionBar(true) } .subscribe({ view?.updateData(it.map { student -> LoginOptionsItem(student) }) }, { errorHandler.proceed(it) })) } - fun onSelectItem(item: AbstractFlexibleItem<*>?) { + fun onItemSelected(item: AbstractFlexibleItem<*>?) { if (item is LoginOptionsItem) { registerStudent(item.student) } } private fun registerStudent(student: Student) { - disposable.add(repository.saveStudent(student) + disposable.add(studentRepository.saveStudent(student.apply { isCurrent = true }) + .andThen(semesterRepository.getSemesters(student, true)) + .onErrorResumeNext { studentRepository.logoutCurrentStudent().andThen(Single.error(it)) } .subscribeOn(schedulers.backgroundThread) .observeOn(schedulers.mainThread) .doOnSubscribe { - view?.run { + view?.apply { showProgress(true) showContent(false) showActionBar(false) @@ -48,6 +53,13 @@ class LoginOptionsPresenter @Inject constructor( .subscribe({ logRegister("Success", true, student.symbol, student.endpoint) view?.openMainView() - }, { errorHandler.proceed(it) })) + }, { + errorHandler.proceed(it) + view?.apply { + showProgress(false) + showContent(true) + showActionBar(true) + } + })) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt index 32b7bf30..f9775309 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt @@ -3,6 +3,8 @@ package io.github.wulkanowy.ui.modules.main import android.content.Context import android.content.Intent import android.os.Bundle +import android.view.Menu +import android.view.MenuItem import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import com.aurelhubert.ahbottomnavigation.AHBottomNavigation.TitleState.ALWAYS_SHOW @@ -12,6 +14,7 @@ import com.ncapdevi.fragnav.FragNavController.Companion.HIDE import io.github.wulkanowy.R import io.github.wulkanowy.services.notification.GradeNotification import io.github.wulkanowy.ui.base.BaseActivity +import io.github.wulkanowy.ui.modules.account.AccountDialog import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment import io.github.wulkanowy.ui.modules.exam.ExamFragment import io.github.wulkanowy.ui.modules.grade.GradeFragment @@ -58,15 +61,16 @@ class MainActivity : BaseActivity(), MainView { navController.initialize(startMenuIndex, savedInstanceState) } + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.action_menu_main, menu) + return true + } + override fun onStart() { super.onStart() presenter.onViewStart() } - override fun onSupportNavigateUp(): Boolean { - return presenter.onUpNavigate() - } - override fun initView() { mainBottomNav.run { addItems( @@ -103,6 +107,15 @@ class MainActivity : BaseActivity(), MainView { } } + override fun onOptionsItemSelected(item: MenuItem?): Boolean { + return if (item?.itemId == R.id.mainMenuAccount) presenter.onAccountManagerSelected() + else false + } + + override fun onSupportNavigateUp(): Boolean { + return presenter.onUpNavigate() + } + override fun switchMenuView(position: Int) { navController.switchTab(position) } @@ -115,6 +128,10 @@ class MainActivity : BaseActivity(), MainView { supportActionBar?.setDisplayHomeAsUpEnabled(show) } + override fun showAccountPicker() { + navController.showDialogFragment(AccountDialog.newInstance()) + } + override fun notifyMenuViewReselected() { (navController.currentStack?.get(0) as? MainView.MainChildView)?.onFragmentReselected() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt index 76db1ef0..cee0f9be 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt @@ -9,6 +9,7 @@ import io.github.wulkanowy.di.scopes.PerActivity import io.github.wulkanowy.di.scopes.PerFragment import io.github.wulkanowy.ui.modules.about.AboutFragment import io.github.wulkanowy.ui.modules.about.AboutModule +import io.github.wulkanowy.ui.modules.account.AccountDialog import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment import io.github.wulkanowy.ui.modules.exam.ExamFragment import io.github.wulkanowy.ui.modules.grade.GradeFragment @@ -57,12 +58,19 @@ abstract class MainModule { @ContributesAndroidInjector(modules = [AboutModule::class]) abstract fun bindAboutFragment(): AboutFragment + @PerFragment @ContributesAndroidInjector abstract fun bindSettingsFragment(): SettingsFragment + @PerFragment @ContributesAndroidInjector abstract fun bindNoteFragment(): NoteFragment + @PerFragment @ContributesAndroidInjector abstract fun bindHomeworkFragment(): HomeworkFragment + + @PerFragment + @ContributesAndroidInjector + abstract fun bindsAccountDialog(): AccountDialog } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt index be1850d5..674a1e73 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt @@ -41,6 +41,11 @@ class MainPresenter @Inject constructor( } } + fun onAccountManagerSelected(): Boolean { + view?.showAccountPicker() + return true + } + fun onUpNavigate(): Boolean { view?.popView() return true diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt index 8848f2f0..5fcace39 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt @@ -18,6 +18,8 @@ interface MainView : BaseView { fun showHomeArrow(show: Boolean) + fun showAccountPicker() + fun notifyMenuViewReselected() fun setViewTitle(title: String) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreFragment.kt index f7c22ca1..1dd8558d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreFragment.kt @@ -76,7 +76,7 @@ class MoreFragment : BaseFragment(), MoreView, MainView.TitledView, MainView.Mai } override fun initView() { - moreAdapter.run { setOnItemClickListener { presenter.onItemSelected(getItem(it)) } } + moreAdapter.run { setOnItemClickListener { presenter.onItemSelected(it) } } moreRecycler.apply { layoutManager = SmoothScrollLinearLayoutManager(context) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreItem.kt index 20bad835..e8571a8c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreItem.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreItem.kt @@ -10,8 +10,7 @@ import io.github.wulkanowy.R import kotlinx.android.extensions.LayoutContainer import kotlinx.android.synthetic.main.item_more.* -class MoreItem(val title: String, private val drawable: Drawable?) - : AbstractFlexibleItem() { +class MoreItem(val title: String, private val drawable: Drawable?) : AbstractFlexibleItem() { override fun getLayoutRes() = R.layout.item_more @@ -19,8 +18,7 @@ class MoreItem(val title: String, private val drawable: Drawable?) return ViewHolder(view, adapter) } - override fun bindViewHolder(adapter: FlexibleAdapter>?, holder: ViewHolder?, - position: Int, payloads: MutableList?) { + override fun bindViewHolder(adapter: FlexibleAdapter>?, holder: ViewHolder?, position: Int, payloads: MutableList?) { holder?.apply { moreItemTitle.text = title moreItemImage.setImageDrawable(drawable) @@ -42,8 +40,7 @@ class MoreItem(val title: String, private val drawable: Drawable?) return title.hashCode() } - class ViewHolder(view: View?, adapter: FlexibleAdapter<*>?) - : FlexibleViewHolder(view, adapter), LayoutContainer { + class ViewHolder(view: View?, adapter: FlexibleAdapter<*>?) : FlexibleViewHolder(view, adapter), LayoutContainer { override val containerView: View? get() = contentView diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteFragment.kt index fc382ee6..a5b198dc 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteFragment.kt @@ -46,7 +46,7 @@ class NoteFragment : BaseFragment(), NoteView, MainView.TitledView { override fun initView() { noteAdapter.run { - setOnItemClickListener { presenter.onNoteItemSelected(getItem(it)) } + setOnItemClickListener { presenter.onNoteItemSelected(it) } } noteRecycler.run { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NotePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NotePresenter.kt index d2c5b4f6..f19839c3 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NotePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NotePresenter.kt @@ -4,7 +4,8 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import io.github.wulkanowy.data.ErrorHandler import io.github.wulkanowy.data.db.entities.Note import io.github.wulkanowy.data.repositories.NoteRepository -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.SemesterRepository +import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.logEvent @@ -14,8 +15,9 @@ import javax.inject.Inject class NotePresenter @Inject constructor( private val errorHandler: ErrorHandler, private val schedulers: SchedulersProvider, - private val sessionRepository: SessionRepository, - private val noteRepository: NoteRepository + private val studentRepository: StudentRepository, + private val noteRepository: NoteRepository, + private val semesterRepository: SemesterRepository ) : BasePresenter(errorHandler) { override fun onAttachView(view: NoteView) { @@ -29,8 +31,8 @@ class NotePresenter @Inject constructor( } private fun loadData(forceRefresh: Boolean = false) { - disposable.add(sessionRepository.getSemesters() - .map { it.single { semester -> semester.current } } + disposable.add(studentRepository.getCurrentStudent() + .flatMap { semesterRepository.getCurrentSemester(it) } .flatMap { noteRepository.getNotes(it, forceRefresh) } .map { items -> items.map { NoteItem(it) } } .map { items -> items.sortedByDescending { it.note.date } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt index 9de0b1ff..949cb8c8 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt @@ -1,20 +1,20 @@ package io.github.wulkanowy.ui.modules.splash import io.github.wulkanowy.data.ErrorHandler -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.utils.logLogin import javax.inject.Inject class SplashPresenter @Inject constructor( - private val sessionRepository: SessionRepository, + private val studentRepository: StudentRepository, errorHandler: ErrorHandler ) : BasePresenter(errorHandler) { override fun onAttachView(view: SplashView) { super.onAttachView(view) view.run { - if (sessionRepository.isSessionSaved) { + if (studentRepository.isStudentSaved) { logLogin("Open app") openMainView() } else openLoginView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt index dbd0ac3f..5247dcee 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt @@ -47,7 +47,7 @@ class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView, override fun initView() { timetableAdapter.run { - setOnItemClickListener { presenter.onTimetableItemSelected(getItem(it)) } + setOnItemClickListener { presenter.onTimetableItemSelected(it) } } timetableRecycler.run { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt index 1a0eae83..6ab909ea 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt @@ -2,7 +2,8 @@ package io.github.wulkanowy.ui.modules.timetable import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import io.github.wulkanowy.data.ErrorHandler -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.SemesterRepository +import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.data.repositories.TimetableRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.utils.SchedulersProvider @@ -22,7 +23,8 @@ class TimetablePresenter @Inject constructor( private val errorHandler: ErrorHandler, private val schedulers: SchedulersProvider, private val timetableRepository: TimetableRepository, - private val sessionRepository: SessionRepository + private val studentRepository: StudentRepository, + private val semesterRepository: SemesterRepository ) : BasePresenter(errorHandler) { lateinit var currentDate: LocalDate @@ -64,9 +66,9 @@ class TimetablePresenter @Inject constructor( currentDate = date disposable.apply { clear() - add(sessionRepository.getSemesters() + add(studentRepository.getCurrentStudent() + .flatMap { semesterRepository.getCurrentSemester(it) } .delay(200, MILLISECONDS) - .map { it.single { semester -> semester.current } } .flatMap { timetableRepository.getTimetable(it, currentDate, currentDate, forceRefresh) } .map { items -> items.map { TimetableItem(it, view?.roomString.orEmpty()) } } .map { items -> items.sortedBy { it.lesson.number } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetFactory.kt b/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetFactory.kt index 6b9868f2..de0913e8 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetFactory.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetFactory.kt @@ -12,7 +12,8 @@ import android.widget.RemoteViewsService import io.github.wulkanowy.R import io.github.wulkanowy.data.db.SharedPrefHelper import io.github.wulkanowy.data.db.entities.Timetable -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.SemesterRepository +import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.data.repositories.TimetableRepository import io.github.wulkanowy.utils.toFormattedString import io.reactivex.disposables.CompositeDisposable @@ -21,7 +22,8 @@ import timber.log.Timber class TimetableWidgetFactory( private val timetableRepository: TimetableRepository, - private val sessionRepository: SessionRepository, + private val studentRepository: StudentRepository, + private val semesterRepository: SemesterRepository, private val sharedPref: SharedPrefHelper, private val context: Context, private val intent: Intent? @@ -46,9 +48,9 @@ class TimetableWidgetFactory( override fun onDataSetChanged() { intent?.action?.let { LocalDate.ofEpochDay(sharedPref.getLong(it, 0)) } ?.let { date -> - if (sessionRepository.isSessionSaved) { - disposable.add(sessionRepository.getSemesters() - .map { it.single { item -> item.current } } + if (studentRepository.isStudentSaved) { + disposable.add(studentRepository.getCurrentStudent() + .flatMap { semesterRepository.getCurrentSemester(it) } .flatMap { timetableRepository.getTimetable(it, date, date) } .map { item -> item.sortedBy { it.number } } .subscribe({ lessons = it }) diff --git a/app/src/main/java/io/github/wulkanowy/utils/FlexibleAdapterExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/FlexibleAdapterExtension.kt index 27b5f94f..bd6867a3 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/FlexibleAdapterExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/FlexibleAdapterExtension.kt @@ -1,10 +1,11 @@ package io.github.wulkanowy.utils import eu.davidea.flexibleadapter.FlexibleAdapter +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem -inline fun FlexibleAdapter<*>.setOnItemClickListener(crossinline listener: (position: Int) -> Unit) { +inline fun FlexibleAdapter<*>.setOnItemClickListener(crossinline listener: (item: AbstractFlexibleItem<*>) -> Unit) { addListener(FlexibleAdapter.OnItemClickListener { _, position -> - listener(position) + listener(getItem(position) as AbstractFlexibleItem<*>) true }) } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_account_add_24dp.xml b/app/src/main/res/drawable/ic_account_add_24dp.xml new file mode 100644 index 00000000..40b15391 --- /dev/null +++ b/app/src/main/res/drawable/ic_account_add_24dp.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/ic_account_circular_border.xml b/app/src/main/res/drawable/ic_account_circular_border.xml new file mode 100644 index 00000000..8ba66975 --- /dev/null +++ b/app/src/main/res/drawable/ic_account_circular_border.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_all_account_24dp.xml b/app/src/main/res/drawable/ic_all_account_24dp.xml new file mode 100644 index 00000000..f645b950 --- /dev/null +++ b/app/src/main/res/drawable/ic_all_account_24dp.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/layout/dialog_account.xml b/app/src/main/res/layout/dialog_account.xml new file mode 100644 index 00000000..9469aae1 --- /dev/null +++ b/app/src/main/res/layout/dialog_account.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/dialog_attendance.xml b/app/src/main/res/layout/dialog_attendance.xml index 8e85ba1f..fe680d68 100644 --- a/app/src/main/res/layout/dialog_attendance.xml +++ b/app/src/main/res/layout/dialog_attendance.xml @@ -10,7 +10,6 @@ android:padding="20dp"> + + + + + + + + diff --git a/app/src/main/res/layout/item_more.xml b/app/src/main/res/layout/item_more.xml index 8d7a2d33..0324c1f0 100644 --- a/app/src/main/res/layout/item_more.xml +++ b/app/src/main/res/layout/item_more.xml @@ -16,7 +16,7 @@ android:layout_height="24dp" android:layout_gravity="center_vertical" app:srcCompat="@drawable/ic_more_settings_24dp" - android:tint="?android:attr/android:textColorSecondary"/> + app:tint="?android:attr/android:textColorSecondary" /> - diff --git a/app/src/main/res/menu/action_menu_grade.xml b/app/src/main/res/menu/action_menu_grade.xml index 4f6749fc..87d6ad80 100644 --- a/app/src/main/res/menu/action_menu_grade.xml +++ b/app/src/main/res/menu/action_menu_grade.xml @@ -1,12 +1,10 @@ + xmlns:app="http://schemas.android.com/apk/res-auto"> diff --git a/app/src/main/res/menu/action_menu_main.xml b/app/src/main/res/menu/action_menu_main.xml new file mode 100644 index 00000000..7acc58c1 --- /dev/null +++ b/app/src/main/res/menu/action_menu_main.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 62fa6277..6fb1959e 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -13,9 +13,10 @@ O aplikacji Uwagi i osiągnięcia Zadania domowe + Wybierz konto - + Zaloguj się za pomocą konta ucznia lub rodzica Podaj symbol dziennika VULCAN Email lub nick @@ -29,6 +30,11 @@ To hasło jest niepoprawne Nie znaleziono ucznia. Sprwadź symbol To pole jest wymagane + Ten student jest już zalogowany + + + + Menadżer kont @@ -140,6 +146,13 @@ Brak zadań domowych + + Dodaj konto + Wyloguj + Czy chcesz wylogować aktualnego ucznia? + Wylogowanie ucznia + + Treść Opis @@ -151,7 +164,6 @@ Szczegóły Kategoria Zamknij - Anuluj Brak danych Przedmiot Poprzedni diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9ff06516..c82767a7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -13,9 +13,10 @@ About Notes and achievements Homework + Choose account - + Sign in with the student or parent account Enter the VULCAN diary symbol Email or nick @@ -29,6 +30,11 @@ This password is incorrect Student not found. Check the symbol This field is required + This student has already been logged in + + + + Account manager @@ -125,6 +131,13 @@ No info about homework + + Add account + Logout + Do you want to log out of an active student? + Student logout + + Content Description @@ -136,7 +149,6 @@ Details Category Close - Cancel No data Subject Prev diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 8228bdf8..b79ef7b7 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -14,7 +14,6 @@ @android:color/primary_text_dark @android:color/white @color/bottom_nav_background_inverse - @null @color/about_libraries_window_background diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/remote/AttendanceRemoteTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/remote/AttendanceRemoteTest.kt index ade7f874..f15f4ea7 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/remote/AttendanceRemoteTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/remote/AttendanceRemoteTest.kt @@ -6,6 +6,7 @@ import io.github.wulkanowy.data.db.entities.Semester import io.mockk.MockKAnnotations import io.mockk.every import io.mockk.impl.annotations.MockK +import io.mockk.impl.annotations.SpyK import io.reactivex.Single import org.junit.Assert.assertEquals import org.junit.Before @@ -15,8 +16,8 @@ import java.sql.Date class AttendanceRemoteTest { - @MockK - private lateinit var mockApi: Api + @SpyK + private var mockApi = Api() @MockK private lateinit var semesterMock: Semester @@ -27,7 +28,7 @@ class AttendanceRemoteTest { } @Test - fun getExamsTest() { + fun getAttendanceTest() { every { mockApi.getAttendance( LocalDate.of(2018, 9, 10), LocalDate.of(2018, 9, 15) diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/remote/ExamRemoteTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/remote/ExamRemoteTest.kt index d7f97b35..71fcd6d5 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/remote/ExamRemoteTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/remote/ExamRemoteTest.kt @@ -6,6 +6,7 @@ import io.github.wulkanowy.data.db.entities.Semester import io.mockk.MockKAnnotations import io.mockk.every import io.mockk.impl.annotations.MockK +import io.mockk.impl.annotations.SpyK import io.reactivex.Single import org.junit.Assert.assertEquals import org.junit.Before @@ -15,8 +16,8 @@ import java.sql.Date class ExamRemoteTest { - @MockK - private lateinit var mockApi: Api + @SpyK + private var mockApi = Api() @MockK private lateinit var semesterMock: Semester diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/remote/SessionRemoteTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/remote/StudentRemoteTest.kt similarity index 79% rename from app/src/test/java/io/github/wulkanowy/data/repositories/remote/SessionRemoteTest.kt rename to app/src/test/java/io/github/wulkanowy/data/repositories/remote/StudentRemoteTest.kt index dc234882..1e615c9c 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/remote/SessionRemoteTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/remote/StudentRemoteTest.kt @@ -10,7 +10,7 @@ import org.mockito.Mock import org.mockito.Mockito.doReturn import org.mockito.MockitoAnnotations -class SessionRemoteTest { +class StudentRemoteTest { @Mock private lateinit var mockApi: Api @@ -23,9 +23,9 @@ class SessionRemoteTest { @Test fun testRemoteAll() { doReturn(Single.just(listOf(Pupil("", "", 1, "test", "", "", Api.LoginType.AUTO)))) - .`when`(mockApi).getPupils() + .`when`(mockApi).getPupils() - val students = SessionRemote(mockApi).getConnectedStudents("", "", "", "http://fakelog.cf").blockingGet() + val students = StudentRemote(mockApi).getStudents("", "", "").blockingGet() assertEquals(1, students.size) assertEquals("test", students.first().studentName) } diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/remote/TimetableRemoteTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/remote/TimetableRemoteTest.kt index dcad80e9..4a5bb6ef 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/remote/TimetableRemoteTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/remote/TimetableRemoteTest.kt @@ -6,6 +6,7 @@ import io.github.wulkanowy.data.db.entities.Semester import io.mockk.MockKAnnotations import io.mockk.every import io.mockk.impl.annotations.MockK +import io.mockk.impl.annotations.SpyK import io.reactivex.Single import org.junit.Assert.assertEquals import org.junit.Before @@ -15,8 +16,8 @@ import java.sql.Date class TimetableRemoteTest { - @MockK - private lateinit var mockApi: Api + @SpyK + private var mockApi = Api() @MockK private lateinit var semesterMock: Semester @@ -27,7 +28,7 @@ class TimetableRemoteTest { } @Test - fun getExamsTest() { + fun getTimetableTest() { every { mockApi.getTimetable( LocalDate.of(2018, 9, 10), LocalDate.of(2018, 9, 15) diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt index 8a0c2358..59702f32 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt @@ -2,7 +2,7 @@ package io.github.wulkanowy.ui.modules.login.form import io.github.wulkanowy.TestSchedulersProvider import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.ui.modules.login.LoginErrorHandler import io.reactivex.Single import org.junit.Before @@ -22,7 +22,7 @@ class LoginFormPresenterTest { lateinit var loginFormView: LoginFormView @Mock - lateinit var repository: SessionRepository + lateinit var repository: StudentRepository @Mock lateinit var errorHandler: LoginErrorHandler @@ -75,7 +75,7 @@ class LoginFormPresenterTest { @Test fun emptySymbolLoginTest() { doReturn(Single.just(emptyList())) - .`when`(repository).getConnectedStudents(anyString(), anyString(), anyString(), anyString()) + .`when`(repository).getStudents(anyString(), anyString(), anyString(), anyString()) presenter.attemptLogin("@", "123456", "", "https://fakelog.cf") presenter.attemptLogin("@", "123456", "", "https://fakelog.cf") @@ -86,7 +86,7 @@ class LoginFormPresenterTest { fun loginTest() { val studentTest = Student(email = "test@", password = "123", endpoint = "https://fakelog.cf", loginType = "AUTO") doReturn(Single.just(listOf(studentTest))) - .`when`(repository).getConnectedStudents(anyString(), anyString(), anyString(), anyString()) + .`when`(repository).getStudents(anyString(), anyString(), anyString(), anyString()) presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf") verify(loginFormView).hideSoftKeyboard() @@ -100,7 +100,7 @@ class LoginFormPresenterTest { @Test fun loginEmptyTest() { doReturn(Single.just(emptyList())) - .`when`(repository).getConnectedStudents(anyString(), anyString(), anyString(), anyString()) + .`when`(repository).getStudents(anyString(), anyString(), anyString(), anyString()) presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf") verify(loginFormView).hideSoftKeyboard() @@ -114,7 +114,7 @@ class LoginFormPresenterTest { @Test fun loginEmptyTwiceTest() { doReturn(Single.just(emptyList())) - .`when`(repository).getConnectedStudents(anyString(), anyString(), anyString(), anyString()) + .`when`(repository).getStudents(anyString(), anyString(), anyString(), anyString()) presenter.attemptLogin("@", "123456", "", "https://fakelog.cf") presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf") @@ -132,7 +132,7 @@ class LoginFormPresenterTest { fun loginErrorTest() { val testException = RuntimeException("test") doReturn(Single.error>(testException)) - .`when`(repository).getConnectedStudents(anyString(), anyString(), anyString(), anyString()) + .`when`(repository).getStudents(anyString(), anyString(), anyString(), anyString()) presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf") verify(loginFormView).hideSoftKeyboard() diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenterTest.kt index 0a2a0b0f..c7c87ded 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenterTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/login/options/LoginOptionsPresenterTest.kt @@ -1,9 +1,11 @@ package io.github.wulkanowy.ui.modules.login.options import io.github.wulkanowy.TestSchedulersProvider -import io.github.wulkanowy.data.ErrorHandler +import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.SemesterRepository +import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.ui.modules.login.LoginErrorHandler import io.reactivex.Completable import io.reactivex.Single import org.junit.Before @@ -17,13 +19,16 @@ import org.mockito.MockitoAnnotations class LoginOptionsPresenterTest { @Mock - lateinit var errorHandler: ErrorHandler + lateinit var errorHandler: LoginErrorHandler @Mock lateinit var loginOptionsView: LoginOptionsView @Mock - lateinit var repository: SessionRepository + lateinit var studentRepository: StudentRepository + + @Mock + lateinit var semesterRepository: SemesterRepository private lateinit var presenter: LoginOptionsPresenter @@ -34,8 +39,9 @@ class LoginOptionsPresenterTest { @Before fun initPresenter() { MockitoAnnotations.initMocks(this) - clearInvocations(repository, loginOptionsView) - presenter = LoginOptionsPresenter(errorHandler, repository, TestSchedulersProvider()) + clearInvocations(studentRepository, loginOptionsView) + clearInvocations(semesterRepository, loginOptionsView) + presenter = LoginOptionsPresenter(errorHandler, studentRepository, semesterRepository, TestSchedulersProvider()) presenter.onAttachView(loginOptionsView) } @@ -46,7 +52,7 @@ class LoginOptionsPresenterTest { @Test fun refreshDataTest() { - doReturn(Single.just(listOf(testStudent))).`when`(repository).cachedStudents + doReturn(Single.just(listOf(testStudent))).`when`(studentRepository).cachedStudents presenter.onParentViewLoadData() verify(loginOptionsView).showActionBar(true) verify(loginOptionsView).updateData(listOf(LoginOptionsItem(testStudent))) @@ -54,7 +60,7 @@ class LoginOptionsPresenterTest { @Test fun refreshDataErrorTest() { - doReturn(Single.error>(testException)).`when`(repository).cachedStudents + doReturn(Single.error>(testException)).`when`(studentRepository).cachedStudents presenter.onParentViewLoadData() verify(loginOptionsView).showActionBar(true) verify(errorHandler).proceed(testException) @@ -62,8 +68,9 @@ class LoginOptionsPresenterTest { @Test fun onSelectedStudentTest() { - doReturn(Completable.complete()).`when`(repository).saveStudent(testStudent) - presenter.onSelectItem(LoginOptionsItem(testStudent)) + doReturn(Completable.complete()).`when`(studentRepository).saveStudent(testStudent) + doReturn(Single.just(emptyList())).`when`(semesterRepository).getSemesters(testStudent, true) + presenter.onItemSelected(LoginOptionsItem(testStudent)) verify(loginOptionsView).showContent(false) verify(loginOptionsView).showProgress(true) verify(loginOptionsView).openMainView() @@ -71,8 +78,10 @@ class LoginOptionsPresenterTest { @Test fun onSelectedStudentErrorTest() { - doReturn(Completable.error(testException)).`when`(repository).saveStudent(testStudent) - presenter.onSelectItem(LoginOptionsItem(testStudent)) + doReturn(Completable.error(testException)).`when`(studentRepository).saveStudent(testStudent) + doReturn(Single.just(emptyList())).`when`(semesterRepository).getSemesters(testStudent, true) + doReturn(Completable.complete()).`when`(studentRepository).logoutCurrentStudent() + presenter.onItemSelected(LoginOptionsItem(testStudent)) verify(loginOptionsView).showContent(false) verify(loginOptionsView).showProgress(true) verify(errorHandler).proceed(testException) diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/splash/SplashPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/splash/SplashPresenterTest.kt index 529c0a2a..d9bc745f 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/splash/SplashPresenterTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/splash/SplashPresenterTest.kt @@ -1,7 +1,7 @@ package io.github.wulkanowy.ui.modules.splash import io.github.wulkanowy.data.ErrorHandler -import io.github.wulkanowy.data.repositories.SessionRepository +import io.github.wulkanowy.data.repositories.StudentRepository import org.junit.Before import org.junit.Test import org.mockito.Mock @@ -15,7 +15,7 @@ class SplashPresenterTest { lateinit var splashView: SplashView @Mock - lateinit var sessionRepository: SessionRepository + lateinit var studentRepository: StudentRepository @Mock lateinit var errorHandler: ErrorHandler @@ -25,19 +25,19 @@ class SplashPresenterTest { @Before fun initPresenter() { MockitoAnnotations.initMocks(this) - presenter = SplashPresenter(sessionRepository, errorHandler) + presenter = SplashPresenter(studentRepository, errorHandler) } @Test fun testOpenLoginView() { - doReturn(false).`when`(sessionRepository).isSessionSaved + doReturn(false).`when`(studentRepository).isStudentSaved presenter.onAttachView(splashView) verify(splashView).openLoginView() } @Test fun testMainMainView() { - doReturn(true).`when`(sessionRepository).isSessionSaved + doReturn(true).`when`(studentRepository).isStudentSaved presenter.onAttachView(splashView) verify(splashView).openMainView() }