forked from github/wulkanowy-mirror
Add menu order settings (#1924)
This commit is contained in:
parent
6df3f22c7d
commit
32d6b4a7a6
@ -10,6 +10,7 @@ import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.enums.*
|
||||
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
|
||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode
|
||||
import io.github.wulkanowy.ui.modules.settings.appearance.menuorder.AppMenuItem
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.serialization.decodeFromString
|
||||
@ -28,9 +29,6 @@ class PreferencesRepository @Inject constructor(
|
||||
private val json: Json,
|
||||
) {
|
||||
|
||||
val startMenuIndex: Int
|
||||
get() = getString(R.string.pref_key_start_menu, R.string.pref_default_startup).toInt()
|
||||
|
||||
val isShowPresent: Boolean
|
||||
get() = getBoolean(
|
||||
R.string.pref_key_attendance_present,
|
||||
@ -315,6 +313,20 @@ class PreferencesRepository @Inject constructor(
|
||||
putBoolean(context.getString(R.string.pref_key_ads_enabled), value)
|
||||
}
|
||||
|
||||
var appMenuItemOrder: List<AppMenuItem>
|
||||
get() {
|
||||
val value = sharedPref.getString(PREF_KEY_APP_MENU_ITEM_ORDER, null)
|
||||
?: return AppMenuItem.defaultAppMenuItemList
|
||||
|
||||
return json.decodeFromString(value)
|
||||
}
|
||||
set(value) = sharedPref.edit {
|
||||
putString(
|
||||
PREF_KEY_APP_MENU_ITEM_ORDER,
|
||||
json.encodeToString(value)
|
||||
)
|
||||
}
|
||||
|
||||
var installationId: String
|
||||
get() = sharedPref.getString(PREF_KEY_INSTALLATION_ID, null).orEmpty()
|
||||
private set(value) = sharedPref.edit { putString(PREF_KEY_INSTALLATION_ID, value) }
|
||||
@ -341,6 +353,7 @@ class PreferencesRepository @Inject constructor(
|
||||
sharedPref.getBoolean(id, context.resources.getBoolean(default))
|
||||
|
||||
private companion object {
|
||||
private const val PREF_KEY_APP_MENU_ITEM_ORDER = "app_menu_item_order"
|
||||
private const val PREF_KEY_INSTALLATION_ID = "installation_id"
|
||||
private const val PREF_KEY_DASHBOARD_ITEMS_POSITION = "dashboard_items_position"
|
||||
private const val PREF_KEY_IN_APP_REVIEW_COUNT = "in_app_review_count"
|
||||
|
@ -10,10 +10,12 @@ import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
||||
import io.github.wulkanowy.ui.modules.homework.HomeworkFragment
|
||||
import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment
|
||||
import io.github.wulkanowy.ui.modules.message.MessageFragment
|
||||
import io.github.wulkanowy.ui.modules.mobiledevice.MobileDeviceFragment
|
||||
import io.github.wulkanowy.ui.modules.more.MoreFragment
|
||||
import io.github.wulkanowy.ui.modules.note.NoteFragment
|
||||
import io.github.wulkanowy.ui.modules.schoolandteachers.school.SchoolFragment
|
||||
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment
|
||||
import io.github.wulkanowy.ui.modules.schoolannouncement.SchoolAnnouncementFragment
|
||||
import io.github.wulkanowy.ui.modules.settings.SettingsFragment
|
||||
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.time.LocalDate
|
||||
@ -39,10 +41,12 @@ sealed class Destination {
|
||||
NOTE(Note),
|
||||
CONFERENCE(Conference),
|
||||
SCHOOL_ANNOUNCEMENT(SchoolAnnouncement),
|
||||
SCHOOL(School),
|
||||
LUCKY_NUMBER(More),
|
||||
SCHOOL_AND_TEACHERS(SchoolAndTeachers),
|
||||
LUCKY_NUMBER(LuckyNumber),
|
||||
MORE(More),
|
||||
MESSAGE(Message);
|
||||
MESSAGE(Message),
|
||||
MOBILE_DEVICE(MobileDevice),
|
||||
SETTINGS(Settings);
|
||||
}
|
||||
|
||||
@Serializable
|
||||
@ -103,9 +107,9 @@ sealed class Destination {
|
||||
}
|
||||
|
||||
@Serializable
|
||||
object School : Destination() {
|
||||
override val destinationType get() = Type.SCHOOL
|
||||
override val destinationFragment get() = SchoolFragment.newInstance()
|
||||
object SchoolAndTeachers : Destination() {
|
||||
override val destinationType get() = Type.SCHOOL_AND_TEACHERS
|
||||
override val destinationFragment get() = SchoolAndTeachersFragment.newInstance()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
@ -125,4 +129,16 @@ sealed class Destination {
|
||||
override val destinationType get() = Type.MESSAGE
|
||||
override val destinationFragment get() = MessageFragment.newInstance()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
object MobileDevice : Destination() {
|
||||
override val destinationType get() = Type.MOBILE_DEVICE
|
||||
override val destinationFragment get() = MobileDeviceFragment.newInstance()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
object Settings : Destination() {
|
||||
override val destinationType get() = Type.SETTINGS
|
||||
override val destinationFragment get() = SettingsFragment.newInstance()
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ConferenceFragment : BaseFragment<FragmentConferenceBinding>(R.layout.fragment_conference),
|
||||
ConferenceView, MainView.TitledView {
|
||||
ConferenceView, MainView.TitledView, MainView.MainChildView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: ConferencePresenter
|
||||
@ -109,6 +109,14 @@ class ConferenceFragment : BaseFragment<FragmentConferenceBinding>(R.layout.frag
|
||||
(activity as? MainActivity)?.showDialogFragment(ConferenceDialog.newInstance(conference))
|
||||
}
|
||||
|
||||
override fun onFragmentReselected() {
|
||||
if (::presenter.isInitialized) presenter.onFragmentReselected()
|
||||
}
|
||||
|
||||
override fun resetView() {
|
||||
binding.conferenceRecycler.smoothScrollToPosition(0)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
presenter.onDetachView()
|
||||
super.onDestroyView()
|
||||
|
@ -96,4 +96,11 @@ class ConferencePresenter @Inject constructor(
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch()
|
||||
}
|
||||
|
||||
fun onFragmentReselected() {
|
||||
Timber.i("Conference is reselected")
|
||||
if (view?.isViewEmpty == false) {
|
||||
view?.resetView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,4 +28,6 @@ interface ConferenceView : BaseView {
|
||||
fun showContent(show: Boolean)
|
||||
|
||||
fun openConferenceDialog(conference: Conference)
|
||||
|
||||
fun resetView()
|
||||
}
|
||||
|
@ -2,9 +2,7 @@ package io.github.wulkanowy.ui.modules.exam
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.View.GONE
|
||||
import android.view.View.INVISIBLE
|
||||
import android.view.View.VISIBLE
|
||||
import android.view.View.*
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.github.wulkanowy.R
|
||||
@ -20,7 +18,7 @@ import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ExamFragment : BaseFragment<FragmentExamBinding>(R.layout.fragment_exam), ExamView,
|
||||
MainView.TitledView {
|
||||
MainView.TitledView, MainView.MainChildView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: ExamPresenter
|
||||
@ -126,6 +124,14 @@ class ExamFragment : BaseFragment<FragmentExamBinding>(R.layout.fragment_exam),
|
||||
(activity as? MainActivity)?.showDialogFragment(ExamDialog.newInstance(exam))
|
||||
}
|
||||
|
||||
override fun onFragmentReselected() {
|
||||
if (::presenter.isInitialized) presenter.onViewReselected()
|
||||
}
|
||||
|
||||
override fun resetView() {
|
||||
binding.examRecycler.smoothScrollToPosition(0)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay())
|
||||
|
@ -175,4 +175,17 @@ class ExamPresenter @Inject constructor(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun onViewReselected() {
|
||||
Timber.i("Exam view is reselected")
|
||||
|
||||
baseDate = now().nextOrSameSchoolDay
|
||||
|
||||
if (currentDate != baseDate) {
|
||||
reloadView(baseDate)
|
||||
loadData()
|
||||
} else if (view?.isViewEmpty == false) {
|
||||
view?.resetView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,4 +34,6 @@ interface ExamView : BaseView {
|
||||
fun showPreButton(show: Boolean)
|
||||
|
||||
fun showExamDialog(exam: Exam)
|
||||
|
||||
fun resetView()
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class HomeworkFragment : BaseFragment<FragmentHomeworkBinding>(R.layout.fragment_homework),
|
||||
HomeworkView, MainView.TitledView {
|
||||
HomeworkView, MainView.TitledView, MainView.MainChildView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: HomeworkPresenter
|
||||
@ -133,6 +133,14 @@ class HomeworkFragment : BaseFragment<FragmentHomeworkBinding>(R.layout.fragment
|
||||
(activity as? MainActivity)?.showDialogFragment(HomeworkAddDialog())
|
||||
}
|
||||
|
||||
override fun onFragmentReselected() {
|
||||
if (::presenter.isInitialized) presenter.onViewReselected()
|
||||
}
|
||||
|
||||
override fun resetView() {
|
||||
binding.homeworkRecycler.smoothScrollToPosition(0)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay())
|
||||
|
@ -177,8 +177,21 @@ class HomeworkPresenter @Inject constructor(
|
||||
showNextButton(!currentDate.plusDays(7).isHolidays)
|
||||
updateNavigationWeek(
|
||||
"${currentDate.monday.toFormattedString("dd.MM")} - " +
|
||||
currentDate.sunday.toFormattedString("dd.MM")
|
||||
currentDate.sunday.toFormattedString("dd.MM")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun onViewReselected() {
|
||||
Timber.i("Homework view is reselected")
|
||||
|
||||
baseDate = LocalDate.now().nextOrSameSchoolDay
|
||||
|
||||
if (currentDate != baseDate) {
|
||||
reloadView(baseDate)
|
||||
loadData()
|
||||
} else if (view?.isViewEmpty == false) {
|
||||
view?.resetView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,4 +36,6 @@ interface HomeworkView : BaseView {
|
||||
fun showHomeworkDialog(homework: Homework)
|
||||
|
||||
fun showAddHomeworkDialog()
|
||||
|
||||
fun resetView()
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import javax.inject.Inject
|
||||
@AndroidEntryPoint
|
||||
class LuckyNumberFragment :
|
||||
BaseFragment<FragmentLuckyNumberBinding>(R.layout.fragment_lucky_number), LuckyNumberView,
|
||||
MainView.TitledView {
|
||||
MainView.TitledView, MainView.MainChildView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: LuckyNumberPresenter
|
||||
@ -86,6 +86,14 @@ class LuckyNumberFragment :
|
||||
(activity as? MainActivity)?.pushView(LuckyNumberHistoryFragment.newInstance())
|
||||
}
|
||||
|
||||
override fun onFragmentReselected() {
|
||||
if (::presenter.isInitialized) presenter.onViewReselected()
|
||||
}
|
||||
|
||||
override fun popView() {
|
||||
(activity as? MainActivity)?.popView()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
presenter.onDetachView()
|
||||
super.onDestroyView()
|
||||
|
@ -99,4 +99,9 @@ class LuckyNumberPresenter @Inject constructor(
|
||||
fun onDetailsClick() {
|
||||
view?.showErrorDetailsDialog(lastError)
|
||||
}
|
||||
|
||||
fun onViewReselected() {
|
||||
Timber.i("Luckynumber view is reselected")
|
||||
view?.popView()
|
||||
}
|
||||
}
|
||||
|
@ -26,4 +26,6 @@ interface LuckyNumberView : BaseView {
|
||||
fun showContent(show: Boolean)
|
||||
|
||||
fun openLuckyNumberHistory()
|
||||
|
||||
fun popView()
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import io.github.wulkanowy.databinding.DialogAdsConsentBinding
|
||||
import io.github.wulkanowy.ui.base.BaseActivity
|
||||
import io.github.wulkanowy.ui.modules.Destination
|
||||
import io.github.wulkanowy.ui.modules.account.accountquick.AccountQuickDialog
|
||||
import io.github.wulkanowy.ui.modules.settings.appearance.menuorder.AppMenuItem
|
||||
import io.github.wulkanowy.utils.*
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
@ -124,13 +125,20 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
||||
return true
|
||||
}
|
||||
|
||||
override fun initView(startMenuIndex: Int, rootDestinations: List<Destination>) {
|
||||
override fun initView(
|
||||
startMenuIndex: Int,
|
||||
rootAppMenuItems: List<AppMenuItem>,
|
||||
rootUpdatedDestinations: List<Destination>
|
||||
) {
|
||||
initializeToolbar()
|
||||
initializeBottomNavigation(startMenuIndex)
|
||||
initializeNavController(startMenuIndex, rootDestinations)
|
||||
initializeBottomNavigation(startMenuIndex, rootAppMenuItems)
|
||||
initializeNavController(startMenuIndex, rootUpdatedDestinations)
|
||||
}
|
||||
|
||||
private fun initializeNavController(startMenuIndex: Int, rootDestinations: List<Destination>) {
|
||||
private fun initializeNavController(
|
||||
startMenuIndex: Int,
|
||||
rootUpdatedDestinations: List<Destination>
|
||||
) {
|
||||
with(navController) {
|
||||
setOnViewChangeListener { destinationView ->
|
||||
presenter.onViewChange(destinationView)
|
||||
@ -140,7 +148,7 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
||||
)
|
||||
}
|
||||
fragmentHideStrategy = HIDE
|
||||
rootFragments = rootDestinations.map { it.destinationFragment }
|
||||
rootFragments = rootUpdatedDestinations.map { it.destinationFragment }
|
||||
|
||||
initialize(startMenuIndex, savedInstanceState)
|
||||
}
|
||||
@ -156,17 +164,16 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeBottomNavigation(startMenuIndex: Int) {
|
||||
private fun initializeBottomNavigation(
|
||||
startMenuIndex: Int,
|
||||
rootAppMenuItems: List<AppMenuItem>
|
||||
) {
|
||||
with(binding.mainBottomNav) {
|
||||
with(menu) {
|
||||
add(Menu.NONE, 0, Menu.NONE, R.string.dashboard_title)
|
||||
.setIcon(R.drawable.ic_main_dashboard)
|
||||
add(Menu.NONE, 1, Menu.NONE, R.string.grade_title)
|
||||
.setIcon(R.drawable.ic_main_grade)
|
||||
add(Menu.NONE, 2, Menu.NONE, R.string.attendance_title)
|
||||
.setIcon(R.drawable.ic_main_attendance)
|
||||
add(Menu.NONE, 3, Menu.NONE, R.string.timetable_title)
|
||||
.setIcon(R.drawable.ic_main_timetable)
|
||||
rootAppMenuItems.forEachIndexed { index, item ->
|
||||
add(Menu.NONE, index, Menu.NONE, item.title)
|
||||
.setIcon(item.icon)
|
||||
}
|
||||
add(Menu.NONE, 4, Menu.NONE, R.string.more_title)
|
||||
.setIcon(R.drawable.ic_main_more)
|
||||
}
|
||||
|
@ -42,17 +42,16 @@ class MainPresenter @Inject constructor(
|
||||
|
||||
private var studentsWitSemesters: List<StudentWithSemesters>? = null
|
||||
|
||||
private val rootDestinationTypeList = listOf(
|
||||
Destination.Type.DASHBOARD,
|
||||
Destination.Type.GRADE,
|
||||
Destination.Type.ATTENDANCE,
|
||||
Destination.Type.TIMETABLE,
|
||||
Destination.Type.MORE
|
||||
)
|
||||
private val rootAppMenuItems = preferencesRepository.appMenuItemOrder
|
||||
.sortedBy { it.order }
|
||||
.take(4)
|
||||
|
||||
private val rootDestinationTypeList = rootAppMenuItems.map { it.destinationType }
|
||||
.plus(Destination.Type.MORE)
|
||||
|
||||
private val Destination?.startMenuIndex
|
||||
get() = when {
|
||||
this == null -> preferencesRepository.startMenuIndex
|
||||
this == null -> 0
|
||||
destinationType in rootDestinationTypeList -> {
|
||||
rootDestinationTypeList.indexOf(destinationType)
|
||||
}
|
||||
@ -69,7 +68,7 @@ class MainPresenter @Inject constructor(
|
||||
if (it == initDestination?.destinationType) initDestination else it.defaultDestination
|
||||
}
|
||||
|
||||
view.initView(startMenuIndex, destinations)
|
||||
view.initView(startMenuIndex, rootAppMenuItems, destinations)
|
||||
if (initDestination != null && startMenuIndex == 4) {
|
||||
view.openMoreDestination(initDestination)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
import io.github.wulkanowy.ui.modules.Destination
|
||||
import io.github.wulkanowy.ui.modules.settings.appearance.menuorder.AppMenuItem
|
||||
|
||||
interface MainView : BaseView {
|
||||
|
||||
@ -15,7 +16,11 @@ interface MainView : BaseView {
|
||||
|
||||
val currentStackSize: Int?
|
||||
|
||||
fun initView(startMenuIndex: Int, rootDestinations: List<Destination>)
|
||||
fun initView(
|
||||
startMenuIndex: Int,
|
||||
rootAppMenuItems: List<AppMenuItem>,
|
||||
rootUpdatedDestinations: List<Destination>
|
||||
)
|
||||
|
||||
fun switchMenuView(position: Int)
|
||||
|
||||
|
@ -15,6 +15,7 @@ import io.github.wulkanowy.data.enums.MessageFolder.*
|
||||
import io.github.wulkanowy.databinding.FragmentMessageBinding
|
||||
import io.github.wulkanowy.ui.base.BaseFragment
|
||||
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||
import io.github.wulkanowy.ui.modules.main.MainView
|
||||
import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
|
||||
import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment
|
||||
@ -24,7 +25,7 @@ import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MessageFragment : BaseFragment<FragmentMessageBinding>(R.layout.fragment_message),
|
||||
MessageView, MainView.TitledView {
|
||||
MessageView, MainView.TitledView, MainView.MainChildView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: MessagePresenter
|
||||
@ -123,8 +124,12 @@ class MessageFragment : BaseFragment<FragmentMessageBinding>(R.layout.fragment_m
|
||||
presenter.onChildViewShowNewMessage(show)
|
||||
}
|
||||
|
||||
fun onFragmentChanged() {
|
||||
presenter.onFragmentChanged()
|
||||
override fun onFragmentReselected() {
|
||||
if (::presenter.isInitialized) presenter.onFragmentReselected()
|
||||
}
|
||||
|
||||
override fun onFragmentChanged() {
|
||||
if (::presenter.isInitialized) presenter.onFragmentChanged()
|
||||
}
|
||||
|
||||
override fun notifyChildLoadData(index: Int, forceRefresh: Boolean) {
|
||||
@ -139,10 +144,19 @@ class MessageFragment : BaseFragment<FragmentMessageBinding>(R.layout.fragment_m
|
||||
}
|
||||
}
|
||||
|
||||
override fun notifyChildParentReselected(index: Int) {
|
||||
(pagerAdapter.getFragmentInstance(index) as? MessageTabFragment)
|
||||
?.onParentReselected()
|
||||
}
|
||||
|
||||
override fun openSendMessage() {
|
||||
context?.let { it.startActivity(SendMessageActivity.getStartIntent(it)) }
|
||||
}
|
||||
|
||||
override fun popView() {
|
||||
(activity as? MainActivity)?.popView()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
presenter.onDetachView()
|
||||
super.onDestroyView()
|
||||
|
@ -39,6 +39,14 @@ class MessagePresenter @Inject constructor(
|
||||
view?.notifyChildrenFinishActionMode()
|
||||
}
|
||||
|
||||
fun onFragmentReselected() {
|
||||
Timber.i("Message view is reselected")
|
||||
view?.run {
|
||||
popView()
|
||||
notifyChildParentReselected(currentPageIndex)
|
||||
}
|
||||
}
|
||||
|
||||
fun onChildViewLoaded() {
|
||||
view?.apply {
|
||||
showContent(true)
|
||||
|
@ -20,5 +20,9 @@ interface MessageView : BaseView {
|
||||
|
||||
fun notifyChildrenFinishActionMode()
|
||||
|
||||
fun notifyChildParentReselected(index: Int)
|
||||
|
||||
fun openSendMessage()
|
||||
|
||||
fun popView()
|
||||
}
|
||||
|
@ -235,6 +235,10 @@ class MessageTabFragment : BaseFragment<FragmentMessageTabBinding>(R.layout.frag
|
||||
presenter.onParentFinishActionMode()
|
||||
}
|
||||
|
||||
fun onParentReselected() {
|
||||
presenter.onParentReselected()
|
||||
}
|
||||
|
||||
private fun onChipChecked(chip: CompoundButton, isChecked: Boolean) {
|
||||
when (chip.id) {
|
||||
R.id.chip_unread -> presenter.onUnreadFilterSelected(isChecked)
|
||||
|
@ -83,6 +83,14 @@ class MessageTabPresenter @Inject constructor(
|
||||
view?.showActionMode(false)
|
||||
}
|
||||
|
||||
fun onParentReselected() {
|
||||
view?.run {
|
||||
if (!isViewEmpty) {
|
||||
resetListPosition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onDestroyActionMode() {
|
||||
isActionMode = false
|
||||
messagesToDelete.clear()
|
||||
|
@ -22,7 +22,7 @@ import javax.inject.Inject
|
||||
@AndroidEntryPoint
|
||||
class MobileDeviceFragment :
|
||||
BaseFragment<FragmentMobileDeviceBinding>(R.layout.fragment_mobile_device), MobileDeviceView,
|
||||
MainView.TitledView {
|
||||
MainView.TitledView, MainView.MainChildView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: MobileDevicePresenter
|
||||
@ -135,6 +135,14 @@ class MobileDeviceFragment :
|
||||
(activity as? MainActivity)?.showDialogFragment(MobileDeviceTokenDialog.newInstance())
|
||||
}
|
||||
|
||||
override fun onFragmentReselected() {
|
||||
if (::presenter.isInitialized) presenter.onFragmentReselected()
|
||||
}
|
||||
|
||||
override fun resetView() {
|
||||
binding.mobileDevicesRecycler.smoothScrollToPosition(0)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
presenter.onDetachView()
|
||||
super.onDestroyView()
|
||||
|
@ -129,4 +129,10 @@ class MobileDevicePresenter @Inject constructor(
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("unregister")
|
||||
}
|
||||
|
||||
fun onFragmentReselected() {
|
||||
if (view?.isViewEmpty == false) {
|
||||
view?.resetView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,4 +32,6 @@ interface MobileDeviceView : BaseView {
|
||||
fun setErrorDetails(message: String)
|
||||
|
||||
fun showTokenDialog()
|
||||
|
||||
fun resetView()
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package io.github.wulkanowy.ui.modules.more
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@ -9,9 +8,9 @@ import javax.inject.Inject
|
||||
|
||||
class MoreAdapter @Inject constructor() : RecyclerView.Adapter<MoreAdapter.ItemViewHolder>() {
|
||||
|
||||
var items = emptyList<Pair<String, Drawable?>>()
|
||||
var items = emptyList<MoreItem>()
|
||||
|
||||
var onClickListener: (name: String) -> Unit = {}
|
||||
var onClickListener: (moreItem: MoreItem) -> Unit = {}
|
||||
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
@ -20,13 +19,14 @@ class MoreAdapter @Inject constructor() : RecyclerView.Adapter<MoreAdapter.ItemV
|
||||
)
|
||||
|
||||
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
|
||||
val (title, drawable) = items[position]
|
||||
val item = items[position]
|
||||
val context = holder.binding.root.context
|
||||
|
||||
with(holder.binding) {
|
||||
moreItemTitle.text = title
|
||||
moreItemImage.setImageDrawable(drawable)
|
||||
moreItemTitle.text = context.getString(item.title)
|
||||
moreItemImage.setImageResource(item.icon)
|
||||
|
||||
root.setOnClickListener { onClickListener(title) }
|
||||
root.setOnClickListener { onClickListener(item) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package io.github.wulkanowy.ui.modules.more
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
@ -8,19 +7,10 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.databinding.FragmentMoreBinding
|
||||
import io.github.wulkanowy.ui.base.BaseFragment
|
||||
import io.github.wulkanowy.ui.modules.conference.ConferenceFragment
|
||||
import io.github.wulkanowy.ui.modules.exam.ExamFragment
|
||||
import io.github.wulkanowy.ui.modules.homework.HomeworkFragment
|
||||
import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment
|
||||
import io.github.wulkanowy.ui.modules.Destination
|
||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||
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.schoolannouncement.SchoolAnnouncementFragment
|
||||
import io.github.wulkanowy.ui.modules.settings.SettingsFragment
|
||||
import io.github.wulkanowy.utils.getCompatDrawable
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
@ -40,36 +30,6 @@ class MoreFragment : BaseFragment<FragmentMoreBinding>(R.layout.fragment_more),
|
||||
override val titleStringId: Int
|
||||
get() = R.string.more_title
|
||||
|
||||
override val messagesRes: Pair<String, Drawable?>?
|
||||
get() = context?.run { getString(R.string.message_title) to getCompatDrawable(R.drawable.ic_more_messages) }
|
||||
|
||||
override val homeworkRes: Pair<String, Drawable?>?
|
||||
get() = context?.run { getString(R.string.homework_title) to getCompatDrawable(R.drawable.ic_more_homework) }
|
||||
|
||||
override val noteRes: Pair<String, Drawable?>?
|
||||
get() = context?.run { getString(R.string.note_title) to getCompatDrawable(R.drawable.ic_more_note) }
|
||||
|
||||
override val conferencesRes: Pair<String, Drawable?>?
|
||||
get() = context?.run { getString(R.string.conferences_title) to getCompatDrawable(R.drawable.ic_more_conferences) }
|
||||
|
||||
override val schoolAnnouncementRes: Pair<String, Drawable?>?
|
||||
get() = context?.run { getString(R.string.school_announcement_title) to getCompatDrawable(R.drawable.ic_all_about) }
|
||||
|
||||
override val schoolAndTeachersRes: Pair<String, Drawable?>?
|
||||
get() = context?.run { getString(R.string.schoolandteachers_title) to getCompatDrawable((R.drawable.ic_more_schoolandteachers)) }
|
||||
|
||||
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 settingsRes: Pair<String, Drawable?>?
|
||||
get() = context?.run { getString(R.string.settings_title) to getCompatDrawable(R.drawable.ic_more_settings) }
|
||||
|
||||
override val examRes: Pair<String, Drawable?>?
|
||||
get() = context?.run { getString(R.string.exam_title) to getCompatDrawable(R.drawable.ic_main_exam) }
|
||||
|
||||
override val luckyNumberRes: Pair<String, Drawable?>?
|
||||
get() = context?.run { getString(R.string.lucky_number_title) to getCompatDrawable(R.drawable.ic_more_lucky_number) }
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding = FragmentMoreBinding.bind(view)
|
||||
@ -94,57 +54,21 @@ class MoreFragment : BaseFragment<FragmentMoreBinding>(R.layout.fragment_more),
|
||||
?.onFragmentChanged()
|
||||
}
|
||||
|
||||
override fun updateData(data: List<Pair<String, Drawable?>>) {
|
||||
override fun updateData(data: List<MoreItem>) {
|
||||
with(moreAdapter) {
|
||||
items = data
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
override fun openMessagesView() {
|
||||
(activity as? MainActivity)?.pushView(MessageFragment.newInstance())
|
||||
}
|
||||
|
||||
override fun openHomeworkView() {
|
||||
(activity as? MainActivity)?.pushView(HomeworkFragment.newInstance())
|
||||
}
|
||||
|
||||
override fun openNoteView() {
|
||||
(activity as? MainActivity)?.pushView(NoteFragment.newInstance())
|
||||
}
|
||||
|
||||
override fun openSchoolAnnouncementView() {
|
||||
(activity as? MainActivity)?.pushView(SchoolAnnouncementFragment.newInstance())
|
||||
}
|
||||
|
||||
override fun openConferencesView() {
|
||||
(activity as? MainActivity)?.pushView(ConferenceFragment.newInstance())
|
||||
}
|
||||
|
||||
override fun openSchoolAndTeachersView() {
|
||||
(activity as? MainActivity)?.pushView(SchoolAndTeachersFragment.newInstance())
|
||||
}
|
||||
|
||||
override fun openMobileDevicesView() {
|
||||
(activity as? MainActivity)?.pushView(MobileDeviceFragment.newInstance())
|
||||
}
|
||||
|
||||
override fun openSettingsView() {
|
||||
(activity as? MainActivity)?.pushView(SettingsFragment.newInstance())
|
||||
}
|
||||
|
||||
override fun openExamView() {
|
||||
(activity as? MainActivity)?.pushView(ExamFragment.newInstance())
|
||||
}
|
||||
|
||||
override fun openLuckyNumberView() {
|
||||
(activity as? MainActivity)?.pushView(LuckyNumberFragment.newInstance())
|
||||
}
|
||||
|
||||
override fun popView(depth: Int) {
|
||||
(activity as? MainActivity)?.popView(depth)
|
||||
}
|
||||
|
||||
override fun openView(destination: Destination) {
|
||||
(activity as? MainActivity)?.pushView(destination.destinationFragment)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
presenter.onDetachView()
|
||||
super.onDestroyView()
|
||||
|
@ -0,0 +1,12 @@
|
||||
package io.github.wulkanowy.ui.modules.more
|
||||
|
||||
import io.github.wulkanowy.ui.modules.Destination
|
||||
|
||||
data class MoreItem(
|
||||
|
||||
val icon: Int,
|
||||
|
||||
val title: Int,
|
||||
|
||||
val destination: Destination
|
||||
)
|
@ -1,16 +1,24 @@
|
||||
package io.github.wulkanowy.ui.modules.more
|
||||
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.ui.modules.Destination
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class MorePresenter @Inject constructor(
|
||||
errorHandler: ErrorHandler,
|
||||
studentRepository: StudentRepository
|
||||
studentRepository: StudentRepository,
|
||||
preferencesRepository: PreferencesRepository
|
||||
) : BasePresenter<MoreView>(errorHandler, studentRepository) {
|
||||
|
||||
private val moreAppMenuItem = preferencesRepository.appMenuItemOrder
|
||||
.sortedBy { it.order }
|
||||
.drop(4)
|
||||
|
||||
override fun onAttachView(view: MoreView) {
|
||||
super.onAttachView(view)
|
||||
view.initView()
|
||||
@ -18,22 +26,10 @@ class MorePresenter @Inject constructor(
|
||||
loadData()
|
||||
}
|
||||
|
||||
fun onItemSelected(title: String) {
|
||||
Timber.i("Select more item \"${title}\"")
|
||||
view?.run {
|
||||
when (title) {
|
||||
messagesRes?.first -> openMessagesView()
|
||||
examRes?.first -> openExamView()
|
||||
homeworkRes?.first -> openHomeworkView()
|
||||
noteRes?.first -> openNoteView()
|
||||
conferencesRes?.first -> openConferencesView()
|
||||
schoolAnnouncementRes?.first -> openSchoolAnnouncementView()
|
||||
schoolAndTeachersRes?.first -> openSchoolAndTeachersView()
|
||||
mobileDevicesRes?.first -> openMobileDevicesView()
|
||||
settingsRes?.first -> openSettingsView()
|
||||
luckyNumberRes?.first -> openLuckyNumberView()
|
||||
}
|
||||
}
|
||||
fun onItemSelected(moreItem: MoreItem) {
|
||||
Timber.i("Select more item \"${moreItem.destination.destinationType}\"")
|
||||
|
||||
view?.openView(moreItem.destination)
|
||||
}
|
||||
|
||||
fun onViewReselected() {
|
||||
@ -43,19 +39,21 @@ class MorePresenter @Inject constructor(
|
||||
|
||||
private fun loadData() {
|
||||
Timber.i("Load items for more view")
|
||||
view?.run {
|
||||
updateData(listOfNotNull(
|
||||
messagesRes,
|
||||
examRes,
|
||||
homeworkRes,
|
||||
noteRes,
|
||||
luckyNumberRes,
|
||||
conferencesRes,
|
||||
schoolAnnouncementRes,
|
||||
schoolAndTeachersRes,
|
||||
mobileDevicesRes,
|
||||
settingsRes
|
||||
))
|
||||
val moreItems = moreAppMenuItem.map {
|
||||
MoreItem(
|
||||
icon = it.icon,
|
||||
title = it.title,
|
||||
destination = it.destinationType.defaultDestination
|
||||
)
|
||||
}
|
||||
.plus(
|
||||
MoreItem(
|
||||
icon = R.drawable.ic_more_settings,
|
||||
title = R.string.settings_title,
|
||||
destination = Destination.Settings
|
||||
)
|
||||
)
|
||||
|
||||
view?.updateData(moreItems)
|
||||
}
|
||||
}
|
||||
|
@ -1,53 +1,15 @@
|
||||
package io.github.wulkanowy.ui.modules.more
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
import io.github.wulkanowy.ui.modules.Destination
|
||||
|
||||
interface MoreView : BaseView {
|
||||
|
||||
val messagesRes: Pair<String, Drawable?>?
|
||||
|
||||
val homeworkRes: Pair<String, Drawable?>?
|
||||
|
||||
val noteRes: Pair<String, Drawable?>?
|
||||
|
||||
val conferencesRes: Pair<String, Drawable?>?
|
||||
|
||||
val schoolAnnouncementRes: Pair<String, Drawable?>?
|
||||
|
||||
val schoolAndTeachersRes: Pair<String, Drawable?>?
|
||||
|
||||
val mobileDevicesRes: Pair<String, Drawable?>?
|
||||
|
||||
val settingsRes: Pair<String, Drawable?>?
|
||||
|
||||
val examRes: Pair<String, Drawable?>?
|
||||
|
||||
val luckyNumberRes: Pair<String, Drawable?>?
|
||||
|
||||
fun initView()
|
||||
|
||||
fun updateData(data: List<Pair<String, Drawable?>>)
|
||||
|
||||
fun openSettingsView()
|
||||
fun updateData(data: List<MoreItem>)
|
||||
|
||||
fun popView(depth: Int)
|
||||
|
||||
fun openMessagesView()
|
||||
|
||||
fun openHomeworkView()
|
||||
|
||||
fun openNoteView()
|
||||
|
||||
fun openSchoolAnnouncementView()
|
||||
|
||||
fun openConferencesView()
|
||||
|
||||
fun openSchoolAndTeachersView()
|
||||
|
||||
fun openMobileDevicesView()
|
||||
|
||||
fun openExamView()
|
||||
|
||||
fun openLuckyNumberView()
|
||||
fun openView(destination: Destination)
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class NoteFragment : BaseFragment<FragmentNoteBinding>(R.layout.fragment_note), NoteView,
|
||||
MainView.TitledView {
|
||||
MainView.TitledView, MainView.MainChildView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: NotePresenter
|
||||
@ -112,6 +112,14 @@ class NoteFragment : BaseFragment<FragmentNoteBinding>(R.layout.fragment_note),
|
||||
binding.noteSwipe.isRefreshing = show
|
||||
}
|
||||
|
||||
override fun onFragmentReselected() {
|
||||
if (::presenter.isInitialized) presenter.onFragmentReselected()
|
||||
}
|
||||
|
||||
override fun resetView() {
|
||||
binding.noteRecycler.smoothScrollToPosition(0)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
presenter.onDetachView()
|
||||
super.onDestroyView()
|
||||
|
@ -121,4 +121,10 @@ class NotePresenter @Inject constructor(
|
||||
}
|
||||
.launch("update_note")
|
||||
}
|
||||
|
||||
fun onFragmentReselected() {
|
||||
if (view?.isViewEmpty == false) {
|
||||
view?.resetView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,4 +30,6 @@ interface NoteView : BaseView {
|
||||
fun showRefresh(show: Boolean)
|
||||
|
||||
fun showNoteDialog(note: Note)
|
||||
|
||||
fun resetView()
|
||||
}
|
||||
|
@ -0,0 +1,206 @@
|
||||
package io.github.wulkanowy.ui.modules.settings.appearance.menuorder
|
||||
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.ui.modules.Destination
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
|
||||
@Serializable
|
||||
sealed class AppMenuItem {
|
||||
|
||||
companion object {
|
||||
val defaultAppMenuItemList = setOf(
|
||||
DashboardAppMenuItem(),
|
||||
GradeAppMenuItem(),
|
||||
TimetableAppMenuItem(),
|
||||
AttendanceAppMenuItem(),
|
||||
ExamsAppMenuItem(),
|
||||
HomeworkAppMenuItem(),
|
||||
NoteAppMenuItem(),
|
||||
LuckyNumberAppMenuItem(),
|
||||
SchoolAnnouncementsAppMenuItem(),
|
||||
SchoolAndTeachersAppMenuItem(),
|
||||
MobileDevicesAppMenuItem(),
|
||||
ConferenceAppMenuItem(),
|
||||
MessageAppMenuItem()
|
||||
).sortedBy { it.order }
|
||||
}
|
||||
|
||||
// https://youtrack.jetbrains.com/issue/KT-38958
|
||||
abstract var order: Int
|
||||
|
||||
abstract val icon: Int
|
||||
|
||||
abstract val title: Int
|
||||
|
||||
abstract val destinationType: Destination.Type
|
||||
|
||||
@Serializable
|
||||
data class DashboardAppMenuItem(override var order: Int = 0) : AppMenuItem() {
|
||||
|
||||
@Transient
|
||||
override val icon = R.drawable.ic_main_dashboard
|
||||
|
||||
@Transient
|
||||
override val title = R.string.dashboard_title
|
||||
|
||||
@Transient
|
||||
override val destinationType = Destination.Type.DASHBOARD
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class GradeAppMenuItem(override var order: Int = 1) : AppMenuItem() {
|
||||
|
||||
@Transient
|
||||
override val icon = R.drawable.ic_main_grade
|
||||
|
||||
@Transient
|
||||
override val title = R.string.grade_title
|
||||
|
||||
@Transient
|
||||
override val destinationType = Destination.Type.GRADE
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class AttendanceAppMenuItem(override var order: Int = 2) : AppMenuItem() {
|
||||
|
||||
@Transient
|
||||
override val icon = R.drawable.ic_main_attendance
|
||||
|
||||
@Transient
|
||||
override val title = R.string.attendance_title
|
||||
|
||||
@Transient
|
||||
override val destinationType = Destination.Type.ATTENDANCE
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class TimetableAppMenuItem(override var order: Int = 3) : AppMenuItem() {
|
||||
|
||||
@Transient
|
||||
override val icon = R.drawable.ic_main_timetable
|
||||
|
||||
@Transient
|
||||
override val title = R.string.timetable_title
|
||||
|
||||
@Transient
|
||||
override val destinationType = Destination.Type.TIMETABLE
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class MessageAppMenuItem(override var order: Int = 4) : AppMenuItem() {
|
||||
|
||||
@Transient
|
||||
override val icon = R.drawable.ic_more_messages
|
||||
|
||||
@Transient
|
||||
override val title = R.string.message_title
|
||||
|
||||
@Transient
|
||||
override val destinationType = Destination.Type.MESSAGE
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class ExamsAppMenuItem(override var order: Int = 5) : AppMenuItem() {
|
||||
|
||||
@Transient
|
||||
override val icon = R.drawable.ic_main_exam
|
||||
|
||||
@Transient
|
||||
override val title = R.string.exam_title
|
||||
|
||||
@Transient
|
||||
override val destinationType = Destination.Type.EXAM
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class HomeworkAppMenuItem(override var order: Int = 6) : AppMenuItem() {
|
||||
|
||||
@Transient
|
||||
override val icon = R.drawable.ic_more_homework
|
||||
|
||||
@Transient
|
||||
override val title = R.string.homework_title
|
||||
|
||||
@Transient
|
||||
override val destinationType = Destination.Type.HOMEWORK
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class NoteAppMenuItem(override var order: Int = 7) : AppMenuItem() {
|
||||
|
||||
@Transient
|
||||
override val icon = R.drawable.ic_more_note
|
||||
|
||||
@Transient
|
||||
override val title = R.string.note_title
|
||||
|
||||
@Transient
|
||||
override val destinationType = Destination.Type.NOTE
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class LuckyNumberAppMenuItem(override var order: Int = 8) : AppMenuItem() {
|
||||
|
||||
@Transient
|
||||
override val icon = R.drawable.ic_more_lucky_number
|
||||
|
||||
@Transient
|
||||
override val title = R.string.lucky_number_title
|
||||
|
||||
@Transient
|
||||
override val destinationType = Destination.Type.LUCKY_NUMBER
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class ConferenceAppMenuItem(override var order: Int = 9) : AppMenuItem() {
|
||||
|
||||
@Transient
|
||||
override val icon = R.drawable.ic_more_conferences
|
||||
|
||||
@Transient
|
||||
override val title = R.string.conferences_title
|
||||
|
||||
@Transient
|
||||
override val destinationType = Destination.Type.CONFERENCE
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class SchoolAnnouncementsAppMenuItem(override var order: Int = 10) : AppMenuItem() {
|
||||
|
||||
@Transient
|
||||
override val icon = R.drawable.ic_all_about
|
||||
|
||||
@Transient
|
||||
override val title = R.string.school_announcement_title
|
||||
|
||||
@Transient
|
||||
override val destinationType = Destination.Type.SCHOOL_ANNOUNCEMENT
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class SchoolAndTeachersAppMenuItem(override var order: Int = 11) : AppMenuItem() {
|
||||
|
||||
@Transient
|
||||
override val icon = R.drawable.ic_more_schoolandteachers
|
||||
|
||||
@Transient
|
||||
override val title = R.string.schoolandteachers_title
|
||||
|
||||
@Transient
|
||||
override val destinationType = Destination.Type.SCHOOL_AND_TEACHERS
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class MobileDevicesAppMenuItem(override var order: Int = 12) : AppMenuItem() {
|
||||
|
||||
@Transient
|
||||
override val icon = R.drawable.ic_more_mobile_devices
|
||||
|
||||
@Transient
|
||||
override val title = R.string.mobile_devices_title
|
||||
|
||||
@Transient
|
||||
override val destinationType = Destination.Type.MOBILE_DEVICE
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package io.github.wulkanowy.ui.modules.settings.appearance.menuorder
|
||||
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import java.util.*
|
||||
|
||||
class MenuItemMoveCallback(
|
||||
private val menuOrderAdapter: MenuOrderAdapter,
|
||||
private var onUserInteractionEndListener: (List<MenuOrderItem>) -> Unit = {}
|
||||
) : ItemTouchHelper.Callback() {
|
||||
|
||||
override fun isLongPressDragEnabled() = true
|
||||
|
||||
override fun isItemViewSwipeEnabled() = false
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
|
||||
//Not implemented
|
||||
}
|
||||
|
||||
override fun getMovementFlags(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder
|
||||
) = makeMovementFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0)
|
||||
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder
|
||||
): Boolean {
|
||||
val list = menuOrderAdapter.items.toMutableList()
|
||||
|
||||
Collections.swap(list, viewHolder.bindingAdapterPosition, target.bindingAdapterPosition)
|
||||
|
||||
menuOrderAdapter.submitList(list)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
|
||||
super.clearView(recyclerView, viewHolder)
|
||||
|
||||
onUserInteractionEndListener(menuOrderAdapter.items.toList())
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,58 @@
|
||||
package io.github.wulkanowy.ui.modules.settings.appearance.menuorder
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.github.wulkanowy.databinding.ItemMenuOrderBinding
|
||||
import javax.inject.Inject
|
||||
|
||||
class MenuOrderAdapter @Inject constructor() :
|
||||
RecyclerView.Adapter<MenuOrderAdapter.ViewHolder>() {
|
||||
|
||||
val items = mutableListOf<MenuOrderItem>()
|
||||
|
||||
fun submitList(newItems: List<MenuOrderItem>) {
|
||||
val diffResult = DiffUtil.calculateDiff(DiffCallback(newItems, items.toMutableList()))
|
||||
|
||||
with(items) {
|
||||
clear()
|
||||
addAll(newItems)
|
||||
}
|
||||
|
||||
diffResult.dispatchUpdatesTo(this)
|
||||
}
|
||||
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
|
||||
ItemMenuOrderBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
)
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item = items[position].appMenuItem
|
||||
|
||||
with(holder.binding) {
|
||||
menuOrderItemTitle.setText(item.title)
|
||||
menuOrderItemIcon.setImageResource(item.icon)
|
||||
}
|
||||
}
|
||||
|
||||
class ViewHolder(val binding: ItemMenuOrderBinding) : RecyclerView.ViewHolder(binding.root)
|
||||
|
||||
private class DiffCallback(
|
||||
private val oldList: List<MenuOrderItem>,
|
||||
private val newList: List<MenuOrderItem>
|
||||
) : DiffUtil.Callback() {
|
||||
|
||||
override fun getNewListSize() = newList.size
|
||||
|
||||
override fun getOldListSize() = oldList.size
|
||||
|
||||
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) =
|
||||
oldList[oldItemPosition] == newList[newItemPosition]
|
||||
|
||||
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) =
|
||||
oldList[oldItemPosition].appMenuItem.destinationType == newList[newItemPosition].appMenuItem.destinationType
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package io.github.wulkanowy.ui.modules.settings.appearance.menuorder
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Rect
|
||||
import android.graphics.drawable.ShapeDrawable
|
||||
import android.view.View
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.core.view.forEach
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||
|
||||
class MenuOrderDividerItemDecoration(private val context: Context) :
|
||||
DividerItemDecoration(context, VERTICAL) {
|
||||
|
||||
private val dividerDrawable = ShapeDrawable()
|
||||
.apply {
|
||||
DrawableCompat.setTint(this, context.getThemeAttrColor(R.attr.colorDivider))
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
|
||||
canvas.save()
|
||||
val dividerLeft = parent.paddingLeft
|
||||
val dividerRight = parent.width - parent.paddingRight
|
||||
|
||||
parent.forEach {
|
||||
if (parent.getChildAdapterPosition(it) == 3) {
|
||||
val params = it.layoutParams as RecyclerView.LayoutParams
|
||||
val dividerTop = it.bottom + params.bottomMargin
|
||||
val dividerBottom = dividerTop + dividerDrawable.intrinsicHeight
|
||||
|
||||
dividerDrawable.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom + 30)
|
||||
dividerDrawable.draw(canvas)
|
||||
}
|
||||
}
|
||||
|
||||
canvas.restore()
|
||||
}
|
||||
|
||||
override fun getItemOffsets(
|
||||
outRect: Rect, view: View, parent: RecyclerView,
|
||||
state: RecyclerView.State
|
||||
) {
|
||||
if (parent.getChildAdapterPosition(view) == 3) {
|
||||
outRect.bottom = dividerDrawable.intrinsicHeight + 30
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
package io.github.wulkanowy.ui.modules.settings.appearance.menuorder
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.activity.addCallback
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.databinding.FragmentMenuOrderBinding
|
||||
import io.github.wulkanowy.ui.base.BaseFragment
|
||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||
import io.github.wulkanowy.ui.modules.main.MainView
|
||||
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MenuOrderFragment : BaseFragment<FragmentMenuOrderBinding>(R.layout.fragment_menu_order),
|
||||
MenuOrderView, MainView.TitledView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: MenuOrderPresenter
|
||||
|
||||
@Inject
|
||||
lateinit var menuOrderAdapter: MenuOrderAdapter
|
||||
|
||||
override val titleStringId = R.string.menu_order_title
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding = FragmentMenuOrderBinding.bind(view)
|
||||
presenter.onAttachView(this)
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
val itemTouchHelper = ItemTouchHelper(
|
||||
MenuItemMoveCallback(menuOrderAdapter, presenter::onDragAndDropEnd)
|
||||
)
|
||||
|
||||
itemTouchHelper.attachToRecyclerView(binding.menuOrderRecycler)
|
||||
|
||||
with(binding.menuOrderRecycler) {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
adapter = menuOrderAdapter
|
||||
addItemDecoration(MenuOrderDividerItemDecoration(context))
|
||||
addItemDecoration(DividerItemDecoration(context))
|
||||
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
|
||||
}
|
||||
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
presenter.onBackSelected()
|
||||
}
|
||||
|
||||
initializeToolbar()
|
||||
}
|
||||
|
||||
private fun initializeToolbar() {
|
||||
requireActivity().addMenuProvider(object : MenuProvider {
|
||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||
}
|
||||
|
||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||
if (menuItem.itemId == android.R.id.home) {
|
||||
presenter.onBackSelected()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
}, viewLifecycleOwner)
|
||||
}
|
||||
|
||||
override fun updateData(data: List<MenuOrderItem>) {
|
||||
menuOrderAdapter.submitList(data)
|
||||
}
|
||||
|
||||
override fun restartApp() {
|
||||
startActivity(MainActivity.getStartIntent(requireContext()))
|
||||
requireActivity().finishAffinity()
|
||||
}
|
||||
|
||||
override fun popView() {
|
||||
(activity as? MainActivity?)?.popView()
|
||||
}
|
||||
|
||||
override fun showRestartConfirmationDialog() {
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.menu_order_confirm_title)
|
||||
.setMessage(R.string.menu_order_confirm_content)
|
||||
.setPositiveButton(R.string.menu_order_confirm_restart) { _, _ -> presenter.onConfirmRestart() }
|
||||
.setNegativeButton(R.string.all_cancel) { _, _ -> presenter.onCancelRestart() }
|
||||
.show()
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package io.github.wulkanowy.ui.modules.settings.appearance.menuorder
|
||||
|
||||
data class MenuOrderItem(
|
||||
val appMenuItem: AppMenuItem,
|
||||
val order: Int
|
||||
)
|
@ -0,0 +1,64 @@
|
||||
package io.github.wulkanowy.ui.modules.settings.appearance.menuorder
|
||||
|
||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class MenuOrderPresenter @Inject constructor(
|
||||
studentRepository: StudentRepository,
|
||||
errorHandler: ErrorHandler,
|
||||
private val preferencesRepository: PreferencesRepository
|
||||
) : BasePresenter<MenuOrderView>(errorHandler, studentRepository) {
|
||||
|
||||
private var updatedMenuOrderItems = emptyList<MenuOrderItem>()
|
||||
|
||||
override fun onAttachView(view: MenuOrderView) {
|
||||
super.onAttachView(view)
|
||||
view.initView()
|
||||
Timber.i("Menu order view was initialized")
|
||||
loadData()
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
val savedMenuItemList = (preferencesRepository.appMenuItemOrder)
|
||||
.sortedBy { it.order }
|
||||
.map { MenuOrderItem(it, it.order) }
|
||||
|
||||
view?.updateData(savedMenuItemList)
|
||||
}
|
||||
|
||||
fun onDragAndDropEnd(list: List<MenuOrderItem>) {
|
||||
val updatedList = list.mapIndexed { index, menuOrderItem ->
|
||||
menuOrderItem.copy(order = index)
|
||||
}
|
||||
|
||||
updatedMenuOrderItems = updatedList
|
||||
view?.updateData(updatedList)
|
||||
}
|
||||
|
||||
fun onBackSelected() {
|
||||
if (updatedMenuOrderItems.isNotEmpty()) {
|
||||
view?.showRestartConfirmationDialog()
|
||||
} else {
|
||||
view?.popView()
|
||||
}
|
||||
}
|
||||
|
||||
fun onConfirmRestart() {
|
||||
updatedMenuOrderItems.forEach {
|
||||
it.appMenuItem.apply {
|
||||
order = it.order
|
||||
}
|
||||
}
|
||||
|
||||
preferencesRepository.appMenuItemOrder = updatedMenuOrderItems.map { it.appMenuItem }
|
||||
view?.restartApp()
|
||||
}
|
||||
|
||||
fun onCancelRestart() {
|
||||
view?.popView()
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package io.github.wulkanowy.ui.modules.settings.appearance.menuorder
|
||||
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface MenuOrderView : BaseView {
|
||||
|
||||
fun initView()
|
||||
|
||||
fun updateData(data: List<MenuOrderItem>)
|
||||
|
||||
fun restartApp()
|
||||
|
||||
fun showRestartConfirmationDialog()
|
||||
|
||||
fun popView()
|
||||
}
|
10
app/src/main/res/drawable/ic_menu_order_drag.xml
Normal file
10
app/src/main/res/drawable/ic_menu_order_drag.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector android:height="24dp"
|
||||
android:tint="#000000"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:width="24dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M20,9H4v2h16V9zM4,15h16v-2H4v2z" />
|
||||
</vector>
|
12
app/src/main/res/layout/fragment_menu_order.xml
Normal file
12
app/src/main/res/layout/fragment_menu_order.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/menu_order_recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:listitem="@layout/item_menu_order" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
46
app/src/main/res/layout/item_menu_order.xml
Normal file
46
app/src/main/res/layout/item_menu_order.xml
Normal file
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?colorSurface"
|
||||
android:minHeight="56dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/menu_order_item_icon"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginStart="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tint="?colorOnSurface"
|
||||
tools:ignore="ContentDescription"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/menu_order_item_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/menu_order_item_drag_icon"
|
||||
app:layout_constraintStart_toEndOf="@id/menu_order_item_icon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="@tools:sample/lorem" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/menu_order_item_drag_icon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:src="@drawable/ic_menu_order_drag"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tint="?colorOnSurface"
|
||||
tools:ignore="ContentDescription" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -40,4 +40,5 @@
|
||||
<string name="pref_key_ads_privacy_policy">ads_privacy_policy</string>
|
||||
<string name="pref_key_ads_consent_data_processing">ads_consent_data_processing</string>
|
||||
<string name="pref_key_ads_over_eighteen">ads_over_eighteen</string>
|
||||
<string name="pref_key_menu_order">appearance_menu_order</string>
|
||||
</resources>
|
||||
|
@ -26,6 +26,7 @@
|
||||
<string name="student_info_title">Student info</string>
|
||||
<string name="dashboard_title">Dashboard</string>
|
||||
<string name="notifications_center_title">Notifications center</string>
|
||||
<string name="menu_order_title">Menu configuartion</string>
|
||||
<!--Subtitles-->
|
||||
<string name="grade_subtitle">Semester %1$d, %2$d/%3$d</string>
|
||||
<!--Login-->
|
||||
@ -595,6 +596,7 @@
|
||||
<string name="all_undo">Undo</string>
|
||||
<string name="all_change">Change</string>
|
||||
<string name="all_add_to_calendar">Add to calendar</string>
|
||||
<string name="all_cancel">Cancel</string>
|
||||
<!--Timetable Widget-->
|
||||
<string name="widget_timetable_no_items">No lessons</string>
|
||||
<string name="widget_timetable_theme_title">Choose theme</string>
|
||||
@ -616,6 +618,8 @@
|
||||
<string name="pref_view_grade_color_scheme">Grades color scheme</string>
|
||||
<string name="pref_view_grade_sorting_mode">Subjects sorting</string>
|
||||
<string name="pref_view_app_language">Language</string>
|
||||
<string name="pref_view_menu_order_title">Menu configuration</string>
|
||||
<string name="pref_view_menu_order_summary">Set the order of functions in the menu</string>
|
||||
<string name="pref_notify_header">Notifications</string>
|
||||
<string name="pref_notify_header_other">Other</string>
|
||||
<string name="pref_notify_switch">Show notifications</string>
|
||||
@ -717,6 +721,10 @@
|
||||
<string name="update_download_success">An update has just been downloaded.</string>
|
||||
<string name="update_download_success_button">Restart</string>
|
||||
<string name="update_failed">Update failed! Wulkanowy may not function properly. Consider updating</string>
|
||||
<!--Menu order-->
|
||||
<string name="menu_order_confirm_title">Application restart</string>
|
||||
<string name="menu_order_confirm_content">The application must restart for the changes to be saved</string>
|
||||
<string name="menu_order_confirm_restart">Restart</string>
|
||||
<!--Errors-->
|
||||
<string name="error_no_internet">No internet connection</string>
|
||||
<string name="error_invalid_device_datetime">An error occurred. Check your device clock</string>
|
||||
|
@ -20,23 +20,21 @@
|
||||
app:key="@string/pref_key_app_theme"
|
||||
app:title="@string/pref_view_app_theme"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
<ListPreference
|
||||
app:defaultValue="@string/pref_default_startup"
|
||||
app:entries="@array/startup_tab_entries"
|
||||
app:entryValues="@array/startup_tab_value"
|
||||
<Preference
|
||||
app:fragment="io.github.wulkanowy.ui.modules.settings.appearance.menuorder.MenuOrderFragment"
|
||||
app:iconSpaceReserved="false"
|
||||
app:key="@string/pref_key_start_menu"
|
||||
app:title="@string/pref_view_list"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
app:key="@string/pref_key_menu_order"
|
||||
app:summary="@string/pref_view_menu_order_summary"
|
||||
app:title="@string/pref_view_menu_order_title" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory
|
||||
app:iconSpaceReserved="false"
|
||||
app:title="@string/pref_dashboard_appearance_header">
|
||||
<MultiSelectListPreference
|
||||
app:defaultValue="@array/pref_default_dashboard_tiles"
|
||||
app:entries="@array/dashboard_tile_entries"
|
||||
app:entryValues="@array/dashboard_tile_values"
|
||||
app:iconSpaceReserved="false"
|
||||
app:defaultValue="@array/pref_default_dashboard_tiles"
|
||||
app:key="@string/pref_key_dashboard_tiles"
|
||||
app:title="@string/pref_dashboard_appearance_tiles_title" />
|
||||
</PreferenceCategory>
|
||||
|
@ -46,7 +46,7 @@ class MainPresenterTest {
|
||||
MockKAnnotations.init(this)
|
||||
clearMocks(mainView)
|
||||
|
||||
every { mainView.initView(any(), any()) } just Runs
|
||||
every { mainView.initView(any(), any(), any()) } just Runs
|
||||
presenter = MainPresenter(
|
||||
errorHandler = errorHandler,
|
||||
studentRepository = studentRepository,
|
||||
|
Loading…
x
Reference in New Issue
Block a user