Use view binding instead of kotlin synthetics (#791)

This commit is contained in:
Mikołaj Pich 2020-05-10 10:39:10 +02:00 committed by GitHub
parent ec80f939f1
commit 8eb0c0351b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 1178 additions and 1096 deletions

View File

@ -1,3 +1,3 @@
component_depth: 8
component_depth: 10
languages:
- kotlin

View File

@ -1,7 +1,6 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'com.github.triplet.play'
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
@ -103,10 +102,6 @@ android {
}
}
androidExtensions {
experimental = true
}
play {
serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL") ?: "jan@fakelog.cf"
serviceAccountCredentials = file('key.p12')

View File

@ -11,6 +11,7 @@ import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.viewbinding.ViewBinding
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
import dagger.android.AndroidInjection
@ -20,10 +21,13 @@ import io.github.wulkanowy.R
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.utils.FragmentLifecycleLogger
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.lifecycleAwareVariable
import javax.inject.Inject
abstract class BaseActivity<T : BasePresenter<out BaseView>> : AppCompatActivity(), BaseView,
HasAndroidInjector {
abstract class BaseActivity<T : BasePresenter<out BaseView>, VB : ViewBinding> :
AppCompatActivity(), BaseView, HasAndroidInjector {
protected var binding: VB by lifecycleAwareVariable()
@Inject
lateinit var androidInjector: DispatchingAndroidInjector<Any>

View File

@ -1,9 +1,13 @@
package io.github.wulkanowy.ui.base
import android.widget.Toast
import androidx.viewbinding.ViewBinding
import dagger.android.support.DaggerAppCompatDialogFragment
import io.github.wulkanowy.utils.lifecycleAwareVariable
abstract class BaseDialogFragment : DaggerAppCompatDialogFragment(), BaseView {
abstract class BaseDialogFragment<VB : ViewBinding> : DaggerAppCompatDialogFragment(), BaseView {
protected var binding: VB by lifecycleAwareVariable()
override fun showError(text: String, error: Throwable) {
showMessage(text)
@ -14,11 +18,11 @@ abstract class BaseDialogFragment : DaggerAppCompatDialogFragment(), BaseView {
}
override fun showExpiredDialog() {
(activity as? BaseActivity<*>)?.showExpiredDialog()
(activity as? BaseActivity<*, *>)?.showExpiredDialog()
}
override fun openClearLoginView() {
(activity as? BaseActivity<*>)?.openClearLoginView()
(activity as? BaseActivity<*, *>)?.openClearLoginView()
}
override fun showErrorDetailsDialog(error: Throwable) {

View File

@ -1,12 +1,18 @@
package io.github.wulkanowy.ui.base
import android.view.View
import androidx.annotation.LayoutRes
import androidx.viewbinding.ViewBinding
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
import dagger.android.support.DaggerFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.utils.lifecycleAwareVariable
abstract class BaseFragment : DaggerFragment(), BaseView {
abstract class BaseFragment<VB : ViewBinding>(@LayoutRes layoutId: Int) : DaggerFragment(layoutId),
BaseView {
protected var binding: VB by lifecycleAwareVariable()
protected var messageContainer: View? = null
@ -16,7 +22,7 @@ abstract class BaseFragment : DaggerFragment(), BaseView {
.setAction(R.string.all_details) { if (isAdded) showErrorDetailsDialog(error) }
.show()
} else {
(activity as? BaseActivity<*>)?.showError(text, error)
(activity as? BaseActivity<*, *>)?.showError(text, error)
}
}
@ -28,15 +34,15 @@ abstract class BaseFragment : DaggerFragment(), BaseView {
if (messageContainer != null) {
Snackbar.make(messageContainer!!, text, LENGTH_LONG).show()
} else {
(activity as? BaseActivity<*>)?.showMessage(text)
(activity as? BaseActivity<*, *>)?.showMessage(text)
}
}
override fun showExpiredDialog() {
(activity as? BaseActivity<*>)?.showExpiredDialog()
(activity as? BaseActivity<*, *>)?.showExpiredDialog()
}
override fun openClearLoginView() {
(activity as? BaseActivity<*>)?.openClearLoginView()
(activity as? BaseActivity<*, *>)?.openClearLoginView()
}
}

View File

@ -11,6 +11,7 @@ import android.widget.Toast
import android.widget.Toast.LENGTH_LONG
import androidx.core.content.getSystemService
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.DialogErrorBinding
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
import io.github.wulkanowy.sdk.exception.ServiceUnavailableException
@ -18,7 +19,6 @@ import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.getString
import io.github.wulkanowy.utils.openEmailClient
import io.github.wulkanowy.utils.openInternetBrowser
import kotlinx.android.synthetic.main.dialog_error.*
import java.io.InterruptedIOException
import java.io.PrintWriter
import java.io.StringWriter
@ -26,7 +26,7 @@ import java.net.SocketTimeoutException
import java.net.UnknownHostException
import javax.inject.Inject
class ErrorDialog : BaseDialogFragment() {
class ErrorDialog : BaseDialogFragment<DialogErrorBinding>() {
private lateinit var error: Throwable
@ -52,7 +52,7 @@ class ErrorDialog : BaseDialogFragment() {
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_error, container, false)
return DialogErrorBinding.inflate(inflater).apply { binding = this }.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
@ -62,27 +62,29 @@ class ErrorDialog : BaseDialogFragment() {
error.printStackTrace(PrintWriter(this))
}
errorDialogContent.text = stringWriter.toString()
with(errorDialogHorizontalScroll) {
post { fullScroll(HorizontalScrollView.FOCUS_LEFT) }
}
errorDialogCopy.setOnClickListener {
val clip = ClipData.newPlainText("wulkanowy", stringWriter.toString())
activity?.getSystemService<ClipboardManager>()?.setPrimaryClip(clip)
with(binding) {
errorDialogContent.text = stringWriter.toString()
with(errorDialogHorizontalScroll) {
post { fullScroll(HorizontalScrollView.FOCUS_LEFT) }
}
errorDialogCopy.setOnClickListener {
val clip = ClipData.newPlainText("wulkanowy", stringWriter.toString())
activity?.getSystemService<ClipboardManager>()?.setPrimaryClip(clip)
Toast.makeText(context, R.string.all_copied, LENGTH_LONG).show()
}
errorDialogCancel.setOnClickListener { dismiss() }
errorDialogReport.setOnClickListener { openEmailClient(stringWriter.toString()) }
errorDialogMessage.text = resources.getString(error)
errorDialogReport.isEnabled = when (error) {
is UnknownHostException,
is InterruptedIOException,
is SocketTimeoutException,
is ServiceUnavailableException,
is FeatureDisabledException,
is FeatureNotAvailableException -> false
else -> true
Toast.makeText(context, R.string.all_copied, LENGTH_LONG).show()
}
errorDialogCancel.setOnClickListener { dismiss() }
errorDialogReport.setOnClickListener { openEmailClient(stringWriter.toString()) }
errorDialogMessage.text = resources.getString(error)
errorDialogReport.isEnabled = when (error) {
is UnknownHostException,
is InterruptedIOException,
is SocketTimeoutException,
is ServiceUnavailableException,
is FeatureDisabledException,
is FeatureNotAvailableException -> false
else -> true
}
}
}

View File

@ -2,11 +2,10 @@ package io.github.wulkanowy.ui.modules.about
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.FragmentAboutBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.about.contributor.ContributorFragment
import io.github.wulkanowy.ui.modules.about.license.LicenseFragment
@ -17,10 +16,10 @@ import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.getCompatDrawable
import io.github.wulkanowy.utils.openEmailClient
import io.github.wulkanowy.utils.openInternetBrowser
import kotlinx.android.synthetic.main.fragment_about.*
import javax.inject.Inject
class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
class AboutFragment : BaseFragment<FragmentAboutBinding>(R.layout.fragment_about), AboutView,
MainView.TitledView {
@Inject
lateinit var presenter: AboutPresenter
@ -77,19 +76,16 @@ class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
fun newInstance() = AboutFragment()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_about, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentAboutBinding.bind(view)
presenter.onAttachView(this)
}
override fun initView() {
aboutAdapter.onClickListener = presenter::onItemSelected
with(aboutRecycler) {
with(binding.aboutRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = aboutAdapter
}

View File

@ -1,22 +1,21 @@
package io.github.wulkanowy.ui.modules.about.contributor
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.pojos.Contributor
import io.github.wulkanowy.databinding.FragmentContributorBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.openInternetBrowser
import kotlinx.android.synthetic.main.fragment_creator.*
import javax.inject.Inject
class ContributorFragment : BaseFragment(), ContributorView, MainView.TitledView {
class ContributorFragment : BaseFragment<FragmentContributorBinding>(R.layout.fragment_contributor),
ContributorView, MainView.TitledView {
@Inject
lateinit var presenter: ContributorPresenter
@ -30,23 +29,20 @@ class ContributorFragment : BaseFragment(), ContributorView, MainView.TitledView
fun newInstance() = ContributorFragment()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_creator, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentContributorBinding.bind(view)
presenter.onAttachView(this)
}
override fun initView() {
with(creatorRecycler) {
with(binding.creatorRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = creatorsAdapter
addItemDecoration(DividerItemDecoration(context))
}
creatorsAdapter.onClickListener = presenter::onItemSelected
creatorSeeMore.setOnClickListener { presenter.onSeeMoreClick() }
binding.creatorSeeMore.setOnClickListener { presenter.onSeeMoreClick() }
}
override fun updateData(data: List<Contributor>) {
@ -65,7 +61,7 @@ class ContributorFragment : BaseFragment(), ContributorView, MainView.TitledView
}
override fun showProgress(show: Boolean) {
creatorProgress.visibility = if (show) VISIBLE else GONE
binding.creatorProgress.visibility = if (show) VISIBLE else GONE
}
override fun onDestroyView() {

View File

@ -1,11 +1,9 @@
package io.github.wulkanowy.ui.modules.about.license
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import androidx.core.text.parseAsHtml
import androidx.recyclerview.widget.LinearLayoutManager
@ -13,12 +11,13 @@ import com.mikepenz.aboutlibraries.Libs
import com.mikepenz.aboutlibraries.entity.Library
import dagger.Lazy
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.FragmentLicenseBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainView
import kotlinx.android.synthetic.main.fragment_license.*
import javax.inject.Inject
class LicenseFragment : BaseFragment(), LicenseView, MainView.TitledView {
class LicenseFragment : BaseFragment<FragmentLicenseBinding>(R.layout.fragment_license),
LicenseView, MainView.TitledView {
@Inject
lateinit var presenter: LicensePresenter
@ -40,19 +39,16 @@ class LicenseFragment : BaseFragment(), LicenseView, MainView.TitledView {
fun newInstance() = LicenseFragment()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_license, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentLicenseBinding.bind(view)
presenter.onAttachView(this)
}
override fun initView() {
licenseAdapter.onClickListener = presenter::onItemSelected
with(licenseRecycler) {
with(binding.licenseRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = licenseAdapter
}
@ -77,7 +73,7 @@ class LicenseFragment : BaseFragment(), LicenseView, MainView.TitledView {
}
override fun showProgress(show: Boolean) {
licenseProgress.visibility = if (show) VISIBLE else GONE
binding.licenseProgress.visibility = if (show) VISIBLE else GONE
}
override fun onDestroyView() {

View File

@ -8,23 +8,22 @@ import android.net.Uri
import android.os.Build.VERSION.SDK_INT
import android.os.Build.VERSION_CODES.LOLLIPOP
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.core.content.FileProvider
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.BuildConfig.APPLICATION_ID
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.FragmentLogviewerBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainView
import kotlinx.android.synthetic.main.fragment_logviewer.*
import java.io.File
import javax.inject.Inject
class LogViewerFragment : BaseFragment(), LogViewerView, MainView.TitledView {
class LogViewerFragment : BaseFragment<FragmentLogviewerBinding>(R.layout.fragment_logviewer),
LogViewerView, MainView.TitledView {
@Inject
lateinit var presenter: LogViewerPresenter
@ -43,13 +42,10 @@ class LogViewerFragment : BaseFragment(), LogViewerView, MainView.TitledView {
setHasOptionsMenu(true)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_logviewer, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
messageContainer = logViewerRecycler
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentLogviewerBinding.bind(view)
messageContainer = binding.logViewerRecycler
presenter.onAttachView(this)
}
@ -63,18 +59,18 @@ class LogViewerFragment : BaseFragment(), LogViewerView, MainView.TitledView {
}
override fun initView() {
with(logViewerRecycler) {
with(binding.logViewerRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = logAdapter
}
logViewRefreshButton.setOnClickListener { presenter.onRefreshClick() }
binding.logViewRefreshButton.setOnClickListener { presenter.onRefreshClick() }
}
override fun setLines(lines: List<String>) {
logAdapter.lines = lines
logAdapter.notifyDataSetChanged()
logViewerRecycler.scrollToPosition(lines.size - 1)
binding.logViewerRecycler.scrollToPosition(lines.size - 1)
}
override fun shareLogs(files: List<File>) {

View File

@ -10,12 +10,12 @@ import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.databinding.DialogAccountBinding
import io.github.wulkanowy.ui.base.BaseDialogFragment
import io.github.wulkanowy.ui.modules.login.LoginActivity
import kotlinx.android.synthetic.main.dialog_account.*
import javax.inject.Inject
class AccountDialog : BaseDialogFragment(), AccountView {
class AccountDialog : BaseDialogFragment<DialogAccountBinding>(), AccountView {
@Inject
lateinit var presenter: AccountPresenter
@ -33,7 +33,7 @@ class AccountDialog : BaseDialogFragment(), AccountView {
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_account, container, false)
return DialogAccountBinding.inflate(inflater).apply { binding = this }.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
@ -44,11 +44,13 @@ class AccountDialog : BaseDialogFragment(), AccountView {
override fun initView() {
accountAdapter.onClickListener = presenter::onItemSelected
accountDialogAdd.setOnClickListener { presenter.onAddSelected() }
accountDialogRemove.setOnClickListener { presenter.onRemoveSelected() }
accountDialogRecycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = accountAdapter
with(binding) {
accountDialogAdd.setOnClickListener { presenter.onAddSelected() }
accountDialogRemove.setOnClickListener { presenter.onRemoveSelected() }
accountDialogRecycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = accountAdapter
}
}
}

View File

@ -5,13 +5,15 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.databinding.DialogAttendanceBinding
import io.github.wulkanowy.utils.lifecycleAwareVariable
import io.github.wulkanowy.utils.toFormattedString
import kotlinx.android.synthetic.main.dialog_attendance.*
class AttendanceDialog : DialogFragment() {
private var binding: DialogAttendanceBinding by lifecycleAwareVariable()
private lateinit var attendance: Attendance
companion object {
@ -33,16 +35,18 @@ class AttendanceDialog : DialogFragment() {
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_attendance, container, false)
return DialogAttendanceBinding.inflate(inflater).apply { binding = this }.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
attendanceDialogSubject.text = attendance.subject
attendanceDialogDescription.text = attendance.name
attendanceDialogDate.text = attendance.date.toFormattedString()
attendanceDialogNumber.text = attendance.number.toString()
attendanceDialogClose.setOnClickListener { dismiss() }
with(binding) {
attendanceDialogSubject.text = attendance.subject
attendanceDialogDescription.text = attendance.name
attendanceDialogDate.text = attendance.date.toFormattedString()
attendanceDialogNumber.text = attendance.number.toString()
attendanceDialogClose.setOnClickListener { dismiss() }
}
}
}

View File

@ -10,13 +10,14 @@ import android.view.View
import android.view.View.GONE
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.view.ActionMode
import androidx.recyclerview.widget.LinearLayoutManager
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.databinding.DialogExcuseBinding
import io.github.wulkanowy.databinding.FragmentAttendanceBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragment
@ -24,12 +25,10 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.SchooldaysRangeLimiter
import io.github.wulkanowy.utils.dpToPx
import kotlinx.android.synthetic.main.dialog_excuse.*
import kotlinx.android.synthetic.main.fragment_attendance.*
import org.threeten.bp.LocalDate
import javax.inject.Inject
class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildView,
class AttendanceFragment : BaseFragment<FragmentAttendanceBinding>(R.layout.fragment_attendance), AttendanceView, MainView.MainChildView,
MainView.TitledView {
@Inject
@ -89,13 +88,10 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie
setHasOptionsMenu(true)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_attendance, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
messageContainer = attendanceRecycler
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentAttendanceBinding.bind(view)
messageContainer = binding.attendanceRecycler
presenter.onAttachView(this, savedInstanceState?.getLong(SAVED_DATE_KEY))
}
@ -105,23 +101,25 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie
onExcuseCheckboxSelect = presenter::onExcuseCheckboxSelect
}
with(attendanceRecycler) {
with(binding.attendanceRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = attendanceAdapter
addItemDecoration(DividerItemDecoration(context))
}
attendanceSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
attendanceErrorRetry.setOnClickListener { presenter.onRetry() }
attendanceErrorDetails.setOnClickListener { presenter.onDetailsClick() }
with(binding) {
attendanceSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
attendanceErrorRetry.setOnClickListener { presenter.onRetry() }
attendanceErrorDetails.setOnClickListener { presenter.onDetailsClick() }
attendancePreviousButton.setOnClickListener { presenter.onPreviousDay() }
attendanceNavDate.setOnClickListener { presenter.onPickDate() }
attendanceNextButton.setOnClickListener { presenter.onNextDay() }
attendancePreviousButton.setOnClickListener { presenter.onPreviousDay() }
attendanceNavDate.setOnClickListener { presenter.onPickDate() }
attendanceNextButton.setOnClickListener { presenter.onNextDay() }
attendanceExcuseButton.setOnClickListener { presenter.onExcuseButtonClick() }
attendanceExcuseButton.setOnClickListener { presenter.onExcuseButtonClick() }
attendanceNavContainer.setElevationCompat(requireContext().dpToPx(8f))
attendanceNavContainer.setElevationCompat(requireContext().dpToPx(8f))
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
@ -141,7 +139,7 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie
}
override fun updateNavigationDay(date: String) {
attendanceNavDate.text = date
binding.attendanceNavDate.text = date
}
override fun clearData() {
@ -152,7 +150,7 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie
}
override fun resetView() {
attendanceRecycler.smoothScrollToPosition(0)
binding.attendanceRecycler.smoothScrollToPosition(0)
}
override fun onFragmentReselected() {
@ -168,43 +166,43 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie
}
override fun showEmpty(show: Boolean) {
attendanceEmpty.visibility = if (show) VISIBLE else GONE
binding.attendanceEmpty.visibility = if (show) VISIBLE else GONE
}
override fun showErrorView(show: Boolean) {
attendanceError.visibility = if (show) VISIBLE else GONE
binding.attendanceError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
attendanceErrorMessage.text = message
binding.attendanceErrorMessage.text = message
}
override fun showProgress(show: Boolean) {
attendanceProgress.visibility = if (show) VISIBLE else GONE
binding.attendanceProgress.visibility = if (show) VISIBLE else GONE
}
override fun enableSwipe(enable: Boolean) {
attendanceSwipe.isEnabled = enable
binding.attendanceSwipe.isEnabled = enable
}
override fun showContent(show: Boolean) {
attendanceRecycler.visibility = if (show) VISIBLE else GONE
binding. attendanceRecycler.visibility = if (show) VISIBLE else GONE
}
override fun hideRefresh() {
attendanceSwipe.isRefreshing = false
binding.attendanceSwipe.isRefreshing = false
}
override fun showPreButton(show: Boolean) {
attendancePreviousButton.visibility = if (show) VISIBLE else INVISIBLE
binding.attendancePreviousButton.visibility = if (show) VISIBLE else INVISIBLE
}
override fun showNextButton(show: Boolean) {
attendanceNextButton.visibility = if (show) VISIBLE else INVISIBLE
binding. attendanceNextButton.visibility = if (show) VISIBLE else INVISIBLE
}
override fun showExcuseButton(show: Boolean) {
attendanceExcuseButton.visibility = if (show) VISIBLE else GONE
binding.attendanceExcuseButton.visibility = if (show) VISIBLE else GONE
}
override fun showAttendanceDialog(lesson: Attendance) {
@ -227,14 +225,15 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie
}
override fun showExcuseDialog() {
val dialogBinding = DialogExcuseBinding.inflate(LayoutInflater.from(context))
AlertDialog.Builder(requireContext())
.setTitle(R.string.attendance_excuse_title)
.setView(R.layout.dialog_excuse)
.setView(dialogBinding.root)
.setNegativeButton(android.R.string.cancel) { _, _ -> }
.create()
.apply {
setButton(BUTTON_POSITIVE, getString(R.string.attendance_excuse_dialog_submit)) { _, _ ->
presenter.onExcuseDialogSubmit(excuseReason.text?.toString().orEmpty())
presenter.onExcuseDialogSubmit(dialogBinding.excuseReason.text?.toString().orEmpty())
}
}.show()
}

View File

@ -23,7 +23,7 @@ class AttendanceSummaryAdapter @Inject constructor() :
var items = emptyList<AttendanceSummary>()
override fun getItemCount() = items.size + 2
override fun getItemCount() = if (items.isNotEmpty()) items.size + 2 else 0
override fun getItemViewType(position: Int) = when (position) {
0 -> ViewType.HEADER.id

View File

@ -1,25 +1,25 @@
package io.github.wulkanowy.ui.modules.attendance.summary
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.AttendanceSummary
import io.github.wulkanowy.databinding.FragmentAttendanceSummaryBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.setOnItemSelectedListener
import kotlinx.android.synthetic.main.fragment_attendance_summary.*
import javax.inject.Inject
class AttendanceSummaryFragment : BaseFragment(), AttendanceSummaryView, MainView.TitledView {
class AttendanceSummaryFragment :
BaseFragment<FragmentAttendanceSummaryBinding>(R.layout.fragment_attendance_summary),
AttendanceSummaryView, MainView.TitledView {
@Inject
lateinit var presenter: AttendanceSummaryPresenter
@ -39,35 +39,34 @@ class AttendanceSummaryFragment : BaseFragment(), AttendanceSummaryView, MainVie
override val isViewEmpty get() = attendanceSummaryAdapter.items.isEmpty()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_attendance_summary, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
messageContainer = attendanceSummaryRecycler
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentAttendanceSummaryBinding.bind(view)
messageContainer = binding.attendanceSummaryRecycler
presenter.onAttachView(this, savedInstanceState?.getInt(SAVED_SUBJECT_KEY))
}
override fun initView() {
with(attendanceSummaryRecycler) {
with(binding.attendanceSummaryRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = attendanceSummaryAdapter
}
attendanceSummarySwipe.setOnRefreshListener(presenter::onSwipeRefresh)
attendanceSummaryErrorRetry.setOnClickListener { presenter.onRetry() }
attendanceSummaryErrorDetails.setOnClickListener { presenter.onDetailsClick() }
with(binding) {
attendanceSummarySwipe.setOnRefreshListener(presenter::onSwipeRefresh)
attendanceSummaryErrorRetry.setOnClickListener { presenter.onRetry() }
attendanceSummaryErrorDetails.setOnClickListener { presenter.onDetailsClick() }
}
subjectsAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, mutableListOf())
subjectsAdapter.setDropDownViewResource(R.layout.item_attendance_summary_subject)
with(attendanceSummarySubjects) {
with(binding.attendanceSummarySubjects) {
adapter = subjectsAdapter
setOnItemSelectedListener<TextView> { presenter.onSubjectSelected(it?.text?.toString()) }
}
attendanceSummarySubjectsContainer.setElevationCompat(requireContext().dpToPx(1f))
binding.attendanceSummarySubjectsContainer.setElevationCompat(requireContext().dpToPx(1f))
}
override fun updateSubjects(data: ArrayList<String>) {
@ -93,35 +92,35 @@ class AttendanceSummaryFragment : BaseFragment(), AttendanceSummaryView, MainVie
}
override fun showEmpty(show: Boolean) {
attendanceSummaryEmpty.visibility = if (show) VISIBLE else GONE
binding.attendanceSummaryEmpty.visibility = if (show) VISIBLE else GONE
}
override fun showErrorView(show: Boolean) {
attendanceSummaryError.visibility = if (show) VISIBLE else GONE
binding.attendanceSummaryError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
attendanceSummaryErrorMessage.text = message
binding.attendanceSummaryErrorMessage.text = message
}
override fun showProgress(show: Boolean) {
attendanceSummaryProgress.visibility = if (show) VISIBLE else GONE
binding.attendanceSummaryProgress.visibility = if (show) VISIBLE else GONE
}
override fun enableSwipe(enable: Boolean) {
attendanceSummarySwipe.isEnabled = enable
binding.attendanceSummarySwipe.isEnabled = enable
}
override fun showContent(show: Boolean) {
attendanceSummaryRecycler.visibility = if (show) VISIBLE else GONE
binding.attendanceSummaryRecycler.visibility = if (show) VISIBLE else GONE
}
override fun showSubjects(show: Boolean) {
attendanceSummarySubjectsContainer.visibility = if (show) VISIBLE else INVISIBLE
binding.attendanceSummarySubjectsContainer.visibility = if (show) VISIBLE else INVISIBLE
}
override fun hideRefresh() {
attendanceSummarySwipe.isRefreshing = false
binding.attendanceSummarySwipe.isRefreshing = false
}
override fun onSaveInstanceState(outState: Bundle) {
@ -130,7 +129,7 @@ class AttendanceSummaryFragment : BaseFragment(), AttendanceSummaryView, MainVie
}
override fun onDestroyView() {
super.onDestroyView()
presenter.onDetachView()
super.onDestroyView()
}
}

View File

@ -5,13 +5,15 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.databinding.DialogExamBinding
import io.github.wulkanowy.utils.lifecycleAwareVariable
import io.github.wulkanowy.utils.toFormattedString
import kotlinx.android.synthetic.main.dialog_exam.*
class ExamDialog : DialogFragment() {
private var binding: DialogExamBinding by lifecycleAwareVariable()
private lateinit var exam: Exam
companion object {
@ -33,18 +35,20 @@ class ExamDialog : DialogFragment() {
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_exam, container, false)
return DialogExamBinding.inflate(inflater).apply { binding = this }.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
examDialogSubjectValue.text = exam.subject
examDialogTypeValue.text = exam.type
examDialogTeacherValue.text = exam.teacher
examDialogDateValue.text = exam.entryDate.toFormattedString()
examDialogDescriptionValue.text = exam.description
with(binding) {
examDialogSubjectValue.text = exam.subject
examDialogTypeValue.text = exam.type
examDialogTeacherValue.text = exam.teacher
examDialogDateValue.text = exam.entryDate.toFormattedString()
examDialogDescriptionValue.text = exam.description
examDialogClose.setOnClickListener { dismiss() }
examDialogClose.setOnClickListener { dismiss() }
}
}
}

View File

@ -1,24 +1,23 @@
package io.github.wulkanowy.ui.modules.exam
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.databinding.FragmentExamBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.dpToPx
import kotlinx.android.synthetic.main.fragment_exam.*
import javax.inject.Inject
class ExamFragment : BaseFragment(), ExamView, MainView.MainChildView, MainView.TitledView {
class ExamFragment : BaseFragment<FragmentExamBinding>(R.layout.fragment_exam), ExamView,
MainView.MainChildView, MainView.TitledView {
@Inject
lateinit var presenter: ExamPresenter
@ -36,37 +35,36 @@ class ExamFragment : BaseFragment(), ExamView, MainView.MainChildView, MainView.
override val isViewEmpty get() = examAdapter.items.isEmpty()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_exam, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
messageContainer = examRecycler
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentExamBinding.bind(view)
messageContainer = binding.examRecycler
presenter.onAttachView(this, savedInstanceState?.getLong(SAVED_DATE_KEY))
}
override fun initView() {
examAdapter.onClickListener = presenter::onExamItemSelected
with(examRecycler) {
with(binding.examRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = examAdapter
addItemDecoration(DividerItemDecoration(context))
}
examSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
examErrorRetry.setOnClickListener { presenter.onRetry() }
examErrorDetails.setOnClickListener { presenter.onDetailsClick() }
with(binding) {
examSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
examErrorRetry.setOnClickListener { presenter.onRetry() }
examErrorDetails.setOnClickListener { presenter.onDetailsClick() }
examPreviousButton.setOnClickListener { presenter.onPreviousWeek() }
examNextButton.setOnClickListener { presenter.onNextWeek() }
examPreviousButton.setOnClickListener { presenter.onPreviousWeek() }
examNextButton.setOnClickListener { presenter.onNextWeek() }
examNavContainer.setElevationCompat(requireContext().dpToPx(8f))
examNavContainer.setElevationCompat(requireContext().dpToPx(8f))
}
}
override fun hideRefresh() {
examSwipe.isRefreshing = false
binding.examSwipe.isRefreshing = false
}
override fun updateData(data: List<ExamItem<*>>) {
@ -77,7 +75,7 @@ class ExamFragment : BaseFragment(), ExamView, MainView.MainChildView, MainView.
}
override fun updateNavigationWeek(date: String) {
examNavDate.text = date
binding.examNavDate.text = date
}
override fun clearData() {
@ -88,7 +86,7 @@ class ExamFragment : BaseFragment(), ExamView, MainView.MainChildView, MainView.
}
override fun resetView() {
examRecycler.scrollToPosition(0)
binding.examRecycler.scrollToPosition(0)
}
override fun onFragmentReselected() {
@ -96,35 +94,35 @@ class ExamFragment : BaseFragment(), ExamView, MainView.MainChildView, MainView.
}
override fun showEmpty(show: Boolean) {
examEmpty.visibility = if (show) VISIBLE else GONE
binding.examEmpty.visibility = if (show) VISIBLE else GONE
}
override fun showErrorView(show: Boolean) {
examError.visibility = if (show) VISIBLE else GONE
binding.examError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
examErrorMessage.text = message
binding.examErrorMessage.text = message
}
override fun showProgress(show: Boolean) {
examProgress.visibility = if (show) VISIBLE else GONE
binding.examProgress.visibility = if (show) VISIBLE else GONE
}
override fun enableSwipe(enable: Boolean) {
examSwipe.isEnabled = enable
binding.examSwipe.isEnabled = enable
}
override fun showContent(show: Boolean) {
examRecycler.visibility = if (show) VISIBLE else GONE
binding.examRecycler.visibility = if (show) VISIBLE else GONE
}
override fun showPreButton(show: Boolean) {
examPreviousButton.visibility = if (show) VISIBLE else INVISIBLE
binding.examPreviousButton.visibility = if (show) VISIBLE else INVISIBLE
}
override fun showNextButton(show: Boolean) {
examNextButton.visibility = if (show) VISIBLE else INVISIBLE
binding.examNextButton.visibility = if (show) VISIBLE else INVISIBLE
}
override fun showExamDialog(exam: Exam) {

View File

@ -1,16 +1,15 @@
package io.github.wulkanowy.ui.modules.grade
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.FragmentGradeBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.modules.grade.details.GradeDetailsFragment
@ -19,10 +18,9 @@ import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.setOnSelectPageListener
import kotlinx.android.synthetic.main.fragment_grade.*
import javax.inject.Inject
class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainView.TitledView {
class GradeFragment : BaseFragment<FragmentGradeBinding>(R.layout.fragment_grade), GradeView, MainView.MainChildView, MainView.TitledView {
@Inject
lateinit var presenter: GradePresenter
@ -42,19 +40,16 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainVie
override var subtitleString = ""
override val currentPageIndex get() = gradeViewPager.currentItem
override val currentPageIndex get() = binding.gradeViewPager.currentItem
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_grade, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentGradeBinding.bind(view)
presenter.onAttachView(this, savedInstanceState?.getInt(SAVED_SEMESTER_KEY))
}
@ -66,7 +61,7 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainVie
override fun initView() {
with(pagerAdapter) {
containerId = gradeViewPager.id
containerId = binding.gradeViewPager.id
addFragmentsWithTitle(mapOf(
GradeDetailsFragment.newInstance() to getString(R.string.all_details),
GradeSummaryFragment.newInstance() to getString(R.string.grade_menu_summary),
@ -74,19 +69,21 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainVie
))
}
with(gradeViewPager) {
with(binding.gradeViewPager) {
adapter = pagerAdapter
offscreenPageLimit = 3
setOnSelectPageListener(presenter::onPageSelected)
}
with(gradeTabLayout) {
setupWithViewPager(gradeViewPager)
with(binding.gradeTabLayout) {
setupWithViewPager(binding.gradeViewPager)
setElevationCompat(context.dpToPx(4f))
}
gradeErrorRetry.setOnClickListener { presenter.onRetry() }
gradeErrorDetails.setOnClickListener { presenter.onDetailsClick() }
with(binding) {
gradeErrorRetry.setOnClickListener { presenter.onRetry() }
gradeErrorDetails.setOnClickListener { presenter.onDetailsClick() }
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
@ -99,20 +96,22 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainVie
}
override fun showContent(show: Boolean) {
gradeViewPager.visibility = if (show) VISIBLE else INVISIBLE
gradeTabLayout.visibility = if (show) VISIBLE else INVISIBLE
with(binding) {
gradeViewPager.visibility = if (show) VISIBLE else INVISIBLE
gradeTabLayout.visibility = if (show) VISIBLE else INVISIBLE
}
}
override fun showProgress(show: Boolean) {
gradeProgress.visibility = if (show) VISIBLE else INVISIBLE
binding.gradeProgress.visibility = if (show) VISIBLE else INVISIBLE
}
override fun showErrorView(show: Boolean) {
gradeError.visibility = if (show) VISIBLE else INVISIBLE
binding.gradeError.visibility = if (show) VISIBLE else INVISIBLE
}
override fun setErrorDetails(message: String) {
gradeErrorMessage.text = message
binding.gradeErrorMessage.text = message
}
override fun showSemesterSwitch(show: Boolean) {
@ -166,7 +165,7 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainVie
}
override fun onDestroyView() {
super.onDestroyView()
presenter.onDetachView()
super.onDestroyView()
}
}

View File

@ -8,14 +8,17 @@ import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.databinding.DialogGradeBinding
import io.github.wulkanowy.utils.colorStringId
import io.github.wulkanowy.utils.getBackgroundColor
import io.github.wulkanowy.utils.getGradeColor
import io.github.wulkanowy.utils.lifecycleAwareVariable
import io.github.wulkanowy.utils.toFormattedString
import kotlinx.android.synthetic.main.dialog_grade.*
class GradeDetailsDialog : DialogFragment() {
private var binding: DialogGradeBinding by lifecycleAwareVariable()
private lateinit var grade: Grade
private lateinit var colorScheme: String
@ -44,47 +47,49 @@ class GradeDetailsDialog : DialogFragment() {
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_grade, container, false)
return DialogGradeBinding.inflate(inflater).apply { binding = this }.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
gradeDialogSubject.text = grade.subject
with(binding) {
gradeDialogSubject.text = grade.subject
gradeDialogColorAndWeightValue.run {
text = context.getString(R.string.grade_weight_value, grade.weight)
setBackgroundResource(grade.getGradeColor())
}
gradeDialogDateValue.text = grade.date.toFormattedString()
gradeDialogColorValue.text = getString(grade.colorStringId)
gradeDialogCommentValue.apply {
if (grade.comment.isBlank()) {
visibility = GONE
gradeDialogComment.visibility = GONE
} else text = grade.comment
}
gradeDialogValue.run {
text = grade.entry
setBackgroundResource(grade.getBackgroundColor(colorScheme))
}
gradeDialogTeacherValue.text = if (grade.teacher.isBlank()) {
getString(R.string.all_no_data)
} else grade.teacher
gradeDialogDescriptionValue.text = grade.run {
when {
description.isBlank() && gradeSymbol.isNotBlank() -> gradeSymbol
description.isBlank() && gradeSymbol.isBlank() -> getString(R.string.all_no_description)
gradeSymbol.isNotBlank() && description.isNotBlank() -> "$gradeSymbol - $description"
else -> description
gradeDialogColorAndWeightValue.run {
text = context.getString(R.string.grade_weight_value, grade.weight)
setBackgroundResource(grade.getGradeColor())
}
}
gradeDialogClose.setOnClickListener { dismiss() }
gradeDialogDateValue.text = grade.date.toFormattedString()
gradeDialogColorValue.text = getString(grade.colorStringId)
gradeDialogCommentValue.apply {
if (grade.comment.isBlank()) {
visibility = GONE
gradeDialogComment.visibility = GONE
} else text = grade.comment
}
gradeDialogValue.run {
text = grade.entry
setBackgroundResource(grade.getBackgroundColor(colorScheme))
}
gradeDialogTeacherValue.text = if (grade.teacher.isBlank()) {
getString(R.string.all_no_data)
} else grade.teacher
gradeDialogDescriptionValue.text = grade.run {
when {
description.isBlank() && gradeSymbol.isNotBlank() -> gradeSymbol
description.isBlank() && gradeSymbol.isBlank() -> getString(R.string.all_no_description)
gradeSymbol.isNotBlank() && description.isNotBlank() -> "$gradeSymbol - $description"
else -> description
}
}
gradeDialogClose.setOnClickListener { dismiss() }
}
}
}

View File

@ -1,7 +1,6 @@
package io.github.wulkanowy.ui.modules.grade.details
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
@ -9,18 +8,19 @@ import android.view.View
import android.view.View.GONE
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.databinding.FragmentGradeDetailsBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.grade.GradeFragment
import io.github.wulkanowy.ui.modules.grade.GradeView
import io.github.wulkanowy.ui.modules.main.MainActivity
import kotlinx.android.synthetic.main.fragment_grade_details.*
import javax.inject.Inject
class GradeDetailsFragment : BaseFragment(), GradeDetailsView, GradeView.GradeChildView {
class GradeDetailsFragment :
BaseFragment<FragmentGradeDetailsBinding>(R.layout.fragment_grade_details), GradeDetailsView,
GradeView.GradeChildView {
@Inject
lateinit var presenter: GradeDetailsPresenter
@ -42,13 +42,10 @@ class GradeDetailsFragment : BaseFragment(), GradeDetailsView, GradeView.GradeCh
setHasOptionsMenu(true)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_grade_details, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
messageContainer = gradeDetailsRecycler
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentGradeDetailsBinding.bind(view)
messageContainer = binding.gradeDetailsRecycler
presenter.onAttachView(this)
}
@ -61,13 +58,15 @@ class GradeDetailsFragment : BaseFragment(), GradeDetailsView, GradeView.GradeCh
override fun initView() {
gradeDetailsAdapter.onClickListener = presenter::onGradeItemSelected
gradeDetailsRecycler.run {
layoutManager = LinearLayoutManager(context)
adapter = gradeDetailsAdapter
with(binding) {
with(gradeDetailsRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = gradeDetailsAdapter
}
gradeDetailsSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
gradeDetailsErrorRetry.setOnClickListener { presenter.onRetry() }
gradeDetailsErrorDetails.setOnClickListener { presenter.onDetailsClick() }
}
gradeDetailsSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
gradeDetailsErrorRetry.setOnClickListener { presenter.onRetry() }
gradeDetailsErrorDetails.setOnClickListener { presenter.onDetailsClick() }
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
@ -99,7 +98,7 @@ class GradeDetailsFragment : BaseFragment(), GradeDetailsView, GradeView.GradeCh
}
override fun scrollToStart() {
gradeDetailsRecycler.smoothScrollToPosition(0)
binding.gradeDetailsRecycler.smoothScrollToPosition(0)
}
override fun getHeaderOfItem(subject: String): GradeDetailsItem {
@ -111,31 +110,31 @@ class GradeDetailsFragment : BaseFragment(), GradeDetailsView, GradeView.GradeCh
}
override fun showProgress(show: Boolean) {
gradeDetailsProgress.visibility = if (show) VISIBLE else GONE
binding.gradeDetailsProgress.visibility = if (show) VISIBLE else GONE
}
override fun enableSwipe(enable: Boolean) {
gradeDetailsSwipe.isEnabled = enable
binding.gradeDetailsSwipe.isEnabled = enable
}
override fun showContent(show: Boolean) {
gradeDetailsRecycler.visibility = if (show) VISIBLE else INVISIBLE
binding.gradeDetailsRecycler.visibility = if (show) VISIBLE else INVISIBLE
}
override fun showEmpty(show: Boolean) {
gradeDetailsEmpty.visibility = if (show) VISIBLE else INVISIBLE
binding.gradeDetailsEmpty.visibility = if (show) VISIBLE else INVISIBLE
}
override fun showErrorView(show: Boolean) {
gradeDetailsError.visibility = if (show) VISIBLE else GONE
binding.gradeDetailsError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
gradeDetailsErrorMessage.text = message
binding.gradeDetailsErrorMessage.text = message
}
override fun showRefresh(show: Boolean) {
gradeDetailsSwipe.isRefreshing = show
binding.gradeDetailsSwipe.isRefreshing = show
}
override fun showGradeDialog(grade: Grade, colorScheme: String) {
@ -167,7 +166,7 @@ class GradeDetailsFragment : BaseFragment(), GradeDetailsView, GradeView.GradeCh
}
override fun onDestroyView() {
super.onDestroyView()
presenter.onDetachView()
super.onDestroyView()
}
}

View File

@ -2,7 +2,6 @@ package io.github.wulkanowy.ui.modules.grade.statistics
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
@ -21,9 +20,9 @@ import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.data.pojos.GradeStatisticsItem
import io.github.wulkanowy.databinding.ItemGradeStatisticsBarBinding
import io.github.wulkanowy.databinding.ItemGradeStatisticsPieBinding
import io.github.wulkanowy.utils.getThemeAttrColor
import kotlinx.android.synthetic.main.item_grade_statistics_bar.view.*
import kotlinx.android.synthetic.main.item_grade_statistics_pie.view.*
import javax.inject.Inject
class GradeStatisticsAdapter @Inject constructor() :
@ -62,30 +61,26 @@ class GradeStatisticsAdapter @Inject constructor() :
override fun getItemCount() = items.size
override fun getItemViewType(position: Int): Int {
return when (items[position].type) {
ViewType.SEMESTER, ViewType.PARTIAL -> R.layout.item_grade_statistics_pie
ViewType.POINTS -> R.layout.item_grade_statistics_bar
}
}
override fun getItemViewType(position: Int) = items[position].type.id
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val viewHolder = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
val inflater = LayoutInflater.from(parent.context)
return when (viewType) {
R.layout.item_grade_statistics_bar -> GradeStatisticsBar(viewHolder)
else -> GradeStatisticsPie(viewHolder)
ViewType.PARTIAL.id, ViewType.SEMESTER.id -> PieViewHolder(ItemGradeStatisticsPieBinding.inflate(inflater, parent, false))
ViewType.POINTS.id -> BarViewHolder(ItemGradeStatisticsBarBinding.inflate(inflater, parent, false))
else -> throw IllegalStateException()
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is GradeStatisticsPie -> bindPieChart(holder, items[position].partial)
is GradeStatisticsBar -> bindBarChart(holder, items[position].points!!)
is PieViewHolder -> bindPieChart(holder, items[position].partial)
is BarViewHolder -> bindBarChart(holder, items[position].points!!)
}
}
private fun bindPieChart(holder: GradeStatisticsPie, partials: List<GradeStatistics>) {
with(holder.view.gradeStatisticsPieTitle) {
private fun bindPieChart(holder: PieViewHolder, partials: List<GradeStatistics>) {
with(holder.binding.gradeStatisticsPieTitle) {
text = partials.firstOrNull()?.subject
visibility = if (items.size == 1) GONE else VISIBLE
}
@ -105,10 +100,10 @@ class GradeStatisticsAdapter @Inject constructor() :
valueTextColor = Color.WHITE
setColors(partials.map {
gradeColors.single { color -> color.first == it.grade }.second
}.toIntArray(), holder.view.context)
}.toIntArray(), holder.binding.root.context)
}
with(holder.view.gradeStatisticsPie) {
with(holder.binding.gradeStatisticsPie) {
setTouchEnabled(false)
if (partials.size == 1) animateXY(1000, 1000)
data = PieData(dataset).apply {
@ -140,8 +135,8 @@ class GradeStatisticsAdapter @Inject constructor() :
}
}
private fun bindBarChart(holder: GradeStatisticsBar, points: GradePointsStatistics) {
with(holder.view.gradeStatisticsBarTitle) {
private fun bindBarChart(holder: BarViewHolder, points: GradePointsStatistics) {
with(holder.binding.gradeStatisticsBarTitle) {
text = points.subject
visibility = if (items.size == 1) GONE else VISIBLE
}
@ -153,14 +148,14 @@ class GradeStatisticsAdapter @Inject constructor() :
with(dataset) {
valueTextSize = 12f
valueTextColor = holder.view.context.getThemeAttrColor(android.R.attr.textColorPrimary)
valueTextColor = holder.binding.root.context.getThemeAttrColor(android.R.attr.textColorPrimary)
valueFormatter = object : ValueFormatter() {
override fun getBarLabel(barEntry: BarEntry) = "${barEntry.y}%"
}
colors = gradePointsColors
}
with(holder.view.gradeStatisticsBar) {
with(holder.binding.gradeStatisticsBar) {
setTouchEnabled(false)
if (items.size == 1) animateXY(1000, 1000)
data = BarData(dataset).apply {
@ -183,7 +178,7 @@ class GradeStatisticsAdapter @Inject constructor() :
description.isEnabled = false
holder.view.context.getThemeAttrColor(android.R.attr.textColorPrimary).let {
holder.binding.root.context.getThemeAttrColor(android.R.attr.textColorPrimary).let {
axisLeft.textColor = it
axisRight.textColor = it
}
@ -203,7 +198,9 @@ class GradeStatisticsAdapter @Inject constructor() :
}
}
class GradeStatisticsPie(val view: View) : RecyclerView.ViewHolder(view)
private class PieViewHolder(val binding: ItemGradeStatisticsPieBinding) :
RecyclerView.ViewHolder(binding.root)
class GradeStatisticsBar(val view: View) : RecyclerView.ViewHolder(view)
private class BarViewHolder(val binding: ItemGradeStatisticsBarBinding) :
RecyclerView.ViewHolder(binding.root)
}

View File

@ -1,23 +1,23 @@
package io.github.wulkanowy.ui.modules.grade.statistics
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.pojos.GradeStatisticsItem
import io.github.wulkanowy.databinding.FragmentGradeStatisticsBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.grade.GradeFragment
import io.github.wulkanowy.ui.modules.grade.GradeView
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.setOnItemSelectedListener
import kotlinx.android.synthetic.main.fragment_grade_statistics.*
import javax.inject.Inject
class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.GradeChildView {
class GradeStatisticsFragment :
BaseFragment<FragmentGradeStatisticsBinding>(R.layout.fragment_grade_statistics),
GradeStatisticsView, GradeView.GradeChildView {
@Inject
lateinit var presenter: GradeStatisticsPresenter
@ -36,24 +36,21 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
override val isViewEmpty get() = statisticsAdapter.items.isEmpty()
override val currentType
get() = when (gradeStatisticsTypeSwitch.checkedRadioButtonId) {
get() = when (binding.gradeStatisticsTypeSwitch.checkedRadioButtonId) {
R.id.gradeStatisticsTypeSemester -> ViewType.SEMESTER
R.id.gradeStatisticsTypePartial -> ViewType.PARTIAL
else -> ViewType.POINTS
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_grade_statistics, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
messageContainer = gradeStatisticsSwipe
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentGradeStatisticsBinding.bind(view)
messageContainer = binding.gradeStatisticsSwipe
presenter.onAttachView(this, savedInstanceState?.getSerializable(SAVED_CHART_TYPE) as? ViewType)
}
override fun initView() {
with(gradeStatisticsRecycler) {
with(binding.gradeStatisticsRecycler) {
layoutManager = LinearLayoutManager(requireContext())
adapter = statisticsAdapter
}
@ -61,16 +58,18 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
subjectsAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, mutableListOf())
subjectsAdapter.setDropDownViewResource(R.layout.item_attendance_summary_subject)
with(gradeStatisticsSubjects) {
with(binding.gradeStatisticsSubjects) {
adapter = subjectsAdapter
setOnItemSelectedListener<TextView> { presenter.onSubjectSelected(it?.text?.toString()) }
}
gradeStatisticsSubjectsContainer.setElevationCompat(requireContext().dpToPx(1f))
with(binding) {
gradeStatisticsSubjectsContainer.setElevationCompat(requireContext().dpToPx(1f))
gradeStatisticsSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
gradeStatisticsErrorRetry.setOnClickListener { presenter.onRetry() }
gradeStatisticsErrorDetails.setOnClickListener { presenter.onDetailsClick() }
gradeStatisticsSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
gradeStatisticsErrorRetry.setOnClickListener { presenter.onRetry() }
gradeStatisticsErrorDetails.setOnClickListener { presenter.onDetailsClick() }
}
}
override fun updateSubjects(data: ArrayList<String>) {
@ -88,8 +87,10 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
}
override fun showSubjects(show: Boolean) {
gradeStatisticsSubjectsContainer.visibility = if (show) View.VISIBLE else View.INVISIBLE
gradeStatisticsTypeSwitch.visibility = if (show) View.VISIBLE else View.INVISIBLE
with(binding) {
gradeStatisticsSubjectsContainer.visibility = if (show) View.VISIBLE else View.INVISIBLE
gradeStatisticsTypeSwitch.visibility = if (show) View.VISIBLE else View.INVISIBLE
}
}
override fun clearView() {
@ -97,35 +98,35 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
}
override fun resetView() {
gradeStatisticsScroll.scrollTo(0, 0)
binding.gradeStatisticsScroll.scrollTo(0, 0)
}
override fun showContent(show: Boolean) {
gradeStatisticsRecycler.visibility = if (show) View.VISIBLE else View.GONE
binding.gradeStatisticsRecycler.visibility = if (show) View.VISIBLE else View.GONE
}
override fun showEmpty(show: Boolean) {
gradeStatisticsEmpty.visibility = if (show) View.VISIBLE else View.INVISIBLE
binding.gradeStatisticsEmpty.visibility = if (show) View.VISIBLE else View.INVISIBLE
}
override fun showErrorView(show: Boolean) {
gradeStatisticsError.visibility = if (show) View.VISIBLE else View.GONE
binding.gradeStatisticsError.visibility = if (show) View.VISIBLE else View.GONE
}
override fun setErrorDetails(message: String) {
gradeStatisticsErrorMessage.text = message
binding.gradeStatisticsErrorMessage.text = message
}
override fun showProgress(show: Boolean) {
gradeStatisticsProgress.visibility = if (show) View.VISIBLE else View.GONE
binding.gradeStatisticsProgress.visibility = if (show) View.VISIBLE else View.GONE
}
override fun enableSwipe(enable: Boolean) {
gradeStatisticsSwipe.isEnabled = enable
binding.gradeStatisticsSwipe.isEnabled = enable
}
override fun showRefresh(show: Boolean) {
gradeStatisticsSwipe.isRefreshing = show
binding.gradeStatisticsSwipe.isRefreshing = show
}
override fun onParentLoadData(semesterId: Int, forceRefresh: Boolean) {
@ -150,7 +151,7 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
override fun onResume() {
super.onResume()
gradeStatisticsTypeSwitch.setOnCheckedChangeListener { _, _ -> presenter.onTypeChange() }
binding.gradeStatisticsTypeSwitch.setOnCheckedChangeListener { _, _ -> presenter.onTypeChange() }
}
override fun onSaveInstanceState(outState: Bundle) {
@ -159,7 +160,7 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
}
override fun onDestroyView() {
super.onDestroyView()
presenter.onDetachView()
super.onDestroyView()
}
}

View File

@ -1,7 +1,7 @@
package io.github.wulkanowy.ui.modules.grade.statistics
enum class ViewType {
SEMESTER,
PARTIAL,
POINTS
enum class ViewType(val id: Int) {
SEMESTER(1),
PARTIAL(2),
POINTS(3)
}

View File

@ -1,22 +1,22 @@
package io.github.wulkanowy.ui.modules.grade.summary
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.databinding.FragmentGradeSummaryBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.grade.GradeFragment
import io.github.wulkanowy.ui.modules.grade.GradeView
import kotlinx.android.synthetic.main.fragment_grade_summary.*
import javax.inject.Inject
class GradeSummaryFragment : BaseFragment(), GradeSummaryView, GradeView.GradeChildView {
class GradeSummaryFragment :
BaseFragment<FragmentGradeSummaryBinding>(R.layout.fragment_grade_summary), GradeSummaryView,
GradeView.GradeChildView {
@Inject
lateinit var presenter: GradeSummaryPresenter
@ -37,24 +37,23 @@ class GradeSummaryFragment : BaseFragment(), GradeSummaryView, GradeView.GradeCh
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)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
messageContainer = gradeSummaryRecycler
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentGradeSummaryBinding.bind(view)
messageContainer = binding.gradeSummaryRecycler
presenter.onAttachView(this)
}
override fun initView() {
gradeSummaryRecycler.run {
with(binding.gradeSummaryRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = gradeSummaryAdapter
}
gradeSummarySwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
gradeSummaryErrorRetry.setOnClickListener { presenter.onRetry() }
gradeSummaryErrorDetails.setOnClickListener { presenter.onDetailsClick() }
with(binding) {
gradeSummarySwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
gradeSummaryErrorRetry.setOnClickListener { presenter.onRetry() }
gradeSummaryErrorDetails.setOnClickListener { presenter.onDetailsClick() }
}
}
override fun updateData(data: List<GradeSummary>) {
@ -72,35 +71,35 @@ class GradeSummaryFragment : BaseFragment(), GradeSummaryView, GradeView.GradeCh
}
override fun resetView() {
gradeSummaryRecycler.scrollToPosition(0)
binding.gradeSummaryRecycler.scrollToPosition(0)
}
override fun showContent(show: Boolean) {
gradeSummaryRecycler.visibility = if (show) VISIBLE else INVISIBLE
binding.gradeSummaryRecycler.visibility = if (show) VISIBLE else INVISIBLE
}
override fun showEmpty(show: Boolean) {
gradeSummaryEmpty.visibility = if (show) VISIBLE else INVISIBLE
binding.gradeSummaryEmpty.visibility = if (show) VISIBLE else INVISIBLE
}
override fun showErrorView(show: Boolean) {
gradeSummaryError.visibility = if (show) VISIBLE else INVISIBLE
binding.gradeSummaryError.visibility = if (show) VISIBLE else INVISIBLE
}
override fun setErrorDetails(message: String) {
gradeSummaryErrorMessage.text = message
binding.gradeSummaryErrorMessage.text = message
}
override fun showProgress(show: Boolean) {
gradeSummaryProgress.visibility = if (show) VISIBLE else GONE
binding.gradeSummaryProgress.visibility = if (show) VISIBLE else GONE
}
override fun enableSwipe(enable: Boolean) {
gradeSummarySwipe.isEnabled = enable
binding.gradeSummarySwipe.isEnabled = enable
}
override fun showRefresh(show: Boolean) {
gradeSummarySwipe.isRefreshing = show
binding.gradeSummarySwipe.isRefreshing = show
}
override fun onParentLoadData(semesterId: Int, forceRefresh: Boolean) {
@ -124,7 +123,7 @@ class GradeSummaryFragment : BaseFragment(), GradeSummaryView, GradeView.GradeCh
}
override fun onDestroyView() {
super.onDestroyView()
presenter.onDetachView()
super.onDestroyView()
}
}

View File

@ -1,24 +1,23 @@
package io.github.wulkanowy.ui.modules.homework
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.databinding.FragmentHomeworkBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.ui.modules.homework.details.HomeworkDetailsDialog
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.dpToPx
import kotlinx.android.synthetic.main.fragment_homework.*
import javax.inject.Inject
class HomeworkFragment : BaseFragment(), HomeworkView, MainView.TitledView {
class HomeworkFragment : BaseFragment<FragmentHomeworkBinding>(R.layout.fragment_homework),
HomeworkView, MainView.TitledView {
@Inject
lateinit var presenter: HomeworkPresenter
@ -36,33 +35,32 @@ class HomeworkFragment : BaseFragment(), HomeworkView, MainView.TitledView {
override val isViewEmpty get() = homeworkAdapter.items.isEmpty()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_homework, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
messageContainer = homeworkRecycler
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentHomeworkBinding.bind(view)
messageContainer = binding.homeworkRecycler
presenter.onAttachView(this, savedInstanceState?.getLong(SAVED_DATE_KEY))
}
override fun initView() {
homeworkAdapter.onClickListener = presenter::onHomeworkItemSelected
with(homeworkRecycler) {
with(binding.homeworkRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = homeworkAdapter
addItemDecoration(DividerItemDecoration(context))
}
homeworkSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
homeworkErrorRetry.setOnClickListener { presenter.onRetry() }
homeworkErrorDetails.setOnClickListener { presenter.onDetailsClick() }
with(binding) {
homeworkSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
homeworkErrorRetry.setOnClickListener { presenter.onRetry() }
homeworkErrorDetails.setOnClickListener { presenter.onDetailsClick() }
homeworkPreviousButton.setOnClickListener { presenter.onPreviousDay() }
homeworkNextButton.setOnClickListener { presenter.onNextDay() }
homeworkPreviousButton.setOnClickListener { presenter.onPreviousDay() }
homeworkNextButton.setOnClickListener { presenter.onNextDay() }
homeworkNavContainer.setElevationCompat(requireContext().dpToPx(8f))
homeworkNavContainer.setElevationCompat(requireContext().dpToPx(8f))
}
}
override fun updateData(data: List<HomeworkItem<*>>) {
@ -84,43 +82,43 @@ class HomeworkFragment : BaseFragment(), HomeworkView, MainView.TitledView {
}
override fun updateNavigationWeek(date: String) {
homeworkNavDate.text = date
binding.homeworkNavDate.text = date
}
override fun hideRefresh() {
homeworkSwipe.isRefreshing = false
binding.homeworkSwipe.isRefreshing = false
}
override fun showEmpty(show: Boolean) {
homeworkEmpty.visibility = if (show) VISIBLE else GONE
binding.homeworkEmpty.visibility = if (show) VISIBLE else GONE
}
override fun showErrorView(show: Boolean) {
homeworkError.visibility = if (show) VISIBLE else GONE
binding.homeworkError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
homeworkErrorMessage.text = message
binding.homeworkErrorMessage.text = message
}
override fun showProgress(show: Boolean) {
homeworkProgress.visibility = if (show) VISIBLE else GONE
binding.homeworkProgress.visibility = if (show) VISIBLE else GONE
}
override fun enableSwipe(enable: Boolean) {
homeworkSwipe.isEnabled = enable
binding.homeworkSwipe.isEnabled = enable
}
override fun showContent(show: Boolean) {
homeworkRecycler.visibility = if (show) VISIBLE else GONE
binding.homeworkRecycler.visibility = if (show) VISIBLE else GONE
}
override fun showPreButton(show: Boolean) {
homeworkPreviousButton.visibility = if (show) VISIBLE else View.INVISIBLE
binding.homeworkPreviousButton.visibility = if (show) VISIBLE else View.INVISIBLE
}
override fun showNextButton(show: Boolean) {
homeworkNextButton.visibility = if (show) VISIBLE else View.INVISIBLE
binding.homeworkNextButton.visibility = if (show) VISIBLE else View.INVISIBLE
}
override fun showTimetableDialog(homework: Homework) {

View File

@ -1,14 +1,13 @@
package io.github.wulkanowy.ui.modules.homework.details
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.databinding.ItemHomeworkDialogAttachmentBinding
import io.github.wulkanowy.databinding.ItemHomeworkDialogAttachmentsHeaderBinding
import io.github.wulkanowy.databinding.ItemHomeworkDialogDetailsBinding
import io.github.wulkanowy.utils.toFormattedString
import kotlinx.android.synthetic.main.item_homework_dialog_attachment.view.*
import kotlinx.android.synthetic.main.item_homework_dialog_details.view.*
import javax.inject.Inject
class HomeworkDetailsAdapter @Inject constructor() :
@ -42,9 +41,9 @@ class HomeworkDetailsAdapter @Inject constructor() :
val inflater = LayoutInflater.from(parent.context)
return when (viewType) {
ViewType.ATTACHMENTS_HEADER.id -> AttachmentsHeaderViewHolder(inflater.inflate(R.layout.item_homework_dialog_attachments_header, parent, false))
ViewType.ATTACHMENT.id -> AttachmentViewHolder(inflater.inflate(R.layout.item_homework_dialog_attachment, parent, false))
else -> DetailsViewHolder(inflater.inflate(R.layout.item_homework_dialog_details, parent, false))
ViewType.ATTACHMENTS_HEADER.id -> AttachmentsHeaderViewHolder(ItemHomeworkDialogAttachmentsHeaderBinding.inflate(inflater, parent, false))
ViewType.ATTACHMENT.id -> AttachmentViewHolder(ItemHomeworkDialogAttachmentBinding.inflate(inflater, parent, false))
else -> DetailsViewHolder(ItemHomeworkDialogDetailsBinding.inflate(inflater, parent, false))
}
}
@ -56,7 +55,7 @@ class HomeworkDetailsAdapter @Inject constructor() :
}
private fun bindDetailsViewHolder(holder: DetailsViewHolder) {
with(holder.view) {
with(holder.binding) {
homeworkDialogDate.text = homework?.date?.toFormattedString()
homeworkDialogEntryDate.text = homework?.entryDate?.toFormattedString()
homeworkDialogSubject.text = homework?.subject
@ -68,17 +67,20 @@ class HomeworkDetailsAdapter @Inject constructor() :
private fun bindAttachmentViewHolder(holder: AttachmentViewHolder, position: Int) {
val item = attachments[position]
with(holder.view) {
with(holder.binding) {
homeworkDialogAttachment.text = item.second
setOnClickListener {
root.setOnClickListener {
onAttachmentClickListener(item.first)
}
}
}
class DetailsViewHolder(val view: View) : RecyclerView.ViewHolder(view)
class DetailsViewHolder(val binding: ItemHomeworkDialogDetailsBinding) :
RecyclerView.ViewHolder(binding.root)
class AttachmentsHeaderViewHolder(val view: View) : RecyclerView.ViewHolder(view)
class AttachmentsHeaderViewHolder(val binding: ItemHomeworkDialogAttachmentsHeaderBinding) :
RecyclerView.ViewHolder(binding.root)
class AttachmentViewHolder(val view: View) : RecyclerView.ViewHolder(view)
class AttachmentViewHolder(val binding: ItemHomeworkDialogAttachmentBinding) :
RecyclerView.ViewHolder(binding.root)
}

View File

@ -8,13 +8,13 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.databinding.DialogHomeworkBinding
import io.github.wulkanowy.ui.base.BaseDialogFragment
import io.github.wulkanowy.ui.modules.homework.HomeworkFragment
import io.github.wulkanowy.utils.openInternetBrowser
import kotlinx.android.synthetic.main.dialog_homework.*
import javax.inject.Inject
class HomeworkDetailsDialog : BaseDialogFragment(), HomeworkDetailsView {
class HomeworkDetailsDialog : BaseDialogFragment<DialogHomeworkBinding>(), HomeworkDetailsView {
@Inject
lateinit var presenter: HomeworkDetailsPresenter
@ -43,7 +43,7 @@ class HomeworkDetailsDialog : BaseDialogFragment(), HomeworkDetailsView {
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_homework, container, false)
return DialogHomeworkBinding.inflate(inflater).apply { binding = this }.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
@ -53,11 +53,13 @@ class HomeworkDetailsDialog : BaseDialogFragment(), HomeworkDetailsView {
@SuppressLint("SetTextI18n")
override fun initView() {
homeworkDialogRead.text = view?.context?.getString(if (homework.isDone) R.string.homework_mark_as_undone else R.string.homework_mark_as_done)
homeworkDialogRead.setOnClickListener { presenter.toggleDone(homework) }
homeworkDialogClose.setOnClickListener { dismiss() }
with(binding) {
homeworkDialogRead.text = view?.context?.getString(if (homework.isDone) R.string.homework_mark_as_undone else R.string.homework_mark_as_done)
homeworkDialogRead.setOnClickListener { presenter.toggleDone(homework) }
homeworkDialogClose.setOnClickListener { dismiss() }
}
with(homeworkDialogRecycler) {
with(binding.homeworkDialogRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = detailsAdapter.apply {
onAttachmentClickListener = { context.openInternetBrowser(it, ::showMessage) }
@ -68,7 +70,7 @@ class HomeworkDetailsDialog : BaseDialogFragment(), HomeworkDetailsView {
override fun updateMarkAsDoneLabel(isDone: Boolean) {
(parentFragment as? HomeworkFragment)?.onReloadList()
homeworkDialogRead.text = view?.context?.getString(if (isDone) R.string.homework_mark_as_undone else R.string.homework_mark_as_done)
binding.homeworkDialogRead.text = view?.context?.getString(if (isDone) R.string.homework_mark_as_undone else R.string.homework_mark_as_done)
}
override fun onDestroyView() {

View File

@ -4,8 +4,8 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.MenuItem
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.databinding.ActivityLoginBinding
import io.github.wulkanowy.ui.base.BaseActivity
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.modules.login.advanced.LoginAdvancedFragment
@ -14,10 +14,9 @@ import io.github.wulkanowy.ui.modules.login.recover.LoginRecoverFragment
import io.github.wulkanowy.ui.modules.login.studentselect.LoginStudentSelectFragment
import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment
import io.github.wulkanowy.utils.setOnSelectPageListener
import kotlinx.android.synthetic.main.activity_login.*
import javax.inject.Inject
class LoginActivity : BaseActivity<LoginPresenter>(), LoginView {
class LoginActivity : BaseActivity<LoginPresenter, ActivityLoginBinding>(), LoginView {
@Inject
override lateinit var presenter: LoginPresenter
@ -30,13 +29,13 @@ class LoginActivity : BaseActivity<LoginPresenter>(), LoginView {
fun getStartIntent(context: Context) = Intent(context, LoginActivity::class.java)
}
override val currentViewIndex get() = loginViewpager.currentItem
override val currentViewIndex get() = binding.loginViewpager.currentItem
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
setSupportActionBar(loginToolbar)
messageContainer = loginContainer
setContentView(ActivityLoginBinding.inflate(layoutInflater).apply { binding = this }.root)
setSupportActionBar(binding.loginToolbar)
messageContainer = binding.loginContainer
presenter.onAttachView(this)
}
@ -48,7 +47,7 @@ class LoginActivity : BaseActivity<LoginPresenter>(), LoginView {
}
with(loginAdapter) {
containerId = loginViewpager.id
containerId = binding.loginViewpager.id
addFragments(listOf(
LoginFormFragment.newInstance(),
LoginSymbolFragment.newInstance(),
@ -58,7 +57,7 @@ class LoginActivity : BaseActivity<LoginPresenter>(), LoginView {
))
}
with(loginViewpager) {
with(binding.loginViewpager) {
offscreenPageLimit = 2
adapter = loginAdapter
setOnSelectPageListener(presenter::onViewSelected)
@ -71,7 +70,7 @@ class LoginActivity : BaseActivity<LoginPresenter>(), LoginView {
}
override fun switchView(index: Int) {
loginViewpager.setCurrentItem(index, false)
binding.loginViewpager.setCurrentItem(index, false)
}
override fun showActionBar(show: Boolean) {

View File

@ -1,15 +1,14 @@
package io.github.wulkanowy.ui.modules.login.advanced
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import android.widget.ArrayAdapter
import androidx.core.widget.doOnTextChanged
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.databinding.FragmentLoginAdvancedBinding
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.login.LoginActivity
@ -17,10 +16,11 @@ import io.github.wulkanowy.ui.modules.login.form.LoginSymbolAdapter
import io.github.wulkanowy.utils.hideSoftInput
import io.github.wulkanowy.utils.setOnEditorDoneSignIn
import io.github.wulkanowy.utils.showSoftInput
import kotlinx.android.synthetic.main.fragment_login_advanced.*
import javax.inject.Inject
class LoginAdvancedFragment : BaseFragment(), LoginAdvancedView {
class LoginAdvancedFragment :
BaseFragment<FragmentLoginAdvancedBinding>(R.layout.fragment_login_advanced),
LoginAdvancedView {
@Inject
lateinit var presenter: LoginAdvancedPresenter
@ -30,17 +30,17 @@ class LoginAdvancedFragment : BaseFragment(), LoginAdvancedView {
}
override val formLoginType: String
get() = when (loginTypeSwitch.checkedRadioButtonId) {
get() = when (binding.loginTypeSwitch.checkedRadioButtonId) {
R.id.loginTypeApi -> "API"
R.id.loginTypeScrapper -> "SCRAPPER"
else -> "HYBRID"
}
override val formUsernameValue: String
get() = loginFormUsername.text.toString().trim()
get() = binding.loginFormUsername.text.toString().trim()
override val formPassValue: String
get() = loginFormPass.text.toString().trim()
get() = binding.loginFormPass.text.toString().trim()
private lateinit var hostKeys: Array<String>
@ -49,19 +49,19 @@ class LoginAdvancedFragment : BaseFragment(), LoginAdvancedView {
private lateinit var hostSymbols: Array<String>
override val formHostValue: String
get() = hostValues.getOrNull(hostKeys.indexOf(loginFormHost.text.toString())).orEmpty()
get() = hostValues.getOrNull(hostKeys.indexOf(binding.loginFormHost.text.toString())).orEmpty()
override val formHostSymbol: String
get() = hostSymbols.getOrNull(hostKeys.indexOf(loginFormHost.text.toString())).orEmpty()
get() = hostSymbols.getOrNull(hostKeys.indexOf(binding.loginFormHost.text.toString())).orEmpty()
override val formPinValue: String
get() = loginFormPin.text.toString().trim()
get() = binding.loginFormPin.text.toString().trim()
override val formSymbolValue: String
get() = loginFormSymbol.text.toString().trim()
get() = binding.loginFormSymbol.text.toString().trim()
override val formTokenValue: String
get() = loginFormToken.text.toString().trim()
get() = binding.loginFormToken.text.toString().trim()
override val nicknameLabel: String
get() = getString(R.string.login_nickname_hint)
@ -69,12 +69,9 @@ class LoginAdvancedFragment : BaseFragment(), LoginAdvancedView {
override val emailLabel: String
get() = getString(R.string.login_email_hint)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_login_advanced, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentLoginAdvancedBinding.bind(view)
presenter.onAttachView(this)
}
@ -83,191 +80,201 @@ class LoginAdvancedFragment : BaseFragment(), LoginAdvancedView {
hostValues = resources.getStringArray(R.array.hosts_values)
hostSymbols = resources.getStringArray(R.array.hosts_symbols)
loginFormUsername.doOnTextChanged { _, _, _, _ -> presenter.onUsernameTextChanged() }
loginFormPass.doOnTextChanged { _, _, _, _ -> presenter.onPassTextChanged() }
loginFormPin.doOnTextChanged { _, _, _, _ -> presenter.onPinTextChanged() }
loginFormSymbol.doOnTextChanged { _, _, _, _ -> presenter.onSymbolTextChanged() }
loginFormToken.doOnTextChanged { _, _, _, _ -> presenter.onTokenTextChanged() }
loginFormHost.setOnItemClickListener { _, _, _, _ -> presenter.onHostSelected() }
loginFormSignIn.setOnClickListener { presenter.onSignInClick() }
with(binding) {
loginFormUsername.doOnTextChanged { _, _, _, _ -> presenter.onUsernameTextChanged() }
loginFormPass.doOnTextChanged { _, _, _, _ -> presenter.onPassTextChanged() }
loginFormPin.doOnTextChanged { _, _, _, _ -> presenter.onPinTextChanged() }
loginFormSymbol.doOnTextChanged { _, _, _, _ -> presenter.onSymbolTextChanged() }
loginFormToken.doOnTextChanged { _, _, _, _ -> presenter.onTokenTextChanged() }
loginFormHost.setOnItemClickListener { _, _, _, _ -> presenter.onHostSelected() }
loginFormSignIn.setOnClickListener { presenter.onSignInClick() }
loginTypeSwitch.setOnCheckedChangeListener { _, checkedId ->
presenter.onLoginModeSelected(when (checkedId) {
R.id.loginTypeApi -> Sdk.Mode.API
R.id.loginTypeScrapper -> Sdk.Mode.SCRAPPER
else -> Sdk.Mode.HYBRID
})
loginTypeSwitch.setOnCheckedChangeListener { _, checkedId ->
presenter.onLoginModeSelected(when (checkedId) {
R.id.loginTypeApi -> Sdk.Mode.API
R.id.loginTypeScrapper -> Sdk.Mode.SCRAPPER
else -> Sdk.Mode.HYBRID
})
}
loginFormPin.setOnEditorDoneSignIn { loginFormSignIn.callOnClick() }
loginFormPass.setOnEditorDoneSignIn { loginFormSignIn.callOnClick() }
loginFormSymbol.setAdapter(ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, resources.getStringArray(R.array.symbols_values)))
}
loginFormPin.setOnEditorDoneSignIn { loginFormSignIn.callOnClick() }
loginFormPass.setOnEditorDoneSignIn { loginFormSignIn.callOnClick() }
loginFormSymbol.setAdapter(ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, resources.getStringArray(R.array.symbols_values)))
with(loginFormHost) {
with(binding.loginFormHost) {
setText(hostKeys.getOrNull(0).orEmpty())
setAdapter(LoginSymbolAdapter(context, R.layout.support_simple_spinner_dropdown_item, hostKeys))
setOnClickListener { if (loginFormContainer.visibility == GONE) dismissDropDown() }
setOnClickListener { if (binding.loginFormContainer.visibility == GONE) dismissDropDown() }
}
}
override fun showMobileApiWarningMessage() {
loginFormAdvancedWarningInfo.text = getString(R.string.login_advanced_warning_mobile_api)
binding.loginFormAdvancedWarningInfo.text = getString(R.string.login_advanced_warning_mobile_api)
}
override fun showScraperWarningMessage() {
loginFormAdvancedWarningInfo.text = getString(R.string.login_advanced_warning_scraper)
binding.loginFormAdvancedWarningInfo.text = getString(R.string.login_advanced_warning_scraper)
}
override fun showHybridWarningMessage() {
loginFormAdvancedWarningInfo.text = getString(R.string.login_advanced_warning_hybrid)
binding.loginFormAdvancedWarningInfo.text = getString(R.string.login_advanced_warning_hybrid)
}
override fun setDefaultCredentials(username: String, pass: String, symbol: String, token: String, pin: String) {
loginFormUsername.setText(username)
loginFormPass.setText(pass)
loginFormToken.setText(token)
loginFormSymbol.setText(symbol)
loginFormPin.setText(pin)
with(binding) {
loginFormUsername.setText(username)
loginFormPass.setText(pass)
loginFormToken.setText(token)
loginFormSymbol.setText(symbol)
loginFormPin.setText(pin)
}
}
override fun setUsernameLabel(label: String) {
loginFormUsernameLayout.hint = label
binding.loginFormUsernameLayout.hint = label
}
override fun setSymbol(symbol: String) {
loginFormSymbol.setText(symbol)
binding.loginFormSymbol.setText(symbol)
}
override fun setErrorUsernameRequired() {
with(loginFormUsernameLayout) {
with(binding.loginFormUsernameLayout) {
requestFocus()
error = getString(R.string.login_field_required)
}
}
override fun setErrorLoginRequired() {
with(loginFormUsernameLayout) {
with(binding.loginFormUsernameLayout) {
requestFocus()
error = getString(R.string.login_invalid_login)
}
}
override fun setErrorEmailRequired() {
with(loginFormUsernameLayout) {
with(binding.loginFormUsernameLayout) {
requestFocus()
error = getString(R.string.login_invalid_email)
}
}
override fun setErrorPassRequired(focus: Boolean) {
with(loginFormPassLayout) {
with(binding.loginFormPassLayout) {
if (focus) requestFocus()
error = getString(R.string.login_field_required)
}
}
override fun setErrorPassInvalid(focus: Boolean) {
with(loginFormPassLayout) {
with(binding.loginFormPassLayout) {
if (focus) requestFocus()
error = getString(R.string.login_invalid_password)
}
}
override fun setErrorPassIncorrect() {
with(loginFormPassLayout) {
with(binding.loginFormPassLayout) {
requestFocus()
error = getString(R.string.login_incorrect_password)
}
}
override fun setErrorPinRequired() {
with(loginFormPinLayout) {
with(binding.loginFormPinLayout) {
requestFocus()
error = getString(R.string.login_field_required)
}
}
override fun setErrorPinInvalid(message: String) {
with(loginFormPinLayout) {
with(binding.loginFormPinLayout) {
requestFocus()
error = message
}
}
override fun setErrorSymbolRequired() {
with(loginFormSymbolLayout) {
with(binding.loginFormSymbolLayout) {
requestFocus()
error = getString(R.string.login_field_required)
}
}
override fun setErrorSymbolInvalid(message: String) {
with(loginFormSymbolLayout) {
with(binding.loginFormSymbolLayout) {
requestFocus()
error = message
}
}
override fun setErrorTokenRequired() {
with(loginFormTokenLayout) {
with(binding.loginFormTokenLayout) {
requestFocus()
error = getString(R.string.login_field_required)
}
}
override fun setErrorTokenInvalid(message: String) {
with(loginFormTokenLayout) {
with(binding.loginFormTokenLayout) {
requestFocus()
error = message
}
}
override fun clearUsernameError() {
loginFormUsernameLayout.error = null
binding.loginFormUsernameLayout.error = null
}
override fun clearPassError() {
loginFormPassLayout.error = null
binding.loginFormPassLayout.error = null
}
override fun clearPinKeyError() {
loginFormPinLayout.error = null
binding.loginFormPinLayout.error = null
}
override fun clearSymbolError() {
loginFormSymbolLayout.error = null
binding.loginFormSymbolLayout.error = null
}
override fun clearTokenError() {
loginFormTokenLayout.error = null
binding.loginFormTokenLayout.error = null
}
override fun showOnlyHybridModeInputs() {
loginFormUsernameLayout.visibility = VISIBLE
loginFormPassLayout.visibility = VISIBLE
loginFormHostLayout.visibility = VISIBLE
loginFormPinLayout.visibility = GONE
loginFormSymbolLayout.visibility = VISIBLE
loginFormTokenLayout.visibility = GONE
with(binding) {
loginFormUsernameLayout.visibility = VISIBLE
loginFormPassLayout.visibility = VISIBLE
loginFormHostLayout.visibility = VISIBLE
loginFormPinLayout.visibility = GONE
loginFormSymbolLayout.visibility = VISIBLE
loginFormTokenLayout.visibility = GONE
}
}
override fun showOnlyScrapperModeInputs() {
loginFormUsernameLayout.visibility = VISIBLE
loginFormPassLayout.visibility = VISIBLE
loginFormHostLayout.visibility = VISIBLE
loginFormPinLayout.visibility = GONE
loginFormSymbolLayout.visibility = VISIBLE
loginFormTokenLayout.visibility = GONE
with(binding) {
loginFormUsernameLayout.visibility = VISIBLE
loginFormPassLayout.visibility = VISIBLE
loginFormHostLayout.visibility = VISIBLE
loginFormPinLayout.visibility = GONE
loginFormSymbolLayout.visibility = VISIBLE
loginFormTokenLayout.visibility = GONE
}
}
override fun showOnlyMobileApiModeInputs() {
loginFormUsernameLayout.visibility = GONE
loginFormPassLayout.visibility = GONE
loginFormHostLayout.visibility = GONE
loginFormPinLayout.visibility = VISIBLE
loginFormSymbolLayout.visibility = VISIBLE
loginFormTokenLayout.visibility = VISIBLE
with(binding) {
loginFormUsernameLayout.visibility = GONE
loginFormPassLayout.visibility = GONE
loginFormHostLayout.visibility = GONE
loginFormPinLayout.visibility = VISIBLE
loginFormSymbolLayout.visibility = VISIBLE
loginFormTokenLayout.visibility = VISIBLE
}
}
override fun showSoftKeyboard() {
@ -279,17 +286,17 @@ class LoginAdvancedFragment : BaseFragment(), LoginAdvancedView {
}
override fun showProgress(show: Boolean) {
loginFormProgress.visibility = if (show) VISIBLE else GONE
binding.loginFormProgress.visibility = if (show) VISIBLE else GONE
}
override fun showContent(show: Boolean) {
loginFormContainer.visibility = if (show) VISIBLE else GONE
binding.loginFormContainer.visibility = if (show) VISIBLE else GONE
}
override fun notifyParentAccountLogged(students: List<Student>) {
(activity as? LoginActivity)?.onFormFragmentAccountLogged(students, Triple(
loginFormUsername.text.toString(),
loginFormPass.text.toString(),
binding.loginFormUsername.text.toString(),
binding.loginFormPass.text.toString(),
resources.getStringArray(R.array.hosts_values)[1]
))
}
@ -300,7 +307,7 @@ class LoginAdvancedFragment : BaseFragment(), LoginAdvancedView {
}
override fun onDestroyView() {
super.onDestroyView()
presenter.onDetachView()
super.onDestroyView()
}
}

View File

@ -2,14 +2,13 @@ package io.github.wulkanowy.ui.modules.login.form
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.core.widget.doOnTextChanged
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.databinding.FragmentLoginFormBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.utils.AppInfo
@ -18,10 +17,10 @@ import io.github.wulkanowy.utils.openEmailClient
import io.github.wulkanowy.utils.openInternetBrowser
import io.github.wulkanowy.utils.setOnEditorDoneSignIn
import io.github.wulkanowy.utils.showSoftInput
import kotlinx.android.synthetic.main.fragment_login_form.*
import javax.inject.Inject
class LoginFormFragment : BaseFragment(), LoginFormView {
class LoginFormFragment : BaseFragment<FragmentLoginFormBinding>(R.layout.fragment_login_form),
LoginFormView {
@Inject
lateinit var presenter: LoginFormPresenter
@ -34,16 +33,16 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
}
override val formUsernameValue: String
get() = loginFormUsername.text.toString()
get() = binding.loginFormUsername.text.toString()
override val formPassValue: String
get() = loginFormPass.text.toString()
get() = binding.loginFormPass.text.toString()
override val formHostValue: String
get() = hostValues.getOrNull(hostKeys.indexOf(loginFormHost.text.toString())).orEmpty()
get() = hostValues.getOrNull(hostKeys.indexOf(binding.loginFormHost.text.toString())).orEmpty()
override val formHostSymbol: String
get() = hostSymbols.getOrNull(hostKeys.indexOf(loginFormHost.text.toString())).orEmpty()
get() = hostSymbols.getOrNull(hostKeys.indexOf(binding.loginFormHost.text.toString())).orEmpty()
override val nicknameLabel: String
get() = getString(R.string.login_nickname_hint)
@ -57,12 +56,9 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
private lateinit var hostSymbols: Array<String>
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_login_form, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentLoginFormBinding.bind(view)
presenter.onAttachView(this)
}
@ -71,81 +67,85 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
hostValues = resources.getStringArray(R.array.hosts_values)
hostSymbols = resources.getStringArray(R.array.hosts_symbols)
loginFormUsername.doOnTextChanged { _, _, _, _ -> presenter.onUsernameTextChanged() }
loginFormPass.doOnTextChanged { _, _, _, _ -> presenter.onPassTextChanged() }
loginFormHost.setOnItemClickListener { _, _, _, _ -> presenter.onHostSelected() }
loginFormSignIn.setOnClickListener { presenter.onSignInClick() }
loginFormAdvancedButton.setOnClickListener { presenter.onAdvancedLoginClick() }
loginFormPrivacyLink.setOnClickListener { presenter.onPrivacyLinkClick() }
loginFormFaq.setOnClickListener { presenter.onFaqClick() }
loginFormContactEmail.setOnClickListener { presenter.onEmailClick() }
loginFormRecoverLink.setOnClickListener { presenter.onRecoverClick() }
loginFormPass.setOnEditorDoneSignIn { loginFormSignIn.callOnClick() }
with(binding) {
loginFormUsername.doOnTextChanged { _, _, _, _ -> presenter.onUsernameTextChanged() }
loginFormPass.doOnTextChanged { _, _, _, _ -> presenter.onPassTextChanged() }
loginFormHost.setOnItemClickListener { _, _, _, _ -> presenter.onHostSelected() }
loginFormSignIn.setOnClickListener { presenter.onSignInClick() }
loginFormAdvancedButton.setOnClickListener { presenter.onAdvancedLoginClick() }
loginFormPrivacyLink.setOnClickListener { presenter.onPrivacyLinkClick() }
loginFormFaq.setOnClickListener { presenter.onFaqClick() }
loginFormContactEmail.setOnClickListener { presenter.onEmailClick() }
loginFormRecoverLink.setOnClickListener { presenter.onRecoverClick() }
loginFormPass.setOnEditorDoneSignIn { loginFormSignIn.callOnClick() }
}
with(loginFormHost) {
with(binding.loginFormHost) {
setText(hostKeys.getOrNull(0).orEmpty())
setAdapter(LoginSymbolAdapter(context, R.layout.support_simple_spinner_dropdown_item, hostKeys))
setOnClickListener { if (loginFormContainer.visibility == GONE) dismissDropDown() }
setOnClickListener { if (binding.loginFormContainer.visibility == GONE) dismissDropDown() }
}
}
override fun setCredentials(username: String, pass: String) {
loginFormUsername.setText(username)
loginFormPass.setText(pass)
with(binding) {
loginFormUsername.setText(username)
loginFormPass.setText(pass)
}
}
override fun setUsernameLabel(label: String) {
loginFormUsernameLayout.hint = label
binding.loginFormUsernameLayout.hint = label
}
override fun setErrorUsernameRequired() {
with(loginFormUsernameLayout) {
with(binding.loginFormUsernameLayout) {
requestFocus()
error = getString(R.string.login_field_required)
}
}
override fun setErrorLoginRequired() {
with(loginFormUsernameLayout) {
with(binding.loginFormUsernameLayout) {
requestFocus()
error = getString(R.string.login_invalid_login)
}
}
override fun setErrorEmailRequired() {
with(loginFormUsernameLayout) {
with(binding.loginFormUsernameLayout) {
requestFocus()
error = getString(R.string.login_invalid_email)
}
}
override fun setErrorPassRequired(focus: Boolean) {
with(loginFormPassLayout) {
with(binding.loginFormPassLayout) {
if (focus) requestFocus()
error = getString(R.string.login_field_required)
}
}
override fun setErrorPassInvalid(focus: Boolean) {
with(loginFormPassLayout) {
with(binding.loginFormPassLayout) {
if (focus) requestFocus()
error = getString(R.string.login_invalid_password)
}
}
override fun setErrorPassIncorrect() {
with(loginFormPassLayout) {
with(binding.loginFormPassLayout) {
requestFocus()
error = getString(R.string.login_incorrect_password)
}
}
override fun clearUsernameError() {
loginFormUsernameLayout.error = null
binding.loginFormUsernameLayout.error = null
}
override fun clearPassError() {
loginFormPassLayout.error = null
binding.loginFormPassLayout.error = null
}
override fun showSoftKeyboard() {
@ -157,16 +157,16 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
}
override fun showProgress(show: Boolean) {
loginFormProgress.visibility = if (show) VISIBLE else GONE
binding.loginFormProgress.visibility = if (show) VISIBLE else GONE
}
override fun showContent(show: Boolean) {
loginFormContainer.visibility = if (show) VISIBLE else GONE
binding.loginFormContainer.visibility = if (show) VISIBLE else GONE
}
@SuppressLint("SetTextI18n")
override fun showVersion() {
loginFormVersion.text = "v${appInfo.versionName}"
binding.loginFormVersion.text = "v${appInfo.versionName}"
}
override fun notifyParentAccountLogged(students: List<Student>, loginData: Triple<String, String, String>) {
@ -178,7 +178,7 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
}
override fun showContact(show: Boolean) {
loginFormContact.visibility = if (show) VISIBLE else GONE
binding.loginFormContact.visibility = if (show) VISIBLE else GONE
}
override fun openAdvancedLogin() {
@ -190,8 +190,8 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
}
override fun onDestroyView() {
super.onDestroyView()
presenter.onDetachView()
super.onDestroyView()
}
override fun openFaqPage() {

View File

@ -3,25 +3,24 @@ package io.github.wulkanowy.ui.modules.login.recover
import android.annotation.SuppressLint
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import android.webkit.JavascriptInterface
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.core.widget.doOnTextChanged
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.FragmentLoginRecoverBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.ui.modules.login.form.LoginSymbolAdapter
import io.github.wulkanowy.utils.hideSoftInput
import io.github.wulkanowy.utils.showSoftInput
import kotlinx.android.synthetic.main.fragment_login_recover.*
import javax.inject.Inject
class LoginRecoverFragment : BaseFragment(), LoginRecoverView {
class LoginRecoverFragment :
BaseFragment<FragmentLoginRecoverBinding>(R.layout.fragment_login_recover), LoginRecoverView {
@Inject
lateinit var presenter: LoginRecoverPresenter
@ -37,13 +36,13 @@ class LoginRecoverFragment : BaseFragment(), LoginRecoverView {
private lateinit var hostSymbols: Array<String>
override val recoverHostValue: String
get() = hostValues.getOrNull(hostKeys.indexOf(loginRecoverHost.text.toString())).orEmpty()
get() = hostValues.getOrNull(hostKeys.indexOf(binding.loginRecoverHost.text.toString())).orEmpty()
override val formHostSymbol: String
get() = hostSymbols.getOrNull(hostKeys.indexOf(loginRecoverHost.text.toString())).orEmpty()
get() = hostSymbols.getOrNull(hostKeys.indexOf(binding.loginRecoverHost.text.toString())).orEmpty()
override val recoverNameValue: String
get() = loginRecoverName.text.toString().trim()
get() = binding.loginRecoverName.text.toString().trim()
override val emailHintString: String
get() = getString(R.string.login_email_hint)
@ -54,91 +53,90 @@ class LoginRecoverFragment : BaseFragment(), LoginRecoverView {
override val invalidEmailString: String
get() = getString(R.string.login_invalid_email)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_login_recover, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentLoginRecoverBinding.bind(view)
presenter.onAttachView(this)
}
override fun initView() {
loginRecoverWebView.setBackgroundColor(Color.TRANSPARENT)
hostKeys = resources.getStringArray(R.array.hosts_keys)
hostValues = resources.getStringArray(R.array.hosts_values)
hostSymbols = resources.getStringArray(R.array.hosts_symbols)
loginRecoverName.doOnTextChanged { _, _, _, _ -> presenter.onNameTextChanged() }
loginRecoverHost.setOnItemClickListener { _, _, _, _ -> presenter.onHostSelected() }
loginRecoverButton.setOnClickListener { presenter.onRecoverClick() }
loginRecoverErrorRetry.setOnClickListener { presenter.onRecoverClick() }
loginRecoverErrorDetails.setOnClickListener { presenter.onDetailsClick() }
loginRecoverLogin.setOnClickListener { (activity as LoginActivity).switchView(0) }
with(binding) {
loginRecoverWebView.setBackgroundColor(Color.TRANSPARENT)
loginRecoverName.doOnTextChanged { _, _, _, _ -> presenter.onNameTextChanged() }
loginRecoverHost.setOnItemClickListener { _, _, _, _ -> presenter.onHostSelected() }
loginRecoverButton.setOnClickListener { presenter.onRecoverClick() }
loginRecoverErrorRetry.setOnClickListener { presenter.onRecoverClick() }
loginRecoverErrorDetails.setOnClickListener { presenter.onDetailsClick() }
loginRecoverLogin.setOnClickListener { (activity as LoginActivity).switchView(0) }
}
with(loginRecoverHost) {
with(binding.loginRecoverHost) {
setText(hostKeys.getOrNull(0).orEmpty())
setAdapter(LoginSymbolAdapter(context, R.layout.support_simple_spinner_dropdown_item, hostKeys))
setOnClickListener { if (loginRecoverFormContainer.visibility == GONE) dismissDropDown() }
setOnClickListener { if (binding.loginRecoverFormContainer.visibility == GONE) dismissDropDown() }
}
}
override fun setDefaultCredentials(username: String) {
loginRecoverName.setText(username)
binding.loginRecoverName.setText(username)
}
override fun setErrorNameRequired() {
with(loginRecoverNameLayout) {
with(binding.loginRecoverNameLayout) {
requestFocus()
error = getString(R.string.login_field_required)
}
}
override fun setUsernameHint(hint: String) {
loginRecoverNameLayout.hint = hint
binding.loginRecoverNameLayout.hint = hint
}
override fun setUsernameError(message: String) {
with(loginRecoverNameLayout) {
with(binding.loginRecoverNameLayout) {
requestFocus()
error = message
}
}
override fun clearUsernameError() {
loginRecoverNameLayout.error = null
binding.loginRecoverNameLayout.error = null
}
override fun showProgress(show: Boolean) {
loginRecoverProgress.visibility = if (show) VISIBLE else GONE
binding.loginRecoverProgress.visibility = if (show) VISIBLE else GONE
}
override fun showRecoverForm(show: Boolean) {
loginRecoverFormContainer.visibility = if (show) VISIBLE else GONE
binding.loginRecoverFormContainer.visibility = if (show) VISIBLE else GONE
}
override fun showCaptcha(show: Boolean) {
loginRecoverCaptchaContainer.visibility = if (show) VISIBLE else GONE
binding.loginRecoverCaptchaContainer.visibility = if (show) VISIBLE else GONE
}
override fun showErrorView(show: Boolean) {
loginRecoverError.visibility = if (show) VISIBLE else GONE
binding.loginRecoverError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
loginRecoverErrorMessage.text = message
binding.loginRecoverErrorMessage.text = message
}
override fun showSuccessView(show: Boolean) {
loginRecoverSuccess.visibility = if (show) VISIBLE else GONE
binding.loginRecoverSuccess.visibility = if (show) VISIBLE else GONE
}
override fun setSuccessTitle(title: String) {
loginRecoverSuccessTitle.text = title
binding.loginRecoverSuccessTitle.text = title
}
override fun setSuccessMessage(message: String) {
loginRecoverSuccessMessage.text = message
binding.loginRecoverSuccessMessage.text = message
}
override fun showSoftKeyboard() {
@ -159,7 +157,7 @@ class LoginRecoverFragment : BaseFragment(), LoginRecoverView {
callback:e =>Android.captchaCallback(e)})</script>
""".trimIndent()
with(loginRecoverWebView) {
with(binding.loginRecoverWebView) {
settings.javaScriptEnabled = true
webViewClient = object : WebViewClient() {
private var recoverWebViewSuccess: Boolean = true
@ -197,8 +195,9 @@ class LoginRecoverFragment : BaseFragment(), LoginRecoverView {
}
override fun onDestroyView() {
super.onDestroyView()
loginRecoverWebView.destroy()
binding.loginRecoverWebView.destroy()
presenter.onDetachView()
super.onDestroyView()
}
}

View File

@ -1,24 +1,24 @@
package io.github.wulkanowy.ui.modules.login.studentselect
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.databinding.FragmentLoginStudentSelectBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.openEmailClient
import io.github.wulkanowy.utils.openInternetBrowser
import kotlinx.android.synthetic.main.fragment_login_student_select.*
import java.io.Serializable
import javax.inject.Inject
class LoginStudentSelectFragment : BaseFragment(), LoginStudentSelectView {
class LoginStudentSelectFragment :
BaseFragment<FragmentLoginStudentSelectBinding>(R.layout.fragment_login_student_select),
LoginStudentSelectView {
@Inject
lateinit var presenter: LoginStudentSelectPresenter
@ -35,24 +35,24 @@ class LoginStudentSelectFragment : BaseFragment(), LoginStudentSelectView {
fun newInstance() = LoginStudentSelectFragment()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_login_student_select, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentLoginStudentSelectBinding.bind(view)
presenter.onAttachView(this, savedInstanceState?.getSerializable(SAVED_STUDENTS))
}
override fun initView() {
loginAdapter.onClickListener = presenter::onItemSelected
loginStudentSelectSignIn.setOnClickListener { presenter.onSignIn() }
loginStudentSelectContactDiscord.setOnClickListener { presenter.onDiscordClick() }
loginStudentSelectContactEmail.setOnClickListener { presenter.onEmailClick() }
loginStudentSelectRecycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = loginAdapter
with(binding) {
loginStudentSelectSignIn.setOnClickListener { presenter.onSignIn() }
loginStudentSelectContactDiscord.setOnClickListener { presenter.onDiscordClick() }
loginStudentSelectContactEmail.setOnClickListener { presenter.onEmailClick() }
with(loginStudentSelectRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = loginAdapter
}
}
}
@ -68,15 +68,15 @@ class LoginStudentSelectFragment : BaseFragment(), LoginStudentSelectView {
}
override fun showProgress(show: Boolean) {
loginStudentSelectProgress.visibility = if (show) VISIBLE else GONE
binding.loginStudentSelectProgress.visibility = if (show) VISIBLE else GONE
}
override fun showContent(show: Boolean) {
loginStudentSelectContent.visibility = if (show) VISIBLE else GONE
binding.loginStudentSelectContent.visibility = if (show) VISIBLE else GONE
}
override fun enableSignIn(enable: Boolean) {
loginStudentSelectSignIn.isEnabled = enable
binding.loginStudentSelectSignIn.isEnabled = enable
}
fun onParentInitStudentSelectFragment(students: List<Student>) {
@ -89,7 +89,7 @@ class LoginStudentSelectFragment : BaseFragment(), LoginStudentSelectView {
}
override fun showContact(show: Boolean) {
loginStudentSelectContact.visibility = if (show) VISIBLE else GONE
binding.loginStudentSelectContact.visibility = if (show) VISIBLE else GONE
}
override fun onDestroyView() {

View File

@ -1,17 +1,16 @@
package io.github.wulkanowy.ui.modules.login.symbol
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo.IME_ACTION_DONE
import android.view.inputmethod.EditorInfo.IME_NULL
import android.widget.ArrayAdapter
import androidx.core.widget.doOnTextChanged
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.databinding.FragmentLoginSymbolBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.utils.AppInfo
@ -19,10 +18,10 @@ import io.github.wulkanowy.utils.hideSoftInput
import io.github.wulkanowy.utils.openEmailClient
import io.github.wulkanowy.utils.openInternetBrowser
import io.github.wulkanowy.utils.showSoftInput
import kotlinx.android.synthetic.main.fragment_login_symbol.*
import javax.inject.Inject
class LoginSymbolFragment : BaseFragment(), LoginSymbolView {
class LoginSymbolFragment :
BaseFragment<FragmentLoginSymbolBinding>(R.layout.fragment_login_symbol), LoginSymbolView {
@Inject
lateinit var presenter: LoginSymbolPresenter
@ -37,29 +36,28 @@ class LoginSymbolFragment : BaseFragment(), LoginSymbolView {
}
override val symbolNameError: CharSequence?
get() = loginSymbolNameLayout.error
get() = binding.loginSymbolNameLayout.error
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_login_symbol, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentLoginSymbolBinding.bind(view)
presenter.onAttachView(this, savedInstanceState?.getSerializable(SAVED_LOGIN_DATA))
}
override fun initView() {
loginSymbolSignIn.setOnClickListener { presenter.attemptLogin(loginSymbolName.text.toString()) }
loginSymbolFaq.setOnClickListener { presenter.onFaqClick() }
loginSymbolContactEmail.setOnClickListener { presenter.onEmailClick() }
with(binding) {
loginSymbolSignIn.setOnClickListener { presenter.attemptLogin(loginSymbolName.text.toString()) }
loginSymbolFaq.setOnClickListener { presenter.onFaqClick() }
loginSymbolContactEmail.setOnClickListener { presenter.onEmailClick() }
loginSymbolName.doOnTextChanged { _, _, _, _ -> presenter.onSymbolTextChanged() }
loginSymbolName.doOnTextChanged { _, _, _, _ -> presenter.onSymbolTextChanged() }
loginSymbolName.apply {
setOnEditorActionListener { _, id, _ ->
if (id == IME_ACTION_DONE || id == IME_NULL) loginSymbolSignIn.callOnClick() else false
loginSymbolName.apply {
setOnEditorActionListener { _, id, _ ->
if (id == IME_ACTION_DONE || id == IME_NULL) loginSymbolSignIn.callOnClick() else false
}
setAdapter(ArrayAdapter(context, android.R.layout.simple_list_item_1, resources.getStringArray(R.array.symbols_values)))
}
setAdapter(ArrayAdapter(context, android.R.layout.simple_list_item_1, resources.getStringArray(R.array.symbols_values)))
}
}
@ -68,25 +66,25 @@ class LoginSymbolFragment : BaseFragment(), LoginSymbolView {
}
override fun setErrorSymbolIncorrect() {
loginSymbolNameLayout.apply {
binding.loginSymbolNameLayout.apply {
requestFocus()
error = getString(R.string.login_incorrect_symbol)
}
}
override fun setErrorSymbolRequire() {
loginSymbolNameLayout.apply {
binding.loginSymbolNameLayout.apply {
requestFocus()
error = getString(R.string.login_field_required)
}
}
override fun clearSymbolError() {
loginSymbolNameLayout.error = null
binding.loginSymbolNameLayout.error = null
}
override fun clearAndFocusSymbol() {
loginSymbolNameLayout.apply {
binding.loginSymbolNameLayout.apply {
editText?.text = null
requestFocus()
}
@ -101,11 +99,11 @@ class LoginSymbolFragment : BaseFragment(), LoginSymbolView {
}
override fun showProgress(show: Boolean) {
loginSymbolProgress.visibility = if (show) VISIBLE else GONE
binding.loginSymbolProgress.visibility = if (show) VISIBLE else GONE
}
override fun showContent(show: Boolean) {
loginSymbolContainer.visibility = if (show) VISIBLE else GONE
binding.loginSymbolContainer.visibility = if (show) VISIBLE else GONE
}
override fun notifyParentAccountLogged(students: List<Student>) {
@ -118,12 +116,12 @@ class LoginSymbolFragment : BaseFragment(), LoginSymbolView {
}
override fun showContact(show: Boolean) {
loginSymbolContact.visibility = if (show) VISIBLE else GONE
binding.loginSymbolContact.visibility = if (show) VISIBLE else GONE
}
override fun onDestroyView() {
super.onDestroyView()
presenter.onDetachView()
super.onDestroyView()
}
override fun openFaqPage() {
@ -139,7 +137,7 @@ class LoginSymbolFragment : BaseFragment(), LoginSymbolView {
"${appInfo.systemManufacturer} ${appInfo.systemModel}",
appInfo.systemVersion.toString(),
appInfo.versionName,
"$host/${loginSymbolName.text}",
"$host/${binding.loginSymbolName.text}",
lastError
)
)

View File

@ -1,19 +1,19 @@
package io.github.wulkanowy.ui.modules.luckynumber
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.databinding.FragmentLuckyNumberBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainView
import kotlinx.android.synthetic.main.fragment_lucky_number.*
import javax.inject.Inject
class LuckyNumberFragment : BaseFragment(), LuckyNumberView, MainView.TitledView {
class LuckyNumberFragment :
BaseFragment<FragmentLuckyNumberBinding>(R.layout.fragment_lucky_number), LuckyNumberView,
MainView.TitledView {
@Inject
lateinit var presenter: LuckyNumberPresenter
@ -25,58 +25,57 @@ class LuckyNumberFragment : BaseFragment(), LuckyNumberView, MainView.TitledView
override val titleStringId: Int
get() = R.string.lucky_number_title
override val isViewEmpty get() = luckyNumberText.text.isBlank()
override val isViewEmpty get() = binding.luckyNumberText.text.isBlank()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_lucky_number, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
messageContainer = luckyNumberSwipe
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentLuckyNumberBinding.bind(view)
messageContainer = binding.luckyNumberSwipe
presenter.onAttachView(this)
}
override fun initView() {
luckyNumberSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
luckyNumberErrorRetry.setOnClickListener { presenter.onRetry() }
luckyNumberErrorDetails.setOnClickListener { presenter.onDetailsClick() }
with(binding) {
luckyNumberSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
luckyNumberErrorRetry.setOnClickListener { presenter.onRetry() }
luckyNumberErrorDetails.setOnClickListener { presenter.onDetailsClick() }
}
}
override fun updateData(data: LuckyNumber) {
luckyNumberText.text = data.luckyNumber.toString()
binding.luckyNumberText.text = data.luckyNumber.toString()
}
override fun hideRefresh() {
luckyNumberSwipe.isRefreshing = false
binding.luckyNumberSwipe.isRefreshing = false
}
override fun showEmpty(show: Boolean) {
luckyNumberEmpty.visibility = if (show) VISIBLE else GONE
binding.luckyNumberEmpty.visibility = if (show) VISIBLE else GONE
}
override fun showErrorView(show: Boolean) {
luckyNumberError.visibility = if (show) VISIBLE else GONE
binding.luckyNumberError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
luckyNumberErrorMessage.text = message
binding.luckyNumberErrorMessage.text = message
}
override fun showProgress(show: Boolean) {
luckyNumberProgress.visibility = if (show) VISIBLE else GONE
binding.luckyNumberProgress.visibility = if (show) VISIBLE else GONE
}
override fun enableSwipe(enable: Boolean) {
luckyNumberSwipe.isEnabled = enable
binding.luckyNumberSwipe.isEnabled = enable
}
override fun showContent(show: Boolean) {
luckyNumberContent.visibility = if (show) VISIBLE else GONE
binding.luckyNumberContent.visibility = if (show) VISIBLE else GONE
}
override fun onDestroyView() {
super.onDestroyView()
presenter.onDetachView()
super.onDestroyView()
}
}

View File

@ -10,13 +10,14 @@ import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.databinding.ActivityWidgetConfigureBinding
import io.github.wulkanowy.ui.base.BaseActivity
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.ui.base.WidgetConfigureAdapter
import kotlinx.android.synthetic.main.activity_widget_configure.*
import io.github.wulkanowy.ui.modules.login.LoginActivity
import javax.inject.Inject
class LuckyNumberWidgetConfigureActivity : BaseActivity<LuckyNumberWidgetConfigurePresenter>(),
class LuckyNumberWidgetConfigureActivity :
BaseActivity<LuckyNumberWidgetConfigurePresenter, ActivityWidgetConfigureBinding>(),
LuckyNumberWidgetConfigureView {
@Inject
@ -30,7 +31,7 @@ class LuckyNumberWidgetConfigureActivity : BaseActivity<LuckyNumberWidgetConfigu
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setResult(RESULT_CANCELED)
setContentView(R.layout.activity_widget_configure)
setContentView(ActivityWidgetConfigureBinding.inflate(layoutInflater).apply { binding = this }.root)
intent.extras.let {
presenter.onAttachView(this, it?.getInt(EXTRA_APPWIDGET_ID))
@ -38,7 +39,7 @@ class LuckyNumberWidgetConfigureActivity : BaseActivity<LuckyNumberWidgetConfigu
}
override fun initView() {
with(widgetConfigureRecycler) {
with(binding.widgetConfigureRecycler) {
adapter = configureAdapter
layoutManager = LinearLayoutManager(context)
}

View File

@ -19,6 +19,7 @@ import com.ncapdevi.fragnav.FragNavController
import com.ncapdevi.fragnav.FragNavController.Companion.HIDE
import dagger.Lazy
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.ActivityMainBinding
import io.github.wulkanowy.ui.base.BaseActivity
import io.github.wulkanowy.ui.modules.account.AccountDialog
import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment
@ -34,11 +35,10 @@ import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.safelyPopFragments
import io.github.wulkanowy.utils.setOnViewChangeListener
import kotlinx.android.synthetic.main.activity_main.*
import timber.log.Timber
import javax.inject.Inject
class MainActivity : BaseActivity<MainPresenter>(), MainView {
class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainView {
@Inject
override lateinit var presenter: MainPresenter
@ -82,9 +82,9 @@ class MainActivity : BaseActivity<MainPresenter>(), MainView {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(mainToolbar)
messageContainer = mainFragmentContainer
setContentView(ActivityMainBinding.inflate(layoutInflater).apply { binding = this }.root)
setSupportActionBar(binding.mainToolbar)
messageContainer = binding.mainFragmentContainer
presenter.onAttachView(this, intent.getSerializableExtra(EXTRA_START_MENU) as? MainView.Section)
@ -100,12 +100,12 @@ class MainActivity : BaseActivity<MainPresenter>(), MainView {
}
override fun initView() {
with(mainToolbar) {
with(binding.mainToolbar) {
if (SDK_INT >= LOLLIPOP) stateListAnimator = null
setBackgroundColor(overlayProvider.get().compositeOverlayWithThemeSurfaceColorIfNeeded(dpToPx(4f)))
}
with(mainBottomNav) {
with(binding.mainBottomNav) {
addItems(listOf(
AHBottomNavigationItem(R.string.grade_title, R.drawable.ic_main_grade, 0),
AHBottomNavigationItem(R.string.attendance_title, R.drawable.ic_main_attendance, 0),
@ -166,7 +166,7 @@ class MainActivity : BaseActivity<MainPresenter>(), MainView {
}
override fun showActionBarElevation(show: Boolean) {
ViewCompat.setElevation(mainToolbar, if (show) dpToPx(4f) else 0f)
ViewCompat.setElevation(binding.mainToolbar, if (show) dpToPx(4f) else 0f)
}
override fun notifyMenuViewReselected() {

View File

@ -1,16 +1,15 @@
package io.github.wulkanowy.ui.modules.message
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import android.view.ViewGroup
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED
import io.github.wulkanowy.data.repositories.message.MessageFolder.SENT
import io.github.wulkanowy.data.repositories.message.MessageFolder.TRASHED
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.MainView
@ -18,10 +17,10 @@ import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.setOnSelectPageListener
import kotlinx.android.synthetic.main.fragment_message.*
import javax.inject.Inject
class MessageFragment : BaseFragment(), MessageView, MainView.TitledView {
class MessageFragment : BaseFragment<FragmentMessageBinding>(R.layout.fragment_message),
MessageView, MainView.TitledView {
@Inject
lateinit var presenter: MessagePresenter
@ -35,20 +34,17 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView {
override val titleStringId get() = R.string.message_title
override val currentPageIndex get() = messageViewPager.currentItem
override val currentPageIndex get() = binding.messageViewPager.currentItem
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_message, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentMessageBinding.bind(view)
presenter.onAttachView(this)
}
override fun initView() {
with(pagerAdapter) {
containerId = messageViewPager.id
containerId = binding.messageViewPager.id
addFragmentsWithTitle(mapOf(
MessageTabFragment.newInstance(RECEIVED) to getString(R.string.message_inbox),
MessageTabFragment.newInstance(SENT) to getString(R.string.message_sent),
@ -56,27 +52,29 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView {
))
}
with(messageViewPager) {
with(binding.messageViewPager) {
adapter = pagerAdapter
offscreenPageLimit = 2
setOnSelectPageListener(presenter::onPageSelected)
}
with(messageTabLayout) {
setupWithViewPager(messageViewPager)
with(binding.messageTabLayout) {
setupWithViewPager(binding.messageViewPager)
setElevationCompat(context.dpToPx(4f))
}
openSendMessageButton.setOnClickListener { presenter.onSendMessageButtonClicked() }
binding.openSendMessageButton.setOnClickListener { presenter.onSendMessageButtonClicked() }
}
override fun showContent(show: Boolean) {
messageViewPager.visibility = if (show) VISIBLE else INVISIBLE
messageTabLayout.visibility = if (show) VISIBLE else INVISIBLE
with(binding) {
messageViewPager.visibility = if (show) VISIBLE else INVISIBLE
messageTabLayout.visibility = if (show) VISIBLE else INVISIBLE
}
}
override fun showProgress(show: Boolean) {
messageProgress.visibility = if (show) VISIBLE else INVISIBLE
binding.messageProgress.visibility = if (show) VISIBLE else INVISIBLE
}
fun onDeleteMessage(message: Message) {

View File

@ -10,10 +10,11 @@ import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageAttachment
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
import io.github.wulkanowy.data.repositories.message.MessageFolder
import io.github.wulkanowy.databinding.ItemMessageAttachmentBinding
import io.github.wulkanowy.databinding.ItemMessageDividerBinding
import io.github.wulkanowy.databinding.ItemMessagePreviewBinding
import io.github.wulkanowy.utils.openInternetBrowser
import io.github.wulkanowy.utils.toFormattedString
import kotlinx.android.synthetic.main.item_message_attachment.view.*
import kotlinx.android.synthetic.main.item_message_preview.view.*
import javax.inject.Inject
class MessagePreviewAdapter @Inject constructor() :
@ -45,44 +46,47 @@ class MessagePreviewAdapter @Inject constructor() :
val inflater = LayoutInflater.from(parent.context)
return when (viewType) {
ViewType.MESSAGE.id -> MessageViewHolder(inflater.inflate(R.layout.item_message_preview, parent, false))
ViewType.DIVIDER.id -> DividerViewHolder(inflater.inflate(R.layout.item_message_divider, parent, false))
ViewType.ATTACHMENT.id -> AttachmentViewHolder(inflater.inflate(R.layout.item_message_attachment, parent, false))
ViewType.MESSAGE.id -> MessageViewHolder(ItemMessagePreviewBinding.inflate(inflater, parent, false))
ViewType.DIVIDER.id -> DividerViewHolder(ItemMessageDividerBinding.inflate(inflater, parent, false))
ViewType.ATTACHMENT.id -> AttachmentViewHolder(ItemMessageAttachmentBinding.inflate(inflater, parent, false))
else -> throw IllegalStateException()
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is MessageViewHolder -> bindMessage(holder.view, requireNotNull(messageWithAttachment).message)
is AttachmentViewHolder -> bindAttachment(holder.view, requireNotNull(messageWithAttachment).attachments[position - 2])
is MessageViewHolder -> bindMessage(holder, requireNotNull(messageWithAttachment).message)
is AttachmentViewHolder -> bindAttachment(holder, requireNotNull(messageWithAttachment).attachments[position - 2])
}
}
@SuppressLint("SetTextI18n")
private fun bindMessage(view: View, message: Message) {
with(view) {
messagePreviewSubject.text = if (message.subject.isNotBlank()) message.subject else context.getString(R.string.message_no_subject)
messagePreviewDate.text = context.getString(R.string.message_date, message.date.toFormattedString("yyyy-MM-dd HH:mm:ss"))
private fun bindMessage(holder: MessageViewHolder, message: Message) {
with(holder.binding) {
messagePreviewSubject.text = if (message.subject.isNotBlank()) message.subject else root.context.getString(R.string.message_no_subject)
messagePreviewDate.text = root.context.getString(R.string.message_date, message.date.toFormattedString("yyyy-MM-dd HH:mm:ss"))
messagePreviewContent.text = message.content
messagePreviewAuthor.text = if (message.folderId == MessageFolder.SENT.id) "${context.getString(R.string.message_to)} ${message.recipient}"
else "${context.getString(R.string.message_from)} ${message.sender}"
messagePreviewAuthor.text = if (message.folderId == MessageFolder.SENT.id) "${root.context.getString(R.string.message_to)} ${message.recipient}"
else "${root.context.getString(R.string.message_from)} ${message.sender}"
}
}
private fun bindAttachment(view: View, attachment: MessageAttachment) {
with(view) {
private fun bindAttachment(holder: AttachmentViewHolder, attachment: MessageAttachment) {
with(holder.binding) {
messagePreviewAttachment.visibility = View.VISIBLE
messagePreviewAttachment.text = attachment.filename
setOnClickListener {
context.openInternetBrowser(attachment.url) { }
root.setOnClickListener {
root.context.openInternetBrowser(attachment.url) { }
}
}
}
class MessageViewHolder(val view: View) : RecyclerView.ViewHolder(view)
class MessageViewHolder(val binding: ItemMessagePreviewBinding) :
RecyclerView.ViewHolder(binding.root)
class DividerViewHolder(val view: View) : RecyclerView.ViewHolder(view)
class DividerViewHolder(val binding: ItemMessageDividerBinding) :
RecyclerView.ViewHolder(binding.root)
class AttachmentViewHolder(val view: View) : RecyclerView.ViewHolder(view)
class AttachmentViewHolder(val binding: ItemMessageAttachmentBinding) :
RecyclerView.ViewHolder(binding.root)
}

View File

@ -1,27 +1,27 @@
package io.github.wulkanowy.ui.modules.message.preview
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
import io.github.wulkanowy.databinding.FragmentMessagePreviewBinding
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.modules.message.MessageFragment
import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
import kotlinx.android.synthetic.main.fragment_message_preview.*
import javax.inject.Inject
class MessagePreviewFragment : BaseFragment(), MessagePreviewView, MainView.TitledView {
class MessagePreviewFragment :
BaseFragment<FragmentMessagePreviewBinding>(R.layout.fragment_message_preview),
MessagePreviewView, MainView.TitledView {
@Inject
lateinit var presenter: MessagePreviewPresenter
@ -56,20 +56,17 @@ class MessagePreviewFragment : BaseFragment(), MessagePreviewView, MainView.Titl
setHasOptionsMenu(true)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_message_preview, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
messageContainer = messagePreviewContainer
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentMessagePreviewBinding.bind(view)
messageContainer = binding.messagePreviewContainer
presenter.onAttachView(this, (savedInstanceState ?: arguments)?.getSerializable(MESSAGE_ID_KEY) as? Message)
}
override fun initView() {
messagePreviewErrorDetails.setOnClickListener { presenter.onDetailsClick() }
binding.messagePreviewErrorDetails.setOnClickListener { presenter.onDetailsClick() }
with(messagePreviewRecycler) {
with(binding.messagePreviewRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = previewAdapter
}
@ -100,11 +97,11 @@ class MessagePreviewFragment : BaseFragment(), MessagePreviewView, MainView.Titl
}
override fun showProgress(show: Boolean) {
messagePreviewProgress.visibility = if (show) VISIBLE else GONE
binding.messagePreviewProgress.visibility = if (show) VISIBLE else GONE
}
override fun showContent(show: Boolean) {
messagePreviewRecycler.visibility = if (show) VISIBLE else GONE
binding.messagePreviewRecycler.visibility = if (show) VISIBLE else GONE
}
override fun showOptions(show: Boolean) {
@ -122,15 +119,15 @@ class MessagePreviewFragment : BaseFragment(), MessagePreviewView, MainView.Titl
}
override fun showErrorView(show: Boolean) {
messagePreviewError.visibility = if (show) VISIBLE else GONE
binding.messagePreviewError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
messagePreviewErrorMessage.text = message
binding.messagePreviewErrorMessage.text = message
}
override fun setErrorRetryCallback(callback: () -> Unit) {
messagePreviewErrorRetry.setOnClickListener { callback() }
binding.messagePreviewErrorRetry.setOnClickListener { callback() }
}
override fun openMessageReply(message: Message?) {

View File

@ -14,14 +14,14 @@ import android.widget.Toast.LENGTH_LONG
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.databinding.ActivitySendMessageBinding
import io.github.wulkanowy.ui.base.BaseActivity
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.hideSoftInput
import io.github.wulkanowy.utils.showSoftInput
import kotlinx.android.synthetic.main.activity_send_message.*
import javax.inject.Inject
class SendMessageActivity : BaseActivity<SendMessagePresenter>(), SendMessageView {
class SendMessageActivity : BaseActivity<SendMessagePresenter, ActivitySendMessageBinding>(), SendMessageView {
@Inject
override lateinit var presenter: SendMessagePresenter
@ -41,17 +41,17 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter>(), SendMessageVie
}
override val isDropdownListVisible: Boolean
get() = sendMessageTo.isDropdownListVisible
get() = binding.sendMessageTo.isDropdownListVisible
@Suppress("UNCHECKED_CAST")
override val formRecipientsData: List<RecipientChipItem>
get() = sendMessageTo.addedChipItems as List<RecipientChipItem>
get() = binding.sendMessageTo.addedChipItems as List<RecipientChipItem>
override val formSubjectValue: String
get() = sendMessageSubject.text.toString()
get() = binding.sendMessageSubject.text.toString()
override val formContentValue: String
get() = sendMessageMessageContent.text.toString()
get() = binding.sendMessageMessageContent.text.toString()
override val messageRequiredRecipients: String
get() = getString(R.string.message_required_recipients)
@ -64,18 +64,20 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter>(), SendMessageVie
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_send_message)
setSupportActionBar(sendMessageToolbar)
setContentView(ActivitySendMessageBinding.inflate(layoutInflater).apply { binding = this }.root)
setSupportActionBar(binding.sendMessageToolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
messageContainer = sendMessageContainer
messageContainer = binding.sendMessageContainer
presenter.onAttachView(this, intent.getSerializableExtra(EXTRA_MESSAGE) as? Message, intent.getSerializableExtra(EXTRA_REPLY) as? Boolean)
}
override fun initView() {
setUpExtendedHitArea()
sendMessageScroll.setOnTouchListener { _, _ -> presenter.onTouchScroll() }
sendMessageTo.onTextChangeListener = presenter::onRecipientsTextChange
with(binding) {
sendMessageScroll.setOnTouchListener { _, _ -> presenter.onTouchScroll() }
sendMessageTo.onTextChangeListener = presenter::onRecipientsTextChange
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
@ -93,27 +95,27 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter>(), SendMessageVie
}
override fun setReportingUnit(unit: ReportingUnit) {
sendMessageFrom.text = unit.senderName
binding.sendMessageFrom.text = unit.senderName
}
override fun setRecipients(recipients: List<RecipientChipItem>) {
sendMessageTo.filterableChipItems = recipients
binding.sendMessageTo.filterableChipItems = recipients
}
override fun setSelectedRecipients(recipients: List<RecipientChipItem>) {
sendMessageTo.addChips(recipients)
binding.sendMessageTo.addChips(recipients)
}
override fun showProgress(show: Boolean) {
sendMessageProgress.visibility = if (show) VISIBLE else GONE
binding.sendMessageProgress.visibility = if (show) VISIBLE else GONE
}
override fun showContent(show: Boolean) {
sendMessageContent.visibility = if (show) VISIBLE else GONE
binding.sendMessageContent.visibility = if (show) VISIBLE else GONE
}
override fun showEmpty(show: Boolean) {
sendMessageEmpty.visibility = if (show) VISIBLE else GONE
binding.sendMessageEmpty.visibility = if (show) VISIBLE else GONE
}
override fun showActionBar(show: Boolean) {
@ -121,11 +123,11 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter>(), SendMessageVie
}
override fun setSubject(subject: String) {
sendMessageSubject.setText(subject)
binding.sendMessageSubject.setText(subject)
}
override fun setContent(content: String) {
sendMessageMessageContent.setText(content)
binding.sendMessageMessageContent.setText(content)
}
override fun showMessage(text: String) {
@ -137,12 +139,14 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter>(), SendMessageVie
}
override fun hideDropdownList() {
sendMessageTo.hideDropdownList()
binding.sendMessageTo.hideDropdownList()
}
override fun scrollToRecipients() {
sendMessageScroll.post {
sendMessageScroll.scrollTo(0, sendMessageTo.bottom - dpToPx(53f).toInt())
with(binding.sendMessageScroll) {
post {
scrollTo(0, binding.sendMessageTo.bottom - dpToPx(53f).toInt())
}
}
}
@ -153,24 +157,24 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter>(), SendMessageVie
private fun setUpExtendedHitArea() {
fun extendHitArea() {
val containerHitRect = Rect().apply {
sendMessageContent.getHitRect(this)
binding.sendMessageContent.getHitRect(this)
}
val contentHitRect = Rect().apply {
sendMessageMessageContent.getHitRect(this)
binding.sendMessageMessageContent.getHitRect(this)
}
contentHitRect.top = contentHitRect.bottom
contentHitRect.bottom = containerHitRect.bottom
sendMessageContent.touchDelegate = TouchDelegate(contentHitRect, sendMessageMessageContent)
binding.sendMessageContent.touchDelegate = TouchDelegate(contentHitRect, binding.sendMessageMessageContent)
}
sendMessageMessageContent.post {
sendMessageMessageContent.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
with(binding.sendMessageMessageContent) {
post {
addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> extendHitArea() }
extendHitArea()
}
extendHitArea()
}
}
}

View File

@ -1,25 +1,24 @@
package io.github.wulkanowy.ui.modules.message.tab
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.repositories.message.MessageFolder
import io.github.wulkanowy.databinding.FragmentMessageTabBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.message.MessageFragment
import io.github.wulkanowy.ui.modules.message.preview.MessagePreviewFragment
import kotlinx.android.synthetic.main.fragment_message_tab.*
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import javax.inject.Inject
class MessageTabFragment : BaseFragment(), MessageTabView {
class MessageTabFragment : BaseFragment<FragmentMessageTabBinding>(R.layout.fragment_message_tab),
MessageTabView {
@Inject
lateinit var presenter: MessageTabPresenter
@ -42,13 +41,10 @@ class MessageTabFragment : BaseFragment(), MessageTabView {
override val isViewEmpty
get() = tabAdapter.items.isEmpty()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_message_tab, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
messageContainer = messageTabRecycler
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentMessageTabBinding.bind(view)
messageContainer = binding.messageTabRecycler
presenter.onAttachView(this, MessageFolder.valueOf(
(savedInstanceState ?: arguments)?.getString(MESSAGE_TAB_FOLDER_ID).orEmpty()
))
@ -57,14 +53,16 @@ class MessageTabFragment : BaseFragment(), MessageTabView {
override fun initView() {
tabAdapter.onClickListener = presenter::onMessageItemSelected
messageTabRecycler.run {
with(binding.messageTabRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = tabAdapter
addItemDecoration(DividerItemDecoration(context))
}
messageTabSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
messageTabErrorRetry.setOnClickListener { presenter.onRetry() }
messageTabErrorDetails.setOnClickListener { presenter.onDetailsClick() }
with(binding) {
messageTabSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
messageTabErrorRetry.setOnClickListener { presenter.onRetry() }
messageTabErrorDetails.setOnClickListener { presenter.onDetailsClick() }
}
}
override fun updateData(data: List<Message>) {
@ -82,31 +80,31 @@ class MessageTabFragment : BaseFragment(), MessageTabView {
}
override fun showProgress(show: Boolean) {
messageTabProgress.visibility = if (show) VISIBLE else GONE
binding.messageTabProgress.visibility = if (show) VISIBLE else GONE
}
override fun enableSwipe(enable: Boolean) {
messageTabSwipe.isEnabled = enable
binding.messageTabSwipe.isEnabled = enable
}
override fun showContent(show: Boolean) {
messageTabRecycler.visibility = if (show) VISIBLE else INVISIBLE
binding.messageTabRecycler.visibility = if (show) VISIBLE else INVISIBLE
}
override fun showEmpty(show: Boolean) {
messageTabEmpty.visibility = if (show) VISIBLE else INVISIBLE
binding.messageTabEmpty.visibility = if (show) VISIBLE else INVISIBLE
}
override fun showErrorView(show: Boolean) {
messageTabError.visibility = if (show) VISIBLE else GONE
binding.messageTabError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
messageTabErrorMessage.text = message
binding.messageTabErrorMessage.text = message
}
override fun showRefresh(show: Boolean) {
messageTabSwipe.isRefreshing = show
binding.messageTabSwipe.isRefreshing = show
}
override fun openMessage(message: Message) {

View File

@ -1,25 +1,25 @@
package io.github.wulkanowy.ui.modules.mobiledevice
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.core.view.postDelayed
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.databinding.FragmentMobileDeviceBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.mobiledevice.token.MobileDeviceTokenDialog
import kotlinx.android.synthetic.main.fragment_mobile_device.*
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import javax.inject.Inject
class MobileDeviceFragment : BaseFragment(), MobileDeviceView, MainView.TitledView {
class MobileDeviceFragment :
BaseFragment<FragmentMobileDeviceBinding>(R.layout.fragment_mobile_device), MobileDeviceView,
MainView.TitledView {
@Inject
lateinit var presenter: MobileDevicePresenter
@ -37,29 +37,28 @@ class MobileDeviceFragment : BaseFragment(), MobileDeviceView, MainView.TitledVi
override val isViewEmpty: Boolean
get() = devicesAdapter.items.isEmpty()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_mobile_device, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
messageContainer = mobileDevicesRecycler
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentMobileDeviceBinding.bind(view)
messageContainer = binding.mobileDevicesRecycler
presenter.onAttachView(this)
}
override fun initView() {
devicesAdapter.onDeviceUnregisterListener = presenter::onUnregisterDevice
with(mobileDevicesRecycler) {
with(binding.mobileDevicesRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = devicesAdapter
addItemDecoration(DividerItemDecoration(context))
}
mobileDevicesSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
mobileDevicesErrorRetry.setOnClickListener { presenter.onRetry() }
mobileDevicesErrorDetails.setOnClickListener { presenter.onDetailsClick() }
mobileDeviceAddButton.setOnClickListener { presenter.onRegisterDevice() }
with(binding) {
mobileDevicesSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
mobileDevicesErrorRetry.setOnClickListener { presenter.onRetry() }
mobileDevicesErrorDetails.setOnClickListener { presenter.onDetailsClick() }
mobileDeviceAddButton.setOnClickListener { presenter.onRegisterDevice() }
}
}
override fun updateData(data: List<MobileDevice>) {
@ -88,7 +87,7 @@ class MobileDeviceFragment : BaseFragment(), MobileDeviceView, MainView.TitledVi
override fun showUndo(device: MobileDevice, position: Int) {
var confirmed = true
Snackbar.make(mobileDevicesRecycler, getString(R.string.mobile_device_removed), 3000)
Snackbar.make(binding.mobileDevicesRecycler, getString(R.string.mobile_device_removed), 3000)
.setAction(R.string.all_undo) {
confirmed = false
presenter.onUnregisterCancelled(device, position)
@ -100,31 +99,31 @@ class MobileDeviceFragment : BaseFragment(), MobileDeviceView, MainView.TitledVi
}
override fun hideRefresh() {
mobileDevicesSwipe.isRefreshing = false
binding.mobileDevicesSwipe.isRefreshing = false
}
override fun showProgress(show: Boolean) {
mobileDevicesProgress.visibility = if (show) VISIBLE else GONE
binding.mobileDevicesProgress.visibility = if (show) VISIBLE else GONE
}
override fun showEmpty(show: Boolean) {
mobileDevicesEmpty.visibility = if (show) VISIBLE else GONE
binding.mobileDevicesEmpty.visibility = if (show) VISIBLE else GONE
}
override fun showErrorView(show: Boolean) {
mobileDevicesError.visibility = if (show) VISIBLE else GONE
binding.mobileDevicesError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
mobileDevicesErrorMessage.text = message
binding.mobileDevicesErrorMessage.text = message
}
override fun enableSwipe(enable: Boolean) {
mobileDevicesSwipe.isEnabled = enable
binding.mobileDevicesSwipe.isEnabled = enable
}
override fun showContent(show: Boolean) {
mobileDevicesRecycler.visibility = if (show) VISIBLE else GONE
binding.mobileDevicesRecycler.visibility = if (show) VISIBLE else GONE
}
override fun showTokenDialog() {

View File

@ -14,11 +14,11 @@ import android.widget.Toast
import androidx.core.content.getSystemService
import io.github.wulkanowy.R
import io.github.wulkanowy.data.pojos.MobileDeviceToken
import io.github.wulkanowy.databinding.DialogMobileDeviceBinding
import io.github.wulkanowy.ui.base.BaseDialogFragment
import kotlinx.android.synthetic.main.dialog_mobile_device.*
import javax.inject.Inject
class MobileDeviceTokenDialog : BaseDialogFragment(), MobileDeviceTokenVIew {
class MobileDeviceTokenDialog : BaseDialogFragment<DialogMobileDeviceBinding>(), MobileDeviceTokenVIew {
@Inject
lateinit var presenter: MobileDeviceTokenPresenter
@ -33,7 +33,7 @@ class MobileDeviceTokenDialog : BaseDialogFragment(), MobileDeviceTokenVIew {
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_mobile_device, container, false)
return DialogMobileDeviceBinding.inflate(inflater).apply { binding = this }.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
@ -42,24 +42,24 @@ class MobileDeviceTokenDialog : BaseDialogFragment(), MobileDeviceTokenVIew {
}
override fun initView() {
mobileDeviceDialogClose.setOnClickListener { dismiss() }
binding.mobileDeviceDialogClose.setOnClickListener { dismiss() }
}
override fun updateData(token: MobileDeviceToken) {
with(mobileDeviceDialogToken) {
with(binding.mobileDeviceDialogToken) {
text = token.token
setOnClickListener { clickCopy(token.token) }
}
with(mobileDeviceDialogSymbol) {
with(binding.mobileDeviceDialogSymbol) {
text = token.symbol
setOnClickListener { clickCopy(token.symbol) }
}
with(mobileDeviceDialogPin) {
with(binding.mobileDeviceDialogPin) {
text = token.pin
setOnClickListener { clickCopy(token.pin) }
}
mobileDeviceQr.setImageBitmap(Base64.decode(token.qr, Base64.DEFAULT).let {
binding.mobileDeviceQr.setImageBitmap(Base64.decode(token.qr, Base64.DEFAULT).let {
BitmapFactory.decodeByteArray(it, 0, it.size)
})
}
@ -71,11 +71,11 @@ class MobileDeviceTokenDialog : BaseDialogFragment(), MobileDeviceTokenVIew {
}
override fun hideLoading() {
mobileDeviceDialogProgress.visibility = GONE
binding.mobileDeviceDialogProgress.visibility = GONE
}
override fun showContent() {
mobileDeviceDialogContent.visibility = VISIBLE
binding.mobileDeviceDialogContent.visibility = VISIBLE
}
override fun closeDialog() {

View File

@ -2,11 +2,10 @@ package io.github.wulkanowy.ui.modules.more
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.FragmentMoreBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.about.AboutFragment
import io.github.wulkanowy.ui.modules.homework.HomeworkFragment
@ -19,10 +18,10 @@ import io.github.wulkanowy.ui.modules.note.NoteFragment
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment
import io.github.wulkanowy.ui.modules.settings.SettingsFragment
import io.github.wulkanowy.utils.getCompatDrawable
import kotlinx.android.synthetic.main.fragment_more.*
import javax.inject.Inject
class MoreFragment : BaseFragment(), MoreView, MainView.TitledView, MainView.MainChildView {
class MoreFragment : BaseFragment<FragmentMoreBinding>(R.layout.fragment_more), MoreView,
MainView.TitledView, MainView.MainChildView {
@Inject
lateinit var presenter: MorePresenter
@ -61,19 +60,16 @@ class MoreFragment : BaseFragment(), MoreView, MainView.TitledView, MainView.Mai
override val aboutRes: Pair<String, Drawable?>?
get() = context?.run { getString(R.string.about_title) to getCompatDrawable(R.drawable.ic_all_about) }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_more, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentMoreBinding.bind(view)
presenter.onAttachView(this)
}
override fun initView() {
moreAdapter.onClickListener = presenter::onItemSelected
moreRecycler.apply {
with(binding.moreRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = moreAdapter
}

View File

@ -9,13 +9,16 @@ import androidx.core.content.ContextCompat
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Note
import io.github.wulkanowy.databinding.DialogNoteBinding
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.toFormattedString
import kotlinx.android.synthetic.main.dialog_note.*
import io.github.wulkanowy.sdk.scrapper.notes.Note.CategoryType
import io.github.wulkanowy.utils.lifecycleAwareVariable
class NoteDialog : DialogFragment() {
private var binding: DialogNoteBinding by lifecycleAwareVariable()
private lateinit var note: Note
companion object {
@ -37,19 +40,22 @@ class NoteDialog : DialogFragment() {
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_note, container, false)
return DialogNoteBinding.inflate(inflater).apply { binding = this }.root
}
@SuppressLint("SetTextI18n")
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
noteDialogDate.text = note.date.toFormattedString()
noteDialogCategory.text = note.category
noteDialogTeacher.text = note.teacher
noteDialogContent.text = note.content
with(binding) {
noteDialogDate.text = note.date.toFormattedString()
noteDialogCategory.text = note.category
noteDialogTeacher.text = note.teacher
noteDialogContent.text = note.content
}
if (note.isPointsShow) {
with(noteDialogPoints) {
with(binding.noteDialogPoints) {
text = "${if (note.points > 0) "+" else ""}${note.points}"
setTextColor(when (CategoryType.getByValue(note.categoryType)) {
CategoryType.POSITIVE -> ContextCompat.getColor(requireContext(), R.color.note_positive)
@ -58,6 +64,7 @@ class NoteDialog : DialogFragment() {
})
}
}
noteDialogClose.setOnClickListener { dismiss() }
binding.noteDialogClose.setOnClickListener { dismiss() }
}
}

View File

@ -1,22 +1,21 @@
package io.github.wulkanowy.ui.modules.note
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Note
import io.github.wulkanowy.databinding.FragmentNoteBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import kotlinx.android.synthetic.main.fragment_note.*
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import javax.inject.Inject
class NoteFragment : BaseFragment(), NoteView, MainView.TitledView {
class NoteFragment : BaseFragment<FragmentNoteBinding>(R.layout.fragment_note), NoteView,
MainView.TitledView {
@Inject
lateinit var presenter: NotePresenter
@ -34,26 +33,25 @@ class NoteFragment : BaseFragment(), NoteView, MainView.TitledView {
override val isViewEmpty: Boolean
get() = noteAdapter.items.isEmpty()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_note, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentNoteBinding.bind(view)
presenter.onAttachView(this)
}
override fun initView() {
noteAdapter.onClickListener = presenter::onNoteItemSelected
noteRecycler.run {
with(binding.noteRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = noteAdapter
addItemDecoration(DividerItemDecoration(context))
}
noteSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
noteErrorRetry.setOnClickListener { presenter.onRetry() }
noteErrorDetails.setOnClickListener { presenter.onDetailsClick() }
with(binding) {
noteSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
noteErrorRetry.setOnClickListener { presenter.onRetry() }
noteErrorDetails.setOnClickListener { presenter.onDetailsClick() }
}
}
override fun showNoteDialog(note: Note) {
@ -82,31 +80,31 @@ class NoteFragment : BaseFragment(), NoteView, MainView.TitledView {
}
override fun showEmpty(show: Boolean) {
noteEmpty.visibility = if (show) VISIBLE else GONE
binding.noteEmpty.visibility = if (show) VISIBLE else GONE
}
override fun showErrorView(show: Boolean) {
noteError.visibility = if (show) VISIBLE else GONE
binding.noteError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
noteErrorMessage.text = message
binding.noteErrorMessage.text = message
}
override fun showProgress(show: Boolean) {
noteProgress.visibility = if (show) VISIBLE else GONE
binding.noteProgress.visibility = if (show) VISIBLE else GONE
}
override fun enableSwipe(enable: Boolean) {
noteSwipe.isEnabled = enable
binding.noteSwipe.isEnabled = enable
}
override fun showContent(show: Boolean) {
noteRecycler.visibility = if (show) VISIBLE else GONE
binding.noteRecycler.visibility = if (show) VISIBLE else GONE
}
override fun hideRefresh() {
noteSwipe.isRefreshing = false
binding.noteSwipe.isRefreshing = false
}
override fun onDestroyView() {

View File

@ -1,12 +1,11 @@
package io.github.wulkanowy.ui.modules.schoolandteachers
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import android.view.ViewGroup
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.FragmentSchoolandteachersBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.modules.main.MainView
@ -14,10 +13,11 @@ import io.github.wulkanowy.ui.modules.schoolandteachers.school.SchoolFragment
import io.github.wulkanowy.ui.modules.schoolandteachers.teacher.TeacherFragment
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.setOnSelectPageListener
import kotlinx.android.synthetic.main.fragment_schoolandteachers.*
import javax.inject.Inject
class SchoolAndTeachersFragment : BaseFragment(), SchoolAndTeachersView, MainView.TitledView {
class SchoolAndTeachersFragment :
BaseFragment<FragmentSchoolandteachersBinding>(R.layout.fragment_schoolandteachers),
SchoolAndTeachersView, MainView.TitledView {
@Inject
lateinit var presenter: SchoolAndTeachersPresenter
@ -31,45 +31,44 @@ class SchoolAndTeachersFragment : BaseFragment(), SchoolAndTeachersView, MainVie
override val titleStringId: Int get() = R.string.schoolandteachers_title
override val currentPageIndex get() = schoolandteachersViewPager.currentItem
override val currentPageIndex get() = binding.schoolandteachersViewPager.currentItem
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_schoolandteachers, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentSchoolandteachersBinding.bind(view)
presenter.onAttachView(this)
}
override fun initView() {
with(pagerAdapter) {
containerId = schoolandteachersViewPager.id
containerId = binding.schoolandteachersViewPager.id
addFragmentsWithTitle(mapOf(
SchoolFragment.newInstance() to getString(R.string.school_title),
TeacherFragment.newInstance() to getString(R.string.teachers_title)
))
}
with(schoolandteachersViewPager) {
with(binding.schoolandteachersViewPager) {
adapter = pagerAdapter
offscreenPageLimit = 2
setOnSelectPageListener(presenter::onPageSelected)
}
with(schoolandteachersTabLayout) {
setupWithViewPager(schoolandteachersViewPager)
with(binding.schoolandteachersTabLayout) {
setupWithViewPager(binding.schoolandteachersViewPager)
setElevationCompat(context.dpToPx(4f))
}
}
override fun showContent(show: Boolean) {
schoolandteachersViewPager.visibility = if (show) VISIBLE else INVISIBLE
schoolandteachersTabLayout.visibility = if (show) VISIBLE else INVISIBLE
with(binding) {
schoolandteachersViewPager.visibility = if (show) VISIBLE else INVISIBLE
schoolandteachersTabLayout.visibility = if (show) VISIBLE else INVISIBLE
}
}
override fun showProgress(show: Boolean) {
schoolandteachersProgress.visibility = if (show) VISIBLE else INVISIBLE
binding.schoolandteachersProgress.visibility = if (show) VISIBLE else INVISIBLE
}
fun onChildFragmentLoaded() {

View File

@ -1,89 +1,89 @@
package io.github.wulkanowy.ui.modules.schoolandteachers.school
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.databinding.FragmentSchoolBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersChildView
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment
import io.github.wulkanowy.utils.openDialer
import io.github.wulkanowy.utils.openNavigation
import kotlinx.android.synthetic.main.fragment_school.*
import javax.inject.Inject
class SchoolFragment : BaseFragment(), SchoolView, MainView.TitledView, SchoolAndTeachersChildView {
class SchoolFragment : BaseFragment<FragmentSchoolBinding>(R.layout.fragment_school), SchoolView,
MainView.TitledView, SchoolAndTeachersChildView {
@Inject
lateinit var presenter: SchoolPresenter
override val titleStringId get() = R.string.school_title
override val isViewEmpty get() = schoolName.text.isBlank()
override val isViewEmpty get() = binding.schoolName.text.isBlank()
companion object {
fun newInstance() = SchoolFragment()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_school, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentSchoolBinding.bind(view)
presenter.onAttachView(this)
}
override fun initView() {
schoolSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
schoolErrorRetry.setOnClickListener { presenter.onRetry() }
schoolErrorDetails.setOnClickListener { presenter.onDetailsClick() }
with(binding) {
schoolSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
schoolErrorRetry.setOnClickListener { presenter.onRetry() }
schoolErrorDetails.setOnClickListener { presenter.onDetailsClick() }
schoolAddressButton.setOnClickListener { presenter.onAddressSelected() }
schoolTelephoneButton.setOnClickListener { presenter.onTelephoneSelected() }
schoolAddressButton.setOnClickListener { presenter.onAddressSelected() }
schoolTelephoneButton.setOnClickListener { presenter.onTelephoneSelected() }
}
}
override fun updateData(data: School) {
schoolName.text = data.name
schoolAddress.text = data.address.ifBlank { "-" }
schoolAddressButton.visibility = if (data.address.isNotBlank()) VISIBLE else GONE
schoolTelephone.text = data.contact.ifBlank { "-" }
schoolTelephoneButton.visibility = if (data.contact.isNotBlank()) VISIBLE else GONE
schoolHeadmaster.text = data.headmaster
schoolPedagogue.text = data.pedagogue
with(binding) {
schoolName.text = data.name
schoolAddress.text = data.address.ifBlank { "-" }
schoolAddressButton.visibility = if (data.address.isNotBlank()) VISIBLE else GONE
schoolTelephone.text = data.contact.ifBlank { "-" }
schoolTelephoneButton.visibility = if (data.contact.isNotBlank()) VISIBLE else GONE
schoolHeadmaster.text = data.headmaster
schoolPedagogue.text = data.pedagogue
}
}
override fun showEmpty(show: Boolean) {
schoolEmpty.visibility = if (show) VISIBLE else GONE
binding.schoolEmpty.visibility = if (show) VISIBLE else GONE
}
override fun showErrorView(show: Boolean) {
schoolError.visibility = if (show) VISIBLE else GONE
binding.schoolError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
schoolErrorMessage.text = message
binding.schoolErrorMessage.text = message
}
override fun showProgress(show: Boolean) {
schoolProgress.visibility = if (show) VISIBLE else GONE
binding.schoolProgress.visibility = if (show) VISIBLE else GONE
}
override fun enableSwipe(enable: Boolean) {
schoolSwipe.isEnabled = enable
binding.schoolSwipe.isEnabled = enable
}
override fun showContent(show: Boolean) {
schoolContent.visibility = if (show) VISIBLE else GONE
binding.schoolContent.visibility = if (show) VISIBLE else GONE
}
override fun hideRefresh() {
schoolSwipe.isRefreshing = false
binding.schoolSwipe.isRefreshing = false
}
override fun notifyParentDataLoaded() {

View File

@ -1,24 +1,22 @@
package io.github.wulkanowy.ui.modules.schoolandteachers.teacher
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Teacher
import io.github.wulkanowy.databinding.FragmentTeacherBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersChildView
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment
import kotlinx.android.synthetic.main.fragment_teacher.*
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import javax.inject.Inject
class TeacherFragment : BaseFragment(), TeacherView, MainView.TitledView,
SchoolAndTeachersChildView {
class TeacherFragment : BaseFragment<FragmentTeacherBinding>(R.layout.fragment_teacher),
TeacherView, MainView.TitledView, SchoolAndTeachersChildView {
@Inject
lateinit var presenter: TeacherPresenter
@ -38,24 +36,23 @@ class TeacherFragment : BaseFragment(), TeacherView, MainView.TitledView,
override val isViewEmpty: Boolean
get() = teacherAdapter.items.isEmpty()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_teacher, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentTeacherBinding.bind(view)
presenter.onAttachView(this)
}
override fun initView() {
teacherRecycler.run {
with(binding.teacherRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = teacherAdapter
addItemDecoration(DividerItemDecoration(context))
}
teacherSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
teacherErrorRetry.setOnClickListener { presenter.onRetry() }
teacherErrorDetails.setOnClickListener { presenter.onDetailsClick() }
with(binding) {
teacherSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
teacherErrorRetry.setOnClickListener { presenter.onRetry() }
teacherErrorDetails.setOnClickListener { presenter.onDetailsClick() }
}
}
override fun updateData(data: List<Teacher>) {
@ -66,31 +63,31 @@ class TeacherFragment : BaseFragment(), TeacherView, MainView.TitledView,
}
override fun showEmpty(show: Boolean) {
teacherEmpty.visibility = if (show) VISIBLE else GONE
binding.teacherEmpty.visibility = if (show) VISIBLE else GONE
}
override fun showErrorView(show: Boolean) {
teacherError.visibility = if (show) VISIBLE else GONE
binding.teacherError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
teacherErrorMessage.text = message
binding.teacherErrorMessage.text = message
}
override fun showProgress(show: Boolean) {
teacherProgress.visibility = if (show) VISIBLE else GONE
binding.teacherProgress.visibility = if (show) VISIBLE else GONE
}
override fun enableSwipe(enable: Boolean) {
teacherSwipe.isEnabled = enable
binding.teacherSwipe.isEnabled = enable
}
override fun showContent(show: Boolean) {
teacherRecycler.visibility = if (show) VISIBLE else GONE
binding.teacherRecycler.visibility = if (show) VISIBLE else GONE
}
override fun hideRefresh() {
teacherSwipe.isRefreshing = false
binding.teacherSwipe.isRefreshing = false
}
override fun notifyParentDataLoaded() {

View File

@ -91,19 +91,19 @@ class SettingsFragment : PreferenceFragmentCompat(),
}
override fun showError(text: String, error: Throwable) {
(activity as? BaseActivity<*>)?.showError(text, error)
(activity as? BaseActivity<*, *>)?.showError(text, error)
}
override fun showMessage(text: String) {
(activity as? BaseActivity<*>)?.showMessage(text)
(activity as? BaseActivity<*, *>)?.showMessage(text)
}
override fun showExpiredDialog() {
(activity as? BaseActivity<*>)?.showExpiredDialog()
(activity as? BaseActivity<*, *>)?.showExpiredDialog()
}
override fun openClearLoginView() {
(activity as? BaseActivity<*>)?.openClearLoginView()
(activity as? BaseActivity<*, *>)?.openClearLoginView()
}
override fun showErrorDetailsDialog(error: Throwable) {

View File

@ -3,12 +3,13 @@ package io.github.wulkanowy.ui.modules.splash
import android.os.Bundle
import android.widget.Toast
import android.widget.Toast.LENGTH_LONG
import androidx.viewbinding.ViewBinding
import io.github.wulkanowy.ui.base.BaseActivity
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.ui.modules.main.MainActivity
import javax.inject.Inject
class SplashActivity : BaseActivity<SplashPresenter>(), SplashView {
class SplashActivity : BaseActivity<SplashPresenter, ViewBinding>(), SplashView {
@Inject
override lateinit var presenter: SplashPresenter

View File

@ -11,13 +11,16 @@ import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.databinding.DialogTimetableBinding
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.lifecycleAwareVariable
import io.github.wulkanowy.utils.toFormattedString
import kotlinx.android.synthetic.main.dialog_timetable.*
import org.threeten.bp.LocalDateTime
class TimetableDialog : DialogFragment() {
private var binding: DialogTimetableBinding by lifecycleAwareVariable()
private lateinit var lesson: Timetable
companion object {
@ -39,13 +42,13 @@ class TimetableDialog : DialogFragment() {
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_timetable, container, false)
return DialogTimetableBinding.inflate(inflater).apply { binding = this }.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
lesson.run {
with(lesson) {
setInfo(info, teacher, canceled, changes)
setSubject(subject, subjectOld)
setTeacher(teacher, teacherOld)
@ -54,74 +57,81 @@ class TimetableDialog : DialogFragment() {
setTime(start, end)
}
timetableDialogClose.setOnClickListener { dismiss() }
binding.timetableDialogClose.setOnClickListener { dismiss() }
}
private fun setSubject(subject: String, subjectOld: String) {
timetableDialogSubject.text = subject
if (subjectOld.isNotBlank() && subjectOld != subject) {
timetableDialogSubject.run {
paintFlags = paintFlags or STRIKE_THRU_TEXT_FLAG
text = subjectOld
}
timetableDialogSubjectNew.run {
visibility = VISIBLE
text = subject
with(binding) {
timetableDialogSubject.text = subject
if (subjectOld.isNotBlank() && subjectOld != subject) {
timetableDialogSubject.run {
paintFlags = paintFlags or STRIKE_THRU_TEXT_FLAG
text = subjectOld
}
timetableDialogSubjectNew.run {
visibility = VISIBLE
text = subject
}
}
}
}
private fun setInfo(info: String, teacher: String, canceled: Boolean, changes: Boolean) {
when {
info.isNotBlank() -> {
if (canceled) {
timetableDialogChangesTitle.setTextColor(requireContext().getThemeAttrColor(R.attr.colorPrimary))
timetableDialogChanges.setTextColor(requireContext().getThemeAttrColor(R.attr.colorPrimary))
} else {
timetableDialogChangesTitle.setTextColor(requireContext().getThemeAttrColor(R.attr.colorTimetableChange))
timetableDialogChanges.setTextColor(requireContext().getThemeAttrColor(R.attr.colorTimetableChange))
}
with(binding) {
when {
info.isNotBlank() -> {
if (canceled) {
timetableDialogChangesTitle.setTextColor(requireContext().getThemeAttrColor(R.attr.colorPrimary))
timetableDialogChanges.setTextColor(requireContext().getThemeAttrColor(R.attr.colorPrimary))
} else {
timetableDialogChangesTitle.setTextColor(requireContext().getThemeAttrColor(R.attr.colorTimetableChange))
timetableDialogChanges.setTextColor(requireContext().getThemeAttrColor(R.attr.colorTimetableChange))
}
timetableDialogChanges.text = when {
canceled && !changes -> "Lekcja odwołana: $info"
changes && teacher.isNotBlank() -> "Zastępstwo: $teacher"
changes && teacher.isBlank() -> "Zastępstwo, ${info.decapitalize()}"
else -> info.capitalize()
timetableDialogChanges.text = when {
canceled && !changes -> "Lekcja odwołana: $info"
changes && teacher.isNotBlank() -> "Zastępstwo: $teacher"
changes && teacher.isBlank() -> "Zastępstwo, ${info.decapitalize()}"
else -> info.capitalize()
}
}
else -> {
timetableDialogChangesTitle.visibility = GONE
timetableDialogChanges.visibility = GONE
}
} else -> {
timetableDialogChangesTitle.visibility = GONE
timetableDialogChanges.visibility = GONE
}
}
}
private fun setTeacher(teacher: String, teacherOld: String) {
when {
teacherOld.isNotBlank() && teacherOld != teacher -> {
timetableDialogTeacher.run {
visibility = VISIBLE
paintFlags = paintFlags or STRIKE_THRU_TEXT_FLAG
text = teacherOld
}
if (teacher.isNotBlank()) {
timetableDialogTeacherNew.run {
with(binding) {
when {
teacherOld.isNotBlank() && teacherOld != teacher -> {
timetableDialogTeacher.run {
visibility = VISIBLE
text = teacher
paintFlags = paintFlags or STRIKE_THRU_TEXT_FLAG
text = teacherOld
}
if (teacher.isNotBlank()) {
timetableDialogTeacherNew.run {
visibility = VISIBLE
text = teacher
}
}
}
}
teacher.isNotBlank() -> timetableDialogTeacher.text = teacher
else -> {
timetableDialogTeacherTitle.visibility = GONE
timetableDialogTeacher.visibility = GONE
teacher.isNotBlank() -> timetableDialogTeacher.text = teacher
else -> {
timetableDialogTeacherTitle.visibility = GONE
timetableDialogTeacher.visibility = GONE
}
}
}
}
private fun setGroup(group: String) {
group.let {
with(binding) {
when {
it.isNotBlank() -> timetableDialogGroup.text = it
group.isNotBlank() -> timetableDialogGroup.text = group
else -> {
timetableDialogGroupTitle.visibility = GONE
timetableDialogGroup.visibility = GONE
@ -131,30 +141,32 @@ class TimetableDialog : DialogFragment() {
}
private fun setRoom(room: String, roomOld: String) {
when {
roomOld.isNotBlank() && roomOld != room -> {
timetableDialogRoom.run {
visibility = VISIBLE
paintFlags = paintFlags or STRIKE_THRU_TEXT_FLAG
text = roomOld
}
if (room.isNotBlank()) {
timetableDialogRoomNew.run {
with(binding) {
when {
roomOld.isNotBlank() && roomOld != room -> {
timetableDialogRoom.run {
visibility = VISIBLE
text = room
paintFlags = paintFlags or STRIKE_THRU_TEXT_FLAG
text = roomOld
}
if (room.isNotBlank()) {
timetableDialogRoomNew.run {
visibility = VISIBLE
text = room
}
}
}
}
room.isNotBlank() -> timetableDialogRoom.text = room
else -> {
timetableDialogRoomTitle.visibility = GONE
timetableDialogRoom.visibility = GONE
room.isNotBlank() -> timetableDialogRoom.text = room
else -> {
timetableDialogRoomTitle.visibility = GONE
timetableDialogRoom.visibility = GONE
}
}
}
}
@SuppressLint("SetTextI18n")
private fun setTime(start: LocalDateTime, end: LocalDateTime) {
timetableDialogTime.text = "${start.toFormattedString("HH:mm")} - ${end.toFormattedString("HH:mm")}"
binding.timetableDialogTime.text = "${start.toFormattedString("HH:mm")} - ${end.toFormattedString("HH:mm")}"
}
}

View File

@ -1,31 +1,29 @@
package io.github.wulkanowy.ui.modules.timetable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.databinding.FragmentTimetableBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.timetable.completed.CompletedLessonsFragment
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.SchooldaysRangeLimiter
import io.github.wulkanowy.utils.dpToPx
import kotlinx.android.synthetic.main.fragment_timetable.*
import org.threeten.bp.LocalDate
import javax.inject.Inject
class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView,
MainView.TitledView {
class TimetableFragment : BaseFragment<FragmentTimetableBinding>(R.layout.fragment_timetable),
TimetableView, MainView.MainChildView, MainView.TitledView {
@Inject
lateinit var presenter: TimetablePresenter
@ -50,34 +48,33 @@ class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView,
setHasOptionsMenu(true)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_timetable, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
messageContainer = timetableRecycler
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentTimetableBinding.bind(view)
messageContainer = binding.timetableRecycler
presenter.onAttachView(this, savedInstanceState?.getLong(SAVED_DATE_KEY))
}
override fun initView() {
timetableAdapter.onClickListener = presenter::onTimetableItemSelected
with(timetableRecycler) {
with(binding.timetableRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = timetableAdapter
addItemDecoration(DividerItemDecoration(context))
}
timetableSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
timetableErrorRetry.setOnClickListener { presenter.onRetry() }
timetableErrorDetails.setOnClickListener { presenter.onDetailsClick() }
with(binding) {
timetableSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
timetableErrorRetry.setOnClickListener { presenter.onRetry() }
timetableErrorDetails.setOnClickListener { presenter.onDetailsClick() }
timetablePreviousButton.setOnClickListener { presenter.onPreviousDay() }
timetableNavDate.setOnClickListener { presenter.onPickDate() }
timetableNextButton.setOnClickListener { presenter.onNextDay() }
timetablePreviousButton.setOnClickListener { presenter.onPreviousDay() }
timetableNavDate.setOnClickListener { presenter.onPickDate() }
timetableNextButton.setOnClickListener { presenter.onNextDay() }
timetableNavContainer.setElevationCompat(requireContext().dpToPx(8f))
timetableNavContainer.setElevationCompat(requireContext().dpToPx(8f))
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
@ -105,15 +102,15 @@ class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView,
}
override fun updateNavigationDay(date: String) {
timetableNavDate.text = date
binding.timetableNavDate.text = date
}
override fun hideRefresh() {
timetableSwipe.isRefreshing = false
binding.timetableSwipe.isRefreshing = false
}
override fun resetView() {
timetableRecycler.smoothScrollToPosition(0)
binding.timetableRecycler.smoothScrollToPosition(0)
}
override fun onFragmentReselected() {
@ -125,35 +122,35 @@ class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView,
}
override fun showEmpty(show: Boolean) {
timetableEmpty.visibility = if (show) VISIBLE else GONE
binding.timetableEmpty.visibility = if (show) VISIBLE else GONE
}
override fun showErrorView(show: Boolean) {
timetableError.visibility = if (show) VISIBLE else GONE
binding.timetableError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
timetableErrorMessage.text = message
binding.timetableErrorMessage.text = message
}
override fun showProgress(show: Boolean) {
timetableProgress.visibility = if (show) VISIBLE else GONE
binding.timetableProgress.visibility = if (show) VISIBLE else GONE
}
override fun enableSwipe(enable: Boolean) {
timetableSwipe.isEnabled = enable
binding.timetableSwipe.isEnabled = enable
}
override fun showContent(show: Boolean) {
timetableRecycler.visibility = if (show) VISIBLE else GONE
binding.timetableRecycler.visibility = if (show) VISIBLE else GONE
}
override fun showPreButton(show: Boolean) {
timetablePreviousButton.visibility = if (show) VISIBLE else View.INVISIBLE
binding.timetablePreviousButton.visibility = if (show) VISIBLE else View.INVISIBLE
}
override fun showNextButton(show: Boolean) {
timetableNextButton.visibility = if (show) VISIBLE else View.INVISIBLE
binding.timetableNextButton.visibility = if (show) VISIBLE else View.INVISIBLE
}
override fun showTimetableDialog(lesson: Timetable) {

View File

@ -6,12 +6,14 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.CompletedLesson
import kotlinx.android.synthetic.main.dialog_lesson_completed.*
import io.github.wulkanowy.databinding.DialogLessonCompletedBinding
import io.github.wulkanowy.utils.lifecycleAwareVariable
class CompletedLessonDialog : DialogFragment() {
private var binding: DialogLessonCompletedBinding by lifecycleAwareVariable()
private lateinit var completedLesson: CompletedLesson
companion object {
@ -28,46 +30,54 @@ class CompletedLessonDialog : DialogFragment() {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
arguments?.run {
completedLesson = getSerializable(CompletedLessonDialog.ARGUMENT_KEY) as CompletedLesson
completedLesson = getSerializable(ARGUMENT_KEY) as CompletedLesson
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_lesson_completed, container, false)
return DialogLessonCompletedBinding.inflate(inflater).apply { binding = this }.root
}
@SuppressLint("SetTextI18n")
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
completedLessonDialogSubject.text = completedLesson.subject
completedLessonDialogTopic.text = completedLesson.topic
completedLessonDialogTeacher.text = completedLesson.teacher
completedLessonDialogAbsence.text = completedLesson.absence
completedLessonDialogChanges.text = completedLesson.substitution
completedLessonDialogResources.text = completedLesson.resources
with(binding) {
completedLessonDialogSubject.text = completedLesson.subject
completedLessonDialogTopic.text = completedLesson.topic
completedLessonDialogTeacher.text = completedLesson.teacher
completedLessonDialogAbsence.text = completedLesson.absence
completedLessonDialogChanges.text = completedLesson.substitution
completedLessonDialogResources.text = completedLesson.resources
}
completedLesson.substitution.let {
if (it.isBlank()) {
completedLessonDialogChangesTitle.visibility = View.GONE
completedLessonDialogChanges.visibility = View.GONE
} else completedLessonDialogChanges.text = it
with(binding) {
completedLessonDialogChangesTitle.visibility = View.GONE
completedLessonDialogChanges.visibility = View.GONE
}
} else binding.completedLessonDialogChanges.text = it
}
completedLesson.absence.let {
if (it.isBlank()) {
completedLessonDialogAbsenceTitle.visibility = View.GONE
completedLessonDialogAbsence.visibility = View.GONE
} else completedLessonDialogAbsence.text = it
with(binding) {
completedLessonDialogAbsenceTitle.visibility = View.GONE
completedLessonDialogAbsence.visibility = View.GONE
}
} else binding.completedLessonDialogAbsence.text = it
}
completedLesson.resources.let {
if (it.isBlank()) {
completedLessonDialogResourcesTitle.visibility = View.GONE
completedLessonDialogResources.visibility = View.GONE
} else completedLessonDialogResources.text = it
with(binding) {
completedLessonDialogResourcesTitle.visibility = View.GONE
completedLessonDialogResources.visibility = View.GONE
}
} else binding.completedLessonDialogResources.text = it
}
completedLessonDialogClose.setOnClickListener { dismiss() }
binding.completedLessonDialogClose.setOnClickListener { dismiss() }
}
}

View File

@ -1,28 +1,28 @@
package io.github.wulkanowy.ui.modules.timetable.completed
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.databinding.FragmentTimetableCompletedBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.SchooldaysRangeLimiter
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.getCompatDrawable
import kotlinx.android.synthetic.main.fragment_timetable_completed.*
import org.threeten.bp.LocalDate
import javax.inject.Inject
class CompletedLessonsFragment : BaseFragment(), CompletedLessonsView, MainView.TitledView {
class CompletedLessonsFragment :
BaseFragment<FragmentTimetableCompletedBinding>(R.layout.fragment_timetable_completed),
CompletedLessonsView, MainView.TitledView {
@Inject
lateinit var presenter: CompletedLessonsPresenter
@ -40,34 +40,33 @@ class CompletedLessonsFragment : BaseFragment(), CompletedLessonsView, MainView.
override val isViewEmpty get() = completedLessonsAdapter.items.isEmpty()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_timetable_completed, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
messageContainer = completedLessonsRecycler
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentTimetableCompletedBinding.bind(view)
messageContainer = binding.completedLessonsRecycler
presenter.onAttachView(this, savedInstanceState?.getLong(SAVED_DATE_KEY))
}
override fun initView() {
completedLessonsAdapter.onClickListener = presenter::onCompletedLessonsItemSelected
with(completedLessonsRecycler) {
with(binding.completedLessonsRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = completedLessonsAdapter
addItemDecoration(DividerItemDecoration(context))
}
completedLessonsSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
completedLessonErrorRetry.setOnClickListener { presenter.onRetry() }
completedLessonErrorDetails.setOnClickListener { presenter.onDetailsClick() }
with(binding) {
completedLessonsSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
completedLessonErrorRetry.setOnClickListener { presenter.onRetry() }
completedLessonErrorDetails.setOnClickListener { presenter.onDetailsClick() }
completedLessonsPreviousButton.setOnClickListener { presenter.onPreviousDay() }
completedLessonsNavDate.setOnClickListener { presenter.onPickDate() }
completedLessonsNextButton.setOnClickListener { presenter.onNextDay() }
completedLessonsPreviousButton.setOnClickListener { presenter.onPreviousDay() }
completedLessonsNavDate.setOnClickListener { presenter.onPickDate() }
completedLessonsNextButton.setOnClickListener { presenter.onNextDay() }
completedLessonsNavContainer.setElevationCompat(requireContext().dpToPx(8f))
completedLessonsNavContainer.setElevationCompat(requireContext().dpToPx(8f))
}
}
override fun updateData(data: List<CompletedLesson>) {
@ -85,48 +84,50 @@ class CompletedLessonsFragment : BaseFragment(), CompletedLessonsView, MainView.
}
override fun updateNavigationDay(date: String) {
completedLessonsNavDate.text = date
binding.completedLessonsNavDate.text = date
}
override fun hideRefresh() {
completedLessonsSwipe.isRefreshing = false
binding.completedLessonsSwipe.isRefreshing = false
}
override fun showEmpty(show: Boolean) {
completedLessonsEmpty.visibility = if (show) VISIBLE else GONE
binding.completedLessonsEmpty.visibility = if (show) VISIBLE else GONE
}
override fun showErrorView(show: Boolean) {
completedLessonError.visibility = if (show) VISIBLE else GONE
binding.completedLessonError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
completedLessonErrorMessage.text = message
binding.completedLessonErrorMessage.text = message
}
override fun showFeatureDisabled() {
completedLessonsInfo.text = getString(R.string.error_feature_disabled)
completedLessonsInfoImage.setImageDrawable(requireContext().getCompatDrawable(R.drawable.ic_all_close_circle))
with(binding) {
completedLessonsInfo.text = getString(R.string.error_feature_disabled)
completedLessonsInfoImage.setImageDrawable(requireContext().getCompatDrawable(R.drawable.ic_all_close_circle))
}
}
override fun showProgress(show: Boolean) {
completedLessonsProgress.visibility = if (show) VISIBLE else GONE
binding.completedLessonsProgress.visibility = if (show) VISIBLE else GONE
}
override fun enableSwipe(enable: Boolean) {
completedLessonsSwipe.isEnabled = enable
binding.completedLessonsSwipe.isEnabled = enable
}
override fun showContent(show: Boolean) {
completedLessonsRecycler.visibility = if (show) VISIBLE else GONE
binding.completedLessonsRecycler.visibility = if (show) VISIBLE else GONE
}
override fun showPreButton(show: Boolean) {
completedLessonsPreviousButton.visibility = if (show) VISIBLE else INVISIBLE
binding.completedLessonsPreviousButton.visibility = if (show) VISIBLE else INVISIBLE
}
override fun showNextButton(show: Boolean) {
completedLessonsNextButton.visibility = if (show) VISIBLE else INVISIBLE
binding.completedLessonsNextButton.visibility = if (show) VISIBLE else INVISIBLE
}
override fun showCompletedLessonDialog(completedLesson: CompletedLesson) {

View File

@ -11,14 +11,15 @@ import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.databinding.ActivityWidgetConfigureBinding
import io.github.wulkanowy.ui.base.BaseActivity
import io.github.wulkanowy.ui.base.WidgetConfigureAdapter
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.EXTRA_FROM_PROVIDER
import kotlinx.android.synthetic.main.activity_widget_configure.*
import javax.inject.Inject
class TimetableWidgetConfigureActivity : BaseActivity<TimetableWidgetConfigurePresenter>(),
class TimetableWidgetConfigureActivity :
BaseActivity<TimetableWidgetConfigurePresenter, ActivityWidgetConfigureBinding>(),
TimetableWidgetConfigureView {
@Inject
@ -32,7 +33,7 @@ class TimetableWidgetConfigureActivity : BaseActivity<TimetableWidgetConfigurePr
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setResult(RESULT_CANCELED)
setContentView(R.layout.activity_widget_configure)
setContentView(ActivityWidgetConfigureBinding.inflate(layoutInflater).apply { binding = this }.root)
intent.extras.let {
presenter.onAttachView(this, it?.getInt(EXTRA_APPWIDGET_ID), it?.getBoolean(EXTRA_FROM_PROVIDER))
@ -40,7 +41,7 @@ class TimetableWidgetConfigureActivity : BaseActivity<TimetableWidgetConfigurePr
}
override fun initView() {
with(widgetConfigureRecycler) {
with(binding.widgetConfigureRecycler) {
adapter = configureAdapter
layoutManager = LinearLayoutManager(context)
}

View File

@ -0,0 +1,55 @@
package io.github.wulkanowy.utils
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class LifecycleAwareVariable<T : Any> : ReadWriteProperty<Fragment, T>, LifecycleObserver {
private var _value: T? = null
override fun setValue(thisRef: Fragment, property: KProperty<*>, value: T) {
thisRef.viewLifecycleOwner.lifecycle.removeObserver(this)
_value = value
thisRef.viewLifecycleOwner.lifecycle.addObserver(this)
}
override fun getValue(thisRef: Fragment, property: KProperty<*>) = _value
?: throw IllegalStateException("Trying to call an lifecycle-aware value outside of the view lifecycle, or the value has not been initialized")
@Suppress("unused")
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroyView() {
_value = null
}
}
class LifecycleAwareVariableActivity<T : Any> : ReadWriteProperty<AppCompatActivity, T>, LifecycleObserver {
private var _value: T? = null
override fun setValue(thisRef: AppCompatActivity, property: KProperty<*>, value: T) {
thisRef.lifecycle.removeObserver(this)
_value = value
thisRef.lifecycle.addObserver(this)
}
override fun getValue(thisRef: AppCompatActivity, property: KProperty<*>) = _value
?: throw IllegalStateException("Trying to call an lifecycle-aware value outside of the view lifecycle, or the value has not been initialized")
@Suppress("unused")
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroyView() {
_value = null
}
}
@Suppress("unused")
fun <T : Any> Fragment.lifecycleAwareVariable() = LifecycleAwareVariable<T>()
fun <T : Any> AppCompatActivity.lifecycleAwareVariable() = LifecycleAwareVariableActivity<T>()

View File

@ -1,10 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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/aboutRecycler"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
tools:listitem="@layout/item_about" />
</FrameLayout>