From 96780b72e85745ab3c30f25cc78abd357a93bee3 Mon Sep 17 00:00:00 2001
From: Caen De Silva <caen@desilva.se>
Date: Fri, 10 Nov 2023 21:16:11 +0100
Subject: [PATCH] Add dashboard hook to interact with fancy serve command
 output

Allows the dashboard to send messages to the new fancy console provided by https://github.com/hydephp/develop/pull/1444
---
 .../realtime-compiler/src/ConsoleOutput.php   | 25 ++++++++++++++++---
 .../src/Http/DashboardController.php          |  3 +++
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/packages/realtime-compiler/src/ConsoleOutput.php b/packages/realtime-compiler/src/ConsoleOutput.php
index c37f8400634..03a04e3b0b6 100644
--- a/packages/realtime-compiler/src/ConsoleOutput.php
+++ b/packages/realtime-compiler/src/ConsoleOutput.php
@@ -17,6 +17,7 @@
 use function sprintf;
 use function str_repeat;
 use function str_replace;
+use function str_contains;
 use function Termwind\render;
 
 class ConsoleOutput
@@ -60,6 +61,13 @@ public static function getFormatter(bool $verbose): Closure
         };
     }
 
+    /** @experimental */
+    public static function printMessage(string $message, string $context): void
+    {
+        $consoleOutput = new \Symfony\Component\Console\Output\ConsoleOutput();
+        $consoleOutput->writeln(sprintf('%s [%s]', $message, $context));
+    }
+
     public function __construct(bool $verbose = false)
     {
         $this->verbose = $verbose;
@@ -87,6 +95,13 @@ protected function formatLineForOutput(string $line): ?string
         if (str_ends_with(trim($line), 'Accepted') || str_ends_with(trim($line), 'Closing')) {
             return $this->verbose ? $this->formatRequestStatusLine($line) : null;
         }
+        if (str_contains($line, '[dashboard@')) {
+            $message = trim(Str::before($line, '[dashboard@'));
+            $context = trim(trim(Str::after($line, $message)), '[]');
+            $success = str_contains($message, 'Created') || str_contains($message, 'Updated');
+
+            return $this->formatLine($message, Carbon::now(), $success ? 'green-500' : 'blue-500', $context);
+        }
 
         return $this->formatLine($line, Carbon::now());
     }
@@ -118,18 +133,22 @@ protected function formatRequestStatusLine(string $line): string
         return $this->formatLine(sprintf('%s %s', $address, $status), $this->parseDate($line));
     }
 
-    protected function formatLine(string $message, Carbon $date, string $iconColor = 'blue-500'): string
+    protected static function formatLine(string $message, Carbon $date, string $iconColor = 'blue-500', string $context = ''): string
     {
+        if ($context) {
+            $context = "$context ";
+        }
+
         return sprintf(<<<'HTML'
             <div class="flex w-full justify-between">
                 <span>
                     <span class="text-%s">i</span>
                     %s
                 </span>
-                <span class="text-gray">%s</span>
+                <span class="text-gray">%s%s</span>
             </div>
             HTML,
-            $iconColor, $message, $date->format('Y-m-d H:i:s')
+            $iconColor, $message, $context, $date->format('Y-m-d H:i:s')
         );
     }
 
diff --git a/packages/realtime-compiler/src/Http/DashboardController.php b/packages/realtime-compiler/src/Http/DashboardController.php
index bb1a1ead4cc..6af6559679f 100644
--- a/packages/realtime-compiler/src/Http/DashboardController.php
+++ b/packages/realtime-compiler/src/Http/DashboardController.php
@@ -20,6 +20,7 @@
 use Desilva\Microserve\JsonResponse;
 use Hyde\Support\Filesystem\MediaFile;
 use Illuminate\Support\Facades\Process;
+use Hyde\RealtimeCompiler\ConsoleOutput;
 use Hyde\Framework\Actions\StaticPageBuilder;
 use Hyde\Framework\Actions\AnonymousViewCompiler;
 use Desilva\Microserve\Request;
@@ -353,6 +354,8 @@ protected function createPage(): void
             $this->abort($exception->getCode(), $exception->getMessage());
         }
 
+        ConsoleOutput::printMessage("Created file '$path'", 'dashboard@createPage');
+
         $this->flash('justCreatedPage', RouteKey::fromPage($pageClass, $pageClass::pathToIdentifier($path))->get());
         $this->setJsonResponse(201, "Created file '$path'!");
     }