From 8721719cd7cf32e94823541eafaba1e9309355a8 Mon Sep 17 00:00:00 2001
From: Yassine Doghri <yassine@doghri.fr>
Date: Wed, 19 Jan 2022 18:31:57 +0000
Subject: [PATCH] feat(vite): add vite config to decouple it from
 CI_ENVIRONMENT

---
 app/Config/Autoload.php                |  1 +
 app/Config/Services.php                | 10 ----
 app/Entities/Media/Image.php           | 12 +----
 app/Language/en/Podcast.php            |  2 -
 app/Language/fr/Podcast.php            |  2 -
 app/Libraries/Vite/Config/Services.php | 30 ++++++++++++
 app/Libraries/Vite/Config/Vite.php     | 20 ++++++++
 app/Libraries/{ => Vite}/Vite.php      | 63 +++++++++++++++-----------
 docs/setup-development.md              |  2 +
 modules/Admin/Language/en/Podcast.php  |  2 -
 modules/Admin/Language/fr/Podcast.php  |  2 -
 themes/cp_app/podcast/episodes.php     |  1 -
 12 files changed, 92 insertions(+), 55 deletions(-)
 create mode 100644 app/Libraries/Vite/Config/Services.php
 create mode 100644 app/Libraries/Vite/Config/Vite.php
 rename app/Libraries/{ => Vite}/Vite.php (54%)

diff --git a/app/Config/Autoload.php b/app/Config/Autoload.php
index b9de27b250..4d0d63009b 100644
--- a/app/Config/Autoload.php
+++ b/app/Config/Autoload.php
@@ -53,6 +53,7 @@ class Autoload extends AutoloadConfig
         'ViewComponents' => APPPATH . 'Libraries/ViewComponents/',
         'ViewThemes' => APPPATH . 'Libraries/ViewThemes/',
         'MediaClipper' => APPPATH . 'Libraries/MediaClipper/',
+        'Vite' => APPPATH . 'Libraries/Vite/',
         'Themes' => ROOTPATH . 'themes',
     ];
 
diff --git a/app/Config/Services.php b/app/Config/Services.php
index a0e120af63..88da0c416a 100644
--- a/app/Config/Services.php
+++ b/app/Config/Services.php
@@ -8,7 +8,6 @@ use App\Libraries\Breadcrumb;
 use App\Libraries\Negotiate;
 use App\Libraries\Router;
 use App\Libraries\View;
-use App\Libraries\Vite;
 use CodeIgniter\Config\BaseService;
 use CodeIgniter\HTTP\Request;
 use CodeIgniter\HTTP\RequestInterface;
@@ -92,13 +91,4 @@ class Services extends BaseService
 
         return new Breadcrumb();
     }
-
-    public static function vite(bool $getShared = true): Vite
-    {
-        if ($getShared) {
-            return self::getSharedInstance('vite');
-        }
-
-        return new Vite();
-    }
 }
diff --git a/app/Entities/Media/Image.php b/app/Entities/Media/Image.php
index 4c00c67b57..833670fec2 100644
--- a/app/Entities/Media/Image.php
+++ b/app/Entities/Media/Image.php
@@ -34,16 +34,8 @@ class Image extends BaseMedia
         helper('media');
 
         foreach ($this->sizes as $name => $size) {
-            if (array_key_exists('extension', $size)) {
-                $extension = $size['extension'];
-            } else {
-                $extension = $this->file_extension;
-            }
-            if (array_key_exists('mimetype', $size)) {
-                $mimetype = $size['mimetype'];
-            } else {
-                $mimetype = $this->file_mimetype;
-            }
+            $extension = array_key_exists('extension', $size) ? $size['extension'] : $this->file_extension;
+            $mimetype = array_key_exists('mimetype', $size) ? $size['mimetype'] : $this->file_mimetype;
             $this->{$name . '_path'} = $this->file_directory . '/' . $this->file_name . '_' . $name . '.' . $extension;
             $this->{$name . '_url'} = media_base_url($this->{$name . '_path'});
             $this->{$name . '_mimetype'} = $mimetype;
diff --git a/app/Language/en/Podcast.php b/app/Language/en/Podcast.php
index d86ce16518..3aef56e5a0 100644
--- a/app/Language/en/Podcast.php
+++ b/app/Language/en/Podcast.php
@@ -15,8 +15,6 @@ return [
     'list_of_episodes_season' =>
         'Season {seasonNumber} episodes ({episodeCount})',
     'no_episode' => 'No episode found!',
-    'no_episode_hint' =>
-        'Navigate the podcast episodes with the navigation bar above.',
     'follow' => 'Follow',
     'followTitle' => 'Follow {actorDisplayName} on the fediverse!',
     'followers' => '{numberOfFollowers, plural,
diff --git a/app/Language/fr/Podcast.php b/app/Language/fr/Podcast.php
index 1b0df14b68..c876515eed 100644
--- a/app/Language/fr/Podcast.php
+++ b/app/Language/fr/Podcast.php
@@ -15,8 +15,6 @@ return [
     'list_of_episodes_season' =>
         'Épisodes de la saison {seasonNumber} ({episodeCount})',
     'no_episode' => 'Aucun épisode trouvé !',
-    'no_episode_hint' =>
-        'Naviguez au sein des épisodes du podcast episodes grâce à la barre de navigation ci-dessus.',
     'follow' => 'Suivre',
     'followTitle' => 'Suivez {actorDisplayName} sur le fédiverse !',
     'followers' => '{numberOfFollowers, plural,
diff --git a/app/Libraries/Vite/Config/Services.php b/app/Libraries/Vite/Config/Services.php
new file mode 100644
index 0000000000..cd5adfdeac
--- /dev/null
+++ b/app/Libraries/Vite/Config/Services.php
@@ -0,0 +1,30 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Vite\Config;
+
+use CodeIgniter\Config\BaseService;
+use Vite\Vite;
+
+/**
+ * Services Configuration file.
+ *
+ * Services are simply other classes/libraries that the system uses to do its job. This is used by CodeIgniter to allow
+ * the core of the framework to be swapped out easily without affecting the usage within the rest of your application.
+ *
+ * This file holds any application-specific services, or service overrides that you might need. An example has been
+ * included with the general method format you should use for your service methods. For more examples, see the core
+ * Services file at system/Config/Services.php.
+ */
+class Services extends BaseService
+{
+    public static function vite(bool $getShared = true): Vite
+    {
+        if ($getShared) {
+            return self::getSharedInstance('vite');
+        }
+
+        return new Vite();
+    }
+}
diff --git a/app/Libraries/Vite/Config/Vite.php b/app/Libraries/Vite/Config/Vite.php
new file mode 100644
index 0000000000..88471e78bd
--- /dev/null
+++ b/app/Libraries/Vite/Config/Vite.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Vite\Config;
+
+use CodeIgniter\Config\BaseConfig;
+
+class Vite extends BaseConfig
+{
+    public string $environment = 'production';
+
+    public string $baseUrl = 'http://localhost:3000/';
+
+    public string $assetsRoot = 'assets';
+
+    public string $manifestFile = 'manifest.json';
+
+    public string $manifestCSSFile = 'manifest-css.json';
+}
diff --git a/app/Libraries/Vite.php b/app/Libraries/Vite/Vite.php
similarity index 54%
rename from app/Libraries/Vite.php
rename to app/Libraries/Vite/Vite.php
index b088f66b43..a7192eed13 100644
--- a/app/Libraries/Vite.php
+++ b/app/Libraries/Vite/Vite.php
@@ -2,14 +2,12 @@
 
 declare(strict_types=1);
 
-namespace App\Libraries;
+namespace Vite;
+
+use ErrorException;
 
 class Vite
 {
-    protected string $manifestPath = 'assets/manifest.json';
-
-    protected string $manifestCSSPath = 'assets/manifest-css.json';
-
     /**
      * @var array<string, mixed>
      */
@@ -22,17 +20,16 @@ class Vite
 
     public function asset(string $path, string $type): string
     {
-        if (ENVIRONMENT !== 'production') {
+        if (config('Vite')->environment !== 'production') {
             return $this->loadDev($path, $type);
         }
 
-        // @phpstan-ignore-next-line
         return $this->loadProd($path, $type);
     }
 
     private function loadDev(string $path, string $type): string
     {
-        return $this->getHtmlTag("http://localhost:3000/assets/{$path}", $type);
+        return $this->getHtmlTag(config('Vite')->baseUrl . config('Vite')->assetsRoot . "/{$path}", $type);
     }
 
     private function loadProd(string $path, string $type): string
@@ -41,35 +38,46 @@ class Vite
             if ($this->manifestCSSData === null) {
                 $cacheName = 'vite-manifest-css';
                 if (! ($cachedManifestCSS = cache($cacheName))) {
-                    if (($manifestCSSContent = file_get_contents($this->manifestCSSPath)) !== false) {
-                        $cachedManifestCSS = json_decode($manifestCSSContent, true);
-                        cache()
-                            ->save($cacheName, $cachedManifestCSS, DECADE);
-                    } else {
+                    $manifestCSSPath = config('Vite')
+                        ->assetsRoot . '/' . config('Vite')
+                        ->manifestCSSFile;
+                    try {
+                        if (($manifestCSSContent = file_get_contents($manifestCSSPath)) !== false) {
+                            $cachedManifestCSS = json_decode($manifestCSSContent, true);
+                            cache()
+                                ->save($cacheName, $cachedManifestCSS, DECADE);
+                        }
+                    } catch (ErrorException) {
                         // ERROR when getting the manifest-css file
-                        $manifestCSSPath = $this->manifestCSSPath;
-                        die("Could not load Vite's <pre>{$manifestCSSPath}</pre> file.");
+                        die("Could not load css manifest: <strong>{$manifestCSSPath}</strong> file not found!");
                     }
                 }
                 $this->manifestCSSData = $cachedManifestCSS;
             }
 
             if (array_key_exists($path, $this->manifestCSSData)) {
-                return $this->getHtmlTag('/assets/' . $this->manifestCSSData[$path]['file'], 'css');
+                return $this->getHtmlTag(
+                    '/' . config('Vite')->assetsRoot . '/' . $this->manifestCSSData[$path]['file'],
+                    'css'
+                );
             }
         }
 
         if ($this->manifestData === null) {
             $cacheName = 'vite-manifest';
             if (! ($cachedManifest = cache($cacheName))) {
-                if (($manifestContents = file_get_contents($this->manifestPath)) !== false) {
-                    $cachedManifest = json_decode($manifestContents, true);
-                    cache()
-                        ->save($cacheName, $cachedManifest, DECADE);
-                } else {
+                $manifestPath = config('Vite')
+                    ->assetsRoot . '/' . config('Vite')
+                    ->manifestFile;
+                try {
+                    if (($manifestContents = file_get_contents($manifestPath)) !== false) {
+                        $cachedManifest = json_decode($manifestContents, true);
+                        cache()
+                            ->save($cacheName, $cachedManifest, DECADE);
+                    }
+                } catch (ErrorException) {
                     // ERROR when retrieving the manifest file
-                    $manifestPath = $this->manifestPath;
-                    die("Could not load Vite's <pre>{$manifestPath}</pre> file.");
+                    die("Could not load manifest: <strong>{$manifestPath}</strong> file not found!");
                 }
             }
             $this->manifestData = $cachedManifest;
@@ -82,7 +90,7 @@ class Vite
             // import css dependencies if any
             if (array_key_exists('css', $manifestElement)) {
                 foreach ($manifestElement['css'] as $cssFile) {
-                    $html .= $this->getHtmlTag('/assets/' . $cssFile, 'css');
+                    $html .= $this->getHtmlTag('/' . config('Vite')->assetsRoot . '/' . $cssFile, 'css');
                 }
             }
 
@@ -90,12 +98,15 @@ class Vite
             if (array_key_exists('imports', $manifestElement)) {
                 foreach ($manifestElement['imports'] as $importPath) {
                     if (array_key_exists($importPath, $this->manifestData)) {
-                        $html .= $this->getHtmlTag('/assets/' . $this->manifestData[$importPath]['file'], 'js');
+                        $html .= $this->getHtmlTag(
+                            '/' . config('Vite')->assetsRoot . '/' . $this->manifestData[$importPath]['file'],
+                            'js'
+                        );
                     }
                 }
             }
 
-            $html .= $this->getHtmlTag('/assets/' . $manifestElement['file'], $type);
+            $html .= $this->getHtmlTag('/' . config('Vite')->assetsRoot . '/' . $manifestElement['file'], $type);
         }
 
         return $html;
diff --git a/docs/setup-development.md b/docs/setup-development.md
index cfd2170939..6887349b77 100644
--- a/docs/setup-development.md
+++ b/docs/setup-development.md
@@ -42,6 +42,8 @@ to help you kickstart your contribution.
 
    ```ini
    CI_ENVIRONMENT="development"
+   # If set to development, you must run `npm run dev` to start the static assets server
+   vite.environment="development"
 
    # By default, this is set to true in the app config.
    # For development, this must be set to false as it is
diff --git a/modules/Admin/Language/en/Podcast.php b/modules/Admin/Language/en/Podcast.php
index c1cd4cdcbc..739767e4ad 100644
--- a/modules/Admin/Language/en/Podcast.php
+++ b/modules/Admin/Language/en/Podcast.php
@@ -223,8 +223,6 @@ return [
     'list_of_episodes_season' =>
         'Season {seasonNumber} episodes ({episodeCount})',
     'no_episode' => 'No episode found!',
-    'no_episode_hint' =>
-        'Navigate the podcast episodes with the navigation bar above.',
     'follow' => 'Follow',
     'followers' => '{numberOfFollowers, plural,
         one {<span class="font-semibold">#</span> follower}
diff --git a/modules/Admin/Language/fr/Podcast.php b/modules/Admin/Language/fr/Podcast.php
index 3d207f04e6..3336fd5890 100644
--- a/modules/Admin/Language/fr/Podcast.php
+++ b/modules/Admin/Language/fr/Podcast.php
@@ -225,8 +225,6 @@ return [
     'list_of_episodes_season' =>
         'Épisodes de la saison {seasonNumber} ({episodeCount})',
     'no_episode' => 'Aucun épisode trouvé !',
-    'no_episode_hint' =>
-        'Naviguez au sein des épisodes du podcast episodes grâce à la barre de navigation ci-dessus.',
     'follow' => 'Suivre',
     'followers' => '{numberOfFollowers, plural,
         one {<span class="font-semibold">#</span> abonné·e}
diff --git a/themes/cp_app/podcast/episodes.php b/themes/cp_app/podcast/episodes.php
index 1db4ec29a8..faf6593161 100644
--- a/themes/cp_app/podcast/episodes.php
+++ b/themes/cp_app/podcast/episodes.php
@@ -50,7 +50,6 @@
     <h1 class="px-4 mb-2 text-xl text-center"><?= lang(
                 'Podcast.no_episode',
             ) ?></h1>
-    <p class="italic text-center"><?= lang('Podcast.no_episode_hint') ?></p>
 <?php endif; ?>
 
 <?= $this->endSection()
-- 
GitLab