forked from github/wulkanowy-mirror
Settings refactor (#166)
This commit is contained in:
parent
b680cc4366
commit
837bce7286
@ -77,11 +77,11 @@ dependencies {
|
||||
implementation "androidx.legacy:legacy-support-v4:$androidx_version"
|
||||
implementation "androidx.appcompat:appcompat:$androidx_version"
|
||||
implementation "androidx.cardview:cardview:$androidx_version"
|
||||
implementation "androidx.legacy:legacy-preference-v14:$androidx_version"
|
||||
implementation "com.google.android.material:material:$androidx_version"
|
||||
implementation 'androidx.multidex:multidex:2.0.0'
|
||||
|
||||
implementation "com.google.android.gms:play-services-oss-licenses:16.0.1"
|
||||
implementation 'com.takisoft.preferencex:preferencex:1.0.0'
|
||||
implementation "com.mikepenz:aboutlibraries:6.2.0"
|
||||
implementation "com.firebase:firebase-jobdispatcher:0.8.5"
|
||||
|
||||
//Do not update dagger https://github.com/google/dagger/issues/1245
|
||||
|
@ -0,0 +1,16 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class PreferencesRepository @Inject constructor(private val sharedPref: SharedPreferences) {
|
||||
|
||||
val startMenuIndex: Int
|
||||
get() = sharedPref.getString("start_menu", "0")?.toInt() ?: 0
|
||||
|
||||
val showPresent: Boolean
|
||||
get() = sharedPref.getBoolean("attendance_present", true)
|
||||
}
|
||||
|
@ -24,6 +24,9 @@ class LoginActivity : BaseActivity(), LoginView, LoginSwitchListener {
|
||||
fun getStartIntent(context: Context) = Intent(context, LoginActivity::class.java)
|
||||
}
|
||||
|
||||
override val currentViewIndex: Int
|
||||
get() = loginViewpager.currentItem
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_login)
|
||||
@ -63,8 +66,6 @@ class LoginActivity : BaseActivity(), LoginView, LoginSwitchListener {
|
||||
(loginAdapter.getItem(index) as LoginOptionsFragment).loadData()
|
||||
}
|
||||
|
||||
override fun currentViewPosition() = loginViewpager.currentItem
|
||||
|
||||
public override fun onDestroy() {
|
||||
presenter.onDetachView()
|
||||
super.onDestroy()
|
||||
|
@ -25,7 +25,7 @@ class LoginPresenter @Inject constructor(errorHandler: ErrorHandler)
|
||||
|
||||
fun onBackPressed(default: () -> Unit) {
|
||||
view?.run {
|
||||
if (currentViewPosition() == 1) {
|
||||
if (currentViewIndex == 1) {
|
||||
switchView(0)
|
||||
hideActionBar()
|
||||
} else default()
|
||||
|
@ -4,6 +4,8 @@ import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface LoginView : BaseView {
|
||||
|
||||
val currentViewIndex: Int
|
||||
|
||||
fun initAdapter()
|
||||
|
||||
fun loadOptionsView(index: Int)
|
||||
@ -11,6 +13,4 @@ interface LoginView : BaseView {
|
||||
fun switchView(position: Int)
|
||||
|
||||
fun hideActionBar()
|
||||
|
||||
fun currentViewPosition(): Int
|
||||
}
|
||||
|
@ -4,10 +4,11 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.aurelhubert.ahbottomnavigation.AHBottomNavigation
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.aurelhubert.ahbottomnavigation.AHBottomNavigation.TitleState.ALWAYS_SHOW
|
||||
import com.aurelhubert.ahbottomnavigation.AHBottomNavigationItem
|
||||
import com.ncapdevi.fragnav.FragNavController
|
||||
import com.ncapdevi.fragnav.FragNavController.Companion.DETACH_ON_NAVIGATE_HIDE_ON_SWITCH
|
||||
import com.ncapdevi.fragnav.FragNavController.Companion.HIDE
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.ui.base.BaseActivity
|
||||
import io.github.wulkanowy.ui.main.attendance.AttendanceFragment
|
||||
@ -15,7 +16,8 @@ import io.github.wulkanowy.ui.main.exam.ExamFragment
|
||||
import io.github.wulkanowy.ui.main.grade.GradeFragment
|
||||
import io.github.wulkanowy.ui.main.more.MoreFragment
|
||||
import io.github.wulkanowy.ui.main.timetable.TimetableFragment
|
||||
import io.github.wulkanowy.utils.setOnTabTransactionListener
|
||||
import io.github.wulkanowy.utils.safelyPopFragment
|
||||
import io.github.wulkanowy.utils.setOnViewChangeListener
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -28,11 +30,20 @@ class MainActivity : BaseActivity(), MainView {
|
||||
lateinit var navController: FragNavController
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_TAB = 2
|
||||
|
||||
fun getStartIntent(context: Context) = Intent(context, MainActivity::class.java)
|
||||
}
|
||||
|
||||
override val isRootView: Boolean
|
||||
get() = navController.isRootFragment
|
||||
|
||||
override val currentViewTitle: String?
|
||||
get() = (navController.currentFrag as? MainView.TitledView)?.titleStringId?.let { getString(it) }
|
||||
|
||||
override val currentStackSize: Int?
|
||||
get() = navController.currentStack?.size
|
||||
|
||||
override var startMenuIndex = 0
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
@ -40,12 +51,16 @@ class MainActivity : BaseActivity(), MainView {
|
||||
messageContainer = mainFragmentContainer
|
||||
|
||||
presenter.onAttachView(this)
|
||||
navController.initialize(DEFAULT_TAB, savedInstanceState)
|
||||
navController.initialize(startMenuIndex, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
presenter.onStartView()
|
||||
presenter.onViewStart()
|
||||
}
|
||||
|
||||
override fun onSupportNavigateUp(): Boolean {
|
||||
return presenter.onUpNavigate()
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
@ -59,19 +74,18 @@ class MainActivity : BaseActivity(), MainView {
|
||||
))
|
||||
accentColor = ContextCompat.getColor(context, R.color.colorPrimary)
|
||||
inactiveColor = ContextCompat.getColor(context, android.R.color.black)
|
||||
titleState = AHBottomNavigation.TitleState.ALWAYS_SHOW
|
||||
currentItem = DEFAULT_TAB
|
||||
titleState = ALWAYS_SHOW
|
||||
currentItem = startMenuIndex
|
||||
isBehaviorTranslationEnabled = false
|
||||
setTitleTextSizeInSp(10f, 10f)
|
||||
|
||||
setOnTabSelectedListener { position, wasSelected ->
|
||||
presenter.onTabSelected(position, wasSelected)
|
||||
}
|
||||
}
|
||||
|
||||
navController.run {
|
||||
setOnTabTransactionListener { presenter.onMenuViewChange(it) }
|
||||
fragmentHideStrategy = DETACH_ON_NAVIGATE_HIDE_ON_SWITCH
|
||||
setOnViewChangeListener { presenter.onViewStart() }
|
||||
fragmentHideStrategy = HIDE
|
||||
rootFragments = listOf(
|
||||
GradeFragment.newInstance(),
|
||||
AttendanceFragment.newInstance(),
|
||||
@ -90,22 +104,24 @@ class MainActivity : BaseActivity(), MainView {
|
||||
supportActionBar?.title = title
|
||||
}
|
||||
|
||||
override fun viewTitle(index: Int): String {
|
||||
return getString(listOf(R.string.grade_title,
|
||||
R.string.attendance_title,
|
||||
R.string.exam_title,
|
||||
R.string.timetable_title,
|
||||
R.string.more_title)[index])
|
||||
override fun showHomeArrow(show: Boolean) {
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(show)
|
||||
}
|
||||
|
||||
override fun currentMenuIndex() = navController.currentStackIndex
|
||||
|
||||
override fun notifyMenuViewReselected() {
|
||||
(navController.currentFrag as? MainView.MenuFragmentView)?.onFragmentReselected()
|
||||
(navController.currentStack?.get(0) as? MainView.MainChildView)?.onFragmentReselected()
|
||||
}
|
||||
|
||||
fun pushView(fragment: Fragment) {
|
||||
navController.pushFragment(fragment)
|
||||
}
|
||||
|
||||
override fun popView() {
|
||||
navController.safelyPopFragment()
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
navController.apply { if (isRootFragment) super.onBackPressed() else popFragment() }
|
||||
presenter.onBackPressed { super.onBackPressed() }
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle?) {
|
||||
|
@ -7,6 +7,8 @@ import dagger.android.ContributesAndroidInjector
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.di.scopes.PerActivity
|
||||
import io.github.wulkanowy.di.scopes.PerFragment
|
||||
import io.github.wulkanowy.ui.main.about.AboutFragment
|
||||
import io.github.wulkanowy.ui.main.about.AboutModule
|
||||
import io.github.wulkanowy.ui.main.attendance.AttendanceFragment
|
||||
import io.github.wulkanowy.ui.main.exam.ExamFragment
|
||||
import io.github.wulkanowy.ui.main.grade.GradeFragment
|
||||
@ -47,4 +49,8 @@ abstract class MainModule {
|
||||
@PerFragment
|
||||
@ContributesAndroidInjector
|
||||
abstract fun bindTimetableFragment(): TimetableFragment
|
||||
|
||||
@PerFragment
|
||||
@ContributesAndroidInjector(modules = [AboutModule::class])
|
||||
abstract fun bindAboutFragment(): AboutFragment
|
||||
}
|
||||
|
@ -1,23 +1,44 @@
|
||||
package io.github.wulkanowy.ui.main
|
||||
|
||||
import io.github.wulkanowy.data.ErrorHandler
|
||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import javax.inject.Inject
|
||||
|
||||
class MainPresenter @Inject constructor(errorHandler: ErrorHandler)
|
||||
class MainPresenter @Inject constructor(
|
||||
errorHandler: ErrorHandler,
|
||||
private val prefRepository: PreferencesRepository)
|
||||
: BasePresenter<MainView>(errorHandler) {
|
||||
|
||||
override fun onAttachView(view: MainView) {
|
||||
super.onAttachView(view)
|
||||
view.initView()
|
||||
view.run {
|
||||
startMenuIndex = prefRepository.startMenuIndex
|
||||
initView()
|
||||
}
|
||||
}
|
||||
|
||||
fun onStartView() {
|
||||
view?.run { setViewTitle(viewTitle(currentMenuIndex())) }
|
||||
fun onViewStart() {
|
||||
view?.apply {
|
||||
currentViewTitle?.let { setViewTitle(it) }
|
||||
currentStackSize?.let {
|
||||
if (it > 1) showHomeArrow(true)
|
||||
else showHomeArrow(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onMenuViewChange(index: Int) {
|
||||
view?.run { setViewTitle(viewTitle(index)) }
|
||||
fun onUpNavigate(): Boolean {
|
||||
view?.popView()
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
fun onBackPressed(default: () -> Unit) {
|
||||
view?.run {
|
||||
if (isRootView) default()
|
||||
else popView()
|
||||
}
|
||||
}
|
||||
|
||||
fun onTabSelected(index: Int, wasSelected: Boolean): Boolean {
|
||||
|
@ -4,20 +4,33 @@ import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface MainView : BaseView {
|
||||
|
||||
var startMenuIndex: Int
|
||||
|
||||
val isRootView: Boolean
|
||||
|
||||
val currentViewTitle: String?
|
||||
|
||||
val currentStackSize: Int?
|
||||
|
||||
fun initView()
|
||||
|
||||
fun switchMenuView(position: Int)
|
||||
|
||||
fun setViewTitle(title: String)
|
||||
|
||||
fun viewTitle(index: Int): String
|
||||
|
||||
fun currentMenuIndex(): Int
|
||||
fun showHomeArrow(show: Boolean)
|
||||
|
||||
fun notifyMenuViewReselected()
|
||||
|
||||
interface MenuFragmentView {
|
||||
fun setViewTitle(title: String)
|
||||
|
||||
fun popView()
|
||||
|
||||
interface MainChildView {
|
||||
|
||||
fun onFragmentReselected()
|
||||
}
|
||||
|
||||
interface TitledView {
|
||||
|
||||
val titleStringId: Int
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,68 @@
|
||||
package io.github.wulkanowy.ui.main.about
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.mikepenz.aboutlibraries.LibsBuilder
|
||||
import com.mikepenz.aboutlibraries.LibsFragmentCompat
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.ui.base.BaseFragment
|
||||
import io.github.wulkanowy.ui.main.MainView
|
||||
import io.github.wulkanowy.utils.withOnExtraListener
|
||||
import javax.inject.Inject
|
||||
|
||||
class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: AboutPresenter
|
||||
|
||||
@Inject
|
||||
lateinit var fragmentCompat: LibsFragmentCompat
|
||||
|
||||
companion object {
|
||||
fun newInstance() = AboutFragment()
|
||||
}
|
||||
|
||||
override val titleStringId: Int
|
||||
get() = R.string.about_title
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
presenter.onAttachView(this)
|
||||
return Bundle().apply {
|
||||
putSerializable("data", LibsBuilder()
|
||||
.withAboutAppName(getString(R.string.app_name))
|
||||
.withAboutVersionShown(true)
|
||||
.withAboutIconShown(true)
|
||||
.withLicenseShown(true)
|
||||
.withAboutSpecial1(getString(R.string.about_source_code))
|
||||
.withAboutSpecial2(getString(R.string.about_feedback))
|
||||
.withCheckCachedDetection(false)
|
||||
.withExcludedLibraries("fastadapter", "AndroidIconics", "gson",
|
||||
"Jsoup", "Retrofit", "okio", "OkHttp")
|
||||
.withOnExtraListener { presenter.onExtraSelect(it) })
|
||||
}.let {
|
||||
fragmentCompat.onCreateView(inflater.context, inflater, container, savedInstanceState, it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
fragmentCompat.onViewCreated(view, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun openSourceWebView() {
|
||||
startActivity(Intent.parseUri("https://github.com/wulkanowy/wulkanowy", 0))
|
||||
}
|
||||
|
||||
override fun openIssuesWebView() {
|
||||
startActivity(Intent.parseUri("https://github.com/wulkanowy/wulkanowy/issues", 0))
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
fragmentCompat.onDestroyView()
|
||||
presenter.onDetachView()
|
||||
super.onDestroyView()
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package io.github.wulkanowy.ui.main.about
|
||||
|
||||
import com.mikepenz.aboutlibraries.LibsFragmentCompat
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.github.wulkanowy.di.scopes.PerFragment
|
||||
|
||||
@Module
|
||||
class AboutModule {
|
||||
|
||||
@PerFragment
|
||||
@Provides
|
||||
fun provideLibsFragmentCompat() = LibsFragmentCompat()
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
package io.github.wulkanowy.ui.main.about
|
||||
|
||||
import com.mikepenz.aboutlibraries.Libs
|
||||
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL1
|
||||
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL2
|
||||
import io.github.wulkanowy.data.ErrorHandler
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import javax.inject.Inject
|
||||
|
||||
class AboutPresenter @Inject constructor(errorHandler: ErrorHandler) : BasePresenter<AboutView>(errorHandler) {
|
||||
|
||||
fun onExtraSelect(type: Libs.SpecialButton?) {
|
||||
view?.run {
|
||||
when (type) {
|
||||
SPECIAL1 -> openSourceWebView()
|
||||
SPECIAL2 -> openIssuesWebView()
|
||||
else -> TODO()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package io.github.wulkanowy.ui.main.about
|
||||
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface AboutView : BaseView {
|
||||
|
||||
fun openSourceWebView()
|
||||
|
||||
fun openIssuesWebView()
|
||||
}
|
@ -15,7 +15,7 @@ import io.github.wulkanowy.utils.setOnItemClickListener
|
||||
import kotlinx.android.synthetic.main.fragment_attendance.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MenuFragmentView {
|
||||
class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildView, MainView.TitledView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: AttendancePresenter
|
||||
@ -29,6 +29,12 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MenuFragment
|
||||
fun newInstance() = AttendanceFragment()
|
||||
}
|
||||
|
||||
override val titleStringId: Int
|
||||
get() = R.string.attendance_title
|
||||
|
||||
override val isViewEmpty: Boolean
|
||||
get() = attendanceAdapter.isEmpty
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_attendance, container, false)
|
||||
}
|
||||
@ -65,8 +71,6 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MenuFragment
|
||||
attendanceAdapter.clear()
|
||||
}
|
||||
|
||||
override fun isViewEmpty() = attendanceAdapter.isEmpty
|
||||
|
||||
override fun onFragmentReselected() {
|
||||
presenter.onViewReselected()
|
||||
}
|
||||
@ -109,4 +113,3 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MenuFragment
|
||||
super.onDestroyView()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.ui.main.attendance
|
||||
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.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.utils.*
|
||||
@ -17,7 +18,8 @@ class AttendancePresenter @Inject constructor(
|
||||
private val errorHandler: ErrorHandler,
|
||||
private val schedulers: SchedulersManager,
|
||||
private val attendanceRepository: AttendanceRepository,
|
||||
private val sessionRepository: SessionRepository
|
||||
private val sessionRepository: SessionRepository,
|
||||
private val prefRepository: PreferencesRepository
|
||||
) : BasePresenter<AttendanceView>(errorHandler) {
|
||||
|
||||
lateinit var currentDate: LocalDate
|
||||
@ -61,6 +63,10 @@ class AttendancePresenter @Inject constructor(
|
||||
.delay(200, MILLISECONDS)
|
||||
.map { it.single { semester -> semester.current } }
|
||||
.flatMap { attendanceRepository.getAttendance(it, date, date, forceRefresh) }
|
||||
.map { list ->
|
||||
if (prefRepository.showPresent) list
|
||||
else list.filter { !it.presence }
|
||||
}
|
||||
.map { items -> items.map { AttendanceItem(it) } }
|
||||
.subscribeOn(schedulers.backgroundThread())
|
||||
.observeOn(schedulers.mainThread())
|
||||
@ -77,7 +83,7 @@ class AttendancePresenter @Inject constructor(
|
||||
showContent(it.isNotEmpty())
|
||||
}
|
||||
}) {
|
||||
view?.run { showEmpty(isViewEmpty()) }
|
||||
view?.run { showEmpty(isViewEmpty) }
|
||||
errorHandler.proceed(it)
|
||||
}
|
||||
)
|
||||
|
@ -5,6 +5,8 @@ import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface AttendanceView : BaseView {
|
||||
|
||||
val isViewEmpty: Boolean
|
||||
|
||||
fun initView()
|
||||
|
||||
fun updateData(data: List<AttendanceItem>)
|
||||
@ -13,8 +15,6 @@ interface AttendanceView : BaseView {
|
||||
|
||||
fun clearData()
|
||||
|
||||
fun isViewEmpty(): Boolean
|
||||
|
||||
fun hideRefresh()
|
||||
|
||||
fun showEmpty(show: Boolean)
|
||||
|
@ -16,7 +16,7 @@ import io.github.wulkanowy.utils.setOnItemClickListener
|
||||
import kotlinx.android.synthetic.main.fragment_exam.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class ExamFragment : BaseFragment(), ExamView, MainView.MenuFragmentView {
|
||||
class ExamFragment : BaseFragment(), ExamView, MainView.MainChildView, MainView.TitledView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: ExamPresenter
|
||||
@ -26,9 +26,16 @@ class ExamFragment : BaseFragment(), ExamView, MainView.MenuFragmentView {
|
||||
|
||||
companion object {
|
||||
private const val SAVED_DATE_KEY = "CURRENT_DATE"
|
||||
|
||||
fun newInstance() = ExamFragment()
|
||||
}
|
||||
|
||||
override val titleStringId: Int
|
||||
get() = R.string.exam_title
|
||||
|
||||
override val isViewEmpty: Boolean
|
||||
get() = examAdapter.isEmpty
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_exam, container, false)
|
||||
}
|
||||
@ -68,8 +75,6 @@ class ExamFragment : BaseFragment(), ExamView, MainView.MenuFragmentView {
|
||||
examAdapter.clear()
|
||||
}
|
||||
|
||||
override fun isViewEmpty() = examAdapter.isEmpty
|
||||
|
||||
override fun onFragmentReselected() {
|
||||
presenter.onViewReselected()
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ class ExamPresenter @Inject constructor(
|
||||
showContent(it.isNotEmpty())
|
||||
}
|
||||
}) {
|
||||
view?.run { showEmpty(isViewEmpty()) }
|
||||
view?.run { showEmpty(isViewEmpty) }
|
||||
errorHandler.proceed(it)
|
||||
})
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface ExamView : BaseView {
|
||||
|
||||
val isViewEmpty: Boolean
|
||||
|
||||
fun initView()
|
||||
|
||||
fun updateData(data: List<ExamItem>)
|
||||
@ -13,8 +15,6 @@ interface ExamView : BaseView {
|
||||
|
||||
fun clearData()
|
||||
|
||||
fun isViewEmpty(): Boolean
|
||||
|
||||
fun hideRefresh()
|
||||
|
||||
fun showEmpty(show: Boolean)
|
||||
|
@ -15,7 +15,7 @@ import io.github.wulkanowy.utils.setOnSelectPageListener
|
||||
import kotlinx.android.synthetic.main.fragment_grade.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class GradeFragment : BaseFragment(), GradeView, MainView.MenuFragmentView {
|
||||
class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainView.TitledView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: GradePresenter
|
||||
@ -29,6 +29,12 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MenuFragmentView {
|
||||
fun newInstance() = GradeFragment()
|
||||
}
|
||||
|
||||
override val titleStringId: Int
|
||||
get() = R.string.grade_title
|
||||
|
||||
override val currentPageIndex: Int
|
||||
get() = gradeViewPager.currentItem
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
@ -93,8 +99,6 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MenuFragmentView {
|
||||
}
|
||||
}
|
||||
|
||||
override fun currentPageIndex() = gradeViewPager.currentItem
|
||||
|
||||
fun onChildRefresh() {
|
||||
presenter.onChildViewRefresh()
|
||||
}
|
||||
@ -124,4 +128,4 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MenuFragmentView {
|
||||
super.onDestroyView()
|
||||
presenter.onDetachView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class GradePresenter @Inject constructor(
|
||||
}
|
||||
|
||||
fun onViewReselected() {
|
||||
view?.run { notifyChildParentReselected(currentPageIndex()) }
|
||||
view?.run { notifyChildParentReselected(currentPageIndex) }
|
||||
}
|
||||
|
||||
fun onSemesterSwitch(): Boolean {
|
||||
@ -46,20 +46,20 @@ class GradePresenter @Inject constructor(
|
||||
loadedSemesterId.clear()
|
||||
view?.let {
|
||||
notifyChildrenSemesterChange()
|
||||
loadChild(it.currentPageIndex())
|
||||
loadChild(it.currentPageIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onChildViewRefresh() {
|
||||
view?.let { loadChild(it.currentPageIndex(), forceRefresh = true) }
|
||||
view?.let { loadChild(it.currentPageIndex, forceRefresh = true) }
|
||||
}
|
||||
|
||||
fun onChildViewLoaded(semesterId: Int) {
|
||||
view?.apply {
|
||||
showContent(true)
|
||||
showProgress(false)
|
||||
loadedSemesterId[currentPageIndex()] = semesterId
|
||||
loadedSemesterId[currentPageIndex] = semesterId
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ class GradePresenter @Inject constructor(
|
||||
.subscribeOn(schedulers.backgroundThread())
|
||||
.observeOn(schedulers.mainThread())
|
||||
.subscribe({ _ ->
|
||||
view?.let { loadChild(it.currentPageIndex()) }
|
||||
view?.let { loadChild(it.currentPageIndex) }
|
||||
}) { errorHandler.proceed(it) })
|
||||
}
|
||||
|
||||
|
@ -4,9 +4,9 @@ import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface GradeView : BaseView {
|
||||
|
||||
fun initView()
|
||||
val currentPageIndex: Int
|
||||
|
||||
fun currentPageIndex(): Int
|
||||
fun initView()
|
||||
|
||||
fun showContent(show: Boolean)
|
||||
|
||||
|
@ -31,6 +31,18 @@ class GradeDetailsFragment : BaseFragment(), GradeDetailsView, GradeView.GradeCh
|
||||
fun newInstance() = GradeDetailsFragment()
|
||||
}
|
||||
|
||||
override val emptyAverageString: String
|
||||
get() = getString(R.string.grade_no_average)
|
||||
|
||||
override val averageString: String
|
||||
get() = getString(R.string.grade_average)
|
||||
|
||||
override val weightString: String
|
||||
get() = getString(R.string.grade_weight)
|
||||
|
||||
override val isViewEmpty
|
||||
get() = gradeDetailsAdapter.isEmpty
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_grade_details, container, false)
|
||||
}
|
||||
@ -80,7 +92,9 @@ class GradeDetailsFragment : BaseFragment(), GradeDetailsView, GradeView.GradeCh
|
||||
return gradeDetailsAdapter.getExpandableOf(item)
|
||||
}
|
||||
|
||||
override fun isViewEmpty() = gradeDetailsAdapter.isEmpty
|
||||
override fun getGradeNumberString(number: Int): String {
|
||||
return resources.getQuantityString(R.plurals.grade_number_item, number, number)
|
||||
}
|
||||
|
||||
override fun showProgress(show: Boolean) {
|
||||
gradeDetailsProgress.visibility = if (show) VISIBLE else GONE
|
||||
@ -122,14 +136,6 @@ class GradeDetailsFragment : BaseFragment(), GradeDetailsView, GradeView.GradeCh
|
||||
(parentFragment as? GradeFragment)?.onChildRefresh()
|
||||
}
|
||||
|
||||
override fun emptyAverageString(): String = getString(R.string.grade_no_average)
|
||||
|
||||
override fun averageString(): String = getString(R.string.grade_average)
|
||||
|
||||
override fun gradeNumberString(number: Int): String = resources.getQuantityString(R.plurals.grade_number_item, number, number)
|
||||
|
||||
override fun weightString(): String = getString(R.string.grade_weight)
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
presenter.onDetachView()
|
||||
|
@ -42,7 +42,7 @@ class GradeDetailsPresenter @Inject constructor(
|
||||
updateData(it)
|
||||
}
|
||||
}) {
|
||||
view?.run { showEmpty(isViewEmpty()) }
|
||||
view?.run { showEmpty(isViewEmpty) }
|
||||
errorHandler.proceed(it)
|
||||
})
|
||||
}
|
||||
@ -72,7 +72,7 @@ class GradeDetailsPresenter @Inject constructor(
|
||||
|
||||
fun onParentViewReselected() {
|
||||
view?.run {
|
||||
if (!isViewEmpty()) resetView()
|
||||
if (!isViewEmpty) resetView()
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,13 +93,13 @@ class GradeDetailsPresenter @Inject constructor(
|
||||
GradeDetailsHeader(
|
||||
subject = it.key,
|
||||
average = formatAverage(average),
|
||||
number = view?.gradeNumberString(it.value.size).orEmpty(),
|
||||
number = view?.getGradeNumberString(it.value.size).orEmpty(),
|
||||
newGrades = it.value.filter { grade -> grade.isNew }.size
|
||||
).apply {
|
||||
subItems = it.value.map { item ->
|
||||
GradeDetailsItem(
|
||||
grade = item,
|
||||
weightString = view?.weightString().orEmpty(),
|
||||
weightString = view?.weightString.orEmpty(),
|
||||
valueColor = item.valueColor
|
||||
)
|
||||
}
|
||||
@ -110,8 +110,8 @@ class GradeDetailsPresenter @Inject constructor(
|
||||
|
||||
private fun formatAverage(average: Double): String {
|
||||
return view?.run {
|
||||
if (average == 0.0) emptyAverageString()
|
||||
else averageString().format(average)
|
||||
if (average == 0.0) emptyAverageString
|
||||
else averageString.format(average)
|
||||
}.orEmpty()
|
||||
}
|
||||
|
||||
|
@ -8,20 +8,24 @@ import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface GradeDetailsView : BaseView {
|
||||
|
||||
val isViewEmpty: Boolean
|
||||
|
||||
val emptyAverageString: String
|
||||
|
||||
val averageString: String
|
||||
|
||||
val weightString: String
|
||||
|
||||
fun initView()
|
||||
|
||||
fun updateData(data: List<GradeDetailsHeader>)
|
||||
|
||||
fun updateItem(item: AbstractFlexibleItem<*>)
|
||||
|
||||
fun getHeaderOfItem(item: AbstractFlexibleItem<*>): IExpandable<*, out IFlexible<*>>?
|
||||
|
||||
fun resetView()
|
||||
|
||||
fun clearView()
|
||||
|
||||
fun isViewEmpty(): Boolean
|
||||
|
||||
fun showGradeDialog(grade: Grade)
|
||||
|
||||
fun showContent(show: Boolean)
|
||||
@ -32,15 +36,11 @@ interface GradeDetailsView : BaseView {
|
||||
|
||||
fun showRefresh(show: Boolean)
|
||||
|
||||
fun emptyAverageString(): String
|
||||
|
||||
fun averageString(): String
|
||||
|
||||
fun gradeNumberString(number: Int): String
|
||||
|
||||
fun weightString(): String
|
||||
|
||||
fun notifyParentDataLoaded(semesterId: Int)
|
||||
|
||||
fun notifyParentRefresh()
|
||||
|
||||
fun getGradeNumberString(number: Int): String
|
||||
|
||||
fun getHeaderOfItem(item: AbstractFlexibleItem<*>): IExpandable<*, out IFlexible<*>>?
|
||||
}
|
||||
|
@ -27,6 +27,15 @@ class GradeSummaryFragment : BaseFragment(), GradeSummaryView, GradeView.GradeCh
|
||||
fun newInstance() = GradeSummaryFragment()
|
||||
}
|
||||
|
||||
override val isViewEmpty
|
||||
get() = gradeSummaryAdapter.isEmpty
|
||||
|
||||
override val predictedString
|
||||
get() = getString(R.string.grade_summary_predicted_grade)
|
||||
|
||||
override val finalString
|
||||
get() = getString(R.string.grade_summary_final_grade)
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_grade_summary, container, false)
|
||||
}
|
||||
@ -63,8 +72,6 @@ class GradeSummaryFragment : BaseFragment(), GradeSummaryView, GradeView.GradeCh
|
||||
gradeSummaryAdapter.smoothScrollToPosition(0)
|
||||
}
|
||||
|
||||
override fun isViewEmpty() = gradeSummaryAdapter.isEmpty
|
||||
|
||||
override fun showContent(show: Boolean) {
|
||||
gradeSummaryRecycler.visibility = if (show) VISIBLE else INVISIBLE
|
||||
}
|
||||
@ -101,10 +108,6 @@ class GradeSummaryFragment : BaseFragment(), GradeSummaryView, GradeView.GradeCh
|
||||
(parentFragment as? GradeFragment)?.onChildRefresh()
|
||||
}
|
||||
|
||||
override fun predictedString() = getString(R.string.grade_summary_predicted_grade)
|
||||
|
||||
override fun finalString() = getString(R.string.grade_summary_final_grade)
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
presenter.onDetachView()
|
||||
|
@ -61,7 +61,7 @@ class GradeSummaryPresenter @Inject constructor(
|
||||
updateDataSet(it.first, it.second)
|
||||
}
|
||||
}) {
|
||||
view?.run { showEmpty(isViewEmpty()) }
|
||||
view?.run { showEmpty(isViewEmpty) }
|
||||
errorHandler.proceed(it)
|
||||
})
|
||||
}
|
||||
@ -72,7 +72,7 @@ class GradeSummaryPresenter @Inject constructor(
|
||||
|
||||
fun onParentViewReselected() {
|
||||
view?.run {
|
||||
if (!isViewEmpty()) resetView()
|
||||
if (!isViewEmpty) resetView()
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,11 +97,11 @@ class GradeSummaryPresenter @Inject constructor(
|
||||
).let {
|
||||
listOf(GradeSummaryItem(
|
||||
header = it,
|
||||
title = view?.predictedString().orEmpty(),
|
||||
title = view?.predictedString.orEmpty(),
|
||||
grade = gradeSummary.predictedGrade
|
||||
), GradeSummaryItem(
|
||||
header = it,
|
||||
title = view?.finalString().orEmpty(),
|
||||
title = view?.finalString.orEmpty(),
|
||||
grade = gradeSummary.finalGrade
|
||||
))
|
||||
}
|
||||
|
@ -4,6 +4,12 @@ import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface GradeSummaryView : BaseView {
|
||||
|
||||
val isViewEmpty: Boolean
|
||||
|
||||
val predictedString: String
|
||||
|
||||
val finalString: String
|
||||
|
||||
fun initView()
|
||||
|
||||
fun updateDataSet(data: List<GradeSummaryItem>, header: GradeSummaryScrollableHeader)
|
||||
@ -12,8 +18,6 @@ interface GradeSummaryView : BaseView {
|
||||
|
||||
fun clearView()
|
||||
|
||||
fun isViewEmpty(): Boolean
|
||||
|
||||
fun showProgress(show: Boolean)
|
||||
|
||||
fun showRefresh(show: Boolean)
|
||||
@ -22,10 +26,6 @@ interface GradeSummaryView : BaseView {
|
||||
|
||||
fun showEmpty(show: Boolean)
|
||||
|
||||
fun predictedString(): String
|
||||
|
||||
fun finalString(): String
|
||||
|
||||
fun notifyParentDataLoaded(semesterId: Int)
|
||||
|
||||
fun notifyParentRefresh()
|
||||
|
@ -1,20 +1,95 @@
|
||||
package io.github.wulkanowy.ui.main.more
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
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.base.BaseFragment
|
||||
import io.github.wulkanowy.ui.main.MainActivity
|
||||
import io.github.wulkanowy.ui.main.MainView
|
||||
import io.github.wulkanowy.ui.main.about.AboutFragment
|
||||
import io.github.wulkanowy.ui.main.settings.SettingsFragment
|
||||
import io.github.wulkanowy.utils.setOnItemClickListener
|
||||
import kotlinx.android.synthetic.main.fragment_more.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class MoreFragment : BaseFragment() {
|
||||
class MoreFragment : BaseFragment(), MoreView, MainView.TitledView, MainView.MainChildView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: MorePresenter
|
||||
|
||||
@Inject
|
||||
lateinit var moreAdapter: FlexibleAdapter<AbstractFlexibleItem<*>>
|
||||
|
||||
companion object {
|
||||
fun newInstance() = MoreFragment()
|
||||
}
|
||||
|
||||
override val titleStringId: Int
|
||||
get() = R.string.more_title
|
||||
|
||||
override val settingsRes: Pair<String, Drawable?>?
|
||||
get() {
|
||||
return context?.run {
|
||||
getString(R.string.settings_title) to
|
||||
ContextCompat.getDrawable(this, R.drawable.ic_more_settings_24dp)
|
||||
}
|
||||
}
|
||||
|
||||
override val aboutRes: Pair<String, Drawable?>?
|
||||
get() {
|
||||
return context?.run {
|
||||
getString(R.string.about_title) to
|
||||
ContextCompat.getDrawable(this, R.drawable.ic_more_about_24dp)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_attendance, container, false)
|
||||
return inflater.inflate(R.layout.fragment_more, container, false)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
presenter.onAttachView(this)
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
moreAdapter.run { setOnItemClickListener { presenter.onItemSelected(getItem(it)) } }
|
||||
|
||||
moreRecycler.apply {
|
||||
layoutManager = SmoothScrollLinearLayoutManager(context)
|
||||
adapter = moreAdapter
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFragmentReselected() {
|
||||
presenter.onViewReselected()
|
||||
}
|
||||
|
||||
override fun updateData(data: List<MoreItem>) {
|
||||
moreAdapter.updateDataSet(data)
|
||||
}
|
||||
|
||||
override fun openSettingsView() {
|
||||
(activity as? MainActivity)?.pushView(SettingsFragment.newInstance())
|
||||
}
|
||||
|
||||
override fun openAboutView() {
|
||||
(activity as? MainActivity)?.pushView(AboutFragment.newInstance())
|
||||
}
|
||||
|
||||
override fun popView() {
|
||||
(activity as? MainActivity)?.popView()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
presenter.onDetachView()
|
||||
super.onDestroyView()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,51 @@
|
||||
package io.github.wulkanowy.ui.main.more
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
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 kotlinx.android.extensions.LayoutContainer
|
||||
import kotlinx.android.synthetic.main.item_more.*
|
||||
|
||||
class MoreItem(val title: String, private val drawable: Drawable?)
|
||||
: AbstractFlexibleItem<MoreItem.ViewHolder>() {
|
||||
|
||||
override fun getLayoutRes() = R.layout.item_more
|
||||
|
||||
override fun createViewHolder(view: View?, adapter: FlexibleAdapter<IFlexible<*>>?): ViewHolder {
|
||||
return ViewHolder(view, adapter)
|
||||
}
|
||||
|
||||
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>?, holder: ViewHolder?,
|
||||
position: Int, payloads: MutableList<Any>?) {
|
||||
holder?.apply {
|
||||
moreItemTitle.text = title
|
||||
moreItemImage.setImageDrawable(drawable)
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as MoreItem
|
||||
|
||||
if (title != other.title) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return title.hashCode()
|
||||
}
|
||||
|
||||
class ViewHolder(view: View?, adapter: FlexibleAdapter<*>?)
|
||||
: FlexibleViewHolder(view, adapter), LayoutContainer {
|
||||
|
||||
override val containerView: View?
|
||||
get() = contentView
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package io.github.wulkanowy.ui.main.more
|
||||
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import io.github.wulkanowy.data.ErrorHandler
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import javax.inject.Inject
|
||||
|
||||
class MorePresenter @Inject constructor(errorHandler: ErrorHandler)
|
||||
: BasePresenter<MoreView>(errorHandler) {
|
||||
|
||||
override fun onAttachView(view: MoreView) {
|
||||
super.onAttachView(view)
|
||||
view.initView()
|
||||
loadData()
|
||||
}
|
||||
|
||||
fun onItemSelected(item: AbstractFlexibleItem<*>?) {
|
||||
if (item is MoreItem) {
|
||||
view?.run {
|
||||
when (item.title) {
|
||||
settingsRes?.first -> openSettingsView()
|
||||
aboutRes?.first -> openAboutView()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onViewReselected() {
|
||||
view?.popView()
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
view?.run {
|
||||
updateData(listOfNotNull(
|
||||
settingsRes?.let { MoreItem(it.first, it.second) },
|
||||
aboutRes?.let { MoreItem(it.first, it.second) }))
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package io.github.wulkanowy.ui.main.more
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface MoreView : BaseView {
|
||||
|
||||
val settingsRes: Pair<String, Drawable?>?
|
||||
|
||||
val aboutRes: Pair<String, Drawable?>?
|
||||
|
||||
fun initView()
|
||||
|
||||
fun updateData(data: List<MoreItem>)
|
||||
|
||||
fun openSettingsView()
|
||||
|
||||
fun openAboutView()
|
||||
|
||||
fun popView()
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package io.github.wulkanowy.ui.main.settings
|
||||
|
||||
import android.os.Bundle
|
||||
import com.takisoft.preferencex.PreferenceFragmentCompat
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.ui.main.MainView
|
||||
|
||||
class SettingsFragment : PreferenceFragmentCompat(), MainView.TitledView {
|
||||
|
||||
companion object {
|
||||
fun newInstance() = SettingsFragment()
|
||||
}
|
||||
|
||||
override val titleStringId: Int
|
||||
get() = R.string.settings_title
|
||||
|
||||
override fun onCreatePreferencesFix(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.scheme_preferences)
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ import io.github.wulkanowy.utils.setOnItemClickListener
|
||||
import kotlinx.android.synthetic.main.fragment_timetable.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimetableFragment : BaseFragment(), TimetableView, MainView.MenuFragmentView {
|
||||
class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView, MainView.TitledView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: TimetablePresenter
|
||||
@ -29,6 +29,12 @@ class TimetableFragment : BaseFragment(), TimetableView, MainView.MenuFragmentVi
|
||||
fun newInstance() = TimetableFragment()
|
||||
}
|
||||
|
||||
override val titleStringId: Int
|
||||
get() = R.string.timetable_title
|
||||
|
||||
override val roomString: String
|
||||
get() = getString(R.string.timetable_room)
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_timetable, container, false)
|
||||
}
|
||||
@ -99,8 +105,6 @@ class TimetableFragment : BaseFragment(), TimetableView, MainView.MenuFragmentVi
|
||||
TimetableDialog.newInstance(lesson).show(fragmentManager, lesson.toString())
|
||||
}
|
||||
|
||||
override fun roomString() = getString(R.string.timetable_room)
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay())
|
||||
|
@ -61,7 +61,7 @@ class TimetablePresenter @Inject constructor(
|
||||
.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.map { TimetableItem(it, view?.roomString.orEmpty()) } }
|
||||
.subscribeOn(schedulers.backgroundThread())
|
||||
.observeOn(schedulers.mainThread())
|
||||
.doFinally {
|
||||
|
@ -5,6 +5,8 @@ import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface TimetableView : BaseView {
|
||||
|
||||
val roomString: String
|
||||
|
||||
fun initView()
|
||||
|
||||
fun updateData(data: List<TimetableItem>)
|
||||
@ -28,6 +30,4 @@ interface TimetableView : BaseView {
|
||||
fun showNextButton(show: Boolean)
|
||||
|
||||
fun showTimetableDialog(lesson: Timetable)
|
||||
|
||||
fun roomString(): String
|
||||
}
|
||||
|
@ -3,11 +3,18 @@ package io.github.wulkanowy.utils
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.ncapdevi.fragnav.FragNavController
|
||||
|
||||
inline fun FragNavController.setOnTabTransactionListener(crossinline listener: (index: Int) -> Unit) {
|
||||
inline fun FragNavController.setOnViewChangeListener(crossinline listener: (fragment: Fragment?) -> Unit) {
|
||||
transactionListener = object : FragNavController.TransactionListener {
|
||||
override fun onFragmentTransaction(fragment: Fragment?, transactionType: FragNavController.TransactionType) {}
|
||||
override fun onFragmentTransaction(fragment: Fragment?, transactionType: FragNavController.TransactionType) {
|
||||
listener(fragment)
|
||||
}
|
||||
|
||||
override fun onTabTransaction(fragment: Fragment?, index: Int) {
|
||||
listener(index)
|
||||
listener(fragment)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun FragNavController.safelyPopFragment() {
|
||||
if (!isRootFragment) popFragment()
|
||||
}
|
||||
|
@ -0,0 +1,16 @@
|
||||
package io.github.wulkanowy.utils
|
||||
|
||||
import android.view.View
|
||||
import com.mikepenz.aboutlibraries.Libs
|
||||
import com.mikepenz.aboutlibraries.LibsBuilder
|
||||
import com.mikepenz.aboutlibraries.LibsConfiguration
|
||||
|
||||
inline fun LibsBuilder.withOnExtraListener(crossinline listener: (Libs.SpecialButton?) -> Unit): LibsBuilder {
|
||||
withListener(object : LibsConfiguration.LibsListenerImpl() {
|
||||
override fun onExtraClicked(v: View?, specialButton: Libs.SpecialButton?): Boolean {
|
||||
listener(specialButton)
|
||||
return true
|
||||
}
|
||||
})
|
||||
return this
|
||||
}
|
@ -4,10 +4,10 @@
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24">
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:fillColor="#000"
|
||||
android:pathData="M11,7h2v2h-2zM11,11h2v6h-2z" />
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:fillColor="#000"
|
||||
android:pathData="M12,2a10,10 0,1 0,0 20,10 10,0 0,0 0,-20zM12,20a8,8 0,1 1,0 -16,8 8,0 0,1
|
||||
0,16z" />
|
||||
</vector>
|
16
app/src/main/res/drawable/ic_more_settings_24dp.xml
Normal file
16
app/src/main/res/drawable/ic_more_settings_24dp.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#000"
|
||||
android:pathData="M19.43 12.98a7.8 7.8 0 0 0 0-1.96l2.11-1.65a0.5 0.5 0 0 0
|
||||
0.12-0.64l-2-3.46c-0.12-0.22-0.39-0.3-0.61-0.22l-2.49 1a7.3 7.3 0 0 0-1.69-0.98l-0.38-2.65A0.49
|
||||
0.49 0 0 0 14 2h-4a0.49 0.49 0 0 0-0.49 0.42l-0.38 2.65c-0.61 0.25-1.17 0.59-1.69 0.98l
|
||||
-2.49-1a 0.49 0.49 0 0 0-0.61 0.22l-2 3.46a0.5 0.5 0 0 0 0.12 0.64l2.11 1.65a7.93 7.93
|
||||
0 0 0 0 1.96l-2.11 1.65a0.5 0.5 0 0 0-0.12 0.64l2 3.46c0.12 0.22 0.39 0.3 0.61 0.22l2.49-1c0.52
|
||||
0.4 1.08 0.73 1.69 0.98l 0.38 2.65c 0.03 0.24 0.24 0.42 0.49 0.42h4c0.25 0 0.46-0.18 0.49-0.42l
|
||||
0.38-2.65a7.68 7.68 0 0 0 1.69-0.98l2.49 1c0.23 0.09 0.49 0 0.61-0.22l2-3.46a0.5 0.5
|
||||
0 0 0-0.12-0.64l-2.11-1.65zM12 15.5a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7z" />
|
||||
</vector>
|
@ -9,6 +9,7 @@
|
||||
android:id="@+id/mainAppBarContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/WulkanowyTheme.ActionBar"
|
||||
app:elevation="0dp">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
|
10
app/src/main/res/layout/fragment_more.xml
Normal file
10
app/src/main/res/layout/fragment_more.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/moreRecycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</FrameLayout>
|
30
app/src/main/res/layout/item_more.xml
Normal file
30
app/src/main/res/layout/item_more.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/moreItemImage"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
app:srcCompat="@drawable/ic_more_settings_24dp" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/moreItemTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginLeft="32dp"
|
||||
android:text="@string/app_name"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</LinearLayout>
|
@ -10,6 +10,7 @@
|
||||
<string name="timetable_title">Plan lekcji</string>
|
||||
<string name="settings_title">Ustawienia</string>
|
||||
<string name="more_title">Więcej</string>
|
||||
<string name="about_title">O aplikacji</string>
|
||||
|
||||
|
||||
<!--Login form-->
|
||||
@ -92,6 +93,9 @@
|
||||
<string name="exam_type">Typ</string>
|
||||
<string name="exam_entry_date">Data wpisu</string>
|
||||
|
||||
<!--About-->
|
||||
<string name="about_source_code">Kod źródłowy</string>
|
||||
<string name="about_feedback">Zgłoś błąd</string>
|
||||
|
||||
<!--Generic-->
|
||||
<string name="all_description">Opis</string>
|
||||
@ -130,22 +134,11 @@
|
||||
<string name="pref_services_interval">Interwał aktualizacji</string>
|
||||
<string name="pref_services_wifi">Tylko WiFi</string>
|
||||
|
||||
<string name="pref_about_description">Informacje o Wulkanowym</string>
|
||||
<string name="pref_about_version">Wersja</string>
|
||||
<string name="pref_about_osl">Licencje open source</string>
|
||||
<string name="pref_about_osl_summary">Szczegóły licencji na oprogramowanie open source</string>
|
||||
<string name="pref_about_support">Kod źródłowy i feedback</string>
|
||||
|
||||
<string name="about_programmer_step1">Nie, nie zostaniesz programistą!</string>
|
||||
<string name="about_programmer_step2">Musisz bardziej się postarać!</string>
|
||||
<string name="about_programmer_step3">Kliknij jeszcze parę razy</string>
|
||||
<string name="about_programmer_description">Odwiedź zakładkę Kod źródłowy i pokaż jaki z ciebie programista!</string>
|
||||
|
||||
<string name="pref_restart">Wymagany restart</string>
|
||||
|
||||
|
||||
<!--Grade notify-->
|
||||
<string name="notify_grade_chanell">Nowe oceny</string>
|
||||
<string name="notify_grade_chanel">Nowe oceny</string>
|
||||
<plurals name="notify_grade_new_items">
|
||||
<item quantity="one">Dostałeś %1$d ocenę</item>
|
||||
<item quantity="few">"Dostałeś %1$d oceny</item>
|
||||
|
17
app/src/main/res/values/library_wulkanowy_api.xml
Normal file
17
app/src/main/res/values/library_wulkanowy_api.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="define_WulkanowyApi" translatable="false" />
|
||||
|
||||
<string name="library_WulkanowyApi_author" translatable="false">Wulkanowy</string>
|
||||
<string name="library_WulkanowyApi_authorWebsite" translatable="false">https://github.com/wulkanowy</string>
|
||||
|
||||
<string name="library_WulkanowyApi_libraryName" translatable="false">UONET+ Scraping API</string>
|
||||
<string name="library_WulkanowyApi_libraryDescription" translatable="false">The UONET+ client using web scraping</string>
|
||||
<string name="library_WulkanowyApi_libraryWebsite" translatable="false">https://github.com/wulkanowy/api</string>
|
||||
<string name="library_WulkanowyApi_libraryVersion" translatable="false">Development</string>
|
||||
|
||||
<string name="library_WulkanowyApi_isOpenSource" translatable="false">true</string>
|
||||
<string name="library_WulkanowyApi_repositoryLink" translatable="false">https://github.com/wulkanowy/api</string>
|
||||
|
||||
<string name="library_WulkanowyApi_licenseId" translatable="false">apache_2_0</string>
|
||||
</resources>
|
@ -10,6 +10,7 @@
|
||||
<string name="timetable_title">Timetable</string>
|
||||
<string name="settings_title">Settings</string>
|
||||
<string name="more_title">More</string>
|
||||
<string name="about_title">About</string>
|
||||
|
||||
|
||||
<!--Login form-->
|
||||
@ -87,6 +88,10 @@
|
||||
<string name="exam_type">Type</string>
|
||||
<string name="exam_entry_date">Entry date</string>
|
||||
|
||||
<!--About-->
|
||||
<string name="about_source_code">Source code</string>
|
||||
<string name="about_feedback">Report a bug</string>
|
||||
|
||||
|
||||
<!--Generic-->
|
||||
<string name="all_description">Description</string>
|
||||
@ -125,22 +130,11 @@
|
||||
<string name="pref_services_interval">Updates interval</string>
|
||||
<string name="pref_services_wifi">Only WiFi</string>
|
||||
|
||||
<string name="pref_about_description">About Wulkanowy</string>
|
||||
<string name="pref_about_version">Version</string>
|
||||
<string name="pref_about_osl">Open source licences</string>
|
||||
<string name="pref_about_osl_summary">License details for open source software</string>
|
||||
<string name="pref_about_support">Source code & feedback</string>
|
||||
|
||||
<string name="about_programmer_step1">No, you will not become a programmer!</string>
|
||||
<string name="about_programmer_step2">You must try harder!</string>
|
||||
<string name="about_programmer_step3">Click a few more times</string>
|
||||
<string name="about_programmer_description">Visit the Source code tab and show how good a programmer you are!</string>
|
||||
|
||||
<string name="pref_restart">Restart required</string>
|
||||
|
||||
|
||||
<!--Grade notify-->
|
||||
<string name="notify_grade_chanell">New grades</string>
|
||||
<string name="notify_grade_chanel">New grades</string>
|
||||
<plurals name="notify_grade_new_items">
|
||||
<item quantity="one">You received %1$d grade</item>
|
||||
<item quantity="other">You received %1$d grades</item>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<resources>
|
||||
|
||||
<style name="WulkanowyTheme" parent="@style/Base.Theme.AppCompat.Light">
|
||||
<style name="WulkanowyTheme" parent="@style/Theme.AppCompat.Light">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorPrimary</item>
|
||||
@ -13,7 +13,6 @@
|
||||
<item name="titleTextColor">@android:color/primary_text_dark</item>
|
||||
<item name="subtitleTextColor">@android:color/primary_text_dark</item>
|
||||
<item name="android:colorBackground">@android:color/white</item>
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
|
||||
<item name="bottomNavBackground">@color/bottom_nav_background_inverse</item>
|
||||
<item name="android:windowAnimationStyle">@null</item>
|
||||
</style>
|
||||
@ -27,12 +26,7 @@
|
||||
<item name="windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<style name="DialogFragmentTheme" parent="Theme.AppCompat.DayNight.Dialog.Alert">
|
||||
<item name="android:textColorTertiary">@android:color/primary_text_light</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">false</item>
|
||||
<item name="android:windowActionBar">false</item>
|
||||
<item name="android:windowNoTitle">false</item>
|
||||
<style name="WulkanowyTheme.ActionBar" parent="WulkanowyTheme">
|
||||
<item name="colorControlNormal">@android:color/white</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
@ -1,67 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceCategory android:title="@string/pref_view_header">
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<PreferenceCategory
|
||||
android:title="@string/pref_view_header"
|
||||
app:iconSpaceReserved="false">
|
||||
<ListPreference
|
||||
android:defaultValue="0"
|
||||
android:entries="@array/startup_tab_entries"
|
||||
android:entryValues="@array/startup_tab_value"
|
||||
android:key="startup_tab"
|
||||
android:key="start_menu"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_view_list" />
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="grades_summary"
|
||||
android:summary="@string/pref_restart"
|
||||
android:title="@string/pref_view_summary" />
|
||||
android:title="@string/pref_view_list"
|
||||
app:iconSpaceReserved="false" />
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="attendance_present"
|
||||
android:summary="@string/pref_restart"
|
||||
android:title="@string/pref_view_present" />
|
||||
<ListPreference
|
||||
android:defaultValue="1"
|
||||
android:entries="@array/theme_entries"
|
||||
android:entryValues="@array/theme_values"
|
||||
android:key="theme"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_view_theme_dark" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/pref_services_header">
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="services_enable"
|
||||
android:title="@string/pref_services_switch" />
|
||||
<ListPreference
|
||||
android:defaultValue="60"
|
||||
android:dependency="services_enable"
|
||||
android:entries="@array/services_interval_entries"
|
||||
android:entryValues="@array/services_interval_value"
|
||||
android:key="services_interval"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_services_interval" />
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:dependency="services_enable"
|
||||
android:key="services_disable_mobile"
|
||||
android:title="@string/pref_services_wifi" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/pref_notify_header">
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:dependency="services_enable"
|
||||
android:key="notify_enable"
|
||||
android:title="@string/pref_notify_switch" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/pref_about_description">
|
||||
<Preference
|
||||
android:key="about_version"
|
||||
android:title="@string/pref_about_version" />
|
||||
<Preference
|
||||
android:key="about_osl"
|
||||
android:summary="@string/pref_about_osl_summary"
|
||||
android:title="@string/pref_about_osl" />
|
||||
<Preference
|
||||
android:key="about_repo"
|
||||
android:title="@string/pref_about_support" />
|
||||
android:title="@string/pref_view_present"
|
||||
app:iconSpaceReserved="false" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
|
@ -21,6 +21,7 @@ class LoginPresenterTest {
|
||||
fun initPresenter() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
clearInvocations(loginView)
|
||||
|
||||
presenter = LoginPresenter(errorHandler)
|
||||
presenter.onAttachView(loginView)
|
||||
}
|
||||
@ -49,7 +50,7 @@ class LoginPresenterTest {
|
||||
@Test
|
||||
fun onBackPressedTest() {
|
||||
clearInvocations(loginView)
|
||||
doReturn(1).`when`(loginView).currentViewPosition()
|
||||
doReturn(1).`when`(loginView).currentViewIndex
|
||||
presenter.onBackPressed { }
|
||||
verify(loginView).switchView(0)
|
||||
verify(loginView).hideActionBar()
|
||||
@ -58,7 +59,7 @@ class LoginPresenterTest {
|
||||
@Test
|
||||
fun onBackPressedDefaultTest() {
|
||||
var i = 0
|
||||
doReturn(0).`when`(loginView).currentViewPosition()
|
||||
doReturn(0).`when`(loginView).currentViewIndex
|
||||
presenter.onBackPressed { i++ }
|
||||
assertNotEquals(0, i)
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
package io.github.wulkanowy.ui.main
|
||||
|
||||
import io.github.wulkanowy.data.ErrorHandler
|
||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.*
|
||||
import org.mockito.Mockito.clearInvocations
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
class MainPresenterTest {
|
||||
@ -12,6 +14,9 @@ class MainPresenterTest {
|
||||
@Mock
|
||||
lateinit var errorHandler: ErrorHandler
|
||||
|
||||
@Mock
|
||||
lateinit var prefRepository: PreferencesRepository
|
||||
|
||||
@Mock
|
||||
lateinit var mainView: MainView
|
||||
|
||||
@ -22,7 +27,7 @@ class MainPresenterTest {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
clearInvocations(mainView)
|
||||
|
||||
presenter = MainPresenter(errorHandler)
|
||||
presenter = MainPresenter(errorHandler, prefRepository)
|
||||
presenter.onAttachView(mainView)
|
||||
}
|
||||
|
||||
@ -36,12 +41,5 @@ class MainPresenterTest {
|
||||
presenter.onTabSelected(1, false)
|
||||
verify(mainView).switchMenuView(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onMenuFragmentChangeTest() {
|
||||
doReturn("Test").`when`(mainView).viewTitle(1)
|
||||
presenter.onMenuViewChange(1)
|
||||
verify(mainView).setViewTitle("Test")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ buildscript {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath "io.fabric.tools:gradle:1.26.0"
|
||||
classpath "com.google.gms:oss-licenses:0.9.2"
|
||||
classpath "com.github.triplet.gradle:play-publisher:1.2.2"
|
||||
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.6.2"
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user