Merge remote-tracking branch 'origin/main'

# Conflicts:
#	app/src/main/res/values-ru/strings.xml
#	app/src/main/res/values/strings.xml
This commit is contained in:
Juja2025 2025-02-20 10:54:58 +03:00
commit fe65b890a0
5 changed files with 82 additions and 7 deletions

View File

@ -14,9 +14,11 @@ class UserInfoMapper @Inject constructor() {
fullname = model.fullname ?: error("fullname is null"), fullname = model.fullname ?: error("fullname is null"),
imageUrl = model.imageUrl ?: error("imageUrl is null"), imageUrl = model.imageUrl ?: error("imageUrl is null"),
position = model.position ?: error("position is null"), position = model.position ?: error("position is null"),
lastEntryMillis = model.lastEntry?.let { date -> lastEntryMillis = model.lastEntry.let { date ->
simpleDateFormat.parse(date)?.time ?: error("parse lastEntry error") simpleDateFormat.parse(date)?.time ?: error("parse lastEntry error")
} ?: error("lastEntry is null") } ?: error("lastEntry is null"),
role = model.role,
blocked = model.blocked
) )
} }
} }

View File

@ -1,8 +1,12 @@
package ru.myitschool.work.domain.profile.entities package ru.myitschool.work.domain.profile.entities
import ru.myitschool.work.data.dto.Role
class UserInfoEntity( class UserInfoEntity(
val fullname: String, val fullname: String,
val imageUrl: String, val imageUrl: String,
val position: String, val position: String,
val role: Role,
val blocked: Boolean,
val lastEntryMillis: Long, val lastEntryMillis: Long,
) )

View File

@ -1,8 +1,15 @@
package ru.myitschool.work.ui.profile package ru.myitschool.work.ui.profile
import android.content.DialogInterface
import android.graphics.Color
import android.graphics.Typeface
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
@ -63,11 +70,13 @@ class ProfileFragment : Fragment(R.layout.fragment_profile) {
binding.lastEntry.text = state.lastEntry binding.lastEntry.text = state.lastEntry
binding.fullname.text = state.fullname binding.fullname.text = state.fullname
if (state.admin){ if (state.admin){
//TODO Приделать админские штучки
binding.admin.visibility = View.VISIBLE binding.admin.visibility = View.VISIBLE
}else{ } else {
binding.admin.visibility = View.GONE binding.admin.visibility = View.GONE
} }
if (state.blocked) {
// TODO: СДЕЛАТЬ ФОН КРАСНЫМ
}
Picasso.get() Picasso.get()
.load(state.imageUrl) .load(state.imageUrl)
.error(R.drawable.ic_no_img) .error(R.drawable.ic_no_img)
@ -78,11 +87,59 @@ class ProfileFragment : Fragment(R.layout.fragment_profile) {
viewModel.action.collectWhenStarted(this) { action -> viewModel.action.collectWhenStarted(this) { action ->
when(action) { when(action) {
is ProfileViewModel.Action.OpenLogin -> { is ProfileViewModel.Action.Logout -> {
findNavController().navigate(LoginDestination) { findNavController().navigate(LoginDestination) {
popUpTo<ProfileDestination> { inclusive = true } popUpTo<ProfileDestination> { inclusive = true }
} }
} }
is ProfileViewModel.Action.OpenLogin -> {
val builder = AlertDialog.Builder(requireContext())
builder.setTitle(ContextCompat.getContextForLanguage(requireContext()).getString(R.string.profile_logout_dialog));
builder.setMessage(ContextCompat.getContextForLanguage(requireContext()).getString(R.string.profile_logout_text_dialog))
builder.setPositiveButton(
ContextCompat.getContextForLanguage(requireContext()).getString(R.string.logout),
DialogInterface.OnClickListener { dialogInterface, i ->
viewModel.logout()
dialogInterface.dismiss()
})
builder.setNegativeButton(
ContextCompat.getContextForLanguage(requireContext()).getString(R.string.cancel),
DialogInterface.OnClickListener { dialogInterface, i ->
dialogInterface.dismiss()
})
val dialog = builder.create()
dialog.setOnShowListener {
val titleView = dialog.findViewById<TextView>(android.R.id.title)
val messageView = dialog.findViewById<TextView>(android.R.id.message)
titleView?.setTextAppearance(R.style.Theme_UiTemplate_TextH2)
messageView?.setTextAppearance(R.style.Theme_UiTemplate_TextH4)
val positiveButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE)
val negativeButton = dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
positiveButton.setTextColor(ContextCompat.getColor(requireContext(), R.color.ErrorRed) )
negativeButton.setTextColor(ContextCompat.getColor(requireContext(), R.color.AccentBlue) )
}
// Установка кнопок
// Показать диалог
dialog.show()
}
is ProfileViewModel.Action.OpenLog -> { is ProfileViewModel.Action.OpenLog -> {
findNavController().navigate(EntryListDestination) { findNavController().navigate(EntryListDestination) {

View File

@ -12,6 +12,7 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import ru.myitschool.work.R import ru.myitschool.work.R
import ru.myitschool.work.data.dto.Role
import ru.myitschool.work.domain.auth.LogoutUseCase import ru.myitschool.work.domain.auth.LogoutUseCase
import ru.myitschool.work.domain.profile.GetUserInfoUseCase import ru.myitschool.work.domain.profile.GetUserInfoUseCase
import ru.myitschool.work.utils.MutablePublishFlow import ru.myitschool.work.utils.MutablePublishFlow
@ -37,11 +38,17 @@ class ProfileViewModel @Inject constructor(
updateUserInfo() updateUserInfo()
} }
fun logout(){
viewModelScope.launch {
logoutUseCase.get().invoke()
_action.emit(Action.Logout)
}
}
fun clickLogout() { fun clickLogout() {
viewModelScope.launch { viewModelScope.launch {
logoutUseCase.get().invoke()
_action.emit(Action.OpenLogin) _action.emit(Action.OpenLogin)
} }
} }
@ -72,7 +79,8 @@ class ProfileViewModel @Inject constructor(
imageUrl = value.imageUrl, imageUrl = value.imageUrl,
position = value.position, position = value.position,
lastEntry = simpleDateFormat.format(Date(value.lastEntryMillis)), lastEntry = simpleDateFormat.format(Date(value.lastEntryMillis)),
admin = true admin = value.role == Role.ADMIN,
blocked = value.blocked
) )
} }
}, },
@ -100,6 +108,7 @@ class ProfileViewModel @Inject constructor(
val position: String, val position: String,
val lastEntry: String, val lastEntry: String,
val admin: Boolean, val admin: Boolean,
val blocked: Boolean
) : State ) : State
} }
@ -108,6 +117,7 @@ class ProfileViewModel @Inject constructor(
data object OpenScan : Action data object OpenScan : Action
data object OpenLog : Action data object OpenLog : Action
data object OpenSearch : Action data object OpenSearch : Action
data object Logout : Action
} }
companion object { companion object {

View File

@ -5,4 +5,6 @@
<string name="profile_main_textview">Home</string> <string name="profile_main_textview">Home</string>
<string name="profile_admin_button">Admin panel</string> <string name="profile_admin_button">Admin panel</string>
<string name="profile_list_button">Entry History</string> <string name="profile_list_button">Entry History</string>
<string name="profile_logout_dialog">Logout</string>
<string name="profile_logout_text_dialog">Are you sure you want to log out?</string>
</resources> </resources>