[6.10.0]数据落盘开发
This commit is contained in:
@@ -739,10 +739,10 @@ class MoGoHmiProvider : IMoGoHmiProvider {
|
||||
/**
|
||||
* 展示数据落盘拷贝成功对话框
|
||||
*/
|
||||
override fun showCopyBagSuccessDialog() {
|
||||
override fun showCopyBagSuccessDialog(title: String,content: String) {
|
||||
ThreadUtils.runOnUiThread{
|
||||
context?.let{
|
||||
val copyBagSuccessDialog = CopyBagSuccessDialog(it)
|
||||
val copyBagSuccessDialog = CopyBagSuccessDialog(it,title, content)
|
||||
copyBagSuccessDialog.show()
|
||||
}
|
||||
}
|
||||
@@ -751,10 +751,10 @@ class MoGoHmiProvider : IMoGoHmiProvider {
|
||||
/**
|
||||
* 展示数据落盘辅助工具-异常情况及建议操作弹窗
|
||||
*/
|
||||
override fun showDiskCopyExceptionDialog() {
|
||||
override fun showDiskCopyExceptionDialog(title: String,content: String) {
|
||||
ThreadUtils.runOnUiThread{
|
||||
context?.let{
|
||||
val diskCopyExceptionDialog = DiskCopyExceptionDialog(it)
|
||||
val diskCopyExceptionDialog = DiskCopyExceptionDialog(it, title, content)
|
||||
diskCopyExceptionDialog.show()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,13 @@ import androidx.lifecycle.LifecycleObserver
|
||||
import com.mogo.eagle.core.function.hmi.R
|
||||
import com.mogo.eagle.core.function.hmi.dialog.BaseFloatDialog
|
||||
import kotlinx.android.synthetic.main.dialog_copy_bag_success.tvCopyBagSuccessClose
|
||||
import kotlinx.android.synthetic.main.dialog_copy_bag_success.tvCopyBagSuccessContent
|
||||
import kotlinx.android.synthetic.main.dialog_copy_bag_success.tvCopyBagSuccessTitle
|
||||
|
||||
/**
|
||||
* 数据落盘拷贝成功对话框
|
||||
*/
|
||||
class CopyBagSuccessDialog(context: Context) :
|
||||
class CopyBagSuccessDialog(context: Context,private val title: String,private val content: String) :
|
||||
BaseFloatDialog(context,TAG), LifecycleObserver {
|
||||
|
||||
companion object {
|
||||
@@ -23,6 +25,8 @@ class CopyBagSuccessDialog(context: Context) :
|
||||
}
|
||||
|
||||
private fun initView(){
|
||||
tvCopyBagSuccessTitle.text = title
|
||||
tvCopyBagSuccessContent.text = content
|
||||
tvCopyBagSuccessClose.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
|
||||
@@ -5,11 +5,13 @@ import androidx.lifecycle.LifecycleObserver
|
||||
import com.mogo.eagle.core.function.hmi.R
|
||||
import com.mogo.eagle.core.function.hmi.dialog.BaseFloatDialog
|
||||
import kotlinx.android.synthetic.main.dialog_disk_copy_exception.tvCopyExceptionClose
|
||||
import kotlinx.android.synthetic.main.dialog_disk_copy_exception.tvCopyExceptionContent
|
||||
import kotlinx.android.synthetic.main.dialog_disk_copy_exception.tvCopyExceptionTitle
|
||||
|
||||
/**
|
||||
* 数据落盘辅助工具-异常情况及建议操作弹窗
|
||||
*/
|
||||
class DiskCopyExceptionDialog(context: Context) :
|
||||
class DiskCopyExceptionDialog(context: Context,private var title: String,private var content: String) :
|
||||
BaseFloatDialog(context,TAG), LifecycleObserver {
|
||||
|
||||
companion object {
|
||||
@@ -23,7 +25,8 @@ class DiskCopyExceptionDialog(context: Context) :
|
||||
}
|
||||
|
||||
private fun initView(){
|
||||
|
||||
tvCopyExceptionTitle.text = title
|
||||
tvCopyExceptionContent.text = content
|
||||
//关闭异常弹窗
|
||||
tvCopyExceptionClose.setOnClickListener {
|
||||
dismiss()
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.mogo.eagle.core.data.deva.diskcopy.CopyCalendarInfo
|
||||
import com.mogo.eagle.core.function.api.devatools.IDiskCopyListener
|
||||
@@ -76,15 +77,13 @@ class DiskCopyView @JvmOverloads constructor(
|
||||
tvCurrentWeek.text = parseWeekDescribe(info.currentDayOfWeek)
|
||||
if(info.canCopy){
|
||||
//开始拷贝数据
|
||||
tvCopyStatus.text = resources.getString(R.string.copy_bag_start)
|
||||
tvCopyStatus.setTextColor(context.getColor(R.color.color_copy_bag_start))
|
||||
copyStatus = 1
|
||||
currentCopyDate = info.ipcDateFormat.toInt()
|
||||
notifyCopyStatusDisplay(copyStatus)
|
||||
}else{
|
||||
//所选日期无法拷贝
|
||||
tvCopyStatus.text = resources.getString(R.string.date_cannot_copy)
|
||||
tvCopyStatus.setTextColor(context.getColor(R.color.color_date_cannot_copy))
|
||||
copyStatus = 5
|
||||
notifyCopyStatusDisplay(copyStatus)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -92,21 +91,32 @@ class DiskCopyView @JvmOverloads constructor(
|
||||
rvCalendar.layoutManager = gridLayoutManager
|
||||
//拷贝状态
|
||||
tvCopyStatus.setOnClickListener {
|
||||
if(copyStatus == 1){
|
||||
//开始拷贝数据
|
||||
CallerAutoPilotControlManager.sendCopyBagCopyDate(currentCopyDate)
|
||||
}else if(copyStatus == 2){
|
||||
//拷贝中
|
||||
ToastUtils.showShort("正在拷贝中...")
|
||||
}else if(copyStatus == 3){
|
||||
//拷贝成功
|
||||
ToastUtils.showShort("当前日期数据已拷贝成功")
|
||||
}else if(copyStatus == 4){
|
||||
//剩余空间不足
|
||||
ToastUtils.showShort("当前硬盘剩余空间不足")
|
||||
}else if(copyStatus == 5){
|
||||
//所选日期无法拷贝
|
||||
ToastUtils.showShort("所选日期无法拷贝")
|
||||
when (copyStatus) {
|
||||
1 -> {
|
||||
//开始拷贝数据
|
||||
val result = CallerAutoPilotControlManager.sendCopyBagCopyDate(currentCopyDate)
|
||||
if(result){
|
||||
//将当前拷贝状态置为拷贝中
|
||||
copyStatus = 2
|
||||
notifyCopyStatusDisplay(copyStatus)
|
||||
}
|
||||
}
|
||||
2 -> {
|
||||
//拷贝中
|
||||
ToastUtils.showShort("正在拷贝中...")
|
||||
}
|
||||
3 -> {
|
||||
//拷贝成功
|
||||
ToastUtils.showShort("当前日期数据已拷贝成功")
|
||||
}
|
||||
4 -> {
|
||||
//剩余空间不足
|
||||
ToastUtils.showShort("当前硬盘剩余空间不足")
|
||||
}
|
||||
5 -> {
|
||||
//所选日期无法拷贝
|
||||
ToastUtils.showShort("所选日期无法拷贝")
|
||||
}
|
||||
}
|
||||
}
|
||||
//拔出硬盘
|
||||
@@ -122,11 +132,16 @@ class DiskCopyView @JvmOverloads constructor(
|
||||
|
||||
//数据日期
|
||||
viewDiskCopyDate.setOnClickListener {
|
||||
//隐藏当前视图
|
||||
pbDiskCopyProgress.visibility = View.GONE
|
||||
groupDiskCopy.visibility = View.GONE
|
||||
//展示日历
|
||||
groupDateSelect.visibility = View.VISIBLE
|
||||
if(copyStatus == 2){
|
||||
//数据拷贝中,不可再选择日期
|
||||
ToastUtils.showShort("数据拷贝中,不可再次选择日期,请耐心等待")
|
||||
}else{
|
||||
//隐藏当前视图
|
||||
pbDiskCopyProgress.visibility = View.GONE
|
||||
groupDiskCopy.visibility = View.GONE
|
||||
//展示日历
|
||||
groupDateSelect.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +290,7 @@ class DiskCopyView @JvmOverloads constructor(
|
||||
calendarList.add(CopyCalendarInfo(false,threeDaysAgo.toString(),threeDaysAgoOfIpc,threeDaysAgoOfUi,threeDaysAgoOfWeek))
|
||||
calendarList.add(CopyCalendarInfo(false,twoDaysAgo.toString(),twoDaysAgoOfIpc,twoDaysAgoOfUi,twoDaysAgoOfWeek))
|
||||
calendarList.add(CopyCalendarInfo(false,yesterday.toString(),yesterdayOfIpc,yesterdayOfUi,yesterdayOfWeek))
|
||||
calendarList.add(CopyCalendarInfo(false,today.toString(),todayOfIpc,todayOfUi,todayOfWeek))
|
||||
calendarList.add(CopyCalendarInfo(false,today.toString(),todayOfIpc,todayOfUi,todayOfWeek, isSelected = true))
|
||||
diskCopyCalendarAdapter?.setData(calendarList)
|
||||
//展示当天日期
|
||||
tvCurrentDate.text = todayOfUi
|
||||
@@ -287,6 +302,59 @@ class DiskCopyView @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新当前拔出硬盘图标显示状态
|
||||
*/
|
||||
private fun notifyCopyStatusDisplay(copyStatus: Int,copyProgress: Int = 0){
|
||||
if(copyStatus == 2){
|
||||
//拷贝中,显示黄色图标
|
||||
ivDiskUnplug.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_disk_unplug_copying
|
||||
))
|
||||
}else{
|
||||
//显示蓝色图标
|
||||
ivDiskUnplug.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_disk_unplug_connected
|
||||
))
|
||||
}
|
||||
when(copyStatus){
|
||||
//默认状态
|
||||
0->{
|
||||
|
||||
}
|
||||
//开始拷贝数据
|
||||
1->{
|
||||
tvCopyStatus.text = resources.getString(R.string.copy_bag_start)
|
||||
tvCopyStatus.setTextColor(context.getColor(R.color.color_copy_bag_start))
|
||||
}
|
||||
//拷贝中
|
||||
2->{
|
||||
tvCopyStatus.text = String.format(resources.getString(R.string.disk_copy_progress),copyProgress)
|
||||
tvCopyStatus.setTextColor(context.getColor(R.color.color_disk_copy_progress))
|
||||
}
|
||||
//拷贝成功
|
||||
3->{
|
||||
tvCopyStatus.text = resources.getString(R.string.copy_bag_success)
|
||||
tvCopyStatus.setTextColor(context.getColor(R.color.color_copy_bag_success))
|
||||
}
|
||||
//剩余空间不足
|
||||
4->{
|
||||
tvCopyStatus.text = resources.getString(R.string.disk_not_enough_space)
|
||||
tvCopyStatus.setTextColor(context.getColor(R.color.color_disk_not_enough_space))
|
||||
}
|
||||
//所选日期无法拷贝
|
||||
5->{
|
||||
tvCopyStatus.text = resources.getString(R.string.date_cannot_copy)
|
||||
tvCopyStatus.setTextColor(context.getColor(R.color.color_date_cannot_copy))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun parseWeekDescribe(currentWeek: Int?): String{
|
||||
return when(currentWeek){
|
||||
//星期日
|
||||
@@ -359,6 +427,24 @@ class DiskCopyView @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
//挂载成功的信息集合
|
||||
Logger.i(TAG,"磁盘空间不足提示: 移动硬盘剩余空间不足,建议更换硬盘="+diskCopy.mountSuccess.tips)
|
||||
if(diskCopy.mountSuccess.tips.isNotEmpty()){
|
||||
//如果磁盘空间不足字段不为空(默认设置的不足100G会提示空间不足,如果收到拷贝开始时会再检查本次拷贝总大小和剩余空间,如果剩余空间不满足本次拷贝也会提示不足)
|
||||
//则更换磁盘空间进度条展示样式,并且进行弹窗提示
|
||||
pbDiskUsedSpaces.progressDrawable = ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.progressbar_disk_not_enough_space
|
||||
)
|
||||
//数据拷贝工具异常
|
||||
CallerHmiManager.showDiskCopyExceptionDialog("数据拷贝工具异常",diskCopy.mountSuccess.tips)
|
||||
copyStatus = 4
|
||||
notifyCopyStatusDisplay(copyStatus)
|
||||
}else{
|
||||
pbDiskUsedSpaces.progressDrawable = ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.progressbar_disk_used_space
|
||||
)
|
||||
}
|
||||
Logger.i(TAG,"磁盘总空间="+diskCopy.mountSuccess.totalSize)
|
||||
Logger.i(TAG,"磁盘剩余空间="+diskCopy.mountSuccess.diskFree)
|
||||
//磁盘剩余空间显示
|
||||
@@ -368,9 +454,6 @@ class DiskCopyView @JvmOverloads constructor(
|
||||
tvDiskUsedPercent.text = String.format(resources.getString(R.string.disk_used_percent),diskUsedPercent)
|
||||
//磁盘已用空间百分比进度条
|
||||
pbDiskUsedSpaces.progress = diskUsedPercent
|
||||
Logger.i(TAG,"磁盘空间不足提示: 移动硬盘剩余空间不足,建议更换硬盘="+diskCopy.mountSuccess.tips)
|
||||
//TODO 需要确定字段具体示意
|
||||
|
||||
Logger.i(TAG,"可拷贝日期数量="+diskCopy.mountSuccess.datesCount)
|
||||
diskCopy.mountSuccess.datesList.forEach {
|
||||
Logger.i(TAG, "可拷贝日期=$it")
|
||||
@@ -385,8 +468,9 @@ class DiskCopyView @JvmOverloads constructor(
|
||||
diskCopyCalendarAdapter?.setData(calendarList)
|
||||
//挂载异常: 移动硬盘挂载失败,请重插或更换硬盘
|
||||
Logger.i(TAG,"挂载异常="+diskCopy.mountError)
|
||||
|
||||
|
||||
if(diskCopy.mountError.isNotEmpty()){
|
||||
CallerHmiManager.showDiskCopyExceptionDialog("数据拷贝工具异常",diskCopy.mountError)
|
||||
}
|
||||
//需要拷贝的文件总大小
|
||||
Logger.i(TAG,"需要拷贝的文件总大小="+diskCopy.copyTotalSize)
|
||||
//已拷贝大小
|
||||
@@ -400,22 +484,38 @@ class DiskCopyView @JvmOverloads constructor(
|
||||
val copyProgress = (diskCopy.copiedSize*100/diskCopy.copyTotalSize).toInt()
|
||||
pbDiskCopyProgress.progress = copyProgress
|
||||
//拷贝状态控件显示当前拷贝进度
|
||||
tvCopyStatus.text = String.format(resources.getString(R.string.disk_copy_progress),copyProgress)
|
||||
tvCopyStatus.setTextColor(context.getColor(R.color.color_disk_copy_progress))
|
||||
copyStatus = 2
|
||||
notifyCopyStatusDisplay(copyStatus)
|
||||
}
|
||||
//拷贝剩余时间
|
||||
Logger.i(TAG,"拷贝剩余时间="+diskCopy.freeTime)
|
||||
//拷贝是否成功,是-True,否-False
|
||||
Logger.i(TAG,"拷贝是否成功,是-True,否-False="+diskCopy.copyStatus)
|
||||
if(diskCopy.copyStatus){
|
||||
//将当前拷贝状态置为拷贝成功
|
||||
copyStatus = 3
|
||||
notifyCopyStatusDisplay(copyStatus)
|
||||
CallerHmiManager.showCopyBagSuccessDialog("数据拷贝完成",diskCopy.successInfo)
|
||||
}
|
||||
//拷贝异常提示,如域控间连接超时拷贝失败,建议查看各域控是否在线,不在线请重启车辆再试
|
||||
Logger.i(TAG,"拷贝异常提示="+diskCopy.copyErr)
|
||||
|
||||
if(diskCopy.copyErr.isNotEmpty()){
|
||||
//拷贝异常
|
||||
CallerHmiManager.showDiskCopyExceptionDialog("数据拷贝工具异常",diskCopy.copyErr)
|
||||
}
|
||||
//即将中止数据拷贝并安全弹出硬盘,是否继续操作?
|
||||
Logger.i(TAG,"即将中止数据拷贝并安全弹出硬盘,是否继续操作?="+diskCopy.abortData)
|
||||
//硬盘是否已安全弹出,是-True,否-False
|
||||
Logger.i(TAG,"硬盘是否已安全弹出,是-True,否-False="+diskCopy.diskUnmount)
|
||||
if(diskCopy.diskUnmount){
|
||||
ToastUtils.showShort("硬盘已安全弹出")
|
||||
}
|
||||
//硬盘弹出失败提示:安全弹出失败,建议车辆下电后拔走硬盘
|
||||
Logger.i(TAG,"硬盘弹出失败提示="+diskCopy.unmountErr)
|
||||
if(diskCopy.unmountErr.isNotEmpty()){
|
||||
//硬盘安全弹出异常
|
||||
CallerHmiManager.showDiskCopyExceptionDialog("硬盘安全弹出异常",diskCopy.unmountErr)
|
||||
}
|
||||
//拷贝成功的信息提示,如当前车辆拷贝的各类型的包各有多少个
|
||||
Logger.i(TAG,"拷贝成功的信息提示="+diskCopy.successInfo)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mogo.eagle.core.data.deva.diskcopy.CopyCalendarInfo
|
||||
import com.mogo.eagle.core.function.hmi.R
|
||||
@@ -17,7 +18,7 @@ class DiskCopyCalendarAdapter(private val context: Context): RecyclerView.Adapte
|
||||
private var data: ArrayList<CopyCalendarInfo> ?= null
|
||||
private val title: Int = 0
|
||||
private var dateSelectListener: DateSelectListener ?= null
|
||||
|
||||
private var previousDate: CopyCalendarInfo ?= null
|
||||
|
||||
fun setData(list: ArrayList<CopyCalendarInfo>){
|
||||
data = list
|
||||
@@ -53,7 +54,20 @@ class DiskCopyCalendarAdapter(private val context: Context): RecyclerView.Adapte
|
||||
}else{
|
||||
holder.tvCalendarContent.setTextColor(context.getColor(R.color.color_disk_copy_date))
|
||||
}
|
||||
if(dateInfo.isSelected){
|
||||
holder.tvCalendarContent.background = AppCompatResources
|
||||
.getDrawable(context,R.drawable.bg_current_select_date)
|
||||
previousDate = dateInfo
|
||||
}else{
|
||||
holder.tvCalendarContent.background = null
|
||||
}
|
||||
holder.tvCalendarContent.setOnClickListener {
|
||||
previousDate?.isSelected = false
|
||||
dateInfo.isSelected = true
|
||||
holder.tvCalendarContent.background = AppCompatResources
|
||||
.getDrawable(context,R.drawable.bg_current_select_date)
|
||||
previousDate = dateInfo
|
||||
notifyDataSetChanged()
|
||||
dateSelectListener?.onDateSelect(dateInfo)
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:paddingLeft="@dimen/dp_0">
|
||||
<!-- 设置背景色 -->
|
||||
<item
|
||||
android:id="@android:id/background"
|
||||
android:width="@dimen/dp_590"
|
||||
android:height="@dimen/dp_60"
|
||||
android:gravity="center_vertical">
|
||||
<shape>
|
||||
<corners android:radius="@dimen/dp_16" />
|
||||
<solid android:color="#FF333333" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- 设置进度条颜色 -->
|
||||
<item
|
||||
android:id="@android:id/progress">
|
||||
<scale android:scaleWidth="100%">
|
||||
<shape>
|
||||
<corners android:radius="@dimen/dp_16" />
|
||||
<gradient
|
||||
android:angle="0"
|
||||
android:startColor="#F9905C"
|
||||
android:endColor="#E6503E"
|
||||
/>
|
||||
</shape>
|
||||
</scale>
|
||||
</item>
|
||||
</layer-list>
|
||||
@@ -32,12 +32,14 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCopyBagSuccessContent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="@dimen/dp_0"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvCopyBagSuccessTitle"
|
||||
android:layout_marginTop="@dimen/dp_10"
|
||||
android:layout_marginStart="@dimen/dp_30"
|
||||
android:layout_marginEnd="@dimen/dp_30"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_36"
|
||||
/>
|
||||
|
||||
@@ -26,18 +26,22 @@
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/ivCopyException"
|
||||
android:layout_marginTop="@dimen/dp_30"
|
||||
android:layout_marginStart="@dimen/dp_30"
|
||||
android:layout_marginEnd="@dimen/dp_30"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_45"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCopyExceptionContent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="@dimen/dp_0"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvCopyExceptionTitle"
|
||||
android:layout_marginTop="@dimen/dp_10"
|
||||
android:layout_marginStart="@dimen/dp_30"
|
||||
android:layout_marginEnd="@dimen/dp_30"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_36"
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/tvCalendarContent"
|
||||
android:layout_width="@dimen/dp_88"
|
||||
android:layout_height="@dimen/dp_69"
|
||||
android:layout_height="@dimen/dp_80"
|
||||
android:textSize="@dimen/sp_32"
|
||||
android:textColor="@color/white"
|
||||
android:gravity="center"
|
||||
|
||||
Reference in New Issue
Block a user