1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2024-09-19 22:39:09 -05:00

Migrate to material3 (#1660)

Co-authored-by: Rafał Borcz <RafalBO99@outlook.com>
Co-authored-by: doteq <doteeqq@gmail.com>
Co-authored-by: Bartosz Bieniek <itsbk20@gmail.com>
This commit is contained in:
Damian Czupryn 2023-03-29 22:14:29 +02:00 committed by GitHub
parent 349307b6a3
commit bb7e927065
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
179 changed files with 2019 additions and 2372 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/colorPrimary" />
<background android:drawable="@color/colorIcon" />
<foreground android:drawable="@drawable/ic_launcher_foreground_dev" />
<monochrome android:drawable="@drawable/ic_launcher_foreground_dev_mono" />
</adaptive-icon>

View File

@ -72,7 +72,7 @@
android:name=".ui.modules.message.send.SendMessageActivity"
android:configChanges="orientation|screenSize"
android:label="@string/send_message_title"
android:theme="@style/WulkanowyTheme.MessageSend"
android:theme="@style/WulkanowyTheme.NoActionBar"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ui.modules.timetablewidget.TimetableWidgetConfigureActivity"

View File

@ -201,13 +201,6 @@ class PreferencesRepository @Inject constructor(
R.bool.pref_default_timetable_show_timers
)
var isHomeworkFullscreen: Boolean
get() = getBoolean(
R.string.pref_key_homework_fullscreen,
R.bool.pref_default_homework_fullscreen
)
set(value) = sharedPref.edit().putBoolean("homework_fullscreen", value).apply()
val showSubjectsWithoutGrades: Boolean
get() = getBoolean(
R.string.pref_key_subjects_without_grades,

View File

@ -13,6 +13,7 @@ import io.github.wulkanowy.utils.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.sync.Mutex
import java.time.Instant
import java.time.LocalDate
import javax.inject.Inject
import javax.inject.Singleton
@ -164,6 +165,11 @@ class TimetableRepository @Inject constructor(
timetableHeaderDb.insertAll(new uniqueSubtract old)
}
fun getLastRefreshTimestamp(semester: Semester, start: LocalDate, end: LocalDate): Instant {
val refreshKey = getRefreshKey(cacheKey, semester, start, end)
return refreshHelper.getLastRefreshTimestamp(refreshKey)
}
suspend fun saveAdditionalList(additionalList: List<TimetableAdditional>) =
timetableAdditionalDb.insertAll(additionalList)

View File

@ -4,7 +4,6 @@ import android.content.Intent
import android.widget.RemoteViewsService
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.SemesterRepository
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.repositories.TimetableRepository
@ -24,14 +23,13 @@ class TimetableWidgetService : RemoteViewsService() {
@Inject
lateinit var semesterRepo: SemesterRepository
@Inject
lateinit var prefRepository: PreferencesRepository
@Inject
lateinit var sharedPref: SharedPrefProvider
override fun onGetViewFactory(intent: Intent?): RemoteViewsFactory {
Timber.d("TimetableWidgetFactory created")
return TimetableWidgetFactory(timetableRepo, studentRepo, semesterRepo, prefRepository, sharedPref, applicationContext, intent)
return TimetableWidgetFactory(
timetableRepo, studentRepo, semesterRepo, sharedPref, applicationContext, intent
)
}
}

View File

@ -4,9 +4,9 @@ import android.app.ActivityManager
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
import io.github.wulkanowy.R
@ -30,6 +30,8 @@ abstract class BaseActivity<T : BasePresenter<out BaseView>, VB : ViewBinding> :
protected var messageContainer: View? = null
protected var messageAnchor: View? = null
abstract var presenter: T
override fun onCreate(savedInstanceState: Bundle?) {
@ -48,6 +50,7 @@ abstract class BaseActivity<T : BasePresenter<out BaseView>, VB : ViewBinding> :
if (messageContainer != null) {
Snackbar.make(messageContainer!!, text, LENGTH_LONG)
.setAction(R.string.all_details) { showErrorDetailsDialog(error) }
.apply { messageAnchor?.let { anchorView = it } }
.show()
} else showMessage(text)
}
@ -57,12 +60,15 @@ abstract class BaseActivity<T : BasePresenter<out BaseView>, VB : ViewBinding> :
}
override fun showMessage(text: String) {
if (messageContainer != null) Snackbar.make(messageContainer!!, text, LENGTH_LONG).show()
else Toast.makeText(this, text, Toast.LENGTH_LONG).show()
if (messageContainer != null) {
Snackbar.make(messageContainer!!, text, LENGTH_LONG)
.apply { messageAnchor?.let { anchorView = it } }
.show()
} else Toast.makeText(this, text, Toast.LENGTH_LONG).show()
}
override fun showExpiredDialog() {
AlertDialog.Builder(this)
MaterialAlertDialogBuilder(this)
.setTitle(R.string.main_session_expired)
.setMessage(R.string.main_session_relogin)
.setPositiveButton(R.string.main_log_in) { _, _ -> presenter.onExpiredLoginSelected() }
@ -74,6 +80,7 @@ abstract class BaseActivity<T : BasePresenter<out BaseView>, VB : ViewBinding> :
messageContainer?.let {
Snackbar.make(it, R.string.error_password_change_required, LENGTH_LONG)
.setAction(R.string.all_change) { openInternetBrowser(redirectUrl) }
.apply { messageAnchor?.let { anchorView = it } }
.show()
}
}

View File

@ -1,8 +1,14 @@
package io.github.wulkanowy.ui.base
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.annotation.CallSuper
import androidx.fragment.app.DialogFragment
import androidx.viewbinding.ViewBinding
import com.google.android.material.elevation.SurfaceColors
import io.github.wulkanowy.utils.AnalyticsHelper
import io.github.wulkanowy.utils.lifecycleAwareVariable
import javax.inject.Inject
@ -38,6 +44,19 @@ abstract class BaseDialogFragment<VB : ViewBinding> : DialogFragment(), BaseView
ErrorDialog.newInstance(error).show(childFragmentManager, error.toString())
}
@CallSuper
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.setBackgroundColor(SurfaceColors.SURFACE_3.getColor(requireContext()))
}
@CallSuper
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = binding.root
override fun onResume() {
super.onResume()
analyticsHelper.setCurrentScreen(requireActivity(), this::class.simpleName)

View File

@ -4,13 +4,13 @@ import android.app.Dialog
import android.content.ClipData
import android.content.ClipboardManager
import android.os.Bundle
import android.view.View
import android.widget.Toast
import android.widget.Toast.LENGTH_LONG
import androidx.appcompat.app.AlertDialog
import androidx.core.content.getSystemService
import androidx.core.os.bundleOf
import androidx.core.view.isGone
import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
@ -20,7 +20,7 @@ import io.github.wulkanowy.utils.*
import javax.inject.Inject
@AndroidEntryPoint
class ErrorDialog : DialogFragment() {
class ErrorDialog : BaseDialogFragment<DialogErrorBinding>() {
@Inject
lateinit var appInfo: AppInfo
@ -28,6 +28,8 @@ class ErrorDialog : DialogFragment() {
@Inject
lateinit var preferencesRepository: PreferencesRepository
private lateinit var error: Throwable
companion object {
private const val ARGUMENT_KEY = "error"
@ -36,32 +38,31 @@ class ErrorDialog : DialogFragment() {
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val error = requireArguments().serializable<Throwable>(ARGUMENT_KEY)
val binding = DialogErrorBinding.inflate(layoutInflater)
binding.bindErrorDetails(error)
return getAlertDialog(binding, error).apply {
enableReportButtonIfErrorIsReportable(error)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
error = requireArguments().serializable(ARGUMENT_KEY)
}
private fun getAlertDialog(binding: DialogErrorBinding, error: Throwable): AlertDialog {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext()).apply {
val errorStacktrace = error.stackTraceToString()
setTitle(R.string.all_details)
setView(binding.root)
setView(DialogErrorBinding.inflate(layoutInflater).apply { binding = this }.root)
setNeutralButton(R.string.about_feedback) { _, _ ->
openConfirmDialog { openEmailClient(errorStacktrace) }
}
setNegativeButton(android.R.string.cancel) { _, _ -> }
setPositiveButton(android.R.string.copy) { _, _ -> copyErrorToClipboard(errorStacktrace) }
}.create()
}.create().apply {
setOnShowListener {
getButton(AlertDialog.BUTTON_NEUTRAL).isEnabled = error.isShouldBeReported()
}
}
}
private fun DialogErrorBinding.bindErrorDetails(error: Throwable) {
return with(this) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
with(binding) {
errorDialogHumanizedMessage.text = resources.getErrorString(error)
errorDialogErrorMessage.text = error.localizedMessage
errorDialogErrorMessage.isGone = error.localizedMessage.isNullOrBlank()
@ -70,12 +71,6 @@ class ErrorDialog : DialogFragment() {
}
}
private fun AlertDialog.enableReportButtonIfErrorIsReportable(error: Throwable) {
setOnShowListener {
getButton(AlertDialog.BUTTON_NEUTRAL).isEnabled = error.isShouldBeReported()
}
}
private fun copyErrorToClipboard(errorStacktrace: String) {
val clip = ClipData.newPlainText("Error details", errorStacktrace)
requireActivity().getSystemService<ClipboardManager>()?.setPrimaryClip(clip)
@ -83,7 +78,7 @@ class ErrorDialog : DialogFragment() {
}
private fun openConfirmDialog(callback: () -> Unit) {
AlertDialog.Builder(requireContext())
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.dialog_error_check_update)
.setMessage(R.string.dialog_error_check_update_message)
.setNeutralButton(R.string.about_feedback) { _, _ -> callback() }
@ -113,8 +108,4 @@ class ErrorDialog : DialogFragment() {
}
)
}
private fun showMessage(text: String) {
Toast.makeText(requireContext(), text, LENGTH_LONG).show()
}
}

View File

@ -6,15 +6,14 @@ import android.content.pm.PackageManager.GET_ACTIVITIES
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
import com.google.android.material.color.DynamicColors
import io.github.wulkanowy.R
import io.github.wulkanowy.data.enums.AppTheme
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetConfigureActivity
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetConfigureActivity
import javax.inject.Inject
import javax.inject.Singleton
@ -28,18 +27,19 @@ class ThemeManager @Inject constructor(private val preferencesRepository: Prefer
when (activity) {
is MainActivity -> activity.setTheme(R.style.WulkanowyTheme_Black)
is LoginActivity -> activity.setTheme(R.style.WulkanowyTheme_Login_Black)
is SendMessageActivity -> activity.setTheme(R.style.WulkanowyTheme_MessageSend_Black)
}
}
} else if (activity is TimetableWidgetConfigureActivity || activity is LuckyNumberWidgetConfigureActivity) {
DynamicColors.applyToActivityIfAvailable(activity)
}
}
fun applyDefaultTheme() {
AppCompatDelegate.setDefaultNightMode(
when (preferencesRepository.appTheme) {
AppTheme.LIGHT -> MODE_NIGHT_NO
AppTheme.DARK, AppTheme.BLACK -> MODE_NIGHT_YES
AppTheme.SYSTEM -> MODE_NIGHT_FOLLOW_SYSTEM
AppTheme.LIGHT -> AppCompatDelegate.MODE_NIGHT_NO
AppTheme.DARK, AppTheme.BLACK -> AppCompatDelegate.MODE_NIGHT_YES
AppTheme.SYSTEM -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
)
}
@ -52,7 +52,6 @@ class ThemeManager @Inject constructor(private val preferencesRepository: Prefer
.let {
it == R.style.WulkanowyTheme_Black || it == R.style.WulkanowyTheme_NoActionBar
|| it == R.style.WulkanowyTheme_Login || it == R.style.WulkanowyTheme_Login_Black
|| it == R.style.WulkanowyTheme_MessageSend || it == R.style.WulkanowyTheme_MessageSend_Black
}
@Suppress("DEPRECATION")

View File

@ -9,6 +9,7 @@ import io.github.wulkanowy.ui.modules.exam.ExamFragment
import io.github.wulkanowy.ui.modules.grade.GradeFragment
import io.github.wulkanowy.ui.modules.homework.HomeworkFragment
import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment
import io.github.wulkanowy.ui.modules.luckynumber.history.LuckyNumberHistoryFragment
import io.github.wulkanowy.ui.modules.message.MessageFragment
import io.github.wulkanowy.ui.modules.mobiledevice.MobileDeviceFragment
import io.github.wulkanowy.ui.modules.more.MoreFragment
@ -43,6 +44,7 @@ sealed class Destination {
SCHOOL_ANNOUNCEMENT(SchoolAnnouncement),
SCHOOL_AND_TEACHERS(SchoolAndTeachers),
LUCKY_NUMBER(LuckyNumber),
LUCKY_NUMBER_HISTORY(LuckyNumberHistory),
MORE(More),
MESSAGE(Message),
MOBILE_DEVICE(MobileDevice),
@ -118,6 +120,12 @@ sealed class Destination {
override val destinationFragment get() = LuckyNumberFragment.newInstance()
}
@Serializable
object LuckyNumberHistory : Destination() {
override val destinationType get() = Type.LUCKY_NUMBER_HISTORY
override val destinationFragment get() = LuckyNumberHistoryFragment.newInstance()
}
@Serializable
object More : Destination() {
override val destinationType get() = Type.MORE

View File

@ -9,6 +9,7 @@ import androidx.appcompat.app.AlertDialog
import androidx.core.os.bundleOf
import androidx.core.view.get
import androidx.core.view.isVisible
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student
@ -114,7 +115,7 @@ class AccountDetailsFragment :
override fun showLogoutConfirmDialog() {
context?.let {
AlertDialog.Builder(it)
MaterialAlertDialogBuilder(it)
.setTitle(R.string.account_logout_student)
.setMessage(R.string.account_confirm)
.setPositiveButton(R.string.account_logout) { _, _ -> presenter.onLogoutConfirm() }

View File

@ -1,11 +1,11 @@
package io.github.wulkanowy.ui.modules.account.accountedit
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.recyclerview.widget.GridLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.databinding.DialogAccountEditBinding
@ -31,16 +31,12 @@ class AccountEditDialog : BaseDialogFragment<DialogAccountEditBinding>(), Accoun
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = DialogAccountEditBinding.inflate(inflater).apply { binding = this }.root
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(DialogAccountEditBinding.inflate(layoutInflater).apply { binding = this }.root)
.create()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

View File

@ -1,11 +1,11 @@
package io.github.wulkanowy.ui.modules.account.accountquick
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.databinding.DialogAccountQuickBinding
@ -36,19 +36,17 @@ class AccountQuickDialog : BaseDialogFragment<DialogAccountQuickBinding>(), Acco
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(
DialogAccountQuickBinding.inflate(layoutInflater)
.apply { binding = this }.root
)
.create()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = DialogAccountQuickBinding.inflate(inflater).apply { binding = this }.root
@Suppress("UNCHECKED_CAST")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val studentsWithSemesters = requireArguments()
.serializable<Array<StudentWithSemesters>>(STUDENTS_ARGUMENT_KEY).toList()

View File

@ -1,21 +1,20 @@
package io.github.wulkanowy.ui.modules.attendance
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.databinding.DialogAttendanceBinding
import io.github.wulkanowy.ui.base.BaseDialogFragment
import io.github.wulkanowy.utils.descriptionRes
import io.github.wulkanowy.utils.lifecycleAwareVariable
import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.toFormattedString
class AttendanceDialog : DialogFragment() {
private var binding: DialogAttendanceBinding by lifecycleAwareVariable()
@AndroidEntryPoint
class AttendanceDialog : BaseDialogFragment<DialogAttendanceBinding>() {
private lateinit var attendance: Attendance
@ -30,15 +29,14 @@ class AttendanceDialog : DialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
attendance = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = DialogAttendanceBinding.inflate(inflater).apply { binding = this }.root
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(DialogAttendanceBinding.inflate(layoutInflater).apply { binding = this }.root)
.create()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

View File

@ -4,10 +4,10 @@ import android.content.DialogInterface.BUTTON_POSITIVE
import android.os.Bundle
import android.view.*
import android.view.View.*
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.view.ActionMode
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Attendance
@ -124,7 +124,7 @@ class AttendanceFragment : BaseFragment<FragmentAttendanceBinding>(R.layout.frag
attendanceExcuseButton.setOnClickListener { presenter.onExcuseButtonClick() }
attendanceNavContainer.elevation = requireContext().dpToPx(8f)
attendanceNavContainer.elevation = requireContext().dpToPx(3f)
}
}
@ -228,7 +228,7 @@ class AttendanceFragment : BaseFragment<FragmentAttendanceBinding>(R.layout.frag
override fun showExcuseDialog() {
val dialogBinding = DialogExcuseBinding.inflate(LayoutInflater.from(context))
AlertDialog.Builder(requireContext())
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.attendance_excuse_title)
.setView(dialogBinding.root)
.setNegativeButton(android.R.string.cancel) { _, _ -> }

View File

@ -1,21 +1,20 @@
package io.github.wulkanowy.ui.modules.conference
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.data.db.entities.Conference
import io.github.wulkanowy.databinding.DialogConferenceBinding
import io.github.wulkanowy.utils.lifecycleAwareVariable
import io.github.wulkanowy.ui.base.BaseDialogFragment
import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.toFormattedString
class ConferenceDialog : DialogFragment() {
private var binding: DialogConferenceBinding by lifecycleAwareVariable()
@AndroidEntryPoint
class ConferenceDialog : BaseDialogFragment<DialogConferenceBinding>() {
private lateinit var conference: Conference
@ -30,15 +29,14 @@ class ConferenceDialog : DialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
conference = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = DialogConferenceBinding.inflate(inflater).also { binding = it }.root
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(DialogConferenceBinding.inflate(layoutInflater).apply { binding = this }.root)
.create()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

View File

@ -11,6 +11,7 @@ import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.FragmentDashboardBinding
@ -148,7 +149,7 @@ class DashboardFragment : BaseFragment<FragmentDashboardBinding>(R.layout.fragme
val values = requireContext().resources.getStringArray(R.array.dashboard_tile_values)
val selectedItemsState = values.map { value -> selectedItems.any { it.name == value } }
AlertDialog.Builder(requireContext())
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.pref_dashboard_appearance_tiles_title)
.setMultiChoiceItems(entries, selectedItemsState.toBooleanArray()) { _, _, _ -> }
.setPositiveButton(android.R.string.ok) { dialog, _ ->

View File

@ -1,5 +1,6 @@
package io.github.wulkanowy.ui.modules.dashboard.adapters
import android.content.res.ColorStateList
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
@ -8,6 +9,7 @@ import io.github.wulkanowy.data.enums.GradeColorTheme
import io.github.wulkanowy.databinding.SubitemDashboardGradesBinding
import io.github.wulkanowy.databinding.SubitemDashboardSmallGradeBinding
import io.github.wulkanowy.utils.getBackgroundColor
import io.github.wulkanowy.utils.getCompatColor
class DashboardGradesAdapter : RecyclerView.Adapter<DashboardGradesAdapter.ViewHolder>() {
@ -37,7 +39,9 @@ class DashboardGradesAdapter : RecyclerView.Adapter<DashboardGradesAdapter.ViewH
with(subitemBinding.dashboardSmallGradeSubitemValue) {
text = it.entry
setBackgroundResource(it.getBackgroundColor(gradeColorTheme))
backgroundTintList = ColorStateList.valueOf(
context.getCompatColor(it.getBackgroundColor(gradeColorTheme))
)
}
dashboardGradesSubitemGradeContainer.addView(subitemBinding.root)

View File

@ -1,23 +1,22 @@
package io.github.wulkanowy.ui.modules.exam
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
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.ui.base.BaseDialogFragment
import io.github.wulkanowy.utils.openCalendarEventAdd
import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.toFormattedString
import java.time.LocalTime
class ExamDialog : DialogFragment() {
private var binding: DialogExamBinding by lifecycleAwareVariable()
@AndroidEntryPoint
class ExamDialog : BaseDialogFragment<DialogExamBinding>() {
private lateinit var exam: Exam
@ -32,15 +31,14 @@ class ExamDialog : DialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
exam = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = DialogExamBinding.inflate(inflater).apply { binding = this }.root
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(DialogExamBinding.inflate(layoutInflater).apply { binding = this }.root)
.create()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

View File

@ -62,7 +62,7 @@ class ExamFragment : BaseFragment<FragmentExamBinding>(R.layout.fragment_exam),
examPreviousButton.setOnClickListener { presenter.onPreviousWeek() }
examNextButton.setOnClickListener { presenter.onNextWeek() }
examNavContainer.elevation = requireContext().dpToPx(8f)
examNavContainer.elevation = requireContext().dpToPx(3f)
}
}

View File

@ -8,6 +8,7 @@ import android.view.View
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import androidx.appcompat.app.AlertDialog
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.tabs.TabLayoutMediator
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
@ -141,7 +142,7 @@ class GradeFragment : BaseFragment<FragmentGradeBinding>(R.layout.fragment_grade
val choices = semesters.map { getString(R.string.grade_semester, it.semesterName) }
.toTypedArray()
AlertDialog.Builder(requireContext())
MaterialAlertDialogBuilder(requireContext())
.setSingleChoiceItems(choices, selectedIndex) { dialog, which ->
presenter.onSemesterSelected(which)
dialog.dismiss()

View File

@ -1,6 +1,7 @@
package io.github.wulkanowy.ui.modules.grade.details
import android.annotation.SuppressLint
import android.content.res.ColorStateList
import android.content.res.Resources
import android.view.LayoutInflater
import android.view.View
@ -17,9 +18,10 @@ import io.github.wulkanowy.databinding.HeaderGradeDetailsBinding
import io.github.wulkanowy.databinding.ItemGradeDetailsBinding
import io.github.wulkanowy.ui.base.BaseExpandableAdapter
import io.github.wulkanowy.utils.getBackgroundColor
import io.github.wulkanowy.utils.getCompatColor
import io.github.wulkanowy.utils.toFormattedString
import timber.log.Timber
import java.util.BitSet
import java.util.*
import javax.inject.Inject
class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<RecyclerView.ViewHolder>() {
@ -203,7 +205,9 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
with(holder.binding) {
gradeItemValue.run {
text = grade.entry
setBackgroundResource(grade.getBackgroundColor(gradeColorTheme))
backgroundTintList = ColorStateList.valueOf(
context.getCompatColor(grade.getBackgroundColor(gradeColorTheme))
)
}
gradeItemDescription.text = when {
grade.description.isNotBlank() -> grade.description

View File

@ -1,22 +1,23 @@
package io.github.wulkanowy.ui.modules.grade.details
import android.app.Dialog
import android.content.res.ColorStateList
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.enums.GradeColorTheme
import io.github.wulkanowy.databinding.DialogGradeBinding
import io.github.wulkanowy.ui.base.BaseDialogFragment
import io.github.wulkanowy.utils.*
class GradeDetailsDialog : DialogFragment() {
private var binding: DialogGradeBinding by lifecycleAwareVariable()
@AndroidEntryPoint
class GradeDetailsDialog : BaseDialogFragment<DialogGradeBinding>() {
private lateinit var grade: Grade
@ -38,16 +39,15 @@ class GradeDetailsDialog : DialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
grade = requireArguments().serializable(ARGUMENT_KEY)
gradeColorTheme = requireArguments().serializable(COLOR_THEME_KEY)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = DialogGradeBinding.inflate(inflater).apply { binding = this }.root
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(DialogGradeBinding.inflate(layoutInflater).apply { binding = this }.root)
.create()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -55,10 +55,9 @@ class GradeDetailsDialog : DialogFragment() {
with(binding) {
gradeDialogSubject.text = grade.subject
gradeDialogColorAndWeightValue.run {
text = context.getString(R.string.grade_weight_value, grade.weight)
setBackgroundResource(grade.getGradeColor())
}
gradeDialogWeightValue.text = grade.weight
gradeDialogWeightLayout.backgroundTintList =
ColorStateList.valueOf(requireContext().getCompatColor(grade.getGradeColor()))
gradeDialogDateValue.text = grade.date.toFormattedString()
gradeDialogColorValue.text = getString(grade.colorStringId)
@ -72,7 +71,12 @@ class GradeDetailsDialog : DialogFragment() {
gradeDialogValue.run {
text = grade.entry
setBackgroundResource(grade.getBackgroundColor(gradeColorTheme))
backgroundTintList = ColorStateList.valueOf(
ContextCompat.getColor(
requireContext(),
grade.getBackgroundColor(gradeColorTheme)
)
)
}
gradeDialogTeacherValue.text = grade.teacher.ifBlank { getString(R.string.all_no_data) }

View File

@ -7,6 +7,7 @@ import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.GradeSummary
@ -118,7 +119,7 @@ class GradeSummaryFragment :
}
override fun showCalculatedAverageHelpDialog() {
AlertDialog.Builder(requireContext())
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.grade_summary_calculated_average_help_dialog_title)
.setMessage(R.string.grade_summary_calculated_average_help_dialog_message)
.setPositiveButton(R.string.all_close) { _, _ -> }
@ -126,7 +127,7 @@ class GradeSummaryFragment :
}
override fun showFinalAverageHelpDialog() {
AlertDialog.Builder(requireContext())
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.grade_summary_final_average_help_dialog_title)
.setMessage(R.string.grade_summary_final_average_help_dialog_message)
.setPositiveButton(R.string.all_close) { _, _ -> }

View File

@ -67,7 +67,7 @@ class HomeworkFragment : BaseFragment<FragmentHomeworkBinding>(R.layout.fragment
openAddHomeworkButton.setOnClickListener { presenter.onHomeworkAddButtonClicked() }
homeworkNavContainer.elevation = requireContext().dpToPx(8f)
homeworkNavContainer.elevation = requireContext().dpToPx(3f)
}
}

View File

@ -1,10 +1,10 @@
package io.github.wulkanowy.ui.modules.homework.add
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.widget.doOnTextChanged
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.DialogHomeworkAddBinding
@ -21,20 +21,15 @@ class HomeworkAddDialog : BaseDialogFragment<DialogHomeworkAddBinding>(), Homewo
@Inject
lateinit var presenter: HomeworkAddPresenter
// todo: move it to presenter
//todo: move it to presenter
private var date: LocalDate? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(DialogHomeworkAddBinding.inflate(layoutInflater).apply { binding = this }.root)
.create()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = DialogHomeworkAddBinding.inflate(inflater).apply { binding = this }.root
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
presenter.onAttachView(this)

View File

@ -31,14 +31,8 @@ class HomeworkDetailsAdapter @Inject constructor() :
attachments = value?.attachments.orEmpty()
}
var isHomeworkFullscreen = false
var onAttachmentClickListener: (url: String) -> Unit = {}
var onFullScreenClickListener = {}
var onFullScreenExitClickListener = {}
var onDeleteClickListener: (homework: Homework) -> Unit = {}
override fun getItemCount() = 1 + if (attachments.isNotEmpty()) attachments.size + 1 else 0
@ -82,18 +76,6 @@ class HomeworkDetailsAdapter @Inject constructor() :
homeworkDialogTeacher.text = homework?.teacher.ifNullOrBlank { noDataString }
homeworkDialogContent.text = homework?.content.ifNullOrBlank { noDataString }
homeworkDialogDelete.visibility = if (homework?.isAddedByUser == true) VISIBLE else GONE
homeworkDialogFullScreen.visibility = if (isHomeworkFullscreen) GONE else VISIBLE
homeworkDialogFullScreenExit.visibility = if (isHomeworkFullscreen) VISIBLE else GONE
homeworkDialogFullScreen.setOnClickListener {
homeworkDialogFullScreen.visibility = GONE
homeworkDialogFullScreenExit.visibility = VISIBLE
onFullScreenClickListener()
}
homeworkDialogFullScreenExit.setOnClickListener {
homeworkDialogFullScreen.visibility = VISIBLE
homeworkDialogFullScreenExit.visibility = GONE
onFullScreenExitClickListener()
}
homeworkDialogDelete.setOnClickListener {
onDeleteClickListener(homework!!)
}

View File

@ -1,14 +1,12 @@
package io.github.wulkanowy.ui.modules.homework.details
import android.annotation.SuppressLint
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import androidx.core.os.bundleOf
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Homework
@ -43,15 +41,14 @@ class HomeworkDetailsDialog : BaseDialogFragment<DialogHomeworkBinding>(), Homew
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
homework = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = DialogHomeworkBinding.inflate(inflater).apply { binding = this }.root
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(DialogHomeworkBinding.inflate(layoutInflater).apply { binding = this }.root)
.create()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -67,26 +64,11 @@ class HomeworkDetailsDialog : BaseDialogFragment<DialogHomeworkBinding>(), Homew
homeworkDialogClose.setOnClickListener { dismiss() }
}
if (presenter.isHomeworkFullscreen) {
dialog?.window?.setLayout(MATCH_PARENT, MATCH_PARENT)
} else {
dialog?.window?.setLayout(WRAP_CONTENT, WRAP_CONTENT)
}
with(binding.homeworkDialogRecycler) {
layoutManager = LinearLayoutManager(context)
adapter = detailsAdapter.apply {
onAttachmentClickListener = { context.openInternetBrowser(it, ::showMessage) }
onFullScreenClickListener = {
dialog?.window?.setLayout(MATCH_PARENT, MATCH_PARENT)
presenter.isHomeworkFullscreen = true
}
onFullScreenExitClickListener = {
dialog?.window?.setLayout(WRAP_CONTENT, WRAP_CONTENT)
presenter.isHomeworkFullscreen = false
}
onDeleteClickListener = { homework -> presenter.deleteHomework(homework) }
isHomeworkFullscreen = presenter.isHomeworkFullscreen
homework = this@HomeworkDetailsDialog.homework
}
}

View File

@ -5,7 +5,6 @@ import io.github.wulkanowy.data.logResourceStatus
import io.github.wulkanowy.data.onResourceError
import io.github.wulkanowy.data.onResourceSuccess
import io.github.wulkanowy.data.repositories.HomeworkRepository
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.resourceFlow
import io.github.wulkanowy.ui.base.BasePresenter
@ -19,15 +18,8 @@ class HomeworkDetailsPresenter @Inject constructor(
studentRepository: StudentRepository,
private val homeworkRepository: HomeworkRepository,
private val analytics: AnalyticsHelper,
private val preferencesRepository: PreferencesRepository
) : BasePresenter<HomeworkDetailsView>(errorHandler, studentRepository) {
var isHomeworkFullscreen
get() = preferencesRepository.isHomeworkFullscreen
set(value) {
preferencesRepository.isHomeworkFullscreen = value
}
override fun onAttachView(view: HomeworkDetailsView) {
super.onAttachView(view)
view.initView()

View File

@ -61,7 +61,7 @@ class LuckyNumberHistoryFragment :
luckyNumberHistoryPreviousButton.setOnClickListener { presenter.onPreviousWeek() }
luckyNumberHistoryNextButton.setOnClickListener { presenter.onNextWeek() }
luckyNumberHistoryNavContainer.elevation = requireContext().dpToPx(8f)
luckyNumberHistoryNavContainer.elevation = requireContext().dpToPx(3f)
}
}

View File

@ -1,16 +1,12 @@
package io.github.wulkanowy.ui.modules.luckynumberwidget
import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS
import android.appwidget.AppWidgetManager.*
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.databinding.ActivityWidgetConfigureBinding
import io.github.wulkanowy.ui.base.BaseActivity
@ -41,7 +37,6 @@ class LuckyNumberWidgetConfigureActivity :
setContentView(
ActivityWidgetConfigureBinding.inflate(layoutInflater).apply { binding = this }.root
)
intent.extras.let {
presenter.onAttachView(this, it?.getInt(EXTRA_APPWIDGET_ID))
}
@ -56,22 +51,6 @@ class LuckyNumberWidgetConfigureActivity :
configureAdapter.onClickListener = presenter::onItemSelect
}
override fun showThemeDialog() {
var items = arrayOf(
getString(R.string.widget_timetable_theme_light),
getString(R.string.widget_timetable_theme_dark)
)
if (appInfo.systemVersion >= Build.VERSION_CODES.Q) items += (getString(R.string.widget_timetable_theme_system))
dialog = AlertDialog.Builder(this, R.style.WulkanowyTheme_WidgetAccountSwitcher)
.setTitle(R.string.widget_timetable_theme_title)
.setOnDismissListener { presenter.onDismissThemeView() }
.setSingleChoiceItems(items, -1) { _, which ->
presenter.onThemeSelect(which)
}
.show()
}
override fun updateData(data: List<StudentWithSemesters>, selectedStudentId: Long) {
with(configureAdapter) {
selectedId = selectedStudentId

View File

@ -8,7 +8,6 @@ import io.github.wulkanowy.data.resourceFlow
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetProvider.Companion.getStudentWidgetKey
import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetProvider.Companion.getThemeWidgetKey
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
import javax.inject.Inject
@ -32,20 +31,9 @@ class LuckyNumberWidgetConfigurePresenter @Inject constructor(
fun onItemSelect(student: Student) {
selectedStudent = student
view?.showThemeDialog()
}
fun onThemeSelect(index: Int) {
appWidgetId?.let {
sharedPref.putLong(getThemeWidgetKey(it), index.toLong())
}
registerStudent(selectedStudent)
}
fun onDismissThemeView() {
view?.finishView()
}
private fun loadData() {
resourceFlow { studentRepository.getSavedStudents(false) }.onEach {
when (it) {
@ -56,10 +44,7 @@ class LuckyNumberWidgetConfigurePresenter @Inject constructor(
} ?: -1
when {
it.data.isEmpty() -> view?.openLoginView()
it.data.size == 1 -> {
selectedStudent = it.data.single().student
view?.showThemeDialog()
}
it.data.size == 1 -> onItemSelect(it.data.single().student)
else -> view?.updateData(it.data, selectedStudentId)
}
}

View File

@ -7,8 +7,6 @@ interface LuckyNumberWidgetConfigureView : BaseView {
fun initView()
fun showThemeDialog()
fun updateData(data: List<StudentWithSemesters>, selectedStudentId: Long)
fun updateLuckyNumberWidget(widgetId: Int)

View File

@ -2,14 +2,12 @@ package io.github.wulkanowy.ui.modules.luckynumberwidget
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT
import android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import android.view.View.GONE
import android.view.View.VISIBLE
import android.util.TypedValue.COMPLEX_UNIT_SP
import android.view.View
import android.widget.RemoteViews
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
@ -17,7 +15,6 @@ import io.github.wulkanowy.data.Resource
import io.github.wulkanowy.data.dataOrNull
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
import io.github.wulkanowy.data.repositories.LuckyNumberRepository
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.toFirstResult
@ -41,16 +38,12 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() {
lateinit var sharedPref: SharedPrefProvider
companion object {
private const val LUCKY_NUMBER_WIDGET_MAX_SIZE = 196
const val LUCKY_NUMBER_PENDING_INTENT_ID = 200
private const val LUCKY_NUMBER_PENDING_INTENT_ID = 300
private const val LUCKY_NUMBER_HISTORY_PENDING_INTENT_ID = 301
fun getStudentWidgetKey(appWidgetId: Int) = "lucky_number_widget_student_$appWidgetId"
fun getThemeWidgetKey(appWidgetId: Int) = "lucky_number_widget_theme_$appWidgetId"
fun getHeightWidgetKey(appWidgetId: Int) = "lucky_number_widget_height_$appWidgetId"
fun getWidthWidgetKey(appWidgetId: Int) = "lucky_number_widget_width_$appWidgetId"
}
override fun onUpdate(
@ -59,107 +52,86 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() {
appWidgetIds: IntArray?
) {
super.onUpdate(context, appWidgetManager, appWidgetIds)
appWidgetIds?.forEach { appWidgetId ->
val luckyNumber =
getLuckyNumber(sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0), appWidgetId)
val appIntent = PendingIntent.getActivity(
context,
LUCKY_NUMBER_PENDING_INTENT_ID,
SplashActivity.getStartIntent(context, Destination.LuckyNumber),
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
)
if (luckyNumber is Resource.Error) {
Timber.e("Error loading lucky number for widget", luckyNumber.error)
}
val appIntent = PendingIntent.getActivity(
context,
LUCKY_NUMBER_PENDING_INTENT_ID,
SplashActivity.getStartIntent(context, Destination.LuckyNumber),
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
)
val remoteView =
RemoteViews(context.packageName, getCorrectLayoutId(appWidgetId, context))
.apply {
setTextViewText(
R.id.luckyNumberWidgetNumber,
luckyNumber.dataOrNull?.luckyNumber?.toString() ?: "#"
)
setOnClickPendingIntent(R.id.luckyNumberWidgetContainer, appIntent)
}
val historyIntent = PendingIntent.getActivity(
context,
LUCKY_NUMBER_HISTORY_PENDING_INTENT_ID,
SplashActivity.getStartIntent(context, Destination.LuckyNumberHistory),
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
)
setStyles(remoteView, appWidgetId)
appWidgetManager.updateAppWidget(appWidgetId, remoteView)
appWidgetIds?.forEach { widgetId ->
val studentId = sharedPref.getLong(getStudentWidgetKey(widgetId), 0)
val luckyNumberResource = getLuckyNumber(studentId, widgetId)
val luckyNumber = luckyNumberResource.dataOrNull?.luckyNumber?.toString()
val remoteView = RemoteViews(context.packageName, R.layout.widget_luckynumber)
.apply {
setTextViewText(R.id.luckyNumberWidgetValue, luckyNumber ?: "-")
setOnClickPendingIntent(R.id.luckyNumberWidgetContainer, appIntent)
setOnClickPendingIntent(R.id.luckyNumberWidgetHistoryButton, historyIntent)
}
resizeWidget(context, appWidgetManager.getAppWidgetOptions(widgetId), remoteView)
appWidgetManager.updateAppWidget(widgetId, remoteView)
}
}
override fun onAppWidgetOptionsChanged(
context: Context?,
appWidgetManager: AppWidgetManager?,
appWidgetId: Int,
newOptions: Bundle?
) {
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions)
if (context == null || newOptions == null || appWidgetManager == null) {
return
}
val remoteView = RemoteViews(context.packageName, R.layout.widget_luckynumber)
resizeWidget(context, newOptions, remoteView)
appWidgetManager.partiallyUpdateAppWidget(appWidgetId, remoteView)
}
private fun resizeWidget(context: Context, options: Bundle, remoteViews: RemoteViews) {
val (width, height) = options.getWidgetSize(context)
val size = minOf(width, height, LUCKY_NUMBER_WIDGET_MAX_SIZE).toFloat()
resizeWidgetContents(size, remoteViews)
Timber.v("LuckyNumberWidget resized: ${width}x${height} ($size)")
}
private fun resizeWidgetContents(size: Float, remoteViews: RemoteViews) {
var historyButtonVisibility = View.VISIBLE
var luckyNumberTextSize = 72f
if (size < 150) {
luckyNumberTextSize = 44f
historyButtonVisibility = View.GONE
}
if (size < 75) {
luckyNumberTextSize = 26f
}
remoteViews.apply {
setTextViewTextSize(R.id.luckyNumberWidgetValue, COMPLEX_UNIT_SP, luckyNumberTextSize)
setViewVisibility(R.id.luckyNumberWidgetHistoryButton, historyButtonVisibility)
}
}
override fun onDeleted(context: Context?, appWidgetIds: IntArray?) {
super.onDeleted(context, appWidgetIds)
appWidgetIds?.forEach { appWidgetId ->
with(sharedPref) {
delete(getHeightWidgetKey(appWidgetId))
delete(getStudentWidgetKey(appWidgetId))
delete(getThemeWidgetKey(appWidgetId))
delete(getWidthWidgetKey(appWidgetId))
}
sharedPref.delete(getStudentWidgetKey(appWidgetId))
}
}
override fun onAppWidgetOptionsChanged(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: Int,
newOptions: Bundle?
) {
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions)
val remoteView = RemoteViews(context.packageName, getCorrectLayoutId(appWidgetId, context))
setStyles(remoteView, appWidgetId, newOptions)
appWidgetManager.updateAppWidget(appWidgetId, remoteView)
}
private fun setStyles(views: RemoteViews, appWidgetId: Int, options: Bundle? = null) {
val width = options?.getInt(OPTION_APPWIDGET_MIN_WIDTH) ?: sharedPref.getLong(
getWidthWidgetKey(appWidgetId), 74
).toInt()
val height = options?.getInt(OPTION_APPWIDGET_MAX_HEIGHT) ?: sharedPref.getLong(
getHeightWidgetKey(appWidgetId), 74
).toInt()
with(sharedPref) {
putLong(getWidthWidgetKey(appWidgetId), width.toLong())
putLong(getHeightWidgetKey(appWidgetId), height.toLong())
}
val rows = getCellsForSize(height)
val cols = getCellsForSize(width)
Timber.d("New lucky number widget measurement: %dx%d", width, height)
Timber.d("Widget size: $cols x $rows")
when {
1 == cols && 1 == rows -> views.setVisibility(imageTop = false, imageLeft = false)
1 == cols && 1 < rows -> views.setVisibility(imageTop = true, imageLeft = false)
1 < cols && 1 == rows -> views.setVisibility(imageTop = false, imageLeft = true)
1 == cols && 1 == rows -> views.setVisibility(imageTop = true, imageLeft = false)
2 == cols && 1 == rows -> views.setVisibility(imageTop = false, imageLeft = true)
else -> views.setVisibility(imageTop = false, imageLeft = false, title = true)
}
}
private fun RemoteViews.setVisibility(
imageTop: Boolean,
imageLeft: Boolean,
title: Boolean = false
) {
setViewVisibility(R.id.luckyNumberWidgetImageTop, if (imageTop) VISIBLE else GONE)
setViewVisibility(R.id.luckyNumberWidgetImageLeft, if (imageLeft) VISIBLE else GONE)
setViewVisibility(R.id.luckyNumberWidgetTitle, if (title) VISIBLE else GONE)
setViewVisibility(R.id.luckyNumberWidgetNumber, VISIBLE)
}
private fun getCellsForSize(size: Int): Int {
var n = 2
while (74 * n - 30 < size) ++n
return n - 1
}
private fun getLuckyNumber(studentId: Long, appWidgetId: Int) = runBlocking {
try {
val students = studentRepository.getSavedStudents()
@ -181,22 +153,24 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() {
Resource.Success<LuckyNumber?>(null)
}
} catch (e: Exception) {
if (e.cause !is NoCurrentStudentException) {
Timber.e(e, "An error has occurred in lucky number provider")
}
Timber.e(e, "An error has occurred in lucky number provider")
Resource.Error(e)
}
}
private fun getCorrectLayoutId(appWidgetId: Int, context: Context): Int {
val savedTheme = sharedPref.getLong(getThemeWidgetKey(appWidgetId), 0)
val isSystemDarkMode =
context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
private fun Bundle.getWidgetSize(context: Context): Pair<Int, Int> {
val minWidth = getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)
val maxWidth = getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)
val minHeight = getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)
val maxHeight = getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT)
return if (savedTheme == 1L || (savedTheme == 2L && isSystemDarkMode)) {
R.layout.widget_luckynumber_dark
val orientation = context.resources.configuration.orientation
val isPortrait = orientation == Configuration.ORIENTATION_PORTRAIT
return if (isPortrait) {
minWidth to maxHeight
} else {
R.layout.widget_luckynumber
maxWidth to minHeight
}
}
}

View File

@ -2,14 +2,14 @@ package io.github.wulkanowy.ui.modules.main
import android.content.Context
import android.content.Intent
import android.os.Build.VERSION_CODES.P
import android.os.Build
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.ViewGroup.MarginLayoutParams
import androidx.activity.OnBackPressedCallback
import androidx.activity.addCallback
import androidx.core.view.ViewCompat
import androidx.core.view.isVisible
import androidx.core.view.*
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.preference.Preference
@ -90,8 +90,16 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
super.onCreate(savedInstanceState)
setContentView(ActivityMainBinding.inflate(layoutInflater).apply { binding = this }.root)
setSupportActionBar(binding.mainToolbar)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
WindowCompat.setDecorFitsSystemWindows(window, false)
binding.mainAppBar.isLifted = true
}
initializeFragmentContainer()
this.savedInstanceState = savedInstanceState
messageContainer = binding.mainMessageContainer
messageAnchor = binding.mainMessageContainer
updateHelper.messageContainer = binding.mainFragmentContainer
onBackCallback = onBackPressedDispatcher.addCallback(this, enabled = false) {
presenter.onBackPressed()
@ -187,6 +195,17 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
}
}
private fun initializeFragmentContainer() {
ViewCompat.setOnApplyWindowInsetsListener(binding.mainFragmentContainer) { view, insets ->
val bottomInsets = insets.getInsets(WindowInsetsCompat.Type.navigationBars())
view.updateLayoutParams<MarginLayoutParams> {
bottomMargin = if (binding.mainBottomNav.isVisible) 0 else bottomInsets.bottom
}
WindowInsetsCompat.CONSUMED
}
}
override fun onPreferenceStartFragment(
caller: PreferenceFragmentCompat,
pref: Preference
@ -231,20 +250,9 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
showDialogFragment(AccountQuickDialog.newInstance(studentWithSemesters))
}
override fun showActionBarElevation(show: Boolean) {
ViewCompat.setElevation(binding.mainToolbar, if (show) dpToPx(4f) else 0f)
}
override fun showBottomNavigation(show: Boolean) {
binding.mainBottomNav.isVisible = show
if (appInfo.systemVersion >= P) {
window.navigationBarColor = if (show) {
getThemeAttrColor(android.R.attr.navigationBarColor)
} else {
getThemeAttrColor(R.attr.colorSurface)
}
}
binding.mainFragmentContainer.requestApplyInsets()
}
override fun openMoreDestination(destination: Destination) {

View File

@ -14,9 +14,6 @@ import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.ui.modules.Destination
import io.github.wulkanowy.ui.modules.account.AccountView
import io.github.wulkanowy.ui.modules.account.accountdetails.AccountDetailsView
import io.github.wulkanowy.ui.modules.grade.GradeView
import io.github.wulkanowy.ui.modules.message.MessageView
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersView
import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoView
import io.github.wulkanowy.utils.AdsHelper
import io.github.wulkanowy.utils.AnalyticsHelper
@ -100,7 +97,6 @@ class MainPresenter @Inject constructor(
fun onViewChange(destinationView: BaseView) {
view?.apply {
showBottomNavigation(shouldShowBottomNavigation(destinationView))
showActionBarElevation(shouldShowActionBarElevation(destinationView))
currentViewTitle?.let { setViewTitle(it) }
currentViewSubtitle?.let { setViewSubTitle(it.ifBlank { null }) }
currentStackSize?.let {
@ -110,13 +106,6 @@ class MainPresenter @Inject constructor(
}
}
private fun shouldShowActionBarElevation(destination: BaseView) = when (destination) {
is GradeView,
is MessageView,
is SchoolAndTeachersView -> false
else -> true
}
private fun shouldShowBottomNavigation(destination: BaseView) = when (destination) {
is AccountView,
is StudentInfoView,

View File

@ -28,8 +28,6 @@ interface MainView : BaseView {
fun showAccountPicker(studentWithSemesters: List<StudentWithSemesters>)
fun showActionBarElevation(show: Boolean)
fun showBottomNavigation(show: Boolean)
fun notifyMenuViewReselected()

View File

@ -1,11 +1,11 @@
package io.github.wulkanowy.ui.modules.message.mailboxchooser
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.fragment.app.setFragmentResult
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.data.db.entities.Mailbox
import io.github.wulkanowy.databinding.DialogMailboxChooserBinding
@ -37,19 +37,19 @@ class MailboxChooserDialog : BaseDialogFragment<DialogMailboxChooserBinding>(),
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(
DialogMailboxChooserBinding.inflate(layoutInflater).apply { binding = this }.root
)
.create()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = DialogMailboxChooserBinding.inflate(inflater).apply { binding = this }.root
@Suppress("UNCHECKED_CAST")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
presenter.onAttachView(
view = this,
requireMailbox = requireArguments().getBoolean(REQUIRED_KEY, false),

View File

@ -1,10 +1,10 @@
package io.github.wulkanowy.ui.modules.message.send
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.graphics.Rect
import android.os.Build
import android.os.Bundle
import android.text.Spanned
import android.view.Menu
@ -12,11 +12,14 @@ import android.view.MenuItem
import android.view.TouchDelegate
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import android.widget.Toast
import android.widget.Toast.LENGTH_LONG
import androidx.core.text.parseAsHtml
import androidx.core.text.toHtml
import androidx.core.view.*
import androidx.core.widget.doOnTextChanged
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Mailbox
@ -24,8 +27,8 @@ import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.databinding.ActivitySendMessageBinding
import io.github.wulkanowy.ui.base.BaseActivity
import io.github.wulkanowy.ui.modules.message.mailboxchooser.MailboxChooserDialog
import io.github.wulkanowy.ui.modules.message.mailboxchooser.MailboxChooserDialog.Companion.MAILBOX_KEY
import io.github.wulkanowy.ui.modules.message.mailboxchooser.MailboxChooserDialog.Companion.LISTENER_KEY
import io.github.wulkanowy.ui.modules.message.mailboxchooser.MailboxChooserDialog.Companion.MAILBOX_KEY
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.hideSoftInput
import io.github.wulkanowy.utils.nullableSerializable
@ -99,6 +102,13 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter, ActivitySendMessa
)
setSupportActionBar(binding.sendMessageToolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
WindowCompat.setDecorFitsSystemWindows(window, false)
binding.sendAppBar.isLifted = true
}
initializeMessageContainer()
messageContainer = binding.sendMessageContainer
formRecipientsData = binding.sendMessageTo.addedChipItems as List<RecipientChipItem>
@ -130,6 +140,17 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter, ActivitySendMessa
}
}
private fun initializeMessageContainer() {
ViewCompat.setOnApplyWindowInsetsListener(binding.sendMessageScroll) { view, insets ->
val bottomInsets = insets.getInsets(WindowInsetsCompat.Type.navigationBars())
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
bottomMargin = bottomInsets.bottom
}
WindowInsetsCompat.CONSUMED
}
}
private fun onMessageSubjectChange(text: CharSequence?) {
formSubjectValue = text.toString()
presenter.onMessageContentChange()
@ -252,7 +273,7 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter, ActivitySendMessa
}
override fun showMessageBackupDialog() {
AlertDialog.Builder(this)
MaterialAlertDialogBuilder(this)
.setTitle(R.string.message_title)
.setMessage(presenter.getMessageBackupContent(presenter.getRecipientsNames()))
.setPositiveButton(R.string.all_yes) { _, _ -> presenter.restoreMessageParts() }

View File

@ -1,5 +1,6 @@
package io.github.wulkanowy.ui.modules.message.tab
import android.annotation.SuppressLint
import android.content.res.ColorStateList
import android.graphics.Typeface
import android.view.LayoutInflater
@ -68,21 +69,23 @@ class MessageTabAdapter @Inject constructor() :
}
}
@SuppressLint("PrivateResource")
private fun bindHeaderViewHolder(holder: HeaderViewHolder, position: Int) {
val item = items[position] as MessageTabDataItem.FilterHeader
val context = holder.binding.root.context
with(holder.binding) {
chipMailbox.text = item.selectedMailbox
?: root.context.getString(R.string.message_chip_all_mailboxes)
chipMailbox.text =
item.selectedMailbox ?: context.getString(R.string.message_chip_all_mailboxes)
chipMailbox.chipBackgroundColor = ColorStateList.valueOf(
if (item.selectedMailbox == null) {
root.context.getCompatColor(R.color.mtrl_choice_chip_background_color)
} else root.context.getThemeAttrColor(android.R.attr.colorPrimary, 64)
context.getCompatColor(R.color.m3_elevated_chip_background_color)
} else context.getThemeAttrColor(R.attr.colorPrimary, 64)
)
chipMailbox.setTextColor(
if (item.selectedMailbox == null) {
root.context.getThemeAttrColor(android.R.attr.textColorPrimary)
} else root.context.getThemeAttrColor(android.R.attr.colorPrimary)
context.getThemeAttrColor(R.attr.colorOnSurfaceVariant)
} else context.getThemeAttrColor(R.attr.colorPrimary)
)
chipMailbox.setOnClickListener { onMailboxClickListener() }

View File

@ -1,17 +1,17 @@
package io.github.wulkanowy.ui.modules.mobiledevice.token
import android.app.Dialog
import android.content.ClipData
import android.content.ClipboardManager
import android.graphics.BitmapFactory
import android.os.Bundle
import android.util.Base64
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.Toast
import androidx.core.content.getSystemService
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.pojos.MobileDeviceToken
@ -31,17 +31,14 @@ class MobileDeviceTokenDialog : BaseDialogFragment<DialogMobileDeviceBinding>(),
fun newInstance() = MobileDeviceTokenDialog()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(
DialogMobileDeviceBinding.inflate(layoutInflater).apply { binding = this }.root
)
.create()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = DialogMobileDeviceBinding.inflate(inflater).apply { binding = this }.root
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
presenter.onAttachView(this)

View File

@ -1,25 +1,24 @@
package io.github.wulkanowy.ui.modules.note
import android.annotation.SuppressLint
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Note
import io.github.wulkanowy.databinding.DialogNoteBinding
import io.github.wulkanowy.sdk.scrapper.notes.NoteCategory
import io.github.wulkanowy.ui.base.BaseDialogFragment
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.lifecycleAwareVariable
import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.toFormattedString
class NoteDialog : DialogFragment() {
private var binding: DialogNoteBinding by lifecycleAwareVariable()
@AndroidEntryPoint
class NoteDialog : BaseDialogFragment<DialogNoteBinding>() {
private lateinit var note: Note
@ -34,15 +33,14 @@ class NoteDialog : DialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
note = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = DialogNoteBinding.inflate(inflater).apply { binding = this }.root
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(DialogNoteBinding.inflate(layoutInflater).apply { binding = this }.root)
.create()
}
@SuppressLint("SetTextI18n")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

View File

@ -3,7 +3,7 @@ package io.github.wulkanowy.ui.modules.notifications
import android.os.Bundle
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
import androidx.appcompat.app.AlertDialog
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.FragmentNotificationsBinding
@ -41,7 +41,7 @@ class NotificationsFragment :
}
private fun showSettingsDialog() {
AlertDialog.Builder(requireContext())
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.notifications_header_title)
.setMessage(R.string.notifications_header_description)
.setNegativeButton(R.string.notifications_skip) { dialog, _ ->

View File

@ -1,21 +1,20 @@
package io.github.wulkanowy.ui.modules.schoolannouncement
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
import io.github.wulkanowy.databinding.DialogSchoolAnnouncementBinding
import io.github.wulkanowy.utils.lifecycleAwareVariable
import io.github.wulkanowy.ui.base.BaseDialogFragment
import io.github.wulkanowy.utils.parseUonetHtml
import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.toFormattedString
class SchoolAnnouncementDialog : DialogFragment() {
private var binding: DialogSchoolAnnouncementBinding by lifecycleAwareVariable()
@AndroidEntryPoint
class SchoolAnnouncementDialog : BaseDialogFragment<DialogSchoolAnnouncementBinding>() {
private lateinit var announcement: SchoolAnnouncement
@ -30,15 +29,17 @@ class SchoolAnnouncementDialog : DialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
announcement = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = DialogSchoolAnnouncementBinding.inflate(inflater).also { binding = it }.root
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(
DialogSchoolAnnouncementBinding.inflate(layoutInflater)
.apply { binding = this }.root
)
.create()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

View File

@ -8,13 +8,13 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreferenceCompat
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.thelittlefireman.appkillermanager.AppKillerManager
import com.thelittlefireman.appkillermanager.exceptions.NoActionFoundException
import dagger.hilt.android.AndroidEntryPoint
@ -149,7 +149,7 @@ class NotificationsFragment : PreferenceFragmentCompat(),
}
override fun showFixSyncDialog() {
AlertDialog.Builder(requireContext())
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.pref_notify_fix_sync_issues)
.setMessage(R.string.pref_notify_fix_sync_issues_message)
.setNegativeButton(android.R.string.cancel) { _, _ -> }
@ -177,7 +177,7 @@ class NotificationsFragment : PreferenceFragmentCompat(),
}
override fun openNotificationsPermissionDialog() {
AlertDialog.Builder(requireContext())
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.notifications_header_title)
.setMessage(R.string.notifications_header_description)
.setPositiveButton(R.string.pref_notification_go_to_settings) { _, _ ->
@ -191,7 +191,7 @@ class NotificationsFragment : PreferenceFragmentCompat(),
}
override fun openNotificationPiggyBackPermissionDialog() {
AlertDialog.Builder(requireContext())
MaterialAlertDialogBuilder(requireContext())
.setTitle(getString(R.string.pref_notification_piggyback_popup_title))
.setMessage(getString(R.string.pref_notification_piggyback_popup_description))
.setPositiveButton(getString(R.string.pref_notification_go_to_settings)) { _, _ ->
@ -205,7 +205,7 @@ class NotificationsFragment : PreferenceFragmentCompat(),
}
override fun openNotificationExactAlarmSettings() {
AlertDialog.Builder(requireContext())
MaterialAlertDialogBuilder(requireContext())
.setTitle(getString(R.string.pref_notification_exact_alarm_popup_title))
.setMessage(getString(R.string.pref_notification_exact_alarm_popup_descriptions))
.setPositiveButton(getString(R.string.pref_notification_go_to_settings)) { _, _ ->

View File

@ -5,6 +5,7 @@ import android.os.Bundle
import android.view.View
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.ui.base.BaseActivity
@ -75,7 +76,11 @@ class SyncFragment : PreferenceFragmentCompat(),
}
override fun showMessage(text: String) {
(activity as? BaseActivity<*, *>)?.showMessage(text)
Snackbar.make(requireView(), text, Snackbar.LENGTH_LONG)
.apply {
anchorView = requireActivity().findViewById(R.id.main_bottom_nav)
show()
}
}
override fun showExpiredDialog() {

View File

@ -160,7 +160,7 @@ class TimetableAdapter @Inject constructor() :
timetableSmallItemDescription.setTextColor(
root.context.getThemeAttrColor(
if (lesson.canceled) R.attr.colorPrimary
if (lesson.canceled) R.attr.colorTimetableCanceled
else R.attr.colorTimetableChange
)
)
@ -185,7 +185,7 @@ class TimetableAdapter @Inject constructor() :
timetableItemDescription.setTextColor(
root.context.getThemeAttrColor(
if (lesson.canceled) R.attr.colorPrimary
if (lesson.canceled) R.attr.colorTimetableCanceled
else R.attr.colorTimetableChange
)
)
@ -228,8 +228,8 @@ class TimetableAdapter @Inject constructor() :
}
private fun updateNumberAndSubjectCanceledColor(numberView: TextView, subjectView: TextView) {
numberView.setTextColor(numberView.context.getThemeAttrColor(R.attr.colorPrimary))
subjectView.setTextColor(subjectView.context.getThemeAttrColor(R.attr.colorPrimary))
numberView.setTextColor(numberView.context.getThemeAttrColor(R.attr.colorTimetableCanceled))
subjectView.setTextColor(subjectView.context.getThemeAttrColor(R.attr.colorTimetableCanceled))
}
private fun updateNumberColor(numberView: TextView, lesson: Timetable) {

View File

@ -1,24 +1,24 @@
package io.github.wulkanowy.ui.modules.timetable
import android.annotation.SuppressLint
import android.app.Dialog
import android.graphics.Paint.STRIKE_THRU_TEXT_FLAG
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.os.bundleOf
import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.databinding.DialogTimetableBinding
import io.github.wulkanowy.ui.base.BaseDialogFragment
import io.github.wulkanowy.utils.*
import java.time.Instant
class TimetableDialog : DialogFragment() {
private var binding: DialogTimetableBinding by lifecycleAwareVariable()
@AndroidEntryPoint
class TimetableDialog : BaseDialogFragment<DialogTimetableBinding>() {
private lateinit var lesson: Timetable
@ -33,15 +33,14 @@ class TimetableDialog : DialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
lesson = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = DialogTimetableBinding.inflate(inflater).apply { binding = this }.root
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(DialogTimetableBinding.inflate(layoutInflater).apply { binding = this }.root)
.create()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -82,12 +81,12 @@ class TimetableDialog : DialogFragment() {
if (canceled) {
timetableDialogChangesTitle.setTextColor(
requireContext().getThemeAttrColor(
R.attr.colorPrimary
R.attr.colorTimetableCanceled
)
)
timetableDialogChangesValue.setTextColor(
requireContext().getThemeAttrColor(
R.attr.colorPrimary
R.attr.colorTimetableCanceled
)
)
} else {

View File

@ -87,7 +87,7 @@ class TimetableFragment : BaseFragment<FragmentTimetableBinding>(R.layout.fragme
timetableNavDate.setOnClickListener { presenter.onPickDate() }
timetableNextButton.setOnClickListener { presenter.onNextDay() }
timetableNavContainer.elevation = requireContext().dpToPx(8f)
timetableNavContainer.elevation = requireContext().dpToPx(3f)
}
}

View File

@ -2,8 +2,8 @@ package io.github.wulkanowy.ui.modules.timetable.additional
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.TimetableAdditional
@ -13,11 +13,7 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.timetable.additional.add.AdditionalLessonAddDialog
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.firstSchoolDayInSchoolYear
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.lastSchoolDayInSchoolYear
import io.github.wulkanowy.utils.openMaterialDatePicker
import io.github.wulkanowy.utils.*
import java.time.LocalDate
import javax.inject.Inject
@ -73,7 +69,7 @@ class AdditionalLessonsFragment :
openAddAdditionalLessonButton.setOnClickListener { presenter.onAdditionalLessonAddButtonClicked() }
additionalLessonsNavContainer.elevation = requireContext().dpToPx(8f)
additionalLessonsNavContainer.elevation = requireContext().dpToPx(3f)
}
}
@ -154,7 +150,7 @@ class AdditionalLessonsFragment :
}
override fun showDeleteLessonDialog(timetableAdditional: TimetableAdditional) {
AlertDialog.Builder(requireContext())
MaterialAlertDialogBuilder(requireContext())
.setTitle(getString(R.string.additional_lessons_delete_title))
.setItems(
arrayOf(

View File

@ -1,10 +1,10 @@
package io.github.wulkanowy.ui.modules.timetable.additional.add
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.widget.doOnTextChanged
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.timepicker.MaterialTimePicker
import com.google.android.material.timepicker.TimeFormat
import dagger.hilt.android.AndroidEntryPoint
@ -29,16 +29,14 @@ class AdditionalLessonAddDialog : BaseDialogFragment<DialogAdditionalAddBinding>
fun newInstance() = AdditionalLessonAddDialog()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = DialogAdditionalAddBinding.inflate(inflater).apply { binding = this }.root
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(
DialogAdditionalAddBinding.inflate(layoutInflater).apply { binding = this }.root
)
.create()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

View File

@ -1,19 +1,18 @@
package io.github.wulkanowy.ui.modules.timetable.completed
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.databinding.DialogLessonCompletedBinding
import io.github.wulkanowy.utils.lifecycleAwareVariable
import io.github.wulkanowy.ui.base.BaseDialogFragment
import io.github.wulkanowy.utils.serializable
class CompletedLessonDialog : DialogFragment() {
private var binding: DialogLessonCompletedBinding by lifecycleAwareVariable()
@AndroidEntryPoint
class CompletedLessonDialog : BaseDialogFragment<DialogLessonCompletedBinding>() {
private lateinit var completedLesson: CompletedLesson
@ -28,15 +27,16 @@ class CompletedLessonDialog : DialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
completedLesson = requireArguments().serializable(ARGUMENT_KEY)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = DialogLessonCompletedBinding.inflate(inflater).apply { binding = this }.root
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(
DialogLessonCompletedBinding.inflate(layoutInflater).apply { binding = this }.root
)
.create()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

View File

@ -2,9 +2,7 @@ package io.github.wulkanowy.ui.modules.timetable.completed
import android.os.Bundle
import android.view.View
import android.view.View.GONE
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import android.view.View.*
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
@ -14,12 +12,7 @@ import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.firstSchoolDayInSchoolYear
import io.github.wulkanowy.utils.getCompatDrawable
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.lastSchoolDayInSchoolYear
import io.github.wulkanowy.utils.openMaterialDatePicker
import io.github.wulkanowy.utils.*
import java.time.LocalDate
import javax.inject.Inject
@ -73,7 +66,7 @@ class CompletedLessonsFragment :
completedLessonsNavDate.setOnClickListener { presenter.onPickDate() }
completedLessonsNextButton.setOnClickListener { presenter.onNextDay() }
completedLessonsNavContainer.elevation = requireContext().dpToPx(8f)
completedLessonsNavContainer.elevation = requireContext().dpToPx(3f)
}
}

View File

@ -2,14 +2,11 @@ package io.github.wulkanowy.ui.modules.timetablewidget
import android.appwidget.AppWidgetManager.*
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.widget.Toast
import android.widget.Toast.LENGTH_LONG
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.databinding.ActivityWidgetConfigureBinding
import io.github.wulkanowy.ui.base.BaseActivity
@ -34,8 +31,6 @@ class TimetableWidgetConfigureActivity :
@Inject
lateinit var appInfo: AppInfo
private var dialog: AlertDialog? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setResult(RESULT_CANCELED)
@ -61,23 +56,6 @@ class TimetableWidgetConfigureActivity :
configureAdapter.onClickListener = presenter::onItemSelect
}
override fun showThemeDialog() {
var items = arrayOf(
getString(R.string.widget_timetable_theme_light),
getString(R.string.widget_timetable_theme_dark)
)
if (appInfo.systemVersion >= Build.VERSION_CODES.Q) items += getString(R.string.widget_timetable_theme_system)
dialog = AlertDialog.Builder(this, R.style.WulkanowyTheme_WidgetAccountSwitcher)
.setTitle(R.string.widget_timetable_theme_title)
.setOnDismissListener { presenter.onDismissThemeView() }
.setSingleChoiceItems(items, -1) { _, which ->
presenter.onThemeSelect(which)
}
.show()
}
override fun updateData(data: List<StudentWithSemesters>, selectedStudentId: Long) {
with(configureAdapter) {
selectedId = selectedStudentId
@ -110,9 +88,4 @@ class TimetableWidgetConfigureActivity :
override fun openLoginView() {
startActivity(LoginActivity.getStartIntent(this))
}
override fun onDestroy() {
super.onDestroy()
dialog?.dismiss()
}
}

View File

@ -8,7 +8,6 @@ import io.github.wulkanowy.data.resourceFlow
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getStudentWidgetKey
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getThemeWidgetKey
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
import javax.inject.Inject
@ -39,22 +38,9 @@ class TimetableWidgetConfigurePresenter @Inject constructor(
fun onItemSelect(student: Student) {
selectedStudent = student
if (isFromProvider) registerStudent(selectedStudent)
else view?.showThemeDialog()
}
fun onThemeSelect(index: Int) {
appWidgetId?.let {
sharedPref.putLong(getThemeWidgetKey(it), index.toLong())
}
registerStudent(selectedStudent)
}
fun onDismissThemeView() {
view?.finishView()
}
private fun loadData() {
resourceFlow { studentRepository.getSavedStudents(false) }.onEach {
when (it) {
@ -65,10 +51,7 @@ class TimetableWidgetConfigurePresenter @Inject constructor(
} ?: -1
when {
it.data.isEmpty() -> view?.openLoginView()
it.data.size == 1 && !isFromProvider -> {
selectedStudent = it.data.single().student
view?.showThemeDialog()
}
it.data.size == 1 && !isFromProvider -> onItemSelect(it.data.single().student)
else -> view?.updateData(it.data, selectedStudentId)
}
}

View File

@ -11,8 +11,6 @@ interface TimetableWidgetConfigureView : BaseView {
fun updateTimetableWidget(widgetId: Int)
fun showThemeDialog()
fun setSuccessResult(widgetId: Int)
fun finishView()

View File

@ -1,27 +1,25 @@
package io.github.wulkanowy.ui.modules.timetablewidget
import android.annotation.SuppressLint
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.graphics.Paint.ANTI_ALIAS_FLAG
import android.graphics.Paint.STRIKE_THRU_TEXT_FLAG
import android.view.View.GONE
import android.view.View.VISIBLE
import android.widget.AdapterView.INVALID_POSITION
import android.widget.RemoteViews
import android.widget.RemoteViewsService
import io.github.wulkanowy.R
import io.github.wulkanowy.data.dataOrNull
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.data.enums.TimetableMode
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.SemesterRepository
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.repositories.TimetableRepository
import io.github.wulkanowy.data.toFirstResult
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getCurrentThemeWidgetKey
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getDateWidgetKey
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getStudentWidgetKey
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getTodayLastLessonEndDateTimeWidgetKey
@ -29,13 +27,13 @@ import io.github.wulkanowy.utils.getCompatColor
import io.github.wulkanowy.utils.toFormattedString
import kotlinx.coroutines.runBlocking
import timber.log.Timber
import java.time.Instant
import java.time.LocalDate
class TimetableWidgetFactory(
private val timetableRepository: TimetableRepository,
private val studentRepository: StudentRepository,
private val semesterRepository: SemesterRepository,
private val prefRepository: PreferencesRepository,
private val sharedPref: SharedPrefProvider,
private val context: Context,
private val intent: Intent?
@ -43,19 +41,22 @@ class TimetableWidgetFactory(
private var lessons = emptyList<Timetable>()
private var savedCurrentTheme: Long? = null
private var primaryColor: Int? = null
private var timetableCanceledColor: Int? = null
private var textColor: Int? = null
private var timetableChangeColor: Int? = null
private var lastSyncInstant: Instant? = null
override fun getLoadingView() = null
override fun hasStableIds() = true
override fun getCount() = lessons.size
override fun getCount() = when {
lessons.isEmpty() -> 0
else -> lessons.size + 1
}
override fun getViewTypeCount() = 2
@ -70,195 +71,170 @@ class TimetableWidgetFactory(
val date = LocalDate.ofEpochDay(sharedPref.getLong(getDateWidgetKey(appWidgetId), 0))
val studentId = sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0)
updateTheme(appWidgetId)
lessons = getLessons(date, studentId)
val todayLastLessonEndTimestamp = lessons.maxOfOrNull { it.end }
if (date == LocalDate.now() && todayLastLessonEndTimestamp != null) {
sharedPref.putLong(
key = getTodayLastLessonEndDateTimeWidgetKey(appWidgetId),
value = todayLastLessonEndTimestamp.epochSecond,
sync = true
)
}
}
}
private fun updateTheme(appWidgetId: Int) {
savedCurrentTheme = sharedPref.getLong(getCurrentThemeWidgetKey(appWidgetId), 0)
if (savedCurrentTheme == 0L) {
primaryColor = R.color.colorPrimary
textColor = android.R.color.black
timetableChangeColor = R.color.timetable_change_dark
} else {
primaryColor = R.color.colorPrimaryLight
textColor = android.R.color.white
timetableChangeColor = R.color.timetable_change_light
}
}
private fun getItemLayout(lesson: Timetable): Int {
return when {
prefRepository.showWholeClassPlan == TimetableMode.SMALL_OTHER_GROUP && !lesson.isStudentPlan -> {
if (savedCurrentTheme == 0L) R.layout.item_widget_timetable_small
else R.layout.item_widget_timetable_small_dark
}
savedCurrentTheme == 1L -> R.layout.item_widget_timetable_dark
else -> R.layout.item_widget_timetable
}
}
private fun getLessons(date: LocalDate, studentId: Long) = try {
runBlocking {
if (!studentRepository.isStudentSaved()) return@runBlocking emptyList<Timetable>()
val students = studentRepository.getSavedStudents()
val student = students.singleOrNull { it.student.id == studentId }?.student
?: return@runBlocking emptyList<Timetable>()
val semester = semesterRepository.getCurrentSemester(student)
timetableRepository.getTimetable(student, semester, date, date, false)
.toFirstResult().dataOrNull?.lessons.orEmpty()
.sortedWith(compareBy({ it.number }, { !it.isStudentPlan }))
.filter {
if (prefRepository.showWholeClassPlan == TimetableMode.ONLY_CURRENT_GROUP) {
it.isStudentPlan
} else true
runCatching {
runBlocking {
val student = getStudent(studentId) ?: return@runBlocking
val semester = semesterRepository.getCurrentSemester(student)
lessons = getLessons(student, semester, date)
lastSyncInstant =
timetableRepository.getLastRefreshTimestamp(semester, date, date)
if (date == LocalDate.now()) {
updateTodayLastLessonEnd(appWidgetId)
}
}
}.onFailure {
Timber.e(it, "An error has occurred in timetable widget factory")
}
}
} catch (e: Exception) {
Timber.e(e, "An error has occurred in timetable widget factory")
emptyList()
}
@SuppressLint("DefaultLocale")
private suspend fun getStudent(studentId: Long): Student? {
val students = studentRepository.getSavedStudents()
return students.singleOrNull { it.student.id == studentId }?.student
}
private suspend fun getLessons(
student: Student, semester: Semester, date: LocalDate
): List<Timetable> {
val timetable = timetableRepository.getTimetable(student, semester, date, date, false)
val lessons = timetable.toFirstResult().dataOrNull?.lessons.orEmpty()
return lessons.sortedBy { it.number }
}
private fun updateTodayLastLessonEnd(appWidgetId: Int) {
val todayLastLessonEnd = lessons.maxOfOrNull { it.end } ?: return
val key = getTodayLastLessonEndDateTimeWidgetKey(appWidgetId)
sharedPref.putLong(key, todayLastLessonEnd.epochSecond, true)
}
companion object {
const val TIME_FORMAT_STYLE = "HH:mm"
}
override fun getViewAt(position: Int): RemoteViews? {
if (position == INVALID_POSITION || lessons.getOrNull(position) == null) return null
val lesson = lessons[position]
return RemoteViews(context.packageName, getItemLayout(lesson)).apply {
setTextViewText(R.id.timetableWidgetItemSubject, lesson.subject)
setTextViewText(R.id.timetableWidgetItemNumber, lesson.number.toString())
setTextViewText(
R.id.timetableWidgetItemTimeStart,
lesson.start.toFormattedString("HH:mm")
)
setTextViewText(
R.id.timetableWidgetItemTimeFinish,
lesson.end.toFormattedString("HH:mm")
)
updateDescription(this, lesson)
if (lesson.canceled) {
updateStylesCanceled(this)
} else {
updateStylesNotCanceled(this, lesson)
if (position == lessons.size) {
val synchronizationInstant = lastSyncInstant ?: Instant.MIN
val synchronizationText = getSynchronizationInfoText(synchronizationInstant)
return RemoteViews(context.packageName, R.layout.item_widget_timetable_footer).apply {
setTextViewText(R.id.timetableWidgetSynchronizationTime, synchronizationText)
}
}
val lesson = lessons.getOrNull(position) ?: return null
val lessonStartTime = lesson.start.toFormattedString(TIME_FORMAT_STYLE)
val lessonEndTime = lesson.end.toFormattedString(TIME_FORMAT_STYLE)
val roomText = "${context.getString(R.string.timetable_room)} ${lesson.room}"
val remoteViews = RemoteViews(context.packageName, R.layout.item_widget_timetable).apply {
setTextViewText(R.id.timetableWidgetItemNumber, lesson.number.toString())
setTextViewText(R.id.timetableWidgetItemTimeStart, lessonStartTime)
setTextViewText(R.id.timetableWidgetItemTimeFinish, lessonEndTime)
setTextViewText(R.id.timetableWidgetItemSubject, lesson.subject)
setTextViewText(R.id.timetableWidgetItemRoom, roomText)
setTextViewText(R.id.timetableWidgetItemTeacher, lesson.teacher)
setTextViewText(R.id.timetableWidgetItemDescription, lesson.info)
setOnClickFillInIntent(R.id.timetableWidgetItemContainer, Intent())
}
updateTheme()
clearLessonStyles(remoteViews)
when {
lesson.canceled -> applyCancelledLessonStyles(remoteViews)
lesson.changes or lesson.info.isNotBlank() -> applyChangedLessonStyles(
remoteViews, lesson
)
}
return remoteViews
}
private fun updateDescription(remoteViews: RemoteViews, lesson: Timetable) {
with(remoteViews) {
if (lesson.info.isNotBlank() && !lesson.changes) {
setTextViewText(R.id.timetableWidgetItemDescription, lesson.info)
setViewVisibility(R.id.timetableWidgetItemDescription, VISIBLE)
setViewVisibility(R.id.timetableWidgetItemRoom, GONE)
setViewVisibility(R.id.timetableWidgetItemTeacher, GONE)
} else {
setViewVisibility(R.id.timetableWidgetItemDescription, GONE)
setViewVisibility(R.id.timetableWidgetItemRoom, VISIBLE)
setViewVisibility(R.id.timetableWidgetItemTeacher, VISIBLE)
private fun updateTheme() {
when (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
Configuration.UI_MODE_NIGHT_YES -> {
textColor = android.R.color.white
timetableChangeColor = R.color.timetable_change_dark
timetableCanceledColor = R.color.timetable_canceled_dark
}
else -> {
textColor = android.R.color.black
timetableChangeColor = R.color.timetable_change_light
timetableCanceledColor = R.color.timetable_canceled_light
}
}
}
private fun updateStylesCanceled(remoteViews: RemoteViews) {
with(remoteViews) {
setInt(
R.id.timetableWidgetItemSubject, "setPaintFlags",
STRIKE_THRU_TEXT_FLAG or ANTI_ALIAS_FLAG
)
setTextColor(R.id.timetableWidgetItemNumber, context.getCompatColor(primaryColor!!))
setTextColor(R.id.timetableWidgetItemSubject, context.getCompatColor(primaryColor!!))
setTextColor(
R.id.timetableWidgetItemDescription,
context.getCompatColor(primaryColor!!)
)
}
}
private fun clearLessonStyles(remoteViews: RemoteViews) {
val defaultTextColor = context.getCompatColor(textColor ?: 0)
private fun updateStylesNotCanceled(remoteViews: RemoteViews, lesson: Timetable) {
with(remoteViews) {
remoteViews.apply {
setInt(R.id.timetableWidgetItemSubject, "setPaintFlags", ANTI_ALIAS_FLAG)
setTextColor(R.id.timetableWidgetItemSubject, context.getCompatColor(textColor!!))
setTextColor(
R.id.timetableWidgetItemDescription,
context.getCompatColor(timetableChangeColor!!)
)
updateNotCanceledLessonNumberColor(this, lesson)
updateNotCanceledSubjectColor(this, lesson)
val teacherChange = lesson.teacherOld.isNotBlank()
updateNotCanceledRoom(this, lesson, teacherChange)
updateNotCanceledTeacher(this, lesson, teacherChange)
setViewVisibility(R.id.timetableWidgetItemRoom, VISIBLE)
setViewVisibility(R.id.timetableWidgetItemTeacher, VISIBLE)
setViewVisibility(R.id.timetableWidgetItemIcon, GONE)
setViewVisibility(R.id.timetableWidgetItemDescription, GONE)
setTextColor(R.id.timetableWidgetItemNumber, defaultTextColor)
setTextColor(R.id.timetableWidgetItemSubject, defaultTextColor)
setTextColor(R.id.timetableWidgetItemRoom, defaultTextColor)
setTextColor(R.id.timetableWidgetItemTeacher, defaultTextColor)
setTextColor(R.id.timetableWidgetItemDescription, defaultTextColor)
}
}
private fun updateNotCanceledLessonNumberColor(remoteViews: RemoteViews, lesson: Timetable) {
remoteViews.setTextColor(
R.id.timetableWidgetItemNumber, context.getCompatColor(
if (lesson.changes || (lesson.info.isNotBlank() && !lesson.canceled)) timetableChangeColor!!
else textColor!!
)
)
}
private fun applyCancelledLessonStyles(remoteViews: RemoteViews) {
val cancelledThemeColor = context.getCompatColor(timetableCanceledColor ?: 0)
val strikeThroughPaintFlags = STRIKE_THRU_TEXT_FLAG or ANTI_ALIAS_FLAG
private fun updateNotCanceledSubjectColor(remoteViews: RemoteViews, lesson: Timetable) {
remoteViews.setTextColor(
R.id.timetableWidgetItemSubject, context.getCompatColor(
if (lesson.subjectOld.isNotBlank() && lesson.subject != lesson.subjectOld) timetableChangeColor!!
else textColor!!
)
)
}
private fun updateNotCanceledRoom(
remoteViews: RemoteViews,
lesson: Timetable,
teacherChange: Boolean
) {
with(remoteViews) {
if (lesson.room.isNotBlank()) {
setTextViewText(
R.id.timetableWidgetItemRoom,
if (teacherChange) lesson.room
else "${context.getString(R.string.timetable_room)} ${lesson.room}"
)
setTextColor(
R.id.timetableWidgetItemRoom, context.getCompatColor(
if (lesson.roomOld.isNotBlank() && lesson.room != lesson.roomOld) timetableChangeColor!!
else textColor!!
)
)
} else setTextViewText(R.id.timetableWidgetItemRoom, "")
remoteViews.apply {
setInt(R.id.timetableWidgetItemSubject, "setPaintFlags", strikeThroughPaintFlags)
setTextColor(R.id.timetableWidgetItemNumber, cancelledThemeColor)
setTextColor(R.id.timetableWidgetItemSubject, cancelledThemeColor)
setTextColor(R.id.timetableWidgetItemDescription, cancelledThemeColor)
setViewVisibility(R.id.timetableWidgetItemDescription, VISIBLE)
setViewVisibility(R.id.timetableWidgetItemRoom, GONE)
setViewVisibility(R.id.timetableWidgetItemTeacher, GONE)
}
}
private fun updateNotCanceledTeacher(
remoteViews: RemoteViews,
lesson: Timetable,
teacherChange: Boolean
) {
remoteViews.setTextViewText(
R.id.timetableWidgetItemTeacher,
if (teacherChange) lesson.teacher
else ""
)
private fun applyChangedLessonStyles(remoteViews: RemoteViews, lesson: Timetable) {
val changesTextColor = context.getCompatColor(timetableChangeColor ?: 0)
remoteViews.apply {
setTextColor(R.id.timetableWidgetItemNumber, changesTextColor)
setTextColor(R.id.timetableWidgetItemDescription, changesTextColor)
setViewVisibility(R.id.timetableWidgetItemIcon, VISIBLE)
setImageViewResource(R.id.timetableWidgetItemIcon, R.drawable.ic_timetable_widget_swap)
}
if (lesson.subject != lesson.subjectOld) {
remoteViews.setTextColor(R.id.timetableWidgetItemSubject, changesTextColor)
}
if (lesson.room != lesson.roomOld) {
remoteViews.setTextColor(R.id.timetableWidgetItemRoom, changesTextColor)
}
if (lesson.teacher != lesson.teacherOld) {
remoteViews.setTextColor(R.id.timetableWidgetItemTeacher, changesTextColor)
}
if (lesson.info.isNotBlank() && !lesson.changes) {
remoteViews.setViewVisibility(R.id.timetableWidgetItemDescription, VISIBLE)
remoteViews.setViewVisibility(R.id.timetableWidgetItemRoom, GONE)
remoteViews.setViewVisibility(R.id.timetableWidgetItemTeacher, GONE)
}
}
private fun getSynchronizationInfoText(synchronizationInstant: Instant) =
synchronizationInstant.run {
val synchronizationTime = toFormattedString(TIME_FORMAT_STYLE)
val synchronizationDate = toFormattedString()
context.getString(
R.string.widget_timetable_last_synchronization,
synchronizationDate,
synchronizationTime,
)
}
}

View File

@ -8,10 +8,10 @@ import android.content.Context
import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Canvas
import android.widget.RemoteViews
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.graphics.drawable.DrawableCompat
import androidx.core.graphics.drawable.toBitmap
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.SharedPrefProvider
@ -70,11 +70,6 @@ class TimetableWidgetProvider : BroadcastReceiver() {
"timetable_widget_today_last_lesson_end_date_time_$appWidgetId"
fun getStudentWidgetKey(appWidgetId: Int) = "timetable_widget_student_$appWidgetId"
fun getThemeWidgetKey(appWidgetId: Int) = "timetable_widget_theme_$appWidgetId"
fun getCurrentThemeWidgetKey(appWidgetId: Int) =
"timetable_widget_current_theme_$appWidgetId"
}
@OptIn(DelicateCoroutinesApi::class)
@ -109,8 +104,7 @@ class TimetableWidgetProvider : BroadcastReceiver() {
val buttonType = intent.getStringExtra(EXTRA_BUTTON_TYPE)
val toggledWidgetId = intent.getIntExtra(EXTRA_TOGGLED_WIDGET_ID, 0)
val student = getStudent(
sharedPref.getLong(getStudentWidgetKey(toggledWidgetId), 0),
toggledWidgetId
sharedPref.getLong(getStudentWidgetKey(toggledWidgetId), 0), toggledWidgetId
)
val savedDate =
LocalDate.ofEpochDay(sharedPref.getLong(getDateWidgetKey(toggledWidgetId), 0))
@ -122,8 +116,7 @@ class TimetableWidgetProvider : BroadcastReceiver() {
}
if (!buttonType.isNullOrBlank()) {
analytics.logEvent(
"changed_timetable_widget_day",
"button" to buttonType
"changed_timetable_widget_day", "button" to buttonType
)
}
updateWidget(context, toggledWidgetId, date, student)
@ -137,49 +130,21 @@ class TimetableWidgetProvider : BroadcastReceiver() {
with(sharedPref) {
delete(getStudentWidgetKey(appWidgetId))
delete(getDateWidgetKey(appWidgetId))
delete(getThemeWidgetKey(appWidgetId))
delete(getCurrentThemeWidgetKey(appWidgetId))
}
}
}
private fun updateWidget(
context: Context,
appWidgetId: Int,
date: LocalDate,
student: Student?
context: Context, appWidgetId: Int, date: LocalDate, student: Student?
) {
val savedConfigureTheme = sharedPref.getLong(getThemeWidgetKey(appWidgetId), 0)
val isSystemDarkMode =
context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
var currentTheme = 0L
var layoutId = R.layout.widget_timetable
if (savedConfigureTheme == 1L || (savedConfigureTheme == 2L && isSystemDarkMode)) {
currentTheme = 1L
layoutId = R.layout.widget_timetable_dark
}
val nextNavIntent = createNavIntent(context, appWidgetId, appWidgetId, BUTTON_NEXT)
val prevNavIntent = createNavIntent(context, -appWidgetId, appWidgetId, BUTTON_PREV)
val resetNavIntent =
createNavIntent(context, Int.MAX_VALUE - appWidgetId, appWidgetId, BUTTON_RESET)
val adapterIntent = Intent(context, TimetableWidgetService::class.java)
.apply {
putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
//make Intent unique
action = appWidgetId.toString()
}
val accountIntent = PendingIntent.getActivity(
context,
-Int.MAX_VALUE + appWidgetId,
Intent(context, TimetableWidgetConfigureActivity::class.java).apply {
addFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK)
putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
putExtra(EXTRA_FROM_PROVIDER, true)
}, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
)
val adapterIntent = Intent(context, TimetableWidgetService::class.java).apply {
putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
action = appWidgetId.toString() //make Intent unique
}
val appIntent = PendingIntent.getActivity(
context,
TIMETABLE_PENDING_INTENT_ID,
@ -187,56 +152,41 @@ class TimetableWidgetProvider : BroadcastReceiver() {
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
)
val remoteView = RemoteViews(context.packageName, layoutId).apply {
val formattedDate = date.toFormattedString("EEE, dd.MM").capitalise()
val remoteView = RemoteViews(context.packageName, R.layout.widget_timetable).apply {
setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty)
setTextViewText(
R.id.timetableWidgetDate,
date.toFormattedString("EEEE, dd.MM").capitalise()
)
setTextViewText(
R.id.timetableWidgetName,
student?.nickOrName ?: context.getString(R.string.all_no_data)
)
student?.let {
setImageViewBitmap(R.id.timetableWidgetAccount, context.createAvatarBitmap(it))
}
setTextViewText(R.id.timetableWidgetDate, formattedDate)
setRemoteAdapter(R.id.timetableWidgetList, adapterIntent)
setOnClickPendingIntent(R.id.timetableWidgetNext, nextNavIntent)
setOnClickPendingIntent(R.id.timetableWidgetPrev, prevNavIntent)
setOnClickPendingIntent(R.id.timetableWidgetDate, resetNavIntent)
setOnClickPendingIntent(R.id.timetableWidgetName, resetNavIntent)
setOnClickPendingIntent(R.id.timetableWidgetAccount, accountIntent)
setPendingIntentTemplate(R.id.timetableWidgetList, appIntent)
}
student?.let {
setupAccountView(context, student, remoteView, appWidgetId)
}
with(sharedPref) {
putLong(getCurrentThemeWidgetKey(appWidgetId), currentTheme)
putLong(getDateWidgetKey(appWidgetId), date.toEpochDay(), true)
}
with(appWidgetManager) {
updateAppWidget(appWidgetId, remoteView)
partiallyUpdateAppWidget(appWidgetId, remoteView)
notifyAppWidgetViewDataChanged(appWidgetId, R.id.timetableWidgetList)
Timber.d("TimetableWidgetProvider updated")
}
Timber.d("TimetableWidgetProvider updated")
}
private fun createNavIntent(
context: Context,
code: Int,
appWidgetId: Int,
buttonType: String
context: Context, code: Int, appWidgetId: Int, buttonType: String
) = PendingIntent.getBroadcast(
context,
code,
Intent(context, TimetableWidgetProvider::class.java).apply {
context, code, Intent(context, TimetableWidgetProvider::class.java).apply {
action = ACTION_APPWIDGET_UPDATE
putExtra(EXTRA_BUTTON_TYPE, buttonType)
putExtra(EXTRA_TOGGLED_WIDGET_ID, appWidgetId)
},
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
}, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
)
private suspend fun getStudent(studentId: Long, appWidgetId: Int) = try {
@ -258,31 +208,6 @@ class TimetableWidgetProvider : BroadcastReceiver() {
null
}
private fun Context.createAvatarBitmap(student: Student): Bitmap {
val avatarColor = if (student.avatarColor == -2937041L) {
getCompatColor(R.color.colorPrimaryLight).toLong()
} else {
student.avatarColor
}
val avatarDrawable = createNameInitialsDrawable(student.nickOrName, avatarColor, 0.5f)
val avatarBitmap =
if (avatarDrawable.intrinsicWidth <= 0 || avatarDrawable.intrinsicHeight <= 0) {
Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
} else {
Bitmap.createBitmap(
avatarDrawable.intrinsicWidth,
avatarDrawable.intrinsicHeight,
Bitmap.Config.ARGB_8888
)
}
val canvas = Canvas(avatarBitmap)
avatarDrawable.setBounds(0, 0, canvas.width, canvas.height)
avatarDrawable.draw(canvas)
return avatarBitmap
}
private fun getWidgetDefaultDateToLoad(appWidgetId: Int): LocalDate {
val lastLessonEndTimestamp =
sharedPref.getLong(getTodayLastLessonEndDateTimeWidgetKey(appWidgetId), 0)
@ -299,4 +224,44 @@ class TimetableWidgetProvider : BroadcastReceiver() {
todayDate.nextOrSameSchoolDay
}
}
private fun setupAccountView(
context: Context,
student: Student,
remoteViews: RemoteViews,
appWidgetId: Int
) {
val accountInitials = student.nickOrName
.split(" ")
.mapNotNull { it.firstOrNull() }.take(2)
.joinToString(separator = "").uppercase()
val accountPickerIntent = PendingIntent.getActivity(
context,
-Int.MAX_VALUE + appWidgetId,
Intent(context, TimetableWidgetConfigureActivity::class.java).apply {
addFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK)
putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
putExtra(EXTRA_FROM_PROVIDER, true)
},
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
)
// Create background bitmap
val avatarDrawableResource = R.drawable.background_timetable_widget_avatar
AppCompatResources.getDrawable(context, avatarDrawableResource)?.let { drawable ->
val screenDensity = context.resources.displayMetrics.density
val avatarSize = (48 * screenDensity).toInt()
val backgroundBitmap = DrawableCompat.wrap(drawable).run {
DrawableCompat.setTint(this, student.avatarColor.toInt())
toBitmap(avatarSize, avatarSize)
}
remoteViews.setImageViewBitmap(R.id.timetableWidgetAccountBackground, backgroundBitmap)
}
remoteViews.apply {
setTextViewText(R.id.timetableWidgetAccountInitials, accountInitials)
setOnClickPendingIntent(R.id.timetableWidgetAccount, accountPickerIntent)
}
}
}

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.utils
import android.os.Handler
import android.os.Looper
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
@ -29,18 +30,18 @@ class LifecycleAwareVariable<T : Any> : ReadWriteProperty<Fragment, T>, DefaultL
}
}
class LifecycleAwareVariableActivity<T : Any> : ReadWriteProperty<AppCompatActivity, T>,
class LifecycleAwareVariableComponent<T : Any> : ReadWriteProperty<LifecycleOwner, T>,
DefaultLifecycleObserver {
private var _value: T? = null
override fun setValue(thisRef: AppCompatActivity, property: KProperty<*>, value: T) {
override fun setValue(thisRef: LifecycleOwner, property: KProperty<*>, value: T) {
thisRef.lifecycle.removeObserver(this)
_value = value
thisRef.lifecycle.addObserver(this)
}
override fun getValue(thisRef: AppCompatActivity, property: KProperty<*>) = _value
override fun getValue(thisRef: LifecycleOwner, property: KProperty<*>) = _value
?: throw IllegalStateException("Trying to call an lifecycle-aware value outside of the view lifecycle, or the value has not been initialized")
override fun onDestroy(owner: LifecycleOwner) {
@ -53,4 +54,8 @@ class LifecycleAwareVariableActivity<T : Any> : ReadWriteProperty<AppCompatActiv
@Suppress("unused")
fun <T : Any> Fragment.lifecycleAwareVariable() = LifecycleAwareVariable<T>()
fun <T : Any> lifecycleAwareVariable() = LifecycleAwareVariableActivity<T>()
@Suppress("unused")
fun <T : Any> DialogFragment.lifecycleAwareVariable() = LifecycleAwareVariableComponent<T>()
@Suppress("unused")
fun <T : Any> AppCompatActivity.lifecycleAwareVariable() = LifecycleAwareVariableComponent<T>()

View File

@ -49,4 +49,9 @@ class AutoRefreshHelper @Inject constructor(
fun updateLastRefreshTimestamp(key: String) {
sharedPref.putLong(key, Instant.now().toEpochMilli())
}
fun getLastRefreshTimestamp(key: String): Instant {
val refreshTimestampMilli = sharedPref.getLong(key, 0)
return Instant.ofEpochMilli(refreshTimestampMilli)
}
}

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/colorPrimaryLight" />
<corners android:radius="12dp" />
</shape>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF" />
<corners android:topLeftRadius="8dp" android:topRightRadius="8dp" />
</shape>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF" />
<corners android:bottomLeftRadius="8dp" android:bottomRightRadius="8dp" />
</shape>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#BB191919" />
<solid android:color="#FFFFFF" />
<corners android:radius="8dp" />
</shape>
</shape>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/colorWidgetTopBar" />
<corners android:radius="3dp" />
</shape>
<solid android:color="#FFFFFF" />
<corners android:radius="4dp" />
</shape>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/colorPrimary" />
<solid android:color="?colorPrimary" />
<corners android:radius="12dp" />
</shape>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#bbffffff" />
<corners android:radius="8dp" />
<solid android:color="#FFFFDAD5" />
<corners android:radius="20dp" />
</shape>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#BB191919" />
<corners android:radius="8dp" />
</shape>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<item>
<shape>
<solid android:color="?attr/colorSurface" />
<corners
android:bottomLeftRadius="28dp"
android:bottomRightRadius="28dp"
android:topLeftRadius="28dp"
android:topRightRadius="28dp" />
</shape>
</item>
<item>
<shape>
<solid
android:color="@color/m3_popupmenu_overlay_color"
tools:ignore="PrivateResource" />
<corners
android:bottomLeftRadius="28dp"
android:bottomRightRadius="28dp"
android:topLeftRadius="28dp"
android:topRightRadius="28dp" />
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF000000" />
<corners android:radius="12dp" />
</shape>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/colorPrimary" />
<corners
android:topLeftRadius="8dp"
android:topRightRadius="8dp" />
</shape>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/colorWidgetTopBar" />
<corners
android:topLeftRadius="8dp"
android:topRightRadius="8dp" />
</shape>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/white" />
<corners android:radius="3dp" />
</shape>
<solid android:color="#FFFFFBFF" />
<corners android:radius="12dp" />
</shape>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#bbffffff" />
<corners android:radius="8dp" />
</shape>
<solid android:color="#FFFFEDEA" />
<corners android:radius="28dp" />
</shape>

View File

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M15.41,7.41L14,6l-6,6 6,6 1.41,-1.41L10.83,12z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#FFFFFF"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M15.41,7.41L14,6l-6,6 6,6 1.41,-1.41L10.83,12z" />
</vector>

View File

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#FFFFFF"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z" />
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M12,21q-3.45,0 -6.012,-2.288Q3.425,16.425 3.05,13L5.1,13q0.35,2.6 2.312,4.3Q9.375,19 12,19q2.925,0 4.962,-2.038Q19,14.925 19,12t-2.038,-4.963Q14.925,5 12,5q-1.725,0 -3.225,0.8T6.25,8L9,8v2L3,10L3,4h2v2.35q1.275,-1.6 3.113,-2.475Q9.95,3 12,3q1.875,0 3.513,0.712 1.637,0.713 2.85,1.925 1.212,1.213 1.925,2.85Q21,10.125 21,12t-0.712,3.512q-0.713,1.638 -1.925,2.85 -1.213,1.213 -2.85,1.926Q13.875,21 12,21ZM14.8,16.2L11,12.4L11,7h2v4.6l3.2,3.2Z"/>
</vector>

View File

@ -0,0 +1,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#FFF" android:pathData="M12,3C10.73,3 9.6,3.8 9.18,5H3V7H4.95L2,14C1.53,16 3,17 5.5,17C8,17 9.56,16 9,14L6.05,7H9.17C9.5,7.85 10.15,8.5 11,8.83V20H2V22H22V20H13V8.82C13.85,8.5 14.5,7.85 14.82,7H17.95L15,14C14.53,16 16,17 18.5,17C21,17 22.56,16 22,14L19.05,7H21V5H14.83C14.4,3.8 13.27,3 12,3M12,5A1,1 0 0,1 13,6A1,1 0 0,1 12,7A1,1 0 0,1 11,6A1,1 0 0,1 12,5M5.5,10.25L7,14H4L5.5,10.25M18.5,10.25L20,14H17L18.5,10.25Z" />
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="m7,20 l-5,-5 5,-5 1.4,1.425L5.825,14L13,14v2L5.825,16L8.4,18.575ZM17,14 L15.6,12.575L18.175,10L11,10L11,8h7.175L15.6,5.425 17,4l5,5Z"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M8.025,22 L6.25,20.225 14.475,12 6.25,3.775 8.025,2l10,10Z" />
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="196dp"
android:height="196dp"
android:viewportWidth="174"
android:viewportHeight="174">
<path
android:fillColor="#FF000000"
android:pathData="M71.54 4.658a32 32 0 0 1 31.068 0.013l11.9 6.614a32.03 32.03 0 0 0 6.735 2.793l13.089 3.749a32 32 0 0 1 21.958 21.978l3.738 13.092c0.669 2.344 1.605 4.605 2.787 6.737l6.604 11.906a32 32 0 0 1-0.013 31.068l-6.615 11.9c-1.184 2.132-2.121 4.391-2.792 6.735l-3.75 13.088c-3.043 10.624-11.351 18.926-21.977 21.959l-13.092 3.738a32 32 0 0 0-6.737 2.787l-11.906 6.604c-9.664 5.36-21.409 5.355-31.068-0.013l-11.9-6.615c-2.131-1.184-4.391-2.121-6.734-2.793l-13.089-3.749a32 32 0 0 1-21.959-21.977l-3.738-13.092a31.95 31.95 0 0 0-2.787-6.737l-6.604-11.906a32 32 0 0 1 0.013-31.068l6.614-11.9c1.185-2.131 2.122-4.391 2.793-6.735l3.749-13.088a32 32 0 0 1 21.978-21.959l13.092-3.738a31.95 31.95 0 0 0 6.737-2.787L71.54 4.658z" />
</vector>

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background_widget_timetable"
android:backgroundTint="?attr/colorSurface"
android:clipToOutline="true"
android:orientation="vertical"
android:paddingHorizontal="16dp"
android:theme="@style/Wulkanowy.Widget.Theme"
tools:context=".ui.modules.timetablewidget.TimetableWidgetProvider">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingVertical="16dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:lines="1"
android:text="Pon, 03.10"
android:textAppearance="?attr/textAppearanceHeadline5"
tools:ignore="HardcodedText" />
<ImageButton
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="12dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/all_prev"
android:rotation="180"
android:src="@drawable/ic_widget_chevron"
android:tint="?attr/colorPrimary"
app:tint="?attr/colorPrimary"
tools:ignore="UseAppTint" />
<ImageButton
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/all_next"
android:src="@drawable/ic_widget_chevron"
android:tint="?attr/colorPrimary"
app:tint="?attr/colorPrimary"
tools:ignore="UseAppTint" />
<TextView
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="12dp"
android:background="@drawable/background_timetable_widget_avatar"
android:backgroundTint="?attr/colorPrimary"
android:contentDescription="@string/account_quick_manager"
android:gravity="center"
android:text="AW"
android:textAppearance="?attr/textAppearanceTitleLarge"
android:textColor="?attr/colorOnPrimary" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:showDividers="middle">
<ImageView
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginBottom="4dp"
android:importantForAccessibility="no"
android:src="@drawable/background_widget_item_timetable"
app:tint="?attr/backgroundColor" />
<ImageView
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginBottom="4dp"
android:importantForAccessibility="no"
android:src="@drawable/background_widget_item_timetable"
app:tint="?attr/backgroundColor" />
<ImageView
android:layout_width="match_parent"
android:layout_height="56dp"
android:importantForAccessibility="no"
android:src="@drawable/background_widget_item_timetable"
app:tint="?attr/backgroundColor" />
</LinearLayout>
</LinearLayout>

View File

@ -1,24 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/main_toolbar"
style="@style/Widget.MaterialComponents.Toolbar.Surface"
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/main_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentInsetStartWithNavigation="0dp"
app:layout_constraintTop_toTopOf="parent" />
android:fitsSystemWindows="true"
app:layout_constraintBaseline_toTopOf="parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/main_fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/main_bottom_nav"
app:layout_constraintTop_toBottomOf="@id/main_toolbar" />
app:layout_constraintTop_toBottomOf="@id/main_app_bar"
tools:layout="@layout/fragment_dashboard" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/main_message_container"

View File

@ -7,16 +7,18 @@
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/sendMessageToolbar"
style="@style/Widget.MaterialComponents.Toolbar.Surface"
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/send_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="4dp"
app:layout_constraintBottom_toTopOf="@id/sendMessageScroll"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:fitsSystemWindows="true"
app:layout_constraintBaseline_toTopOf="parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/sendMessageToolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
</com.google.android.material.appbar.AppBarLayout>
<io.github.wulkanowy.materialchipsinput.ConsumedNestedScrollView
android:id="@+id/sendMessageScroll"
@ -26,7 +28,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/sendMessageToolbar">
app:layout_constraintTop_toBottomOf="@id/send_app_bar">
<FrameLayout
android:layout_width="match_parent"
@ -185,7 +187,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/sendMessageToolbar"
app:layout_constraintTop_toBottomOf="@id/send_app_bar"
tools:ignore="UseCompoundDrawables">
<ImageView
@ -214,5 +216,5 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/sendMessageToolbar" />
app:layout_constraintTop_toBottomOf="@id/send_app_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,19 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:layout_width="280dp"
android:layout_height="1dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/accountEditDetailsHeader"
@ -32,7 +27,7 @@
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/accountEditDetailsNick"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
@ -88,17 +83,16 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/accountEditDetailsSave"
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_marginTop="36dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="24dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="88dp"
android:text="@string/all_save"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@ -106,17 +100,16 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/accountEditDetailsCancel"
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_marginTop="36dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:layout_marginBottom="24dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="88dp"
android:text="@android:string/cancel"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/accountEditDetailsSave"

View File

@ -41,7 +41,7 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/account_quick_dialog_manger"
style="@style/Widget.MaterialComponents.Button.TextButton"
style="@style/Widget.Material3.Button.TextButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"

View File

@ -2,37 +2,35 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:minWidth="300dp"
android:paddingStart="8dp"
android:paddingEnd="8dp">
android:layout_height="match_parent">
<LinearLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minWidth="300dp"
android:orientation="vertical">
android:paddingStart="24dp"
android:paddingEnd="24dp">
<TextView
android:id="@+id/addadditionalLessonHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:text="@string/additional_lessons_add_title"
android:textSize="21sp"
android:textStyle="bold" />
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:textColor="?attr/colorOnSurface"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/additionalLessonDialogDate"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="28dp"
android:hint="@string/all_date"
app:layout_constraintTop_toBottomOf="@id/addadditionalLessonHeader"
app:startIconDrawable="@drawable/ic_calendar_all">
<com.google.android.material.textfield.TextInputEditText
@ -45,22 +43,22 @@
tools:ignore="Deprecated" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.switchmaterial.SwitchMaterial
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/additionalLessonDialogRepeat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="6dp"
android:text="@string/additional_lessons_repeat" />
android:text="@string/additional_lessons_repeat"
app:layout_constraintTop_toBottomOf="@id/additionalLessonDialogDate" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/additionalLessonDialogStart"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="6dp"
android:hint="@string/additional_lessons_start"
app:layout_constraintTop_toBottomOf="@id/additionalLessonDialogRepeat"
app:startIconDrawable="@drawable/ic_all_clock">
<com.google.android.material.textfield.TextInputEditText
@ -78,9 +76,9 @@
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:hint="@string/additional_lessons_end"
app:layout_constraintTop_toBottomOf="@id/additionalLessonDialogStart"
app:startIconDrawable="@drawable/ic_all_clock">
<com.google.android.material.textfield.TextInputEditText
@ -98,59 +96,52 @@
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:hint="@string/all_subject">
android:hint="@string/all_subject"
app:layout_constraintTop_toBottomOf="@id/additionalLessonDialogEnd">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/additionalLessonDialogContentEdit"
android:layout_width="match_parent"
android:inputType="text"
android:layout_height="wrap_content"
android:inputType="text"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="end"
android:minHeight="52dp"
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
android:id="@+id/additionalLessonDialogClose"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_gravity="center_vertical"
android:layout_marginTop="24dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="24dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:text="@string/all_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/additionalLessonDialogAdd"
app:layout_constraintTop_toBottomOf="@id/additionalLessonDialogContent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/additionalLessonDialogClose"
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="0dp"
android:layout_marginLeft="0dp"
android:layout_marginBottom="8dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="88dp"
android:text="@string/all_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/additionalLessonDialogAdd"
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_gravity="center_vertical"
android:layout_marginBottom="8dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="88dp"
android:text="@string/all_add"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/additionalLessonDialogAdd"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_gravity="center_vertical"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:text="@string/all_add"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/additionalLessonDialogContent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

View File

@ -63,7 +63,7 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/ads_consent_cancel"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"

View File

@ -5,28 +5,21 @@
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="24dp"
android:paddingEnd="8dp">
<View
android:layout_width="280dp"
android:layout_height="1dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/allDetailsHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:text="@string/all_details"
android:textSize="21sp"
android:textStyle="bold"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:textColor="?attr/colorOnSurface"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -36,12 +29,11 @@
android:id="@+id/attendanceDialogSubjectTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="28dp"
android:layout_marginEnd="24dp"
android:text="@string/all_subject"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -51,13 +43,13 @@
android:id="@+id/attendanceDialogSubjectValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="24dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -68,12 +60,11 @@
android:id="@+id/attendanceDialogDescriptionTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/all_description"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -83,13 +74,13 @@
android:id="@+id/attendanceDialogDescriptionValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="24dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -99,12 +90,11 @@
android:id="@+id/attendanceDialogDateTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/all_date"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -114,13 +104,13 @@
android:id="@+id/attendanceDialogDateValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="24dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -130,12 +120,11 @@
android:id="@+id/attendanceDialogNumberTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/attendance_number"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -145,13 +134,13 @@
android:id="@+id/attendanceDialogNumberValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="24dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -159,17 +148,16 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/attendanceDialogClose"
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_marginTop="36dp"
android:layout_marginEnd="0dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="24dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="88dp"
android:text="@string/all_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@ -6,28 +6,20 @@
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="24dp"
android:paddingEnd="8dp">
<View
android:layout_width="280dp"
android:layout_height="1dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/allDetailsHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:text="@string/all_details"
android:textSize="21sp"
android:textStyle="bold"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:textColor="?attr/colorOnSurface"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -37,12 +29,11 @@
android:id="@+id/conferenceDialogHeaderTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="28dp"
android:layout_marginEnd="24dp"
android:text="@string/conference_place"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -52,13 +43,13 @@
android:id="@+id/conferenceDialogHeaderValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="24dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -68,12 +59,11 @@
android:id="@+id/conferenceDialogSubjectTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/conference_topic"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -83,13 +73,13 @@
android:id="@+id/conferenceDialogSubjectValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="24dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -99,12 +89,11 @@
android:id="@+id/conferenceDialogDateTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/all_date"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -114,13 +103,13 @@
android:id="@+id/conferenceDialogDateValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="24dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -130,12 +119,11 @@
android:id="@+id/conferenceDialogPresentTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/conferences_present"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -145,13 +133,13 @@
android:id="@+id/conferenceDialogPresentValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="24dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -161,12 +149,11 @@
android:id="@+id/conferenceDialogAgendaTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/conference_agenda"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -176,13 +163,13 @@
android:id="@+id/conferenceDialogAgendaValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="24dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -192,17 +179,16 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/conferenceDialogClose"
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_marginTop="36dp"
android:layout_marginEnd="0dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="24dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="88dp"
android:text="@string/all_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@ -1,24 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.modules.exam.ExamDialog">
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:paddingEnd="8dp">
<View
android:layout_width="280dp"
android:layout_height="1dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/allDetailsHeader"
android:layout_width="wrap_content"
@ -27,8 +18,8 @@
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:text="@string/all_details"
android:textSize="21sp"
android:textStyle="bold"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:textColor="?attr/colorOnSurface"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -42,8 +33,8 @@
android:layout_marginTop="28dp"
android:layout_marginEnd="24dp"
android:text="@string/all_subject"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -58,8 +49,9 @@
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -73,8 +65,8 @@
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/exam_type"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -89,8 +81,9 @@
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -104,8 +97,8 @@
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/all_teacher"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -120,8 +113,9 @@
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -166,8 +160,8 @@
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/exam_entry_date"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -182,8 +176,9 @@
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -197,8 +192,8 @@
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/all_description"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -213,8 +208,9 @@
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -222,10 +218,11 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/examDialogAddToCalendar"
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog.Flush"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="24dp"
android:contentDescription="@string/all_add_to_calendar"
android:insetLeft="0dp"
android:insetTop="0dp"
@ -234,21 +231,20 @@
android:text="@string/all_add"
app:icon="@drawable/ic_calendar_all"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
app:layout_constraintEnd_toStartOf="@+id/examDialogClose" />
<com.google.android.material.button.MaterialButton
android:id="@+id/examDialogClose"
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_marginTop="36dp"
android:layout_marginEnd="0dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="24dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="88dp"
android:text="@string/all_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@ -6,7 +6,7 @@
android:padding="20dp">
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content">

View File

@ -32,43 +32,57 @@
android:id="@+id/gradeDialogValue"
android:layout_width="match_parent"
android:layout_height="86dp"
android:layout_marginStart="0dp"
android:layout_marginEnd="16dp"
android:background="@color/grade_material_default"
android:background="@drawable/background_grade_details_rounded"
android:backgroundTint="@color/grade_material_default"
android:gravity="center"
android:textColor="@android:color/white"
android:textSize="30sp"
tools:text="6" />
<TextView
android:id="@+id/gradeDialogColorAndWeightValue"
<LinearLayout
android:id="@+id/gradeDialogWeightLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginStart="0dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="16dp"
android:background="@color/grade_black"
android:gravity="center"
android:maxLines="2"
android:minHeight="32dp"
android:textColor="@android:color/white"
android:textIsSelectable="true"
android:textSize="14sp"
tools:text="Waga: 1.00" />
android:background="@drawable/background_grade_details_weight_rounded"
android:backgroundTint="@color/grade_black"
android:gravity="center_horizontal">
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_gravity="center"
android:layout_marginRight="4dp"
android:background="@drawable/ic_scale_balance" />
<TextView
android:id="@+id/gradeDialogWeightValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:maxLines="2"
android:minHeight="32dp"
android:textColor="@android:color/white"
android:textIsSelectable="true"
android:textSize="14sp"
tools:text="1.00" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/gradeDialogHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginEnd="14dp"
android:layout_marginRight="14dp"
android:layout_toStartOf="@+id/gradeDialogValueLayout"
android:layout_toLeftOf="@+id/gradeDialogValueLayout"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:orientation="vertical">
<TextView
@ -78,18 +92,19 @@
android:layout_gravity="start"
android:gravity="center_vertical"
android:text="@string/grade_header"
android:textIsSelectable="true"
android:textSize="21sp"
android:textStyle="bold" />
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true" />
<TextView
android:id="@+id/gradeDialogDescriptionValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/all_no_description"
android:layout_marginTop="8dp"
android:textIsSelectable="true"
android:textSize="16sp" />
android:text="@string/all_no_description"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true" />
</LinearLayout>
<TextView
@ -101,8 +116,8 @@
android:layout_alignParentLeft="true"
android:layout_marginTop="16dp"
android:text="@string/all_date"
android:textColor="?android:textColorSecondary"
android:textSize="12sp" />
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant" />
<TextView
android:id="@+id/gradeDialogDateValue"
@ -114,8 +129,9 @@
android:layout_marginEnd="24dp"
android:layout_toStartOf="@+id/gradeDialogValueLayout"
android:text="@string/all_date"
android:textIsSelectable="true"
android:textSize="16sp" />
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true" />
<TextView
android:id="@+id/gradeDialogComment"
@ -126,8 +142,8 @@
android:layout_alignParentLeft="true"
android:layout_marginTop="16dp"
android:text="@string/grade_comment"
android:textColor="?android:textColorSecondary"
android:textSize="12sp" />
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant" />
<TextView
android:id="@+id/gradeDialogCommentValue"
@ -138,8 +154,9 @@
android:layout_alignParentLeft="true"
android:layout_toStartOf="@+id/gradeDialogValueLayout"
android:text="@string/grade_comment"
android:textIsSelectable="true"
android:textSize="16sp" />
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true" />
<TextView
android:id="@+id/gradeDialogTeacher"
@ -150,8 +167,8 @@
android:layout_alignParentLeft="true"
android:layout_marginTop="16dp"
android:text="@string/all_teacher"
android:textColor="?android:textColorSecondary"
android:textSize="12sp" />
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant" />
<TextView
android:id="@+id/gradeDialogTeacherValue"
@ -162,8 +179,9 @@
android:layout_alignParentLeft="true"
android:layout_toStartOf="@+id/gradeDialogValueLayout"
android:text="@string/all_teacher"
android:textIsSelectable="true"
android:textSize="16sp" />
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true" />
<TextView
android:id="@+id/gradeDialogColor"
@ -174,8 +192,8 @@
android:layout_alignParentLeft="true"
android:layout_marginTop="16dp"
android:text="@string/all_color"
android:textColor="?android:textColorSecondary"
android:textSize="12sp" />
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant" />
<TextView
android:id="@+id/gradeDialogColorValue"
@ -186,26 +204,25 @@
android:layout_alignParentLeft="true"
android:layout_toStartOf="@+id/gradeDialogValueLayout"
android:text="@string/all_color"
android:textIsSelectable="true"
android:textSize="16sp" />
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true" />
<com.google.android.material.button.MaterialButton
android:id="@+id/gradeDialogClose"
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_below="@+id/gradeDialogColorValue"
android:layout_alignParentRight="true"
android:layout_marginTop="36dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="24dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="88dp"
android:text="@string/all_close" />
</RelativeLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View File

@ -1,71 +1,56 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="300dp"
android:orientation="vertical">
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/homeworkDialogRecycler"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:minWidth="300dp"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:overScrollMode="ifContentScrolls"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toTopOf="@id/homeworkDialogClose"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0"
tools:itemCount="1"
tools:listitem="@layout/item_homework_dialog_details" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@drawable/ic_all_divider" />
android:background="@drawable/ic_all_divider"
app:layout_constraintTop_toBottomOf="@id/homeworkDialogRecycler" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:minHeight="52dp"
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
android:id="@+id/homeworkDialogRead"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_gravity="center_vertical"
android:layout_marginEnd="8dp"
android:layout_marginBottom="24dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:text="@string/homework_mark_as_done"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/homeworkDialogClose" />
<com.google.android.material.button.MaterialButton
android:id="@+id/homeworkDialogRead"
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:layout_gravity="center_vertical"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="88dp"
android:text="@string/homework_mark_as_done"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/homeworkDialogClose"
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_gravity="center_vertical"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="88dp"
android:text="@string/all_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/homeworkDialogClose"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="24dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:text="@string/all_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -2,37 +2,35 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:minWidth="300dp"
android:paddingStart="8dp"
android:paddingEnd="8dp">
android:layout_height="match_parent">
<LinearLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minWidth="300dp"
android:orientation="vertical">
android:paddingStart="24dp"
android:paddingEnd="24dp">
<TextView
android:id="@+id/addHomeworkHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:text="@string/homework_add"
android:textSize="21sp"
android:textStyle="bold" />
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:textColor="?attr/colorOnSurface"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/homeworkDialogDate"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="28dp"
android:hint="@string/all_date"
app:layout_constraintTop_toBottomOf="@id/addHomeworkHeader"
app:startIconDrawable="@drawable/ic_calendar_all">
<com.google.android.material.textfield.TextInputEditText
@ -48,12 +46,12 @@
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/homeworkDialogSubject"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:hint="@string/all_subject">
android:hint="@string/all_subject"
app:layout_constraintTop_toBottomOf="@id/homeworkDialogDate">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/homeworkDialogSubjectEdit"
@ -63,12 +61,12 @@
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/homeworkDialogTeacher"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:hint="@string/all_teacher">
android:hint="@string/all_teacher"
app:layout_constraintTop_toBottomOf="@id/homeworkDialogSubject">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/homeworkDialogTeacherEdit"
@ -78,13 +76,13 @@
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/homeworkDialogContent"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:hint="@string/all_content">
android:hint="@string/all_content"
app:layout_constraintTop_toBottomOf="@id/homeworkDialogTeacher">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/homeworkDialogContentEdit"
@ -92,43 +90,38 @@
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="62dp">
<com.google.android.material.button.MaterialButton
android:id="@+id/homeworkDialogClose"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_gravity="center_vertical"
android:layout_marginTop="24dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="24dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:text="@string/all_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/homeworkDialogAdd"
app:layout_constraintTop_toBottomOf="@id/homeworkDialogContent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/homeworkDialogClose"
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="0dp"
android:layout_marginLeft="0dp"
android:layout_marginBottom="8dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="88dp"
android:text="@string/all_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/homeworkDialogAdd"
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_marginBottom="8dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="88dp"
android:text="@string/all_add"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/homeworkDialogAdd"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:text="@string/all_add"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/homeworkDialogContent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
@ -7,28 +8,20 @@
tools:context=".ui.modules.timetable.completed.CompletedLessonDialog">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="24dp"
android:paddingEnd="8dp">
<View
android:layout_width="280dp"
android:layout_height="1dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/allDetailsHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:text="@string/all_details"
android:textSize="21sp"
android:textStyle="bold"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:textColor="?attr/colorOnSurface"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -38,12 +31,11 @@
android:id="@+id/completedLessonDialogSubjectTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="28dp"
android:layout_marginEnd="24dp"
android:text="@string/timetable_lesson"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -53,13 +45,13 @@
android:id="@+id/completedLessonDialogSubjectValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="24dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -69,12 +61,11 @@
android:id="@+id/completedLessonDialogTopicTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/completed_lessons_topic"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -84,13 +75,13 @@
android:id="@+id/completedLessonDialogTopicValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="24dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -100,12 +91,11 @@
android:id="@+id/completedLessonDialogTeacherTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/all_teacher"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -115,13 +105,13 @@
android:id="@+id/completedLessonDialogTeacherValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="24dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -131,12 +121,11 @@
android:id="@+id/completedLessonDialogChangesTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/timetable_changes"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?colorTimetableChange"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -146,14 +135,13 @@
android:id="@+id/completedLessonDialogChangesValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="24dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?colorTimetableChange"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -163,12 +151,11 @@
android:id="@+id/completedLessonDialogAbsenceTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/completed_lessons_absence"
android:textColor="?colorPrimary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?colorTimetableCanceled"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -178,14 +165,13 @@
android:id="@+id/completedLessonDialogAbsenceValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="24dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@string/all_no_data"
android:textColor="?colorPrimary"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?colorTimetableCanceled"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -195,12 +181,11 @@
android:id="@+id/completedLessonDialogResourcesTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="@string/completed_lessons_resources"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -210,14 +195,14 @@
android:id="@+id/completedLessonDialogResourcesValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="24dp"
android:autoLink="web"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:autoLink="web"
android:text="@string/all_no_data"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
@ -225,17 +210,16 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/completedLessonDialogClose"
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_marginTop="36dp"
android:layout_marginEnd="0dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="24dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="88dp"
android:text="@string/all_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@ -7,18 +7,10 @@
tools:context=".ui.modules.mobiledevice.token.MobileDeviceTokenDialog">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:layout_width="292dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/mobileDeviceQr"
android:layout_width="150dp"
@ -119,17 +111,16 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/mobileDeviceDialogClose"
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_marginTop="36dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="24dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="88dp"
android:text="@string/all_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

Some files were not shown because too many files have changed in this diff Show More