Add panic button

This commit is contained in:
Mikołaj Pich 2024-05-23 07:37:49 +02:00
parent 5ca9ac3978
commit 87fb1916d8
No known key found for this signature in database
9 changed files with 184 additions and 80 deletions

View File

@ -125,6 +125,7 @@ class DashboardFragment : BaseFragment<FragmentDashboardBinding>(R.layout.fragme
mainActivity.pushView(ConferenceFragment.newInstance()) mainActivity.pushView(ConferenceFragment.newInstance())
} }
onAdminMessageClickListener = presenter::onAdminMessageSelected onAdminMessageClickListener = presenter::onAdminMessageSelected
onPanicButtonClickListener = presenter::onPanicButtonClicked
onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed
registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
@ -208,7 +209,11 @@ class DashboardFragment : BaseFragment<FragmentDashboardBinding>(R.layout.fragme
binding = binding.dashboardErrorAdminMessage, binding = binding.dashboardErrorAdminMessage,
onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed, onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed,
onAdminMessageClickListener = presenter::onAdminMessageSelected, onAdminMessageClickListener = presenter::onAdminMessageSelected,
).bind(adminMessageItem.adminMessage) onPanicButtonClickListener = presenter::onPanicButtonClicked,
).bind(
item = adminMessageItem.adminMessage,
showPanicButton = true,
)
} }
} }

View File

@ -11,6 +11,7 @@ import io.github.wulkanowy.data.errorOrNull
import io.github.wulkanowy.data.flatResourceFlow import io.github.wulkanowy.data.flatResourceFlow
import io.github.wulkanowy.data.mapResourceData import io.github.wulkanowy.data.mapResourceData
import io.github.wulkanowy.data.onResourceError import io.github.wulkanowy.data.onResourceError
import io.github.wulkanowy.data.onResourceSuccess
import io.github.wulkanowy.data.repositories.AttendanceSummaryRepository import io.github.wulkanowy.data.repositories.AttendanceSummaryRepository
import io.github.wulkanowy.data.repositories.ConferenceRepository import io.github.wulkanowy.data.repositories.ConferenceRepository
import io.github.wulkanowy.data.repositories.ExamRepository import io.github.wulkanowy.data.repositories.ExamRepository
@ -23,6 +24,7 @@ import io.github.wulkanowy.data.repositories.SchoolAnnouncementRepository
import io.github.wulkanowy.data.repositories.SemesterRepository import io.github.wulkanowy.data.repositories.SemesterRepository
import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.repositories.TimetableRepository import io.github.wulkanowy.data.repositories.TimetableRepository
import io.github.wulkanowy.data.resourceFlow
import io.github.wulkanowy.domain.adminmessage.GetAppropriateAdminMessageUseCase import io.github.wulkanowy.domain.adminmessage.GetAppropriateAdminMessageUseCase
import io.github.wulkanowy.domain.timetable.IsStudentHasLessonsOnWeekendUseCase import io.github.wulkanowy.domain.timetable.IsStudentHasLessonsOnWeekendUseCase
import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.BasePresenter
@ -44,6 +46,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import okhttp3.HttpUrl.Companion.toHttpUrl
import timber.log.Timber import timber.log.Timber
import java.time.Instant import java.time.Instant
import java.time.LocalDate import java.time.LocalDate
@ -282,6 +285,22 @@ class DashboardPresenter @Inject constructor(
url?.let { view?.openInternetBrowser(it) } url?.let { view?.openInternetBrowser(it) }
} }
fun onPanicButtonClicked() {
resourceFlow { studentRepository.getCurrentStudent() }
.onResourceError { errorHandler.dispatch(it) }
.onResourceSuccess {
val baseUrl = it.scrapperBaseUrl.toHttpUrl()
val urlToOpen = baseUrl.newBuilder()
.host("uonetplus${it.scrapperDomainSuffix}.${baseUrl.host}")
.addPathSegment(it.symbol)
.build()
.toString()
view?.openInternetBrowser(urlToOpen)
}
.launch("panic_button")
}
private fun loadHorizontalGroup(student: Student, forceRefresh: Boolean) { private fun loadHorizontalGroup(student: Student, forceRefresh: Boolean) {
flow { flow {
val selectedTiles = selectedDashboardTiles val selectedTiles = selectedDashboardTiles

View File

@ -59,6 +59,8 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
var onAdminMessageClickListener: (String?) -> Unit = {} var onAdminMessageClickListener: (String?) -> Unit = {}
var onPanicButtonClickListener: () -> Unit = {}
var onAdminMessageDismissClickListener: (AdminMessage) -> Unit = {} var onAdminMessageDismissClickListener: (AdminMessage) -> Unit = {}
val items = mutableListOf<DashboardItem>() val items = mutableListOf<DashboardItem>()
@ -86,35 +88,46 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
DashboardItem.Type.ACCOUNT.ordinal -> AccountViewHolder( DashboardItem.Type.ACCOUNT.ordinal -> AccountViewHolder(
ItemDashboardAccountBinding.inflate(inflater, parent, false) ItemDashboardAccountBinding.inflate(inflater, parent, false)
) )
DashboardItem.Type.HORIZONTAL_GROUP.ordinal -> HorizontalGroupViewHolder( DashboardItem.Type.HORIZONTAL_GROUP.ordinal -> HorizontalGroupViewHolder(
ItemDashboardHorizontalGroupBinding.inflate(inflater, parent, false) ItemDashboardHorizontalGroupBinding.inflate(inflater, parent, false)
) )
DashboardItem.Type.GRADES.ordinal -> GradesViewHolder( DashboardItem.Type.GRADES.ordinal -> GradesViewHolder(
ItemDashboardGradesBinding.inflate(inflater, parent, false) ItemDashboardGradesBinding.inflate(inflater, parent, false)
) )
DashboardItem.Type.LESSONS.ordinal -> LessonsViewHolder( DashboardItem.Type.LESSONS.ordinal -> LessonsViewHolder(
ItemDashboardLessonsBinding.inflate(inflater, parent, false) ItemDashboardLessonsBinding.inflate(inflater, parent, false)
) )
DashboardItem.Type.HOMEWORK.ordinal -> HomeworkViewHolder( DashboardItem.Type.HOMEWORK.ordinal -> HomeworkViewHolder(
ItemDashboardHomeworkBinding.inflate(inflater, parent, false) ItemDashboardHomeworkBinding.inflate(inflater, parent, false)
) )
DashboardItem.Type.ANNOUNCEMENTS.ordinal -> AnnouncementsViewHolder( DashboardItem.Type.ANNOUNCEMENTS.ordinal -> AnnouncementsViewHolder(
ItemDashboardAnnouncementsBinding.inflate(inflater, parent, false) ItemDashboardAnnouncementsBinding.inflate(inflater, parent, false)
) )
DashboardItem.Type.EXAMS.ordinal -> ExamsViewHolder( DashboardItem.Type.EXAMS.ordinal -> ExamsViewHolder(
ItemDashboardExamsBinding.inflate(inflater, parent, false) ItemDashboardExamsBinding.inflate(inflater, parent, false)
) )
DashboardItem.Type.CONFERENCES.ordinal -> ConferencesViewHolder( DashboardItem.Type.CONFERENCES.ordinal -> ConferencesViewHolder(
ItemDashboardConferencesBinding.inflate(inflater, parent, false) ItemDashboardConferencesBinding.inflate(inflater, parent, false)
) )
DashboardItem.Type.ADMIN_MESSAGE.ordinal -> AdminMessageViewHolder( DashboardItem.Type.ADMIN_MESSAGE.ordinal -> AdminMessageViewHolder(
ItemDashboardAdminMessageBinding.inflate(inflater, parent, false), ItemDashboardAdminMessageBinding.inflate(inflater, parent, false),
onAdminMessageDismissClickListener = onAdminMessageDismissClickListener, onAdminMessageDismissClickListener = onAdminMessageDismissClickListener,
onAdminMessageClickListener = onAdminMessageClickListener, onAdminMessageClickListener = onAdminMessageClickListener,
onPanicButtonClickListener = onPanicButtonClickListener,
) )
DashboardItem.Type.ADS.ordinal -> AdsViewHolder( DashboardItem.Type.ADS.ordinal -> AdsViewHolder(
ItemDashboardAdsBinding.inflate(inflater, parent, false) ItemDashboardAdsBinding.inflate(inflater, parent, false)
) )
else -> throw IllegalArgumentException() else -> throw IllegalArgumentException()
} }
} }
@ -129,7 +142,11 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
is AnnouncementsViewHolder -> bindAnnouncementsViewHolder(holder, position) is AnnouncementsViewHolder -> bindAnnouncementsViewHolder(holder, position)
is ExamsViewHolder -> bindExamsViewHolder(holder, position) is ExamsViewHolder -> bindExamsViewHolder(holder, position)
is ConferencesViewHolder -> bindConferencesViewHolder(holder, position) is ConferencesViewHolder -> bindConferencesViewHolder(holder, position)
is AdminMessageViewHolder -> holder.bind((items[position] as DashboardItem.AdminMessages).adminMessage) is AdminMessageViewHolder -> holder.bind(
(items[position] as DashboardItem.AdminMessages).adminMessage,
showPanicButton = true
)
is AdsViewHolder -> bindAdsViewHolder(holder, position) is AdsViewHolder -> bindAdsViewHolder(holder, position)
} }
} }
@ -240,12 +257,15 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
attendancePercentage == null || attendancePercentage == .0 -> { attendancePercentage == null || attendancePercentage == .0 -> {
root.context.getThemeAttrColor(R.attr.colorOnSurface) root.context.getThemeAttrColor(R.attr.colorOnSurface)
} }
attendancePercentage <= ATTENDANCE_SECOND_WARNING_THRESHOLD -> { attendancePercentage <= ATTENDANCE_SECOND_WARNING_THRESHOLD -> {
root.context.getThemeAttrColor(R.attr.colorPrimary) root.context.getThemeAttrColor(R.attr.colorPrimary)
} }
attendancePercentage <= ATTENDANCE_FIRST_WARNING_THRESHOLD -> { attendancePercentage <= ATTENDANCE_FIRST_WARNING_THRESHOLD -> {
root.context.getThemeAttrColor(R.attr.colorTimetableChange) root.context.getThemeAttrColor(R.attr.colorTimetableChange)
} }
else -> root.context.getThemeAttrColor(R.attr.colorOnSurface) else -> root.context.getThemeAttrColor(R.attr.colorOnSurface)
} }
val attendanceString = if (attendancePercentage == null || attendancePercentage == .0) { val attendanceString = if (attendancePercentage == null || attendancePercentage == .0) {
@ -336,24 +356,28 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
binding.dashboardLessonsItemTitleTomorrow.isVisible = false binding.dashboardLessonsItemTitleTomorrow.isVisible = false
binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false
} }
tomorrowTimetable.isNotEmpty() -> { tomorrowTimetable.isNotEmpty() -> {
dateToNavigate = tomorrowDate dateToNavigate = tomorrowDate
updateLessonView(item, tomorrowTimetable, binding) updateLessonView(item, tomorrowTimetable, binding)
binding.dashboardLessonsItemTitleTomorrow.isVisible = true binding.dashboardLessonsItemTitleTomorrow.isVisible = true
binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false
} }
currentDayHeader != null && currentDayHeader.content.isNotBlank() -> { currentDayHeader != null && currentDayHeader.content.isNotBlank() -> {
dateToNavigate = currentDate dateToNavigate = currentDate
updateLessonView(item, emptyList(), binding, currentDayHeader) updateLessonView(item, emptyList(), binding, currentDayHeader)
binding.dashboardLessonsItemTitleTomorrow.isVisible = false binding.dashboardLessonsItemTitleTomorrow.isVisible = false
binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false
} }
tomorrowDayHeader != null && tomorrowDayHeader.content.isNotBlank() -> { tomorrowDayHeader != null && tomorrowDayHeader.content.isNotBlank() -> {
dateToNavigate = tomorrowDate dateToNavigate = tomorrowDate
updateLessonView(item, emptyList(), binding, tomorrowDayHeader) updateLessonView(item, emptyList(), binding, tomorrowDayHeader)
binding.dashboardLessonsItemTitleTomorrow.isVisible = true binding.dashboardLessonsItemTitleTomorrow.isVisible = true
binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false
} }
else -> { else -> {
dateToNavigate = currentDate dateToNavigate = currentDate
updateLessonView(item, emptyList(), binding) updateLessonView(item, emptyList(), binding)
@ -461,6 +485,7 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
firstTitleText = firstTitleText =
context.getString(R.string.dashboard_timetable_first_lesson_title_moment) context.getString(R.string.dashboard_timetable_first_lesson_title_moment)
} }
minutesToStartLesson < 240 -> { minutesToStartLesson < 240 -> {
firstTitleAndValueTextColor = firstTitleAndValueTextColor =
context.getThemeAttrColor(R.attr.colorOnSurface) context.getThemeAttrColor(R.attr.colorOnSurface)
@ -468,6 +493,7 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
firstTitleText = firstTitleText =
context.getString(R.string.dashboard_timetable_first_lesson_title_soon) context.getString(R.string.dashboard_timetable_first_lesson_title_soon)
} }
else -> { else -> {
firstTitleAndValueTextColor = firstTitleAndValueTextColor =
context.getThemeAttrColor(R.attr.colorOnSurface) context.getThemeAttrColor(R.attr.colorOnSurface)

View File

@ -13,9 +13,10 @@ class AdminMessageViewHolder(
private val binding: ItemDashboardAdminMessageBinding, private val binding: ItemDashboardAdminMessageBinding,
private val onAdminMessageDismissClickListener: (AdminMessage) -> Unit, private val onAdminMessageDismissClickListener: (AdminMessage) -> Unit,
private val onAdminMessageClickListener: (String?) -> Unit, private val onAdminMessageClickListener: (String?) -> Unit,
private val onPanicButtonClickListener: () -> Unit,
) : RecyclerView.ViewHolder(binding.root) { ) : RecyclerView.ViewHolder(binding.root) {
fun bind(item: AdminMessage?) { fun bind(item: AdminMessage?, showPanicButton: Boolean = false) {
item ?: return item ?: return
val context = binding.root.context val context = binding.root.context
@ -48,10 +49,14 @@ class AdminMessageViewHolder(
dashboardAdminMessageItemClose.setOnClickListener { dashboardAdminMessageItemClose.setOnClickListener {
onAdminMessageDismissClickListener(item) onAdminMessageDismissClickListener(item)
} }
dashboardPanicSection.root.isVisible = showPanicButton
dashboardPanicSection.dashboardPanicButton.setOnClickListener {
onPanicButtonClickListener()
}
root.setCardBackgroundColor(backgroundColor?.let { ColorStateList.valueOf(it) }) dashboardAdminMessage.setCardBackgroundColor(backgroundColor?.let { ColorStateList.valueOf(it) })
item.destinationUrl?.let { url -> item.destinationUrl?.let { url ->
root.setOnClickListener { onAdminMessageClickListener(url) } dashboardAdminMessage.setOnClickListener { onAdminMessageClickListener(url) }
} }
} }
} }

View File

@ -238,6 +238,7 @@ class LoginFormFragment : BaseFragment<FragmentLoginFormBinding>(R.layout.fragme
binding = binding.loginFormMessage, binding = binding.loginFormMessage,
onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed, onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed,
onAdminMessageClickListener = presenter::onAdminMessageSelected, onAdminMessageClickListener = presenter::onAdminMessageSelected,
onPanicButtonClickListener = {},
).bind(message) ).bind(message)
binding.loginFormMessage.root.isVisible = message != null binding.loginFormMessage.root.isVisible = message != null
} }

View File

@ -118,6 +118,7 @@ class LoginStudentSelectFragment :
binding = binding.loginStudentSelectAdminMessage, binding = binding.loginStudentSelectAdminMessage,
onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed, onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed,
onAdminMessageClickListener = presenter::onAdminMessageSelected, onAdminMessageClickListener = presenter::onAdminMessageSelected,
onPanicButtonClickListener = {},
).bind(adminMessage) ).bind(adminMessage)
binding.loginStudentSelectAdminMessage.root.isVisible = adminMessage != null binding.loginStudentSelectAdminMessage.root.isVisible = adminMessage != null
} }

View File

@ -188,6 +188,7 @@ class LoginSymbolFragment :
binding = binding.loginSymbolAdminMessage, binding = binding.loginSymbolAdminMessage,
onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed, onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed,
onAdminMessageClickListener = presenter::onAdminMessageSelected, onAdminMessageClickListener = presenter::onAdminMessageSelected,
onPanicButtonClickListener = {},
).bind(adminMessage) ).bind(adminMessage)
binding.loginSymbolAdminMessage.root.isVisible = adminMessage != null binding.loginSymbolAdminMessage.root.isVisible = adminMessage != null
} }

View File

@ -1,87 +1,105 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp" android:orientation="vertical">
android:layout_marginVertical="6dp">
<androidx.constraintlayout.widget.ConstraintLayout <com.google.android.material.card.MaterialCardView
android:id="@+id/dashboard_admin_message_item_content" android:id="@+id/dashboard_admin_message"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:layout_marginVertical="6dp">
<ImageView
android:id="@+id/dashboard_admin_message_item_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:src="@drawable/ic_error"
app:layout_constraintBottom_toBottomOf="@id/dashboard_admin_message_item_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/dashboard_admin_message_item_title"
tools:ignore="ContentDescription"
tools:tint="@android:color/black" />
<TextView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/dashboard_admin_message_item_title" android:id="@+id/dashboard_admin_message_item_content"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent">
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/dashboard_admin_message_item_close"
app:layout_constraintStart_toEndOf="@id/dashboard_admin_message_item_icon"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem" />
<ImageView <ImageView
android:id="@+id/dashboard_admin_message_item_close" android:id="@+id/dashboard_admin_message_item_icon"
android:layout_width="48dp" android:layout_width="24dp"
android:layout_height="48dp" android:layout_height="24dp"
android:layout_marginTop="4dp" android:layout_marginStart="16dp"
android:layout_marginEnd="4dp" android:layout_marginEnd="16dp"
android:padding="12dp" android:src="@drawable/ic_error"
android:background="?selectableItemBackgroundBorderless" app:layout_constraintBottom_toBottomOf="@id/dashboard_admin_message_item_title"
android:src="@drawable/ic_close" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@id/dashboard_admin_message_item_title"
app:layout_constraintTop_toTopOf="parent" tools:ignore="ContentDescription"
tools:ignore="ContentDescription" /> tools:tint="@android:color/black" />
<TextView <TextView
android:id="@+id/dashboard_admin_message_item_description" android:id="@+id/dashboard_admin_message_item_title"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp" android:textSize="18sp"
android:textSize="14sp" android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@id/dashboard_admin_message_item_close"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/dashboard_admin_message_item_icon"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toBottomOf="@id/dashboard_admin_message_item_title" tools:text="@tools:sample/lorem" />
app:layout_constraintVertical_bias="0"
app:lineHeight="20dp"
tools:maxLines="5"
tools:text="@tools:sample/lorem/random" />
<com.google.android.material.button.MaterialButton <ImageView
android:id="@+id/dashboard_admin_message_item_dismiss" android:id="@+id/dashboard_admin_message_item_close"
style="@style/Widget.Material3.Button.TextButton.Dialog" android:layout_width="48dp"
android:layout_width="wrap_content" android:layout_height="48dp"
android:layout_height="wrap_content" android:layout_marginTop="4dp"
android:layout_marginTop="8dp" android:layout_marginEnd="4dp"
android:layout_marginEnd="16dp" android:background="?selectableItemBackgroundBorderless"
android:layout_marginBottom="8dp" android:padding="12dp"
android:text="@android:string/ok" android:src="@drawable/ic_close"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toBottomOf="@id/dashboard_admin_message_item_description" tools:ignore="ContentDescription" />
app:layout_constraintVertical_bias="0" />
</androidx.constraintlayout.widget.ConstraintLayout> <TextView
</com.google.android.material.card.MaterialCardView> android:id="@+id/dashboard_admin_message_item_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/dashboard_admin_message_item_title"
app:layout_constraintVertical_bias="0"
app:lineHeight="20dp"
tools:maxLines="5"
tools:text="@tools:sample/lorem/random" />
<com.google.android.material.button.MaterialButton
android:id="@+id/dashboard_admin_message_item_dismiss"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:text="@android:string/ok"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/dashboard_admin_message_item_description"
app:layout_constraintVertical_bias="0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<include
android:id="@+id/dashboard_panic_section"
layout="@layout/item_dashboard_panic_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="16dp"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/dashboard_error_admin_message" />
</LinearLayout>

View File

@ -0,0 +1,28 @@
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:layout_marginVertical="6dp">
<LinearLayout
android:layout_margin="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Aplikacja nie działa?"
android:textSize="18sp"
android:textStyle="bold" />
<com.google.android.material.button.MaterialButton
android:id="@+id/dashboard_panic_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Otwórz stronę dziennika" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>