mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-06-07 08:56:58 +00:00
Finish translation for permissions
This commit is contained in:
parent
17a568674f
commit
b69fd5338a
@ -42,6 +42,7 @@
|
|||||||
"id": "group id",
|
"id": "group id",
|
||||||
"invites": "group invites",
|
"invites": "group invites",
|
||||||
"group": "group",
|
"group": "group",
|
||||||
|
"group_name": "group: {{ name }}",
|
||||||
"group_other": "groups",
|
"group_other": "groups",
|
||||||
"groups_admin": "groups where you are an admin",
|
"groups_admin": "groups where you are an admin",
|
||||||
"management": "group management",
|
"management": "group management",
|
||||||
|
@ -92,6 +92,7 @@
|
|||||||
"token_not_supported": "{{ token }} is not supported for this call",
|
"token_not_supported": "{{ token }} is not supported for this call",
|
||||||
"transaction_activity_summary": "error in transaction activity summary",
|
"transaction_activity_summary": "error in transaction activity summary",
|
||||||
"unknown_error": "unknown error",
|
"unknown_error": "unknown error",
|
||||||
|
"unknown_admin_action_type": "unknown admin action type: {{ type }}",
|
||||||
"update_foreign_fee": "failed to update foreign fee",
|
"update_foreign_fee": "failed to update foreign fee",
|
||||||
"update_tradebot": "unable to update tradebot",
|
"update_tradebot": "unable to update tradebot",
|
||||||
"upload_encryption": "upload failed due to failed encryption",
|
"upload_encryption": "upload failed due to failed encryption",
|
||||||
@ -156,6 +157,23 @@
|
|||||||
"permission_buy_name": "do you give this application permission to buy a name?",
|
"permission_buy_name": "do you give this application permission to buy a name?",
|
||||||
"permission_buy_name_detail": "buying {{ name }} for {{ price }} QORT",
|
"permission_buy_name_detail": "buying {{ name }} for {{ price }} QORT",
|
||||||
"permission_sign_fee": "do you give this application permission to sign the required fees for all your trade offers?",
|
"permission_sign_fee": "do you give this application permission to sign the required fees for all your trade offers?",
|
||||||
|
"permission_update_foreign_fee": "do you give this application permission to update foreign fees on your node?",
|
||||||
|
"permission_perform_admin_action": "do you give this application permission to perform the admin action: {{ type }}",
|
||||||
|
"permission_perform_admin_action_with_value": "with value: {{ value }}",
|
||||||
|
"permission_sign_transaction": "do you give this application permission to sign a transaction?",
|
||||||
|
"permission_sign_process_transaction": "do you give this application permission to sign and process a transaction?",
|
||||||
|
"permission_register_name": "do you give this application permission to register this name?",
|
||||||
|
"permission_leave_group": "do you give this application permission to leave the following group?",
|
||||||
|
"permission_invite": "do you give this application permission to invite {{ invitee }}?",
|
||||||
|
"permission_kick": "do you give this application permission to kick {{ partecipant }} from the group?",
|
||||||
|
"permission_ban": "do you give this application permission to ban {{ partecipant }} from the group?",
|
||||||
|
"permission_cancel_ban": "do you give this application permission to cancel the group ban for user {{ partecipant }}?",
|
||||||
|
"permission_add_admin": "do you give this application permission to add user {{ invitee }} as an admin?",
|
||||||
|
"permission_remove_admin": "do you give this application permission to remove user {{ partecipant }} as an admin?",
|
||||||
|
"permission_cancel_group_invite": "do you give this application permission to cancel the group invite for {{ invitee }}?",
|
||||||
|
"permission_create_group": "do you give this application permission to create a group?",
|
||||||
|
"permission_update_group": "do you give this application permission to update this group?",
|
||||||
|
"permission_update_group_detail": "new owner: {{ owner }}",
|
||||||
"poll": "poll: {{ name }}",
|
"poll": "poll: {{ name }}",
|
||||||
"provide_recipient_group_id": "please provide a recipient or groupId",
|
"provide_recipient_group_id": "please provide a recipient or groupId",
|
||||||
"request_create_poll": "you are requesting to create the poll below:",
|
"request_create_poll": "you are requesting to create the poll below:",
|
||||||
@ -167,5 +185,6 @@
|
|||||||
"to_group": "to: group {{ group_id }}",
|
"to_group": "to: group {{ group_id }}",
|
||||||
"to_recipient": "to: {{ recipient }}",
|
"to_recipient": "to: {{ recipient }}",
|
||||||
"total_locking_fee": "total Locking Fee:",
|
"total_locking_fee": "total Locking Fee:",
|
||||||
"total_unlocking_fee": "total Unlocking Fee:"
|
"total_unlocking_fee": "total Unlocking Fee:",
|
||||||
|
"value": "value: {{ value }}"
|
||||||
}
|
}
|
||||||
|
@ -3290,10 +3290,14 @@ export const updateForeignFee = async (data, isFromExtension) => {
|
|||||||
: '';
|
: '';
|
||||||
const resPermission = await getUserPermission(
|
const resPermission = await getUserPermission(
|
||||||
{
|
{
|
||||||
text1: `Do you give this application permission to update foreign fees on your node?`,
|
text1: i18n.t('question:permission_update_foreign_fee', {
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
text2: `type: ${type === 'feerequired' ? 'unlocking' : 'locking'}`,
|
text2: `type: ${type === 'feerequired' ? 'unlocking' : 'locking'}`,
|
||||||
text3: `value: ${text3}`,
|
text3: i18n.t('question:value', {
|
||||||
text4,
|
value: text3,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
highlightedText: i18n.t('question:coin', {
|
highlightedText: i18n.t('question:coin', {
|
||||||
coin: coin,
|
coin: coin,
|
||||||
postProcess: 'capitalizeFirstChar',
|
postProcess: 'capitalizeFirstChar',
|
||||||
@ -5030,12 +5034,26 @@ export const adminAction = async (data, isFromExtension) => {
|
|||||||
includeValueInBody = true;
|
includeValueInBody = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown admin action type: ${data.type}`);
|
throw new Error(
|
||||||
|
i18n.t('question:message.error.unknown_admin_action_type', {
|
||||||
|
type: data.type,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// Prepare the permission prompt text
|
// Prepare the permission prompt text
|
||||||
let permissionText = `Do you give this application permission to perform the admin action: ${data.type}`;
|
let permissionText = i18n.t('question:permission_perform_admin_action', {
|
||||||
|
type: data.type,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
});
|
||||||
|
|
||||||
if (data.value) {
|
if (data.value) {
|
||||||
permissionText += ` with value: ${data.value}`;
|
permissionText +=
|
||||||
|
' ' +
|
||||||
|
i18n.t('question:permission_perform_admin_action_with_value', {
|
||||||
|
value: data.value,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const resPermission = await getUserPermission(
|
const resPermission = await getUserPermission(
|
||||||
@ -5044,7 +5062,9 @@ export const adminAction = async (data, isFromExtension) => {
|
|||||||
},
|
},
|
||||||
isFromExtension
|
isFromExtension
|
||||||
);
|
);
|
||||||
|
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
// Set up options for the API call
|
// Set up options for the API call
|
||||||
const options: RequestInit = {
|
const options: RequestInit = {
|
||||||
@ -5097,11 +5117,11 @@ export const signTransaction = async (data, isFromExtension) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const shouldProcess = data?.process || false;
|
const shouldProcess = data?.process || false;
|
||||||
let _url = await createEndpoint(
|
const _url = await createEndpoint(
|
||||||
'/transactions/decode?ignoreValidityChecks=false'
|
'/transactions/decode?ignoreValidityChecks=false'
|
||||||
);
|
);
|
||||||
|
|
||||||
let _body = data.unsignedBytes;
|
const _body = data.unsignedBytes;
|
||||||
const response = await fetch(_url, {
|
const response = await fetch(_url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@ -5109,6 +5129,7 @@ export const signTransaction = async (data, isFromExtension) => {
|
|||||||
},
|
},
|
||||||
body: _body,
|
body: _body,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok)
|
if (!response.ok)
|
||||||
throw new Error(
|
throw new Error(
|
||||||
i18n.t('question:message.error.decode_transaction', {
|
i18n.t('question:message.error.decode_transaction', {
|
||||||
@ -5118,7 +5139,13 @@ export const signTransaction = async (data, isFromExtension) => {
|
|||||||
const decodedData = await response.json();
|
const decodedData = await response.json();
|
||||||
const resPermission = await getUserPermission(
|
const resPermission = await getUserPermission(
|
||||||
{
|
{
|
||||||
text1: `Do you give this application permission to ${shouldProcess ? 'SIGN and PROCESS' : 'SIGN'} a transaction?`,
|
text1: shouldProcess
|
||||||
|
? i18n.t('question:permission_sign_process_transaction', {
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
})
|
||||||
|
: i18n.t('question:permission_sign_transaction', {
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
highlightedText: i18n.t(
|
highlightedText: i18n.t(
|
||||||
'question:message.generic.read_transaction_carefully',
|
'question:message.generic.read_transaction_carefully',
|
||||||
{ postProcess: 'capitalizeFirstChar' }
|
{ postProcess: 'capitalizeFirstChar' }
|
||||||
@ -5128,6 +5155,7 @@ export const signTransaction = async (data, isFromExtension) => {
|
|||||||
},
|
},
|
||||||
isFromExtension
|
isFromExtension
|
||||||
);
|
);
|
||||||
|
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
let urlConverted = await createEndpoint('/transactions/convert');
|
let urlConverted = await createEndpoint('/transactions/convert');
|
||||||
@ -5325,7 +5353,9 @@ export const registerNameRequest = async (data, isFromExtension) => {
|
|||||||
const fee = await getFee('REGISTER_NAME');
|
const fee = await getFee('REGISTER_NAME');
|
||||||
const resPermission = await getUserPermission(
|
const resPermission = await getUserPermission(
|
||||||
{
|
{
|
||||||
text1: `Do you give this application permission to register this name?`,
|
text1: i18n.t('question:permission_register_name', {
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
highlightedText: data.name,
|
highlightedText: data.name,
|
||||||
text2: data?.description,
|
text2: data?.description,
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
@ -5369,7 +5399,9 @@ export const updateNameRequest = async (data, isFromExtension) => {
|
|||||||
const fee = await getFee('UPDATE_NAME');
|
const fee = await getFee('UPDATE_NAME');
|
||||||
const resPermission = await getUserPermission(
|
const resPermission = await getUserPermission(
|
||||||
{
|
{
|
||||||
text1: `Do you give this application permission to register this name?`,
|
text1: i18n.t('question:permission_register_name', {
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
highlightedText: data.newName,
|
highlightedText: data.newName,
|
||||||
text2: data?.description,
|
text2: data?.description,
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
@ -5430,7 +5462,9 @@ export const leaveGroupRequest = async (data, isFromExtension) => {
|
|||||||
const fee = await getFee('LEAVE_GROUP');
|
const fee = await getFee('LEAVE_GROUP');
|
||||||
const resPermission = await getUserPermission(
|
const resPermission = await getUserPermission(
|
||||||
{
|
{
|
||||||
text1: `Do you give this application permission to leave the following group?`,
|
text1: i18n.t('question:permission_leave_group', {
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
highlightedText: `${groupInfo.groupName}`,
|
highlightedText: `${groupInfo.groupName}`,
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
},
|
},
|
||||||
@ -5495,8 +5529,14 @@ export const inviteToGroupRequest = async (data, isFromExtension) => {
|
|||||||
const fee = await getFee('GROUP_INVITE');
|
const fee = await getFee('GROUP_INVITE');
|
||||||
const resPermission = await getUserPermission(
|
const resPermission = await getUserPermission(
|
||||||
{
|
{
|
||||||
text1: `Do you give this application permission to invite ${displayInvitee || qortalAddress}?`,
|
text1: i18n.t('question:permission_invite', {
|
||||||
highlightedText: `Group: ${groupInfo.groupName}`,
|
invitee: displayInvitee || qortalAddress,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
|
highlightedText: i18n.t('group:group.group_name', {
|
||||||
|
name: groupInfo?.groupName,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
},
|
},
|
||||||
isFromExtension
|
isFromExtension
|
||||||
@ -5564,8 +5604,14 @@ export const kickFromGroupRequest = async (data, isFromExtension) => {
|
|||||||
const fee = await getFee('GROUP_KICK');
|
const fee = await getFee('GROUP_KICK');
|
||||||
const resPermission = await getUserPermission(
|
const resPermission = await getUserPermission(
|
||||||
{
|
{
|
||||||
text1: `Do you give this application permission to kick ${displayInvitee || qortalAddress} from the group?`,
|
text1: i18n.t('question:permission_kick', {
|
||||||
highlightedText: `Group: ${groupInfo.groupName}`,
|
partecipant: displayInvitee || qortalAddress,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
|
highlightedText: i18n.t('group:group.group_name', {
|
||||||
|
name: groupInfo?.groupName,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
},
|
},
|
||||||
isFromExtension
|
isFromExtension
|
||||||
@ -5633,8 +5679,14 @@ export const banFromGroupRequest = async (data, isFromExtension) => {
|
|||||||
const fee = await getFee('GROUP_BAN');
|
const fee = await getFee('GROUP_BAN');
|
||||||
const resPermission = await getUserPermission(
|
const resPermission = await getUserPermission(
|
||||||
{
|
{
|
||||||
text1: `Do you give this application permission to ban ${displayInvitee || qortalAddress} from the group?`,
|
text1: i18n.t('question:permission_ban', {
|
||||||
highlightedText: `Group: ${groupInfo.groupName}`,
|
partecipant: displayInvitee || qortalAddress,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
|
highlightedText: i18n.t('group:group.group_name', {
|
||||||
|
name: groupInfo?.groupName,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
},
|
},
|
||||||
isFromExtension
|
isFromExtension
|
||||||
@ -5702,8 +5754,14 @@ export const cancelGroupBanRequest = async (data, isFromExtension) => {
|
|||||||
const fee = await getFee('CANCEL_GROUP_BAN');
|
const fee = await getFee('CANCEL_GROUP_BAN');
|
||||||
const resPermission = await getUserPermission(
|
const resPermission = await getUserPermission(
|
||||||
{
|
{
|
||||||
text1: `Do you give this application permission to cancel the group ban for user ${displayInvitee || qortalAddress}?`,
|
text1: i18n.t('question:permission_cancel_ban', {
|
||||||
highlightedText: `Group: ${groupInfo.groupName}`,
|
partecipant: displayInvitee || qortalAddress,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
|
highlightedText: i18n.t('group:group.group_name', {
|
||||||
|
name: groupInfo?.groupName,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
},
|
},
|
||||||
isFromExtension
|
isFromExtension
|
||||||
@ -5769,8 +5827,14 @@ export const addGroupAdminRequest = async (data, isFromExtension) => {
|
|||||||
const fee = await getFee('ADD_GROUP_ADMIN');
|
const fee = await getFee('ADD_GROUP_ADMIN');
|
||||||
const resPermission = await getUserPermission(
|
const resPermission = await getUserPermission(
|
||||||
{
|
{
|
||||||
text1: `Do you give this application permission to add user ${displayInvitee || qortalAddress} as an admin?`,
|
text1: i18n.t('question:permission_add_admin', {
|
||||||
highlightedText: `Group: ${groupInfo.groupName}`,
|
invitee: displayInvitee || qortalAddress,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
|
highlightedText: i18n.t('group:group.group_name', {
|
||||||
|
name: groupInfo?.groupName,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
},
|
},
|
||||||
isFromExtension
|
isFromExtension
|
||||||
@ -5836,8 +5900,14 @@ export const removeGroupAdminRequest = async (data, isFromExtension) => {
|
|||||||
const fee = await getFee('REMOVE_GROUP_ADMIN');
|
const fee = await getFee('REMOVE_GROUP_ADMIN');
|
||||||
const resPermission = await getUserPermission(
|
const resPermission = await getUserPermission(
|
||||||
{
|
{
|
||||||
text1: `Do you give this application permission to remove user ${displayInvitee || qortalAddress} as admin?`,
|
text1: i18n.t('question:permission_remove_admin', {
|
||||||
highlightedText: `Group: ${groupInfo.groupName}`,
|
partecipant: displayInvitee || qortalAddress,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
|
highlightedText: i18n.t('group:group.group_name', {
|
||||||
|
name: groupInfo?.groupName,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
},
|
},
|
||||||
isFromExtension
|
isFromExtension
|
||||||
@ -5903,13 +5973,21 @@ export const cancelGroupInviteRequest = async (data, isFromExtension) => {
|
|||||||
const fee = await getFee('CANCEL_GROUP_INVITE');
|
const fee = await getFee('CANCEL_GROUP_INVITE');
|
||||||
const resPermission = await getUserPermission(
|
const resPermission = await getUserPermission(
|
||||||
{
|
{
|
||||||
text1: `Do you give this application permission to cancel the group invite for ${displayInvitee || qortalAddress}?`,
|
text1: i18n.t('question:permission_cancel_group_invite', {
|
||||||
highlightedText: `Group: ${groupInfo.groupName}`,
|
invitee: displayInvitee || qortalAddress,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
|
highlightedText: i18n.t('group:group.group_name', {
|
||||||
|
name: groupInfo?.groupName,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
},
|
},
|
||||||
isFromExtension
|
isFromExtension
|
||||||
);
|
);
|
||||||
|
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
const response = await cancelInvitationToGroup({
|
const response = await cancelInvitationToGroup({
|
||||||
groupId,
|
groupId,
|
||||||
@ -5927,13 +6005,13 @@ export const cancelGroupInviteRequest = async (data, isFromExtension) => {
|
|||||||
|
|
||||||
export const createGroupRequest = async (data, isFromExtension) => {
|
export const createGroupRequest = async (data, isFromExtension) => {
|
||||||
const requiredFields = [
|
const requiredFields = [
|
||||||
'groupId',
|
|
||||||
'qortalAddress',
|
|
||||||
'groupName',
|
|
||||||
'type',
|
|
||||||
'approvalThreshold',
|
'approvalThreshold',
|
||||||
'minBlock',
|
'groupId',
|
||||||
|
'groupName',
|
||||||
'maxBlock',
|
'maxBlock',
|
||||||
|
'minBlock',
|
||||||
|
'qortalAddress',
|
||||||
|
'type',
|
||||||
];
|
];
|
||||||
const missingFields: string[] = [];
|
const missingFields: string[] = [];
|
||||||
requiredFields.forEach((field) => {
|
requiredFields.forEach((field) => {
|
||||||
@ -5959,8 +6037,13 @@ export const createGroupRequest = async (data, isFromExtension) => {
|
|||||||
const fee = await getFee('CREATE_GROUP');
|
const fee = await getFee('CREATE_GROUP');
|
||||||
const resPermission = await getUserPermission(
|
const resPermission = await getUserPermission(
|
||||||
{
|
{
|
||||||
text1: `Do you give this application permission to create a group?`,
|
text1: i18n.t('question:permission_create_group', {
|
||||||
highlightedText: `Group name: ${groupName}`,
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
|
highlightedText: i18n.t('group:group.group_name', {
|
||||||
|
name: groupName,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
},
|
},
|
||||||
isFromExtension
|
isFromExtension
|
||||||
@ -6042,9 +6125,17 @@ export const updateGroupRequest = async (data, isFromExtension) => {
|
|||||||
const fee = await getFee('CREATE_GROUP');
|
const fee = await getFee('CREATE_GROUP');
|
||||||
const resPermission = await getUserPermission(
|
const resPermission = await getUserPermission(
|
||||||
{
|
{
|
||||||
text1: `Do you give this application permission to update this group?`,
|
text1: i18n.t('question:permission_update_group', {
|
||||||
text2: `New owner: ${displayInvitee || newOwner}`,
|
postProcess: 'capitalizeFirstChar',
|
||||||
highlightedText: `Group: ${groupInfo.groupName}`,
|
}),
|
||||||
|
text2: i18n.t('question:permission_update_group_detail', {
|
||||||
|
owner: displayInvitee || newOwner,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
|
highlightedText: i18n.t('group:group.group_name', {
|
||||||
|
name: groupInfo?.groupName,
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
}),
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
},
|
},
|
||||||
isFromExtension
|
isFromExtension
|
||||||
|
Loading…
x
Reference in New Issue
Block a user