updated backup script to include vendor directory added git suggestion and also spell check on comments
This commit is contained in:
@@ -451,7 +451,7 @@
|
||||
<label for="ticket-comment-subject"
|
||||
class="mb-2 block text-xs font-bold text-zinc-700 dark:text-zinc-200">Subject</label>
|
||||
<input id="ticket-comment-subject" name="subject" value="{{ old('subject') }}"
|
||||
placeholder="Response subject"
|
||||
placeholder="Response subject" spellcheck="true" lang="en-GB" autocorrect="on" autocomplete="on" autocapitalize="sentences" inputmode="text"
|
||||
class="block min-h-10 w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm font-semibold text-zinc-900 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100"
|
||||
data-helpdesk-comment-subject>
|
||||
</div>
|
||||
@@ -481,7 +481,7 @@
|
||||
|
||||
<div id="ticket-comment-body-editor" dusk="comment-body" data-dusk="comment-body"
|
||||
data-helpdesk-rich-editor data-helpdesk-sync-target="ticket-comment-body"
|
||||
contenteditable="true" spellcheck="true" lang="en-GB" autocorrect="on" autocomplete="on"
|
||||
contenteditable="true" role="textbox" aria-multiline="true" spellcheck="true" lang="en-GB" autocorrect="on" autocomplete="on" autocapitalize="sentences" inputmode="text"
|
||||
class="prose prose-sm min-h-[12rem] max-w-none bg-white p-4 text-sm leading-6 text-zinc-900 outline-none dark:prose-invert dark:bg-zinc-950 dark:text-zinc-100"
|
||||
data-placeholder="Write a public reply or internal note. Right-click or Ctrl-click underlined words for spelling suggestions.">{!! $oldCommentBody !!}</div>
|
||||
|
||||
@@ -534,7 +534,7 @@
|
||||
|
||||
@if ($canSeeInternalNotes)
|
||||
<div class="grid gap-3 sm:grid-cols-2">
|
||||
<label class="flex cursor-pointer items-start gap-3 rounded-xl border border-emerald-300 bg-emerald-50 p-3 text-emerald-950 shadow-sm transition hover:bg-emerald-100 dark:border-emerald-900 dark:bg-emerald-950/60 dark:text-emerald-100">
|
||||
<label class="flex cursor-pointer items-start gap-3 rounded-xl border border-emerald-300 bg-emerald-50 p-3 text-emerald-950 shadow-sm transition hover:border-emerald-400 hover:bg-emerald-100/80 focus-within:border-emerald-500 focus-within:bg-emerald-100/80 focus-within:ring-2 focus-within:ring-emerald-400/30 active:bg-emerald-100/80 dark:border-emerald-900 dark:bg-emerald-950/60 dark:text-emerald-100 dark:hover:border-emerald-700 dark:hover:bg-emerald-900/50 dark:focus-within:bg-emerald-900/50">
|
||||
<input type="radio" name="internal" value="0" @checked(! old('internal')) class="mt-1 border-emerald-400 text-emerald-600 focus:ring-emerald-500">
|
||||
<span>
|
||||
<span class="block text-sm font-extrabold">Public reply</span>
|
||||
@@ -542,7 +542,7 @@
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<label class="flex cursor-pointer items-start gap-3 rounded-xl border border-purple-300 bg-purple-50 p-3 text-purple-950 shadow-sm transition hover:bg-purple-100 dark:border-purple-900 dark:bg-purple-950/60 dark:text-purple-100">
|
||||
<label class="flex cursor-pointer items-start gap-3 rounded-xl border border-purple-300 bg-purple-50 p-3 text-purple-950 shadow-sm transition hover:border-purple-400 hover:bg-purple-100/80 focus-within:border-purple-500 focus-within:bg-purple-100/80 focus-within:ring-2 focus-within:ring-purple-400/30 active:bg-purple-100/80 dark:border-purple-900 dark:bg-purple-950/60 dark:text-purple-100 dark:hover:border-purple-700 dark:hover:bg-purple-900/50 dark:focus-within:bg-purple-900/50">
|
||||
<input type="radio" name="internal" value="1" @checked((bool) old('internal')) class="mt-1 border-purple-400 text-purple-600 focus:ring-purple-500">
|
||||
<span>
|
||||
<span class="block text-sm font-extrabold">Internal note</span>
|
||||
@@ -643,6 +643,13 @@
|
||||
return;
|
||||
}
|
||||
|
||||
const copyBranchButton = event.target.closest('[data-helpdesk-copy-branch-command]');
|
||||
|
||||
if (copyBranchButton) {
|
||||
copyHelpdeskBranchCommand(copyBranchButton);
|
||||
return;
|
||||
}
|
||||
|
||||
const replyButton = event.target.closest('[data-helpdesk-reply-toggle]');
|
||||
|
||||
if (!replyButton) {
|
||||
@@ -695,6 +702,12 @@
|
||||
});
|
||||
}
|
||||
|
||||
const branchSuffix = event.target.closest('[data-helpdesk-branch-suffix]');
|
||||
|
||||
if (branchSuffix) {
|
||||
updateHelpdeskBranchCommand(branchSuffix.closest('[data-helpdesk-branch-command]'));
|
||||
}
|
||||
|
||||
const fileInput = event.target.closest('[data-helpdesk-file-input]');
|
||||
|
||||
if (fileInput) {
|
||||
@@ -712,6 +725,66 @@
|
||||
}
|
||||
});
|
||||
|
||||
function updateHelpdeskBranchCommand(container) {
|
||||
if (!container) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const prefix = container.dataset.helpdeskBranchPrefix || '';
|
||||
const input = container.querySelector('[data-helpdesk-branch-suffix]');
|
||||
const output = container.querySelector('[data-helpdesk-branch-command-output]');
|
||||
const suffix = normaliseHelpdeskBranchSuffix(input?.value || 'short-description');
|
||||
const command = `${prefix}${suffix}`;
|
||||
|
||||
if (output) {
|
||||
output.textContent = command;
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
function normaliseHelpdeskBranchSuffix(value) {
|
||||
const slug = String(value || '')
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/[^a-z0-9]+/g, '-')
|
||||
.replace(/^-+|-+$/g, '')
|
||||
.replace(/-{2,}/g, '-');
|
||||
|
||||
return slug || 'short-description';
|
||||
}
|
||||
|
||||
async function copyHelpdeskBranchCommand(button) {
|
||||
const container = button.closest('[data-helpdesk-branch-command]');
|
||||
const status = container?.querySelector('[data-helpdesk-branch-copy-status]');
|
||||
const command = updateHelpdeskBranchCommand(container);
|
||||
|
||||
if (!command) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(command);
|
||||
} catch (error) {
|
||||
const fallback = document.createElement('textarea');
|
||||
fallback.value = command;
|
||||
fallback.setAttribute('readonly', 'readonly');
|
||||
fallback.style.position = 'fixed';
|
||||
fallback.style.opacity = '0';
|
||||
document.body.appendChild(fallback);
|
||||
fallback.select();
|
||||
document.execCommand('copy');
|
||||
fallback.remove();
|
||||
}
|
||||
|
||||
if (status) {
|
||||
status.classList.remove('hidden');
|
||||
window.setTimeout(() => status.classList.add('hidden'), 2200);
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelectorAll('[data-helpdesk-branch-command]').forEach(updateHelpdeskBranchCommand);
|
||||
|
||||
function updateCommentToggleButtons() {
|
||||
const commentCards = Array.from(document.querySelectorAll('[data-helpdesk-comment-card]'));
|
||||
const expandButton = document.querySelector('[data-helpdesk-expand-comments]');
|
||||
@@ -1222,24 +1295,80 @@
|
||||
<i class="fa-solid fa-code-branch text-lg" aria-hidden="true"></i>
|
||||
</span>
|
||||
<div class="min-w-0">
|
||||
<h2 class="text-lg font-black uppercase tracking-wide">Git commits</h2>
|
||||
<p class="text-xs font-semibold text-violet-100">Code commits linked to this ticket</p>
|
||||
<h2 class="text-lg font-black uppercase tracking-wide">Git activity</h2>
|
||||
<p class="text-xs font-semibold text-violet-100">Branches and commits linked to this ticket</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@can('update', $ticket)
|
||||
<div class="mb-4 rounded-xl border border-violet-200 bg-violet-50/80 p-3 shadow-sm dark:border-violet-900/70 dark:bg-violet-950/30"
|
||||
data-helpdesk-branch-command
|
||||
data-helpdesk-branch-prefix="git checkout -b bugfix/{{ $ticket->reference }}-">
|
||||
<div class="flex items-start gap-3">
|
||||
<span class="mt-0.5 inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-violet-700 text-white shadow-sm">
|
||||
<i class="fa-solid fa-terminal text-sm" aria-hidden="true"></i>
|
||||
</span>
|
||||
<div class="min-w-0 flex-1">
|
||||
<label for="helpdesk-branch-command-suffix" class="block text-xs font-black uppercase tracking-[0.16em] text-violet-900 dark:text-violet-100">
|
||||
Branch command
|
||||
</label>
|
||||
<p class="mt-1 text-xs font-semibold text-violet-800/80 dark:text-violet-200/80">
|
||||
Ticket reference is fixed. Enter the short branch description after {{ $ticket->reference }}-.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 grid gap-2">
|
||||
<div class="flex flex-col gap-2 sm:flex-row">
|
||||
<div class="flex min-h-10 flex-1 overflow-hidden rounded-lg border border-violet-200 bg-white shadow-sm focus-within:border-violet-500 focus-within:ring-2 focus-within:ring-violet-400/30 dark:border-violet-800 dark:bg-zinc-950">
|
||||
<span class="hidden items-center border-r border-violet-100 bg-violet-100/70 px-3 font-mono text-[0.68rem] font-black text-violet-900 dark:border-violet-900 dark:bg-violet-950 dark:text-violet-100 sm:inline-flex">
|
||||
bugfix/{{ $ticket->reference }}-
|
||||
</span>
|
||||
<input id="helpdesk-branch-command-suffix" type="text" inputmode="text" autocomplete="off" spellcheck="false"
|
||||
value="helpdesk-ticket-branch-linking"
|
||||
class="min-h-10 flex-1 border-0 bg-transparent px-3 py-2 font-mono text-xs font-semibold text-zinc-900 outline-none placeholder:text-zinc-400 focus:ring-0 dark:text-zinc-100"
|
||||
placeholder="short-description"
|
||||
data-helpdesk-branch-suffix>
|
||||
</div>
|
||||
|
||||
<button type="button"
|
||||
class="inline-flex min-h-10 items-center justify-center rounded-lg bg-violet-700 px-3 py-2 text-xs font-black text-white shadow-sm transition hover:bg-violet-800 focus:outline-none focus:ring-2 focus:ring-violet-400/70"
|
||||
data-helpdesk-copy-branch-command>
|
||||
<i class="fa-solid fa-copy mr-2" aria-hidden="true"></i>
|
||||
Copy command
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<code class="block overflow-x-auto rounded-lg border border-violet-100 bg-white/80 px-3 py-2 font-mono text-[0.68rem] font-bold text-violet-950 dark:border-violet-900 dark:bg-zinc-950/80 dark:text-violet-100"
|
||||
data-helpdesk-branch-command-output>git checkout -b bugfix/{{ $ticket->reference }}-helpdesk-ticket-branch-linking</code>
|
||||
<p class="hidden text-xs font-bold text-emerald-700 dark:text-emerald-300" data-helpdesk-branch-copy-status>
|
||||
Copied to clipboard.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@endcan
|
||||
|
||||
<div class="space-y-2">
|
||||
@forelse ($ticket->gitCommits as $commit)
|
||||
<a href="{{ $commit->url ?: '#' }}" target="_blank"
|
||||
class="block rounded-lg border border-zinc-100 p-2 dark:border-zinc-800">
|
||||
<div class="font-mono text-[0.68rem] text-zinc-500">{{ $commit->short_hash }} ·
|
||||
{{ $commit->repository?->name }}</div>
|
||||
<div class="font-mono text-[0.68rem] text-zinc-500">
|
||||
{{ $commit->short_hash === 'branch' ? 'branch' : $commit->short_hash }} ·
|
||||
{{ $commit->repository?->name }}
|
||||
</div>
|
||||
@if ($commit->branch)
|
||||
<div class="mt-1 break-words font-mono text-[0.68rem] font-semibold text-violet-700 dark:text-violet-300">
|
||||
{{ $commit->branch }}
|
||||
</div>
|
||||
@endif
|
||||
<div class="mt-1 text-xs font-medium text-zinc-900 dark:text-zinc-100">
|
||||
{{ $commit->message }}</div>
|
||||
{{ $commit->message }}
|
||||
</div>
|
||||
</a>
|
||||
@empty
|
||||
<div
|
||||
class="rounded-lg border border-dashed border-zinc-300 p-3 text-center text-xs text-zinc-500 dark:border-zinc-700">
|
||||
No commits linked.
|
||||
No Git activity linked.
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
@@ -202,6 +202,7 @@
|
||||
class="mb-2 block text-sm font-bold text-zinc-700 dark:text-zinc-200">Subject</label>
|
||||
<input id="reply-subject-{{ $comment->id }}" name="subject"
|
||||
value="{{ old('subject', 'RE: ' . $commentSubject) }}"
|
||||
spellcheck="true" lang="en-GB" autocorrect="on" autocomplete="on" autocapitalize="sentences" inputmode="text"
|
||||
class="block w-full rounded-xl border border-zinc-300 bg-white p-3 text-sm font-semibold text-zinc-900 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100">
|
||||
</div>
|
||||
<label for="reply-body-{{ $comment->id }}"
|
||||
@@ -232,7 +233,7 @@
|
||||
@can('update', $currentTicket)
|
||||
@if ($canSeeInternalNotes)
|
||||
<div class="mt-3 grid gap-3 sm:grid-cols-2">
|
||||
<label class="flex cursor-pointer items-start gap-3 rounded-xl border border-emerald-300 bg-emerald-50 p-3 text-emerald-950 shadow-sm transition hover:bg-emerald-100 dark:border-emerald-900 dark:bg-emerald-950/60 dark:text-emerald-100">
|
||||
<label class="flex cursor-pointer items-start gap-3 rounded-xl border border-emerald-300 bg-emerald-50 p-3 text-emerald-950 shadow-sm transition hover:border-emerald-400 hover:bg-emerald-100/80 focus-within:border-emerald-500 focus-within:bg-emerald-100/80 focus-within:ring-2 focus-within:ring-emerald-400/30 active:bg-emerald-100/80 dark:border-emerald-900 dark:bg-emerald-950/60 dark:text-emerald-100 dark:hover:border-emerald-700 dark:hover:bg-emerald-900/50 dark:focus-within:bg-emerald-900/50">
|
||||
<input type="radio" name="internal" value="0" checked class="mt-1 border-emerald-400 text-emerald-600 focus:ring-emerald-500">
|
||||
<span>
|
||||
<span class="block text-sm font-extrabold">Public reply</span>
|
||||
@@ -240,7 +241,7 @@
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<label class="flex cursor-pointer items-start gap-3 rounded-xl border border-purple-300 bg-purple-50 p-3 text-purple-950 shadow-sm transition hover:bg-purple-100 dark:border-purple-900 dark:bg-purple-950/60 dark:text-purple-100">
|
||||
<label class="flex cursor-pointer items-start gap-3 rounded-xl border border-purple-300 bg-purple-50 p-3 text-purple-950 shadow-sm transition hover:border-purple-400 hover:bg-purple-100/80 focus-within:border-purple-500 focus-within:bg-purple-100/80 focus-within:ring-2 focus-within:ring-purple-400/30 active:bg-purple-100/80 dark:border-purple-900 dark:bg-purple-950/60 dark:text-purple-100 dark:hover:border-purple-700 dark:hover:bg-purple-900/50 dark:focus-within:bg-purple-900/50">
|
||||
<input type="radio" name="internal" value="1" class="mt-1 border-purple-400 text-purple-600 focus:ring-purple-500">
|
||||
<span>
|
||||
<span class="block text-sm font-extrabold">Internal note</span>
|
||||
|
||||
@@ -47,8 +47,9 @@ final class GitSpellcheckSettingsUiFilesTest extends TestCase
|
||||
$ticketShowContents = file_get_contents($ticketShow) ?: '';
|
||||
$commentThreadContents = file_get_contents($commentThread) ?: '';
|
||||
|
||||
self::assertStringContainsString('contenteditable="true" spellcheck="true" lang="en-GB"', $ticketShowContents);
|
||||
self::assertStringContainsString('contenteditable="true" role="textbox" aria-multiline="true" spellcheck="true" lang="en-GB"', $ticketShowContents);
|
||||
self::assertStringContainsString('name="commentBody" required spellcheck="true" lang="en-GB"', $ticketShowContents);
|
||||
self::assertStringContainsString('data-helpdesk-comment-subject', $ticketShowContents);
|
||||
self::assertStringContainsString('spellcheck="true" lang="en-GB" autocorrect="on"', $commentThreadContents);
|
||||
self::assertStringContainsString('autocapitalize="sentences" inputmode="text"', $commentThreadContents);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* TicketBranchCommandUiFilesTest.php
|
||||
*
|
||||
* Guards the ticket-level Git activity branch command builder and comment UI polish.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Tests\Feature;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class TicketBranchCommandUiFilesTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Ensure ticket Git activity exposes a professional branch command copy workflow.
|
||||
*/
|
||||
public function test_ticket_git_activity_has_branch_command_builder_and_copy_button(): void
|
||||
{
|
||||
$viewPath = dirname(__DIR__, 2) . '/Resources/views/livewire/ticket-show.blade.php';
|
||||
|
||||
self::assertFileExists($viewPath);
|
||||
|
||||
$view = file_get_contents($viewPath);
|
||||
|
||||
self::assertIsString($view);
|
||||
self::assertStringContainsString('data-helpdesk-branch-command', $view);
|
||||
self::assertStringContainsString('git checkout -b bugfix/{{ $ticket->reference }}-', $view);
|
||||
self::assertStringContainsString('data-helpdesk-branch-suffix', $view);
|
||||
self::assertStringContainsString('data-helpdesk-copy-branch-command', $view);
|
||||
self::assertStringContainsString('copyHelpdeskBranchCommand', $view);
|
||||
self::assertStringContainsString('normaliseHelpdeskBranchSuffix', $view);
|
||||
self::assertStringContainsString('Copied to clipboard.', $view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure visibility selectors keep their accent backgrounds during interaction.
|
||||
*/
|
||||
public function test_visibility_controls_keep_accent_backgrounds_on_hover_and_focus(): void
|
||||
{
|
||||
$ticketViewPath = dirname(__DIR__, 2) . '/Resources/views/livewire/ticket-show.blade.php';
|
||||
$threadViewPath = dirname(__DIR__, 2) . '/Resources/views/partials/comment-thread.blade.php';
|
||||
|
||||
$ticketView = file_get_contents($ticketViewPath);
|
||||
$threadView = file_get_contents($threadViewPath);
|
||||
|
||||
self::assertIsString($ticketView);
|
||||
self::assertIsString($threadView);
|
||||
self::assertStringContainsString('hover:bg-emerald-100/80', $ticketView);
|
||||
self::assertStringContainsString('focus-within:bg-emerald-100/80', $ticketView);
|
||||
self::assertStringContainsString('hover:bg-purple-100/80', $ticketView);
|
||||
self::assertStringContainsString('focus-within:bg-purple-100/80', $ticketView);
|
||||
self::assertStringContainsString('hover:bg-emerald-100/80', $threadView);
|
||||
self::assertStringContainsString('hover:bg-purple-100/80', $threadView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure ticket comments and threaded replies expose browser spelling hints.
|
||||
*/
|
||||
public function test_ticket_comment_subjects_and_bodies_enable_spellcheck(): void
|
||||
{
|
||||
$ticketViewPath = dirname(__DIR__, 2) . '/Resources/views/livewire/ticket-show.blade.php';
|
||||
$threadViewPath = dirname(__DIR__, 2) . '/Resources/views/partials/comment-thread.blade.php';
|
||||
|
||||
$ticketView = file_get_contents($ticketViewPath);
|
||||
$threadView = file_get_contents($threadViewPath);
|
||||
|
||||
self::assertIsString($ticketView);
|
||||
self::assertIsString($threadView);
|
||||
self::assertStringContainsString('data-helpdesk-comment-subject', $ticketView);
|
||||
self::assertStringContainsString('spellcheck="true" lang="en-GB" autocorrect="on" autocomplete="on" autocapitalize="sentences" inputmode="text"', $ticketView);
|
||||
self::assertStringContainsString('role="textbox" aria-multiline="true" spellcheck="true"', $ticketView);
|
||||
self::assertStringContainsString('id="reply-subject-{{ $comment->id }}"', $threadView);
|
||||
self::assertStringContainsString('spellcheck="true" lang="en-GB" autocorrect="on" autocomplete="on" autocapitalize="sentences" inputmode="text"', $threadView);
|
||||
}
|
||||
}
|
||||
@@ -573,3 +573,26 @@
|
||||
- Added regression coverage for create/edit spellcheck wiring and directly linked Git commit visibility for ticket-level views.
|
||||
- Preserved append-only changelog history.
|
||||
|
||||
|
||||
- version: 1.10.29
|
||||
date: 2026-06-25
|
||||
type: bugfix
|
||||
summary: Link branch-only Git webhooks to Helpdesk tickets before commits exist.
|
||||
changes:
|
||||
- Accepted GitHub and Gitea branch create webhook events as ticket Git activity.
|
||||
- Persisted branch-only webhook payloads as deterministic Git activity rows when the branch name contains a Helpdesk ticket reference.
|
||||
- Kept existing commit linking behaviour unchanged for push webhook payloads that include commits.
|
||||
- Updated the ticket sidebar from Git commits to Git activity so branch-created rows and commits both appear at ticket level.
|
||||
- Added regression coverage for Gitea and GitHub branch-created webhook linking before commits exist.
|
||||
- Preserved append-only changelog history.
|
||||
|
||||
- version: 1.10.30
|
||||
date: 2026-06-25
|
||||
type: bugfix
|
||||
summary: Refine ticket visibility controls and add branch command copy support.
|
||||
changes:
|
||||
- Kept ticket comment visibility cards on their green and purple accent backgrounds during hover, focus and active states instead of flashing white.
|
||||
- Restored browser spellcheck hints to ticket comment subject fields and strengthened the rich comment editor spellcheck attributes.
|
||||
- Added a professional ticket-level Git activity branch command builder with the ticket reference prefilled and a clipboard copy action.
|
||||
- Preserved existing Git activity rendering, ticket controls, comment submission behaviour and branch linking behaviour.
|
||||
- Preserved append-only changelog history.
|
||||
|
||||
@@ -23,5 +23,5 @@
|
||||
"Modules\\Helpdesk\\Providers\\HelpdeskServiceProvider"
|
||||
],
|
||||
"files": [],
|
||||
"version": "1.10.28"
|
||||
"version": "1.10.30"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user