mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-27 21:54:15 +01:00
-set up cover size limit to 1090 pixel instead of 1024
This commit is contained in:
parent
d896cb7436
commit
60e103b1bf
@ -8,6 +8,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/iosupport.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "wifi_gecko.h"
|
||||
|
||||
@ -18,7 +19,7 @@ bool textVideoInit = false;
|
||||
bool bufferMessages = true;
|
||||
bool WriteToSD = false;
|
||||
|
||||
#include <stdarg.h>
|
||||
char *tmpfilebuffer = NULL;
|
||||
|
||||
static ssize_t __out_write(struct _reent *r __attribute__((unused)), int fd __attribute__((unused)), const char *ptr, size_t len)
|
||||
{
|
||||
@ -29,36 +30,35 @@ static ssize_t __out_write(struct _reent *r __attribute__((unused)), int fd __at
|
||||
usb_sendbuffer(1, ptr, len);
|
||||
IRQ_Restore(level);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static const devoptab_t gecko_out = {
|
||||
"stdout", // device name
|
||||
0, // size of file structure
|
||||
NULL, // device open
|
||||
NULL, // device close
|
||||
__out_write,// device write
|
||||
NULL, // device read
|
||||
NULL, // device seek
|
||||
NULL, // device fstat
|
||||
NULL, // device stat
|
||||
NULL, // device link
|
||||
NULL, // device unlink
|
||||
NULL, // device chdir
|
||||
NULL, // device rename
|
||||
NULL, // device mkdir
|
||||
0, // dirStateSize
|
||||
NULL, // device diropen_r
|
||||
NULL, // device dirreset_r
|
||||
NULL, // device dirnext_r
|
||||
NULL, // device dirclose_r
|
||||
NULL, // device statvfs_r
|
||||
NULL, // device ftruncate_r
|
||||
NULL, // device fsync_r
|
||||
NULL, // device deviceData
|
||||
NULL, // device chmod_r
|
||||
NULL, // device fchmod_r
|
||||
"stdout", // device name
|
||||
0, // size of file structure
|
||||
NULL, // device open
|
||||
NULL, // device close
|
||||
__out_write, // device write
|
||||
NULL, // device read
|
||||
NULL, // device seek
|
||||
NULL, // device fstat
|
||||
NULL, // device stat
|
||||
NULL, // device link
|
||||
NULL, // device unlink
|
||||
NULL, // device chdir
|
||||
NULL, // device rename
|
||||
NULL, // device mkdir
|
||||
0, // dirStateSize
|
||||
NULL, // device diropen_r
|
||||
NULL, // device dirreset_r
|
||||
NULL, // device dirnext_r
|
||||
NULL, // device dirclose_r
|
||||
NULL, // device statvfs_r
|
||||
NULL, // device ftruncate_r
|
||||
NULL, // device fsync_r
|
||||
NULL, // device deviceData
|
||||
NULL, // device chmod_r
|
||||
NULL, // device fchmod_r
|
||||
};
|
||||
|
||||
static void USBGeckoOutput()
|
||||
@ -67,8 +67,6 @@ static void USBGeckoOutput()
|
||||
devoptab_list[STD_ERR] = &gecko_out;
|
||||
}
|
||||
|
||||
|
||||
char *tmpfilebuffer = NULL;
|
||||
void WriteToFile(char* tmp)
|
||||
{
|
||||
if(bufferMessages)
|
||||
@ -116,38 +114,50 @@ void gprintf( const char *format, ... )
|
||||
SAFE_FREE(tmp);
|
||||
}
|
||||
|
||||
char ascii(char s) {
|
||||
if(s < 0x20) return '.';
|
||||
if(s > 0x7E) return '.';
|
||||
return s;
|
||||
char ascii(char s)
|
||||
{
|
||||
if(s < 0x20)
|
||||
return '.';
|
||||
if(s > 0x7E)
|
||||
return '.';
|
||||
return s;
|
||||
}
|
||||
|
||||
void ghexdump(void *d, int len) {
|
||||
u8 *data;
|
||||
int i, off;
|
||||
data = (u8*)d;
|
||||
void ghexdump(void *d, int len)
|
||||
{
|
||||
u8 *data;
|
||||
int i, off;
|
||||
data = (u8*)d;
|
||||
|
||||
gprintf("\n 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF");
|
||||
gprintf("\n==== =============================================== ================\n");
|
||||
gprintf("\n 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF");
|
||||
gprintf("\n==== =============================================== ================\n");
|
||||
|
||||
for (off=0; off<len; off += 16)
|
||||
{
|
||||
gprintf("%04x ",off);
|
||||
for(i=0; i<16; i++)
|
||||
if((i+off)>=len) gprintf(" ");
|
||||
else gprintf("%02x ",data[off+i]);
|
||||
|
||||
gprintf(" ");
|
||||
for(i=0; i<16; i++)
|
||||
if((i+off)>=len) gprintf(" ");
|
||||
else gprintf("%c",ascii(data[off+i]));
|
||||
gprintf("\n");
|
||||
}
|
||||
for (off = 0; off < len; off += 16)
|
||||
{
|
||||
gprintf("%04x ",off);
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
if((i+off)>=len)
|
||||
gprintf(" ");
|
||||
else
|
||||
gprintf("%02x ",data[off+i]);
|
||||
}
|
||||
gprintf(" ");
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
if((i+off)>=len)
|
||||
gprintf(" ");
|
||||
else
|
||||
gprintf("%c",ascii(data[off+i]));
|
||||
}
|
||||
gprintf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
bool InitGecko()
|
||||
{
|
||||
if (geckoinit) return geckoinit;
|
||||
if (geckoinit)
|
||||
return geckoinit;
|
||||
|
||||
USBGeckoOutput();
|
||||
|
||||
@ -158,10 +168,11 @@ bool InitGecko()
|
||||
#endif
|
||||
|
||||
u32 geckoattached = usb_isgeckoalive(EXI_CHANNEL_1);
|
||||
if (geckoattached)
|
||||
if(geckoattached)
|
||||
{
|
||||
usb_flush(EXI_CHANNEL_1);
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -2506,7 +2506,7 @@ bool CCoverFlow::fullCoverCached(const char *id)
|
||||
found = fread(&header, 1, sizeof header, file) == sizeof header
|
||||
&& header.full != 0 && m_compressTextures == (header.cmpr != 0)
|
||||
&& header.getWidth() >= 8 && header.getHeight() >= 8
|
||||
&& header.getWidth() <= 1024 && header.getHeight() <= 1024;
|
||||
&& header.getWidth() <= 1090 && header.getHeight() <= 1090;
|
||||
SAFE_CLOSE(file);
|
||||
}
|
||||
return found;
|
||||
|
@ -10,7 +10,7 @@ using namespace std;
|
||||
static u32 upperPower(u32 width)
|
||||
{
|
||||
u32 i = 8;
|
||||
u32 maxWidth = 1024;
|
||||
u32 maxWidth = 1090;
|
||||
while (i < width && i < maxWidth)
|
||||
i <<= 1;
|
||||
return i;
|
||||
@ -280,7 +280,7 @@ STexture::TexErr STexture::fromPNG(const u8 *buffer, u8 f, Alloc alloc, u32 minM
|
||||
PNGU_ReleaseImageContext(ctx);
|
||||
return STexture::TE_ERROR;
|
||||
}
|
||||
if (imgProp.imgWidth > 1024 || imgProp.imgHeight > 1024)
|
||||
if (imgProp.imgWidth > 1090 || imgProp.imgHeight > 1090)
|
||||
{
|
||||
PNGU_ReleaseImageContext(ctx);
|
||||
return STexture::TE_ERROR;
|
||||
|
@ -15,10 +15,13 @@ void CMenu::_hideCategorySettings(bool instant)
|
||||
m_btnMgr.hide(m_categoryLblPage, instant);
|
||||
m_btnMgr.hide(m_categoryBtnPageM, instant);
|
||||
m_btnMgr.hide(m_categoryBtnPageP, instant);
|
||||
for (u32 i = 0; i < ARRAY_SIZE(m_categoryLblUser); ++i)
|
||||
if (m_categoryLblUser[i] != -1u) m_btnMgr.hide(m_categoryLblUser[i], instant);
|
||||
for(u32 i = 0; i < ARRAY_SIZE(m_categoryLblUser); ++i)
|
||||
{
|
||||
if(m_categoryLblUser[i] != -1u)
|
||||
m_btnMgr.hide(m_categoryLblUser[i], instant);
|
||||
}
|
||||
|
||||
for (int i=0; i<21; ++i)
|
||||
for(int i = 0; i < 21; ++i)
|
||||
{
|
||||
m_btnMgr.hide(m_categoryLblCat[i]);
|
||||
m_btnMgr.hide(m_categoryBtn[i]);
|
||||
@ -28,7 +31,11 @@ void CMenu::_hideCategorySettings(bool instant)
|
||||
void CMenu::_showCategorySettings(void)
|
||||
{
|
||||
_setBg(m_categoryBg, m_categoryBg);
|
||||
for (u32 i = 0; i < ARRAY_SIZE(m_categoryLblUser); ++i) if (m_categoryLblUser[i] != -1u) m_btnMgr.show(m_categoryLblUser[i]);
|
||||
for(u32 i = 0; i < ARRAY_SIZE(m_categoryLblUser); ++i)
|
||||
{
|
||||
if(m_categoryLblUser[i] != -1u)
|
||||
m_btnMgr.show(m_categoryLblUser[i]);
|
||||
}
|
||||
m_btnMgr.show(m_categoryLblTitle);
|
||||
m_btnMgr.show(m_categoryBtnBack);
|
||||
_updateCheckboxes();
|
||||
@ -36,57 +43,67 @@ void CMenu::_showCategorySettings(void)
|
||||
|
||||
void CMenu::_updateCheckboxes(void)
|
||||
{
|
||||
if (m_max_categories > 10)
|
||||
if(m_max_categories > 10)
|
||||
{
|
||||
m_btnMgr.setText(m_categoryLblPage, wfmt(L"%i / 2", C_curPage));
|
||||
m_btnMgr.show(m_categoryLblPage);
|
||||
m_btnMgr.show(m_categoryBtnPageM);
|
||||
m_btnMgr.show(m_categoryBtnPageP);
|
||||
}
|
||||
for (int i=0; i<21; ++i)
|
||||
for(int i = 0; i < 21; ++i)
|
||||
{
|
||||
m_btnMgr.hide(m_categoryBtn[i]);
|
||||
m_btnMgr.hide(m_categoryLblCat[i]);
|
||||
}
|
||||
string id;
|
||||
if (m_current_view != COVERFLOW_EMU) id = m_cf.getId();
|
||||
if(m_current_view != COVERFLOW_EMU)
|
||||
id = m_cf.getId();
|
||||
else
|
||||
{
|
||||
dir_discHdr *hdr = m_cf.getHdr();
|
||||
string tempname(hdr->path);
|
||||
tempname.erase(0, tempname.find_first_of('/')+1);
|
||||
string dirName = tempname.substr(0, tempname.find_first_of('/')+1);
|
||||
tempname.assign(&tempname[tempname.find_last_of('/') + 1]);
|
||||
if(tempname.find_last_of('.') != string::npos)
|
||||
tempname.erase(tempname.find_last_of('.'), tempname.size() - tempname.find_last_of('.'));
|
||||
id = dirName+tempname;
|
||||
}
|
||||
{
|
||||
dir_discHdr *hdr = m_cf.getHdr();
|
||||
string tempname(hdr->path);
|
||||
tempname.erase(0, tempname.find_first_of('/')+1);
|
||||
string dirName = tempname.substr(0, tempname.find_first_of('/')+1);
|
||||
tempname.assign(&tempname[tempname.find_last_of('/') + 1]);
|
||||
if(tempname.find_last_of('.') != string::npos)
|
||||
tempname.erase(tempname.find_last_of('.'), tempname.size() - tempname.find_last_of('.'));
|
||||
id = dirName+tempname;
|
||||
}
|
||||
const char *catflags;
|
||||
if (gameSet) catflags = m_cat.getString("CATEGORIES", id, "").c_str();
|
||||
else catflags = m_cat.getString(_domainFromView(), "categories", "100000000000000000000").c_str();
|
||||
if(gameSet)
|
||||
catflags = m_cat.getString("CATEGORIES", id, "").c_str();
|
||||
else
|
||||
catflags = m_cat.getString(_domainFromView(), "categories", "100000000000000000000").c_str();
|
||||
memset(&m_categories, '0', sizeof(m_categories));
|
||||
if (strlen(catflags) == sizeof(m_categories)) memcpy(&m_categories, catflags, sizeof(m_categories));
|
||||
if(strlen(catflags) == sizeof(m_categories))
|
||||
memcpy(&m_categories, catflags, sizeof(m_categories));
|
||||
|
||||
if (C_curPage == 1)
|
||||
if(C_curPage == 1)
|
||||
{
|
||||
int j = 11;
|
||||
if (m_max_categories < 11) j = m_max_categories;
|
||||
for (int i = 0; i < j; ++i)
|
||||
if(m_max_categories < 11)
|
||||
j = m_max_categories;
|
||||
for(int i = 0; i < j; ++i)
|
||||
{
|
||||
if (i == 0 && gameSet) continue;
|
||||
if(i == 0 && gameSet)
|
||||
continue;
|
||||
m_btnMgr.show(m_categoryLblCat[i]);
|
||||
if (catflags[i] == '1') m_categoryBtn[i] = m_categoryBtnCats[i];
|
||||
else m_categoryBtn[i] = m_categoryBtnCat[i];
|
||||
if(catflags[i] == '1')
|
||||
m_categoryBtn[i] = m_categoryBtnCats[i];
|
||||
else
|
||||
m_categoryBtn[i] = m_categoryBtnCat[i];
|
||||
m_btnMgr.show(m_categoryBtn[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 11; i < m_max_categories; ++i)
|
||||
for(int i = 11; i < m_max_categories; ++i)
|
||||
{
|
||||
m_btnMgr.show(m_categoryLblCat[i]);
|
||||
if (catflags[i] == '1') m_categoryBtn[i] = m_categoryBtnCats[i];
|
||||
else m_categoryBtn[i] = m_categoryBtnCat[i];
|
||||
if(catflags[i] == '1')
|
||||
m_categoryBtn[i] = m_categoryBtnCats[i];
|
||||
else
|
||||
m_categoryBtn[i] = m_categoryBtnCat[i];
|
||||
m_btnMgr.show(m_categoryBtn[i]);
|
||||
}
|
||||
}
|
||||
@ -98,56 +115,65 @@ void CMenu::_CategorySettings(bool fromGameSet)
|
||||
C_curPage = 1;
|
||||
gameSet = fromGameSet;
|
||||
_showCategorySettings();
|
||||
while (true)
|
||||
while(true)
|
||||
{
|
||||
_mainLoopCommon();
|
||||
if (!m_btnMgr.selected(lastBtn)) m_btnMgr.noHover(false);
|
||||
if (BTN_HOME_PRESSED || BTN_B_PRESSED)
|
||||
{
|
||||
m_cat.save();
|
||||
break;
|
||||
}
|
||||
else if (BTN_UP_PRESSED)
|
||||
if(!m_btnMgr.selected(lastBtn))
|
||||
m_btnMgr.noHover(false);
|
||||
if(BTN_HOME_PRESSED || BTN_B_PRESSED)
|
||||
{
|
||||
m_cat.save();
|
||||
break;
|
||||
}
|
||||
else if(BTN_UP_PRESSED)
|
||||
m_btnMgr.up();
|
||||
else if (BTN_DOWN_PRESSED)
|
||||
else if(BTN_DOWN_PRESSED)
|
||||
m_btnMgr.down();
|
||||
if (((BTN_MINUS_PRESSED || BTN_LEFT_PRESSED) && m_max_categories>11) || (BTN_A_PRESSED && m_btnMgr.selected(m_categoryBtnPageM)))
|
||||
if(((BTN_MINUS_PRESSED || BTN_LEFT_PRESSED) && m_max_categories>11) || (BTN_A_PRESSED && m_btnMgr.selected(m_categoryBtnPageM)))
|
||||
{
|
||||
lastBtn = m_categoryBtnPageM;
|
||||
m_btnMgr.noHover(true);
|
||||
C_curPage = C_curPage == 1 ? 2 : 1;
|
||||
if (BTN_LEFT_PRESSED || BTN_MINUS_PRESSED) m_btnMgr.click(m_categoryBtnPageM);
|
||||
if(BTN_LEFT_PRESSED || BTN_MINUS_PRESSED)
|
||||
m_btnMgr.click(m_categoryBtnPageM);
|
||||
_updateCheckboxes();
|
||||
}
|
||||
else if (((BTN_PLUS_PRESSED || BTN_RIGHT_PRESSED) && m_max_categories>11) || (BTN_A_PRESSED && m_btnMgr.selected(m_categoryBtnPageP)))
|
||||
else if(((BTN_PLUS_PRESSED || BTN_RIGHT_PRESSED) && m_max_categories>11) || (BTN_A_PRESSED && m_btnMgr.selected(m_categoryBtnPageP)))
|
||||
{
|
||||
lastBtn = m_categoryBtnPageP;
|
||||
m_btnMgr.noHover(true);
|
||||
C_curPage = C_curPage == 1 ? 2 : 1;
|
||||
if(BTN_RIGHT_PRESSED || BTN_PLUS_PRESSED) m_btnMgr.click(m_categoryBtnPageP);
|
||||
if(BTN_RIGHT_PRESSED || BTN_PLUS_PRESSED)
|
||||
m_btnMgr.click(m_categoryBtnPageP);
|
||||
_updateCheckboxes();
|
||||
}
|
||||
if (BTN_A_PRESSED)
|
||||
if(BTN_A_PRESSED)
|
||||
{
|
||||
if (m_btnMgr.selected(m_categoryBtnBack))
|
||||
if(m_btnMgr.selected(m_categoryBtnBack))
|
||||
{
|
||||
m_cat.save();
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < 21; ++i)
|
||||
for(int i = 0; i < 21; ++i)
|
||||
{
|
||||
if (m_btnMgr.selected(m_categoryBtn[i]))
|
||||
if(m_btnMgr.selected(m_categoryBtn[i]))
|
||||
{
|
||||
lastBtn = m_categoryBtn[i];
|
||||
m_btnMgr.noHover(true);
|
||||
m_categories[i] = m_categories[i] == '1' ? '0' : '1';
|
||||
if (i == 0 && m_categories[i] == '1') for (int j=1; j<21; ++j) m_categories[j] = '0';
|
||||
else m_categories[0] = '0';
|
||||
if(i == 0 && m_categories[i] == '1')
|
||||
{
|
||||
for(int j = 1; j < 21; ++j)
|
||||
m_categories[j] = '0';
|
||||
}
|
||||
else
|
||||
m_categories[0] = '0';
|
||||
char catflags[22];
|
||||
memset(&catflags, 0, sizeof(catflags));
|
||||
memcpy(&catflags, &m_categories, sizeof(m_categories));
|
||||
string id;
|
||||
if (m_current_view != COVERFLOW_EMU) id = m_cf.getId();
|
||||
if(m_current_view != COVERFLOW_EMU)
|
||||
id = m_cf.getId();
|
||||
else
|
||||
{
|
||||
dir_discHdr *hdr = m_cf.getHdr();
|
||||
@ -159,9 +185,12 @@ void CMenu::_CategorySettings(bool fromGameSet)
|
||||
tempname.erase(tempname.find_last_of('.'), tempname.size() - tempname.find_last_of('.'));
|
||||
id = dirName+tempname;
|
||||
}
|
||||
if (string (catflags) == "000000000000000000000") catflags[0] = '1';
|
||||
if (gameSet) m_cat.setString("CATEGORIES", id, catflags);
|
||||
else m_cat.setString(_domainFromView(), "categories", catflags);
|
||||
if(string (catflags) == "000000000000000000000")
|
||||
catflags[0] = '1';
|
||||
if(gameSet)
|
||||
m_cat.setString("CATEGORIES", id, catflags);
|
||||
else
|
||||
m_cat.setString(_domainFromView(), "categories", catflags);
|
||||
_updateCheckboxes();
|
||||
break;
|
||||
}
|
||||
@ -183,7 +212,7 @@ void CMenu::_initCategorySettingsMenu(CMenu::SThemeData &theme)
|
||||
m_categoryLblCat[0] = _addLabel(theme, "CATEGORY/CAT_0", theme.lblFont, L"", 85, 390, 100, 48, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_categoryBtnCat[0] = _addPicButton(theme, "CATEGORY/CAT_0_BTN", theme.checkboxoff, theme.checkboxoffs, 30, 390, 44, 48);
|
||||
m_categoryBtnCats[0] = _addPicButton(theme, "CATEGORY/CAT_0_BTNS", theme.checkboxon, theme.checkboxons, 30, 390, 44, 48);
|
||||
for (int i = 1; i < 6; ++i)
|
||||
for(int i = 1; i < 6; ++i)
|
||||
{ // Page 1
|
||||
m_categoryLblCat[i] = _addLabel(theme, fmt("CATEGORY/CAT_%i", i), theme.lblFont, L"", 85, (42+i*58), 230, 48, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_categoryBtnCat[i] = _addPicButton(theme, fmt("CATEGORY/CAT_%i_BTN", i), theme.checkboxoff, theme.checkboxoffs, 30, (42+i*58), 44, 48);
|
||||
@ -206,7 +235,8 @@ void CMenu::_initCategorySettingsMenu(CMenu::SThemeData &theme)
|
||||
_setHideAnim(m_categoryBtnPageM, "CATEGORY/PAGE_MINUS", 0, 200, 1.f, 0.f);
|
||||
_setHideAnim(m_categoryBtnPageP, "CATEGORY/PAGE_PLUS", 0, 200, 1.f, 0.f);
|
||||
_setHideAnim(m_categoryBtnBack, "CATEGORY/BACK_BTN", 0, 200, 1.f, 0.f);
|
||||
for (int i = 0; i < 21; ++i) {
|
||||
for(int i = 0; i < 21; ++i)
|
||||
{
|
||||
_setHideAnim(m_categoryBtnCat[i], fmt("CATEGORY/CAT_%i_BTN", i), 0, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_categoryBtnCats[i], fmt("CATEGORY/CAT_%i_BTNS", i), 0, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_categoryLblCat[i], fmt("CATEGORY/CAT_%i", i), 0, 0, 1.f, 0.f);
|
||||
@ -220,10 +250,11 @@ void CMenu::_textCategorySettings(void)
|
||||
{
|
||||
m_btnMgr.setText(m_categoryLblTitle, _t("", L"Select Categories"));
|
||||
m_btnMgr.setText(m_categoryBtnBack, _t("cd1", L"Back"));
|
||||
for (int i=0; i<21; ++i)
|
||||
for(int i = 0; i < 21; ++i)
|
||||
{
|
||||
if (i == 0) m_btnMgr.setText(m_categoryLblCat[i], _t("dl3", L"All"));
|
||||
else m_btnMgr.setText(m_categoryLblCat[i], m_cat.getWString("GENERAL", fmt("cat%d",i), wfmt(L"Category %i",i).c_str()));
|
||||
if(i == 0)
|
||||
m_btnMgr.setText(m_categoryLblCat[i], _t("dl3", L"All"));
|
||||
else
|
||||
m_btnMgr.setText(m_categoryLblCat[i], m_cat.getWString("GENERAL", fmt("cat%d",i), wfmt(L"Category %i",i).c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user