Add school info (#557)

* Add db layer to school info

* Add base classes

* Add database migration

* Add base view

* Update icon

* Fix textviews height

* Handle error and empty results

* Improve school info look

* Add strings

* Fix action bar elevation in school fragment

* Add missing blank lines

* Reorganize strings

* Make field title first in order

* Make fields views selectable

* Rename SchoolInfo to School
This commit is contained in:
Mikołaj Pich
2019-10-21 21:25:15 +02:00
committed by Rafał Borcz
parent 1b492d50fe
commit 7a4cf694ca
39 changed files with 2453 additions and 38 deletions

View File

@ -144,4 +144,8 @@ internal class RepositoryModule {
@Singleton
@Provides
fun provideTeacherDao(database: AppDatabase) = database.teacherDao
@Singleton
@Provides
fun provideSchoolInfoDao(database: AppDatabase) = database.schoolDao
}

View File

@ -22,6 +22,7 @@ import io.github.wulkanowy.data.db.dao.MobileDeviceDao
import io.github.wulkanowy.data.db.dao.NoteDao
import io.github.wulkanowy.data.db.dao.RecipientDao
import io.github.wulkanowy.data.db.dao.ReportingUnitDao
import io.github.wulkanowy.data.db.dao.SchoolDao
import io.github.wulkanowy.data.db.dao.SemesterDao
import io.github.wulkanowy.data.db.dao.StudentDao
import io.github.wulkanowy.data.db.dao.SubjectDao
@ -42,6 +43,7 @@ import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.data.db.entities.Note
import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.Subject
@ -55,6 +57,7 @@ import io.github.wulkanowy.data.db.migrations.Migration14
import io.github.wulkanowy.data.db.migrations.Migration15
import io.github.wulkanowy.data.db.migrations.Migration16
import io.github.wulkanowy.data.db.migrations.Migration17
import io.github.wulkanowy.data.db.migrations.Migration18
import io.github.wulkanowy.data.db.migrations.Migration2
import io.github.wulkanowy.data.db.migrations.Migration3
import io.github.wulkanowy.data.db.migrations.Migration4
@ -87,7 +90,8 @@ import javax.inject.Singleton
ReportingUnit::class,
Recipient::class,
MobileDevice::class,
Teacher::class
Teacher::class,
School::class
],
version = AppDatabase.VERSION_SCHEMA,
exportSchema = true
@ -96,7 +100,7 @@ import javax.inject.Singleton
abstract class AppDatabase : RoomDatabase() {
companion object {
const val VERSION_SCHEMA = 17
const val VERSION_SCHEMA = 18
fun getMigrations(): Array<Migration> {
return arrayOf(
@ -115,7 +119,8 @@ abstract class AppDatabase : RoomDatabase() {
Migration14(),
Migration15(),
Migration16(),
Migration17()
Migration17(),
Migration18()
)
}
@ -168,4 +173,6 @@ abstract class AppDatabase : RoomDatabase() {
abstract val mobileDeviceDao: MobileDeviceDao
abstract val teacherDao: TeacherDao
abstract val schoolDao: SchoolDao
}

View File

@ -0,0 +1,23 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.School
import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@Dao
interface SchoolDao {
@Insert
fun insert(school: School)
@Delete
fun delete(school: School)
@Query("SELECT * FROM School WHERE student_id = :studentId AND class_id = :classId")
fun load(studentId: Int, classId: Int): Maybe<School>
}

View File

@ -13,10 +13,10 @@ import javax.inject.Singleton
interface TeacherDao {
@Insert
fun insertAll(devices: List<Teacher>)
fun insertAll(teachers: List<Teacher>)
@Delete
fun deleteAll(devices: List<Teacher>)
fun deleteAll(teachers: List<Teacher>)
@Query("SELECT * FROM Teachers WHERE student_id = :studentId AND class_id = :classId")
fun loadAll(studentId: Int, classId: Int): Maybe<List<Teacher>>

View File

@ -0,0 +1,30 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
@Entity(tableName = "School")
data class School(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "class_id")
val classId: Int,
val name: String,
val address: String,
val contact: String,
val headmaster: String,
val pedagogue: String
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View File

@ -0,0 +1,22 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration18 : Migration(17, 18) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("""
CREATE TABLE IF NOT EXISTS School (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL,
class_id INTEGER NOT NULL,
name TEXT NOT NULL,
address TEXT NOT NULL,
contact TEXT NOT NULL,
headmaster TEXT NOT NULL,
pedagogue TEXT NOT NULL
)
""")
}
}

View File

@ -0,0 +1,22 @@
package io.github.wulkanowy.data.repositories.school
import io.github.wulkanowy.data.db.dao.SchoolDao
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.data.db.entities.Semester
import io.reactivex.Maybe
import javax.inject.Inject
class SchoolLocal @Inject constructor(private val schoolDb: SchoolDao) {
fun saveSchool(school: School) {
schoolDb.insert(school)
}
fun deleteSchool(school: School) {
schoolDb.delete(school)
}
fun getSchool(semester: Semester): Maybe<School> {
return schoolDb.load(semester.studentId, semester.classId)
}
}

View File

@ -0,0 +1,26 @@
package io.github.wulkanowy.data.repositories.school
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.data.db.entities.Semester
import io.reactivex.Single
import javax.inject.Inject
class SchoolRemote @Inject constructor(private val api: Api) {
fun getSchoolInfo(semester: Semester): Single<School> {
return Single.just(api.apply { diaryId = semester.diaryId })
.flatMap { it.getSchool() }
.map {
School(
studentId = semester.studentId,
classId = semester.classId,
name = it.name,
address = it.address,
contact = it.contact,
headmaster = it.headmaster,
pedagogue = it.pedagogue
)
}
}
}

View File

@ -0,0 +1,41 @@
package io.github.wulkanowy.data.repositories.school
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.School
import io.github.wulkanowy.data.db.entities.Semester
import io.reactivex.Maybe
import io.reactivex.Single
import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class SchoolRepository @Inject constructor(
private val settings: InternetObservingSettings,
private val local: SchoolLocal,
private val remote: SchoolRemote
) {
fun getSchoolInfo(semester: Semester, forceRefresh: Boolean = false): Maybe<School> {
return local.getSchool(semester).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getSchoolInfo(semester)
else Single.error(UnknownHostException())
}.flatMapMaybe { new ->
local.getSchool(semester)
.doOnSuccess { old ->
if (new != old) {
local.deleteSchool(old)
local.saveSchool(new)
}
}
.doOnComplete {
local.saveSchool(new)
}
}.flatMap({ local.getSchool(semester) }, { Maybe.error(it) },
{ local.getSchool(semester) })
)
}
}

View File

@ -6,7 +6,8 @@ import io.github.wulkanowy.data.db.entities.Teacher
import io.reactivex.Maybe
import javax.inject.Inject
class TeacherLocal @Inject constructor(private val teacherDb: TeacherDao) {
class TeacherLocal @Inject constructor(private val teacherDb: TeacherDao) {
fun saveTeachers(teachers: List<Teacher>) {
teacherDb.insertAll(teachers)
}

View File

@ -16,6 +16,7 @@ class TeacherRepository @Inject constructor(
private val local: TeacherLocal,
private val remote: TeacherRemote
) {
fun getTeachers(semester: Semester, forceRefresh: Boolean = false): Single<List<Teacher>> {
return local.getTeachers(semester).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)

View File

@ -26,8 +26,10 @@ import io.github.wulkanowy.ui.modules.mobiledevice.MobileDeviceModule
import io.github.wulkanowy.ui.modules.mobiledevice.token.MobileDeviceTokenDialog
import io.github.wulkanowy.ui.modules.more.MoreFragment
import io.github.wulkanowy.ui.modules.note.NoteFragment
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersModule
import io.github.wulkanowy.ui.modules.settings.SettingsFragment
import io.github.wulkanowy.ui.modules.teacher.TeacherFragment
import io.github.wulkanowy.ui.modules.schoolandteachers.teacher.TeacherFragment
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
import io.github.wulkanowy.ui.modules.timetable.completed.CompletedLessonsFragment
@ -123,6 +125,6 @@ abstract class MainModule {
abstract fun bindLicenseFragment(): LicenseFragment
@PerFragment
@ContributesAndroidInjector
abstract fun bindTeacherFragment(): TeacherFragment
@ContributesAndroidInjector(modules = [SchoolAndTeachersModule::class])
abstract fun bindSchoolAndTeachersFragment(): SchoolAndTeachersFragment
}

View File

@ -7,6 +7,7 @@ import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.ui.modules.main.MainView.Section.GRADE
import io.github.wulkanowy.ui.modules.main.MainView.Section.MESSAGE
import io.github.wulkanowy.ui.modules.main.MainView.Section.SCHOOL
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import timber.log.Timber
@ -38,7 +39,7 @@ class MainPresenter @Inject constructor(
fun onViewChange(section: MainView.Section?) {
view?.apply {
showActionBarElevation(section != GRADE && section != MESSAGE)
showActionBarElevation(section != GRADE && section != MESSAGE && section != SCHOOL)
currentViewTitle?.let { setViewTitle(it) }
currentStackSize?.let {
if (it > 1) showHomeArrow(true)

View File

@ -51,6 +51,7 @@ interface MainView : BaseView {
NOTE(7),
LUCKY_NUMBER(8),
SETTINGS(9),
ABOUT(10)
ABOUT(10),
SCHOOL(11)
}
}

View File

@ -18,8 +18,9 @@ import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.message.MessageFragment
import io.github.wulkanowy.ui.modules.mobiledevice.MobileDeviceFragment
import io.github.wulkanowy.ui.modules.note.NoteFragment
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment
import io.github.wulkanowy.ui.modules.settings.SettingsFragment
import io.github.wulkanowy.ui.modules.teacher.TeacherFragment
import io.github.wulkanowy.ui.modules.schoolandteachers.teacher.TeacherFragment
import io.github.wulkanowy.utils.getCompatDrawable
import io.github.wulkanowy.utils.setOnItemClickListener
import kotlinx.android.synthetic.main.fragment_more.*
@ -55,8 +56,8 @@ class MoreFragment : BaseFragment(), MoreView, MainView.TitledView, MainView.Mai
override val mobileDevicesRes: Pair<String, Drawable?>?
get() = context?.run { getString(R.string.mobile_devices_title) to getCompatDrawable(R.drawable.ic_more_mobile_devices) }
override val teachersRes: Pair<String, Drawable?>?
get() = context?.run { getString(R.string.teachers_title) to getCompatDrawable((R.drawable.ic_more_teacher)) }
override val schoolAndTeachersRes: Pair<String, Drawable?>?
get() = context?.run { getString(R.string.schoolandteachers_title) to getCompatDrawable((R.drawable.ic_more_schoolandteachers)) }
override val settingsRes: Pair<String, Drawable?>?
get() = context?.run { getString(R.string.settings_title) to getCompatDrawable(R.drawable.ic_more_settings) }
@ -110,8 +111,8 @@ class MoreFragment : BaseFragment(), MoreView, MainView.TitledView, MainView.Mai
(activity as? MainActivity)?.pushView(MobileDeviceFragment.newInstance())
}
override fun openTeachersView() {
(activity as? MainActivity)?.pushView(TeacherFragment.newInstance())
override fun openSchoolAndTeachersView() {
(activity as? MainActivity)?.pushView(SchoolAndTeachersFragment.newInstance())
}
override fun openSettingsView() {

View File

@ -31,7 +31,7 @@ class MorePresenter @Inject constructor(
noteRes?.first -> openNoteView()
luckyNumberRes?.first -> openLuckyNumberView()
mobileDevicesRes?.first -> openMobileDevicesView()
teachersRes?.first -> openTeachersView()
schoolAndTeachersRes?.first -> openSchoolAndTeachersView()
settingsRes?.first -> openSettingsView()
aboutRes?.first -> openAboutView()
}
@ -52,7 +52,7 @@ class MorePresenter @Inject constructor(
noteRes?.let { MoreItem(it.first, it.second) },
luckyNumberRes?.let { MoreItem(it.first, it.second) },
mobileDevicesRes?.let { MoreItem(it.first, it.second) },
teachersRes?.let { MoreItem(it.first, it.second) },
schoolAndTeachersRes?.let { MoreItem(it.first, it.second) },
settingsRes?.let { MoreItem(it.first, it.second) },
aboutRes?.let { MoreItem(it.first, it.second) })
)

View File

@ -15,7 +15,7 @@ interface MoreView : BaseView {
val mobileDevicesRes: Pair<String, Drawable?>?
val teachersRes: Pair<String, Drawable?>?
val schoolAndTeachersRes: Pair<String, Drawable?>?
val settingsRes: Pair<String, Drawable?>?
@ -41,5 +41,5 @@ interface MoreView : BaseView {
fun openMobileDevicesView()
fun openTeachersView()
fun openSchoolAndTeachersView()
}

View File

@ -0,0 +1,8 @@
package io.github.wulkanowy.ui.modules.schoolandteachers
interface SchoolAndTeachersChildView {
fun notifyParentDataLoaded()
fun onParentLoadData(forceRefresh: Boolean)
}

View File

@ -0,0 +1,87 @@
package io.github.wulkanowy.ui.modules.schoolandteachers
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import android.view.ViewGroup
import io.github.wulkanowy.R
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.schoolandteachers.school.SchoolFragment
import io.github.wulkanowy.ui.modules.schoolandteachers.teacher.TeacherFragment
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.setOnSelectPageListener
import kotlinx.android.synthetic.main.fragment_schoolandteachers.*
import javax.inject.Inject
class SchoolAndTeachersFragment : BaseFragment(), SchoolAndTeachersView, MainView.TitledView {
@Inject
lateinit var presenter: SchoolAndTeachersPresenter
@Inject
lateinit var pagerAdapter: BaseFragmentPagerAdapter
companion object {
fun newInstance() = SchoolAndTeachersFragment()
}
override val titleStringId: Int get() = R.string.schoolandteachers_title
override val currentPageIndex get() = schoolandteachersViewPager.currentItem
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_schoolandteachers, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
presenter.onAttachView(this)
}
override fun initView() {
with(pagerAdapter) {
containerId = schoolandteachersViewPager.id
addFragmentsWithTitle(mapOf(
SchoolFragment.newInstance() to getString(R.string.school_title),
TeacherFragment.newInstance() to getString(R.string.teachers_title)
))
}
with(schoolandteachersViewPager) {
adapter = pagerAdapter
offscreenPageLimit = 2
setOnSelectPageListener(presenter::onPageSelected)
}
with(schoolandteachersTabLayout) {
setupWithViewPager(schoolandteachersViewPager)
setElevationCompat(context.dpToPx(4f))
}
}
override fun showContent(show: Boolean) {
schoolandteachersViewPager.visibility = if (show) VISIBLE else INVISIBLE
schoolandteachersTabLayout.visibility = if (show) VISIBLE else INVISIBLE
}
override fun showProgress(show: Boolean) {
schoolandteachersProgress.visibility = if (show) VISIBLE else INVISIBLE
}
fun onChildFragmentLoaded() {
presenter.onChildViewLoaded()
}
override fun notifyChildLoadData(index: Int, forceRefresh: Boolean) {
(pagerAdapter.getFragmentInstance(index) as? SchoolAndTeachersChildView)?.onParentLoadData(forceRefresh)
}
override fun onDestroyView() {
presenter.onDetachView()
super.onDestroyView()
}
}

View File

@ -0,0 +1,32 @@
package io.github.wulkanowy.ui.modules.schoolandteachers
import dagger.Module
import dagger.Provides
import dagger.android.ContributesAndroidInjector
import io.github.wulkanowy.di.scopes.PerChildFragment
import io.github.wulkanowy.di.scopes.PerFragment
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.modules.schoolandteachers.school.SchoolFragment
import io.github.wulkanowy.ui.modules.schoolandteachers.teacher.TeacherFragment
@Suppress("unused")
@Module
abstract class SchoolAndTeachersModule {
@Module
companion object {
@JvmStatic
@PerFragment
@Provides
fun provideSchoolAndTeachersAdapter(fragment: SchoolAndTeachersFragment) = BaseFragmentPagerAdapter(fragment.childFragmentManager)
}
@PerChildFragment
@ContributesAndroidInjector
abstract fun provideSchoolFragment(): SchoolFragment
@PerChildFragment
@ContributesAndroidInjector
abstract fun provideTeacherFragment(): TeacherFragment
}

View File

@ -0,0 +1,47 @@
package io.github.wulkanowy.ui.modules.schoolandteachers
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.SchedulersProvider
import io.reactivex.Completable
import timber.log.Timber
import java.util.concurrent.TimeUnit
import javax.inject.Inject
class SchoolAndTeachersPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository
) : BasePresenter<SchoolAndTeachersView>(errorHandler, studentRepository, schedulers) {
override fun onAttachView(view: SchoolAndTeachersView) {
super.onAttachView(view)
disposable.add(Completable.timer(150, TimeUnit.MILLISECONDS, schedulers.mainThread)
.subscribe {
view.initView()
Timber.i("Message view was initialized")
loadData()
})
}
fun onPageSelected(index: Int) {
loadChild(index)
}
private fun loadData() {
view?.run { loadChild(currentPageIndex) }
}
private fun loadChild(index: Int, forceRefresh: Boolean = false) {
Timber.i("Load schoolandteachers child view index: $index")
view?.notifyChildLoadData(index, forceRefresh)
}
fun onChildViewLoaded() {
view?.apply {
showContent(true)
showProgress(false)
}
}
}

View File

@ -0,0 +1,16 @@
package io.github.wulkanowy.ui.modules.schoolandteachers
import io.github.wulkanowy.ui.base.BaseView
interface SchoolAndTeachersView : BaseView {
val currentPageIndex: Int
fun initView()
fun showContent(show: Boolean)
fun showProgress(show: Boolean)
fun notifyChildLoadData(index: Int, forceRefresh: Boolean)
}

View File

@ -0,0 +1,80 @@
package io.github.wulkanowy.ui.modules.schoolandteachers.school
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersChildView
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment
import kotlinx.android.synthetic.main.fragment_school.*
import javax.inject.Inject
class SchoolFragment : BaseFragment(), SchoolView, MainView.TitledView, SchoolAndTeachersChildView {
@Inject
lateinit var presenter: SchoolPresenter
override val titleStringId get() = R.string.school_title
companion object {
fun newInstance() = SchoolFragment()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_school, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
presenter.onAttachView(this)
}
override fun initView() {
schoolSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
}
override fun updateData(data: School) {
schoolName.text = data.name
schoolAddress.text = data.address.ifBlank { "-" }
schoolTelephone.text = data.contact.ifBlank { "-" }
schoolHeadmaster.text = data.headmaster
schoolPedagogue.text = data.pedagogue
}
override fun showEmpty(show: Boolean) {
schoolEmpty.visibility = if (show) View.VISIBLE else View.GONE
}
override fun showProgress(show: Boolean) {
schoolProgress.visibility = if (show) View.VISIBLE else View.GONE
}
override fun enableSwipe(enable: Boolean) {
schoolSwipe.isEnabled = enable
}
override fun showContent(show: Boolean) {
schoolContent.visibility = if (show) View.VISIBLE else View.GONE
}
override fun hideRefresh() {
schoolSwipe.isRefreshing = false
}
override fun notifyParentDataLoaded() {
(parentFragment as? SchoolAndTeachersFragment)?.onChildFragmentLoaded()
}
override fun onParentLoadData(forceRefresh: Boolean) {
presenter.onParentViewLoadData(forceRefresh)
}
override fun onDestroyView() {
presenter.onDetachView()
super.onDestroyView()
}
}

View File

@ -0,0 +1,70 @@
package io.github.wulkanowy.ui.modules.schoolandteachers.school
import io.github.wulkanowy.data.repositories.school.SchoolRepository
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import timber.log.Timber
import javax.inject.Inject
class SchoolPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val semesterRepository: SemesterRepository,
private val schoolRepository: SchoolRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<SchoolView>(errorHandler, studentRepository, schedulers) {
override fun onAttachView(view: SchoolView) {
super.onAttachView(view)
view.initView()
Timber.i("School view was initialized")
loadData()
}
fun onSwipeRefresh() {
loadData(true)
}
fun onParentViewLoadData(forceRefresh: Boolean) {
loadData(forceRefresh)
}
private fun loadData(forceRefresh: Boolean = false) {
Timber.i("Loading school info started")
disposable.add(studentRepository.getCurrentStudent()
.flatMap { semesterRepository.getCurrentSemester(it) }
.flatMapMaybe { schoolRepository.getSchoolInfo(it, forceRefresh) }
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
.doFinally {
view?.run {
hideRefresh()
showProgress(false)
enableSwipe(true)
notifyParentDataLoaded()
}
}.subscribe({
Timber.i("Loading teachers result: Success")
view?.run {
updateData(it)
showContent(true)
showEmpty(false)
}
analytics.logEvent("load_school", "force_refresh" to forceRefresh)
}, {
Timber.i("Loading school result: An exception occurred")
errorHandler.dispatch(it)
}, {
Timber.i("Loading school result: No school info found")
view?.run {
showContent(false)
showEmpty(true)
}
}))
}
}

View File

@ -0,0 +1,22 @@
package io.github.wulkanowy.ui.modules.schoolandteachers.school
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.ui.base.BaseView
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersChildView
interface SchoolView : BaseView, SchoolAndTeachersChildView {
fun initView()
fun updateData(data: School)
fun showEmpty(show: Boolean)
fun showProgress(show: Boolean)
fun enableSwipe(enable: Boolean)
fun showContent(show: Boolean)
fun hideRefresh()
}

View File

@ -1,4 +1,4 @@
package io.github.wulkanowy.ui.modules.teacher
package io.github.wulkanowy.ui.modules.schoolandteachers.teacher
import android.os.Bundle
import android.view.LayoutInflater
@ -11,10 +11,13 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import io.github.wulkanowy.R
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersChildView
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment
import kotlinx.android.synthetic.main.fragment_teacher.*
import javax.inject.Inject
class TeacherFragment : BaseFragment(), TeacherView, MainView.TitledView {
class TeacherFragment : BaseFragment(), TeacherView, MainView.TitledView, SchoolAndTeachersChildView {
@Inject
lateinit var presenter: TeacherPresenter
@ -86,6 +89,14 @@ class TeacherFragment : BaseFragment(), TeacherView, MainView.TitledView {
teacherSwipe.isRefreshing = false
}
override fun notifyParentDataLoaded() {
(parentFragment as? SchoolAndTeachersFragment)?.onChildFragmentLoaded()
}
override fun onParentLoadData(forceRefresh: Boolean) {
presenter.onParentViewLoadData(forceRefresh)
}
override fun onDestroyView() {
presenter.onDetachView()
super.onDestroyView()

View File

@ -1,4 +1,4 @@
package io.github.wulkanowy.ui.modules.teacher
package io.github.wulkanowy.ui.modules.schoolandteachers.teacher
import android.annotation.SuppressLint
import android.view.View

View File

@ -1,4 +1,4 @@
package io.github.wulkanowy.ui.modules.teacher
package io.github.wulkanowy.ui.modules.schoolandteachers.teacher
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
import io.github.wulkanowy.data.repositories.student.StudentRepository
@ -14,7 +14,6 @@ class TeacherPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val semesterRepository: SemesterRepository,
private val teacherRepository: TeacherRepository,
private val analytics: FirebaseAnalyticsHelper
@ -31,12 +30,16 @@ class TeacherPresenter @Inject constructor(
loadData(true)
}
fun onParentViewLoadData(forceRefresh: Boolean) {
loadData(forceRefresh)
}
private fun loadData(forceRefresh: Boolean = false) {
Timber.i("Loading teachers data started")
disposable.add(studentRepository.getCurrentStudent()
.flatMap { semesterRepository.getCurrentSemester(it) }
.flatMap { teacherRepository.getTeachers(it, forceRefresh) }
.map { it.filter { teacher -> teacher.name.isNotBlank() } }
.map { it.filter { teacher -> teacher.name.isNotBlank() } }
.map { items -> items.map { TeacherItem(it, view?.noSubjectString.orEmpty()) } }
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
@ -45,6 +48,7 @@ class TeacherPresenter @Inject constructor(
hideRefresh()
showProgress(false)
enableSwipe(true)
notifyParentDataLoaded()
}
}.subscribe({
Timber.i("Loading teachers result: Success")

View File

@ -1,9 +1,10 @@
package io.github.wulkanowy.ui.modules.teacher
package io.github.wulkanowy.ui.modules.schoolandteachers.teacher
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import io.github.wulkanowy.ui.base.BaseView
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersChildView
interface TeacherView : BaseView {
interface TeacherView : BaseView, SchoolAndTeachersChildView {
val isViewEmpty: Boolean

View File

@ -11,6 +11,7 @@ import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.message.MessageFragment
import io.github.wulkanowy.ui.modules.more.MoreFragment
import io.github.wulkanowy.ui.modules.note.NoteFragment
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment
import io.github.wulkanowy.ui.modules.settings.SettingsFragment
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
@ -27,6 +28,7 @@ fun Fragment.toSection(): MainView.Section? {
is LuckyNumberFragment -> MainView.Section.LUCKY_NUMBER
is SettingsFragment -> MainView.Section.SETTINGS
is AboutFragment -> MainView.Section.ABOUT
is SchoolAndTeachersFragment -> MainView.Section.SCHOOL
else -> null
}
}