diff --git a/app/Console/Commands/AddChannelPermissions.php b/app/Console/Commands/AddChannelPermissions.php index 7c16a59..3c8fa59 100644 --- a/app/Console/Commands/AddChannelPermissions.php +++ b/app/Console/Commands/AddChannelPermissions.php @@ -47,7 +47,6 @@ class AddChannelPermissions extends Command */ public function handle() { - // Give the user a list of channels to choose from. $channels = TraceChannel::all(); $channel = $this->choice('Which channel would you like to add permissions to?', $channels->pluck('channel_login')->toArray()); $channel = $channels->where('channel_login', $channel)->first(); @@ -64,7 +63,6 @@ public function handle() $users = array_values($users); - // Get the user details from the Twitch API. $response = Http::get($this->usersApi, [ 'login' => $users, ]); diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index c855b7b..c50f49c 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -21,10 +21,11 @@ public function index(Request $request) public function channel(ChannelActionsRequest $request, Channel $channel) { $limit = $request->input('limit', 50); + $actions = $channel->actions()->orderBy('timestamp', 'desc')->paginate($limit); return view('dashboard.channel', [ 'channel' => $channel, - 'actions' => $channel->actions()->orderBy('timestamp', 'desc')->paginate($limit), + 'actions' => $actions, ]); } } diff --git a/app/Http/Controllers/ViewerController.php b/app/Http/Controllers/ViewerController.php new file mode 100644 index 0000000..4a07fab --- /dev/null +++ b/app/Http/Controllers/ViewerController.php @@ -0,0 +1,39 @@ +where('author_login', $viewerId) + ->firstOrFail(); + $viewerId = $message->author_id; + } + + // Check if viewerId exists + $initialMessage = Message::orderBy('timestamp', 'desc') + ->where('author_id', $viewerId) + ->firstOrFail(); + + // Get distinct author_login based on author_id + $usernames = Message::where('author_id', $viewerId) + ->distinct('author_login') + ->get() + ->pluck('author_login') + ->toArray(); + + return view('viewer.index', [ + 'id' => $viewerId, + 'username' => $initialMessage->author_login, + 'usernames' => $usernames, + ]); + } +} diff --git a/app/Models/Trace/ModeratorAction.php b/app/Models/Trace/ModeratorAction.php index 7ea291f..7ef5d5a 100644 --- a/app/Models/Trace/ModeratorAction.php +++ b/app/Models/Trace/ModeratorAction.php @@ -20,7 +20,7 @@ class ModeratorAction extends Model * * @return string */ - public function formatted() : string + public function formatted($asHtml = false) : string { $cmd = $this->action; $discriminator = $this->discriminator; @@ -38,7 +38,12 @@ public function formatted() : string } if ($cmd === 'delete') { - return sprintf('/%s %s %s %s', $cmd, $this->targetName(), $this->message, $this->message_id); + $message = $this->message; + if ($asHtml) { + $message = htmlspecialchars($message); + } + + return sprintf('/%s %s %s %s', $cmd, $this->targetName(), $message, $this->message_id); } /** @@ -46,11 +51,21 @@ public function formatted() : string */ if ($cmd === 'timeout') { $duration = $this->timeout_duration; - return sprintf('/%s %s %s %s', $cmd, $this->targetName(), $duration, $this->timeout_reason ?? ''); + $reason = $this->timeout_reason; + if ($asHtml) { + $reason = htmlspecialchars($reason); + } + + return sprintf('/%s %s %s %s', $cmd, $this->targetName(), $duration, $reason ?? ''); } if ($discriminator === 'TermAction') { - return sprintf('/%s %s %s', $cmd, $this->text, $this->term_id); + $text = $this->text; + if ($asHtml) { + $text = htmlspecialchars($text); + } + + return sprintf('/%s %s %s', $cmd, $text, $this->term_id); } return trim(sprintf('/%s %s', $cmd, $this->targetName())); diff --git a/resources/views/dashboard/channel.blade.php b/resources/views/dashboard/channel.blade.php index c188f5f..3e4c4e1 100644 --- a/resources/views/dashboard/channel.blade.php +++ b/resources/views/dashboard/channel.blade.php @@ -32,6 +32,7 @@ @endforeach + @if ($actions->hasPages()) @@ -39,6 +40,7 @@ + @endif diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index ddf1e8f..b896d85 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -14,8 +14,8 @@ @vite(['resources/css/app.css', 'resources/js/app.js']) - -
+ +
@@ -34,13 +34,14 @@

This is the initial implementation of this project. A few different things that are planned:

    -
  • Channels that are tracked where you have moderator access will be automatically retrieved from Twitch's API. At the moment you have to be manually added to the database.
  • +
  • Channels that are tracked where you have moderator access will be automatically retrieved from Twitch's API upon login. At the moment I have to manually give permissions via the database.
  • Different filtering options: Type of action (timeout, raid etc.), moderator (whodunit), user/viewer (next point).
  • See related moderation actions, for example if a specific viewer has been timed out or banned multiple times.
  • Searching by text.
  • Linking any affected viewer's to their Twitch viewer card.
  • Automatic conversion to local time. Currently it's displayed in UTC.
  • Ability to see a viewer's chat messages at the time of action, alongside messages before/after to see context.
  • +
  • Username history of a user
  • ... and probably more I'll figure out as I go along.
@@ -49,9 +50,25 @@
-
+
{{ $slot }}
+ + + diff --git a/resources/views/vendor/pagination/tailwind.blade.php b/resources/views/vendor/pagination/tailwind.blade.php index a81609d..3cce9a5 100644 --- a/resources/views/vendor/pagination/tailwind.blade.php +++ b/resources/views/vendor/pagination/tailwind.blade.php @@ -63,7 +63,7 @@ {{-- "Three Dots" Separator --}} @if (is_string($element)) - {{ $element }} + {{ $element }} @endif diff --git a/resources/views/viewer/index.blade.php b/resources/views/viewer/index.blade.php new file mode 100644 index 0000000..24d7790 --- /dev/null +++ b/resources/views/viewer/index.blade.php @@ -0,0 +1,28 @@ + + +

+ {{ __('Viewer Details') }} +

+
+ +
+
+
+
+

+ Viewer details for: {{ $username }} [{{ $id }}] +

+ +

Seen under the following usernames:

+ + +
    + @foreach ($usernames as $username) +
  • {{ $username }}
  • + @endforeach +
+
+
+
+
+
diff --git a/routes/auth.php b/routes/auth.php index fa56c0d..df1e4f3 100644 --- a/routes/auth.php +++ b/routes/auth.php @@ -2,6 +2,7 @@ use App\Http\Controllers\Auth\TwitchController; use App\Http\Controllers\DashboardController; +use App\Http\Controllers\ViewerController; use Illuminate\Support\Facades\Route; Route::middleware('guest')->group(function () { @@ -16,6 +17,9 @@ Route::get('/channel/{channel}', [DashboardController::class, 'channel']) ->name('dashboard.channel'); + Route::get('/viewer/{viewerId}', [ViewerController::class, 'index']) + ->name('viewer'); + Route::post('logout', [TwitchController::class, 'logout']) ->name('logout'); });