mirror of
https://github.com/libretro/RetroArch
synced 2025-01-29 18:32:44 +00:00
(Menu) render_messagebox/render/frame functions from menu_ctx no longer
get a rgui handle passed to them
This commit is contained in:
parent
a59c3cba6e
commit
6307202a6d
6
driver.h
6
driver.h
@ -411,9 +411,9 @@ typedef struct menu_ctx_driver_backend
|
||||
typedef struct menu_ctx_driver
|
||||
{
|
||||
void (*set_texture)(void*, bool);
|
||||
void (*render_messagebox)(void*, const char*);
|
||||
void (*render)(void*);
|
||||
void (*frame)(void*);
|
||||
void (*render_messagebox)(const char*);
|
||||
void (*render)(void);
|
||||
void (*frame)(void);
|
||||
void* (*init)(void);
|
||||
void (*free)(void*);
|
||||
void (*init_assets)(void*);
|
||||
|
@ -471,7 +471,7 @@ static int menu_start_screen_iterate(unsigned action)
|
||||
return 0;
|
||||
|
||||
if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render)
|
||||
driver.menu_ctx->render(rgui);
|
||||
driver.menu_ctx->render();
|
||||
|
||||
char desc[6][64];
|
||||
static const unsigned binds[] = {
|
||||
@ -526,7 +526,7 @@ static int menu_start_screen_iterate(unsigned action)
|
||||
desc[0], desc[1], desc[2], desc[3], desc[4], desc[5]);
|
||||
|
||||
if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render_messagebox)
|
||||
driver.menu_ctx->render_messagebox(rgui, msg);
|
||||
driver.menu_ctx->render_messagebox(msg);
|
||||
|
||||
if (action == RGUI_ACTION_OK)
|
||||
file_list_pop(rgui->menu_stack, &rgui->selection_ptr);
|
||||
@ -758,17 +758,14 @@ static int menu_settings_iterate(unsigned action)
|
||||
menu_common_entries_init(driver.menu, RGUI_SETTINGS);
|
||||
}
|
||||
|
||||
if (rgui)
|
||||
{
|
||||
if (rgui && driver.menu_ctx && driver.menu_ctx->render)
|
||||
driver.menu_ctx->render(rgui);
|
||||
if (driver.menu_ctx && driver.menu_ctx->render)
|
||||
driver.menu_ctx->render();
|
||||
|
||||
// Have to defer it so we let settings refresh.
|
||||
if (rgui->push_start_screen)
|
||||
{
|
||||
rgui->push_start_screen = false;
|
||||
file_list_push(rgui->menu_stack, "", RGUI_START_SCREEN, 0);
|
||||
}
|
||||
// Have to defer it so we let settings refresh.
|
||||
if (rgui->push_start_screen)
|
||||
{
|
||||
rgui->push_start_screen = false;
|
||||
file_list_push(rgui->menu_stack, "", RGUI_START_SCREEN, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -905,7 +902,7 @@ static int menu_viewport_iterate(unsigned action)
|
||||
file_list_get_last(rgui->menu_stack, NULL, &menu_type);
|
||||
|
||||
if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render)
|
||||
driver.menu_ctx->render(rgui);
|
||||
driver.menu_ctx->render();
|
||||
|
||||
const char *base_msg = NULL;
|
||||
char msg[64];
|
||||
@ -936,7 +933,7 @@ static int menu_viewport_iterate(unsigned action)
|
||||
}
|
||||
|
||||
if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render_messagebox)
|
||||
driver.menu_ctx->render_messagebox(rgui, msg);
|
||||
driver.menu_ctx->render_messagebox(msg);
|
||||
|
||||
if (!custom->width)
|
||||
custom->width = stride_x;
|
||||
@ -1198,13 +1195,13 @@ static int menu_custom_bind_iterate(void *data, unsigned action)
|
||||
(void)action; // Have to ignore action here. Only bind that should work here is Quit RetroArch or something like that.
|
||||
|
||||
if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render)
|
||||
driver.menu_ctx->render(rgui);
|
||||
driver.menu_ctx->render();
|
||||
|
||||
char msg[256];
|
||||
snprintf(msg, sizeof(msg), "[%s]\npress joypad\n(RETURN to skip)", input_config_bind_map[rgui->binds.begin - RGUI_SETTINGS_BIND_BEGIN].desc);
|
||||
|
||||
if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render_messagebox)
|
||||
driver.menu_ctx->render_messagebox(rgui, msg);
|
||||
driver.menu_ctx->render_messagebox(msg);
|
||||
|
||||
struct rgui_bind_state binds = rgui->binds;
|
||||
menu_poll_bind_state(&binds);
|
||||
@ -1231,7 +1228,7 @@ static int menu_custom_bind_iterate_keyboard(void *data, unsigned action)
|
||||
(void)action; // Have to ignore action here.
|
||||
|
||||
if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render)
|
||||
driver.menu_ctx->render(rgui);
|
||||
driver.menu_ctx->render();
|
||||
|
||||
int64_t current = rarch_get_time_usec();
|
||||
int timeout = (rgui->binds.timeout_end - current) / 1000000;
|
||||
@ -1241,7 +1238,7 @@ static int menu_custom_bind_iterate_keyboard(void *data, unsigned action)
|
||||
input_config_bind_map[rgui->binds.begin - RGUI_SETTINGS_BIND_BEGIN].desc, timeout);
|
||||
|
||||
if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render_messagebox)
|
||||
driver.menu_ctx->render_messagebox(rgui, msg);
|
||||
driver.menu_ctx->render_messagebox(msg);
|
||||
|
||||
bool timed_out = false;
|
||||
if (timeout <= 0)
|
||||
@ -1700,7 +1697,7 @@ static int menu_common_iterate(unsigned action)
|
||||
driver.menu_ctx->iterate(rgui, action);
|
||||
|
||||
if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render)
|
||||
driver.menu_ctx->render(rgui);
|
||||
driver.menu_ctx->render();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ static int menu_lakka_iterate(unsigned action)
|
||||
driver.menu_ctx->iterate(rgui, action);
|
||||
|
||||
if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render)
|
||||
driver.menu_ctx->render(rgui);
|
||||
driver.menu_ctx->render();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -727,13 +727,13 @@ void lakka_draw_icon(void *data, GLuint texture, float x, float y, float alpha,
|
||||
gl->coords.color = gl->white_color_ptr;
|
||||
}
|
||||
|
||||
static void lakka_frame(void *data)
|
||||
static void lakka_frame(void)
|
||||
{
|
||||
int i, j, k;
|
||||
struct font_output_list *msg;
|
||||
gl_t *gl = (gl_t*)driver.video_data;
|
||||
rgui_handle_t *rgui = (rgui_handle_t*)data;
|
||||
menu_category_t *active_category = (menu_category_t*)&categories[menu_active_category];
|
||||
rgui_handle_t *rgui = (rgui_handle_t*)driver.menu;
|
||||
|
||||
if (!rgui || !gl)
|
||||
return;
|
||||
|
@ -107,10 +107,14 @@ static void fill_rect(uint16_t *buf, unsigned pitch,
|
||||
buf[j * (pitch >> 1) + i] = col(i, j);
|
||||
}
|
||||
|
||||
static void blit_line(rgui_handle_t *rgui,
|
||||
int x, int y, const char *message, bool green)
|
||||
static void blit_line(int x, int y, const char *message, bool green)
|
||||
{
|
||||
int j, i;
|
||||
rgui_handle_t *rgui = (rgui_handle_t*)driver.menu;
|
||||
|
||||
if (!rgui)
|
||||
return;
|
||||
|
||||
while (*message)
|
||||
{
|
||||
for (j = 0; j < FONT_HEIGHT; j++)
|
||||
@ -172,8 +176,13 @@ static bool rguidisp_init_font(void *data)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rgui_render_background(rgui_handle_t *rgui)
|
||||
static void rgui_render_background(void)
|
||||
{
|
||||
rgui_handle_t *rgui = (rgui_handle_t*)driver.menu;
|
||||
|
||||
if (!rgui)
|
||||
return;
|
||||
|
||||
fill_rect(rgui->frame_buf, rgui->frame_buf_pitch,
|
||||
0, 0, rgui->width, rgui->height, gray_filler);
|
||||
|
||||
@ -190,12 +199,12 @@ static void rgui_render_background(rgui_handle_t *rgui)
|
||||
rgui->width - 10, 5, 5, rgui->height - 10, green_filler);
|
||||
}
|
||||
|
||||
static void rgui_render_messagebox(void *data, const char *message)
|
||||
static void rgui_render_messagebox(const char *message)
|
||||
{
|
||||
rgui_handle_t *rgui = (rgui_handle_t*)data;
|
||||
size_t i;
|
||||
rgui_handle_t *rgui = (rgui_handle_t*)driver.menu;
|
||||
|
||||
if (!message || !*message)
|
||||
if (!rgui || !message || !*message)
|
||||
return;
|
||||
|
||||
struct string_list *list = string_split(message, "\n");
|
||||
@ -251,24 +260,24 @@ static void rgui_render_messagebox(void *data, const char *message)
|
||||
const char *msg = list->elems[i].data;
|
||||
int offset_x = FONT_WIDTH_STRIDE * (glyphs_width - strlen(msg)) / 2;
|
||||
int offset_y = FONT_HEIGHT_STRIDE * i;
|
||||
blit_line(rgui, x + 8 + offset_x, y + 8 + offset_y, msg, false);
|
||||
blit_line(x + 8 + offset_x, y + 8 + offset_y, msg, false);
|
||||
}
|
||||
|
||||
string_list_free(list);
|
||||
}
|
||||
|
||||
static void rgui_render(void *data)
|
||||
static void rgui_render(void)
|
||||
{
|
||||
rgui_handle_t *rgui = (rgui_handle_t*)data;
|
||||
size_t begin, end;
|
||||
rgui_handle_t *rgui = (rgui_handle_t*)driver.menu;
|
||||
|
||||
if (rgui->need_refresh &&
|
||||
(g_extern.lifecycle_state & (1ULL << MODE_MENU))
|
||||
&& !rgui->msg_force)
|
||||
return;
|
||||
|
||||
size_t begin = rgui->selection_ptr >= RGUI_TERM_HEIGHT / 2 ?
|
||||
rgui->selection_ptr - RGUI_TERM_HEIGHT / 2 : 0;
|
||||
size_t end = rgui->selection_ptr + RGUI_TERM_HEIGHT <= rgui->selection_buf->size ?
|
||||
begin = (rgui->selection_ptr >= RGUI_TERM_HEIGHT / 2) ? rgui->selection_ptr - RGUI_TERM_HEIGHT / 2 : 0;
|
||||
end = (rgui->selection_ptr + RGUI_TERM_HEIGHT <= rgui->selection_buf->size) ?
|
||||
rgui->selection_ptr + RGUI_TERM_HEIGHT : rgui->selection_buf->size;
|
||||
|
||||
// Do not scroll if all items are visible.
|
||||
@ -278,7 +287,7 @@ static void rgui_render(void *data)
|
||||
if (end - begin > RGUI_TERM_HEIGHT)
|
||||
end = begin + RGUI_TERM_HEIGHT;
|
||||
|
||||
rgui_render_background(rgui);
|
||||
rgui_render_background();
|
||||
|
||||
char title[256];
|
||||
const char *dir = NULL;
|
||||
@ -407,7 +416,7 @@ static void rgui_render(void *data)
|
||||
|
||||
char title_buf[256];
|
||||
menu_ticker_line(title_buf, RGUI_TERM_WIDTH - 3, g_extern.frame_count / 15, title, true);
|
||||
blit_line(rgui, RGUI_TERM_START_X + 15, 15, title_buf, true);
|
||||
blit_line(RGUI_TERM_START_X + 15, 15, title_buf, true);
|
||||
|
||||
char title_msg[64];
|
||||
const char *core_name = rgui->info.library_name;
|
||||
@ -423,7 +432,7 @@ static void rgui_render(void *data)
|
||||
core_version = "";
|
||||
|
||||
snprintf(title_msg, sizeof(title_msg), "%s - %s %s", PACKAGE_VERSION, core_name, core_version);
|
||||
blit_line(rgui, RGUI_TERM_START_X + 15, (RGUI_TERM_HEIGHT * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y + 2, title_msg, true);
|
||||
blit_line(RGUI_TERM_START_X + 15, (RGUI_TERM_HEIGHT * FONT_HEIGHT_STRIDE) + RGUI_TERM_START_Y + 2, title_msg, true);
|
||||
|
||||
unsigned x, y;
|
||||
size_t i;
|
||||
@ -545,7 +554,7 @@ static void rgui_render(void *data)
|
||||
w,
|
||||
type_str_buf);
|
||||
|
||||
blit_line(rgui, x, y, message, selected);
|
||||
blit_line(x, y, message, selected);
|
||||
}
|
||||
|
||||
#ifdef GEKKO
|
||||
@ -559,7 +568,7 @@ static void rgui_render(void *data)
|
||||
else
|
||||
message_queue = driver.current_msg;
|
||||
|
||||
rgui_render_messagebox(rgui, message_queue);
|
||||
rgui_render_messagebox(message_queue);
|
||||
#endif
|
||||
|
||||
if (rgui->keyboard.display)
|
||||
@ -569,7 +578,7 @@ static void rgui_render(void *data)
|
||||
if (!str)
|
||||
str = "";
|
||||
snprintf(msg, sizeof(msg), "%s\n%s", rgui->keyboard.label, str);
|
||||
rgui_render_messagebox(rgui, msg);
|
||||
rgui_render_messagebox(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,11 +66,11 @@ struct texture_image *menu_texture;
|
||||
static bool render_normal = true;
|
||||
static bool menu_texture_inited =false;
|
||||
|
||||
static void rmenu_render_background(rgui_handle_t *rgui)
|
||||
static void rmenu_render_background(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void rmenu_render_messagebox(void *data, const char *message)
|
||||
static void rmenu_render_messagebox(const char *message)
|
||||
{
|
||||
font_params_t font_parms;
|
||||
|
||||
@ -114,11 +114,14 @@ static void rmenu_render_messagebox(void *data, const char *message)
|
||||
render_normal = false;
|
||||
}
|
||||
|
||||
static void rmenu_render(void *data)
|
||||
static void rmenu_render(void)
|
||||
{
|
||||
size_t begin, end;
|
||||
rgui_handle_t *rgui = (rgui_handle_t*)data;
|
||||
font_params_t font_parms;
|
||||
rgui_handle_t *rgui = (rgui_handle_t*)driver.menu;
|
||||
|
||||
if (!rgui)
|
||||
return;
|
||||
|
||||
if (!render_normal)
|
||||
{
|
||||
@ -126,9 +129,6 @@ static void rmenu_render(void *data)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rgui)
|
||||
return;
|
||||
|
||||
if (rgui->need_refresh &&
|
||||
(g_extern.lifecycle_state & (1ULL << MODE_MENU))
|
||||
&& !rgui->msg_force)
|
||||
@ -146,7 +146,7 @@ static void rmenu_render(void *data)
|
||||
if (end - begin > ENTRIES_HEIGHT)
|
||||
end = begin + ENTRIES_HEIGHT;
|
||||
|
||||
rmenu_render_background(rgui);
|
||||
rmenu_render_background();
|
||||
|
||||
char title[256];
|
||||
const char *dir = NULL;
|
||||
@ -464,7 +464,6 @@ static void *rmenu_init(void)
|
||||
if (!rgui)
|
||||
return NULL;
|
||||
|
||||
|
||||
rmenu_init_assets(rgui);
|
||||
|
||||
return rgui;
|
||||
|
@ -180,11 +180,10 @@ static void* rmenu_xui_init(void)
|
||||
|
||||
hr = app.InitShared(d3d->dev, &d3dpp, XuiPNGTextureLoader);
|
||||
|
||||
if (hr != S_OK)
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RARCH_ERR("Failed initializing XUI application.\n");
|
||||
free(rgui);
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Register font */
|
||||
@ -194,36 +193,32 @@ static void* rmenu_xui_init(void)
|
||||
typeface.szReserved1 = NULL;
|
||||
|
||||
hr = XuiRegisterTypeface( &typeface, TRUE );
|
||||
if (hr != S_OK)
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RARCH_ERR("Failed to register default typeface.\n");
|
||||
free(rgui);
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
hr = XuiLoadVisualFromBinary( L"file://game:/media/rarch_scene_skin.xur", NULL);
|
||||
if (hr != S_OK)
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RARCH_ERR("Failed to load skin.\n");
|
||||
free(rgui);
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
hr = XuiSceneCreate(hdmenus_allowed ? L"file://game:/media/hd/" : L"file://game:/media/sd/", L"rarch_main.xur", NULL, &root_menu);
|
||||
if (hr != S_OK)
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RARCH_ERR("Failed to create scene 'rarch_main.xur'.\n");
|
||||
free(rgui);
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
current_menu = root_menu;
|
||||
hr = XuiSceneNavigateFirst(app.GetRootObj(), current_menu, XUSER_INDEX_FOCUS);
|
||||
if (hr != S_OK)
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RARCH_ERR("XuiSceneNavigateFirst failed.\n");
|
||||
free(rgui);
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (driver.video_data && driver.video_poke && driver.video_poke->set_texture_enable)
|
||||
@ -233,6 +228,10 @@ static void* rmenu_xui_init(void)
|
||||
xui_msg_queue = msg_queue_new(16);
|
||||
|
||||
return rgui;
|
||||
|
||||
error:
|
||||
free(rgui);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rmenu_xui_free(void *data)
|
||||
@ -360,40 +359,39 @@ static int rmenu_xui_input_postprocess(uint64_t old_state)
|
||||
return process_input_ret_old;
|
||||
}
|
||||
|
||||
static void blit_line(rgui_handle_t *rgui,
|
||||
int x, int y, const char *message, bool green)
|
||||
static void blit_line(int x, int y, const char *message, bool green)
|
||||
{
|
||||
}
|
||||
|
||||
static void rmenu_xui_render_background(void *data)
|
||||
static void rmenu_xui_render_background(void)
|
||||
{
|
||||
(void)data;
|
||||
}
|
||||
|
||||
static void rmenu_xui_render_messagebox(void *data, const char *message)
|
||||
static void rmenu_xui_render_messagebox(const char *message)
|
||||
{
|
||||
msg_queue_clear(xui_msg_queue);
|
||||
msg_queue_push(xui_msg_queue, message, 2, 1);
|
||||
}
|
||||
|
||||
static void rmenu_xui_render(void *data)
|
||||
static void rmenu_xui_render(void)
|
||||
{
|
||||
rgui_handle_t *rgui = (rgui_handle_t*)data;
|
||||
|
||||
if (rgui->need_refresh &&
|
||||
(g_extern.lifecycle_state & (1ULL << MODE_MENU))
|
||||
&& !rgui->msg_force)
|
||||
return;
|
||||
|
||||
size_t begin = rgui->selection_ptr;
|
||||
size_t end = rgui->selection_buf->size;
|
||||
|
||||
rmenu_xui_render_background(rgui);
|
||||
|
||||
size_t begin, end;
|
||||
char title[256];
|
||||
const char *dir = NULL;
|
||||
unsigned menu_type = 0;
|
||||
unsigned menu_type_is = 0;
|
||||
rgui_handle_t *rgui = (rgui_handle_t*)driver.menu;
|
||||
|
||||
if (!rgui || rgui->need_refresh &&
|
||||
(g_extern.lifecycle_state & (1ULL << MODE_MENU))
|
||||
&& !rgui->msg_force)
|
||||
return;
|
||||
|
||||
begin = rgui->selection_ptr;
|
||||
end = rgui->selection_buf->size;
|
||||
|
||||
rmenu_xui_render_background();
|
||||
|
||||
file_list_get_last(rgui->menu_stack, &dir, &menu_type);
|
||||
|
||||
if (driver.menu_ctx && driver.menu_ctx->backend && driver.menu_ctx->backend->type_is)
|
||||
@ -515,7 +513,7 @@ static void rmenu_xui_render(void *data)
|
||||
|
||||
char title_buf[256];
|
||||
menu_ticker_line(title_buf, RXUI_TERM_WIDTH - 3, g_extern.frame_count / 15, title, true);
|
||||
blit_line(rgui, RXUI_TERM_START_X + 15, 15, title_buf, true);
|
||||
blit_line(RXUI_TERM_START_X + 15, 15, title_buf, true);
|
||||
|
||||
char title_msg[64];
|
||||
const char *core_name = rgui->info.library_name;
|
||||
@ -531,7 +529,7 @@ static void rmenu_xui_render(void *data)
|
||||
core_version = "";
|
||||
|
||||
snprintf(title_msg, sizeof(title_msg), "%s - %s %s", PACKAGE_VERSION, core_name, core_version);
|
||||
blit_line(rgui, RXUI_TERM_START_X + 15, (RXUI_TERM_HEIGHT * FONT_HEIGHT_STRIDE) + RXUI_TERM_START_Y + 2, title_msg, true);
|
||||
blit_line(RXUI_TERM_START_X + 15, (RXUI_TERM_HEIGHT * FONT_HEIGHT_STRIDE) + RXUI_TERM_START_Y + 2, title_msg, true);
|
||||
|
||||
unsigned x, y;
|
||||
size_t i;
|
||||
@ -648,7 +646,7 @@ static void rmenu_xui_render(void *data)
|
||||
wchar_t msg_w[256];
|
||||
mbstowcs(msg_w, message, sizeof(msg_w) / sizeof(wchar_t));
|
||||
XuiListSetText(m_menulist, i, msg_w);
|
||||
blit_line(rgui, x, y, message, i);
|
||||
blit_line(x, y, message, i);
|
||||
}
|
||||
|
||||
if (rgui->keyboard.display)
|
||||
|
2
gfx/gl.c
2
gfx/gl.c
@ -1621,7 +1621,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
||||
|
||||
#if defined(HAVE_MENU)
|
||||
if (g_extern.lifecycle_state & (1ULL << MODE_MENU) && driver.menu_ctx && driver.menu_ctx->frame)
|
||||
driver.menu_ctx->frame(gl);
|
||||
driver.menu_ctx->frame();
|
||||
|
||||
if (gl->rgui_texture_enable)
|
||||
gl_draw_texture(gl);
|
||||
|
@ -912,7 +912,7 @@ static bool d3d_frame(void *data, const void *frame,
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
if (g_extern.lifecycle_state & (1ULL << MODE_MENU) && driver.menu_ctx && driver.menu_ctx->frame)
|
||||
driver.menu_ctx->frame(d3d);
|
||||
driver.menu_ctx->frame();
|
||||
|
||||
if (d3d && d3d->rgui_texture_enable)
|
||||
d3d_draw_texture(d3d);
|
||||
|
Loading…
x
Reference in New Issue
Block a user