feat(plugins): load and display LICENSE.md file if found in plugin's directory

This commit is contained in:
Yassine Doghri 2024-07-04 17:50:54 +00:00
parent 1a439083a2
commit fee7905935
6 changed files with 90 additions and 10 deletions

View File

@ -22,6 +22,7 @@ import ValidateFileSize from "./modules/ValidateFileSize";
import "./modules/video-clip-previewer"; import "./modules/video-clip-previewer";
import VideoClipBuilder from "./modules/VideoClipBuilder"; import VideoClipBuilder from "./modules/VideoClipBuilder";
import "./modules/xml-editor"; import "./modules/xml-editor";
import "@patternfly/elements/pf-tabs/pf-tabs.js";
Dropdown(); Dropdown();
Tooltip(); Tooltip();

View File

@ -17,6 +17,7 @@ Plugins are ways to extend Castopod's core features.
- … - …
- icon.svg - icon.svg
- manifest.json // required - manifest.json // required
- LICENSE.md
- Plugin.php // required - Plugin.php // required
- README.md - README.md
@ -97,6 +98,12 @@ through.
It should be used for any additional information to help guide the user in using It should be used for any additional information to help guide the user in using
the plugin. the plugin.
### Plugin LICENSE
In addition to specifying [the license in the manifest](./manifest#license), you
may add a `LICENSE.md` file. Just as the `README.md` file, its contents will be
loaded into the plugin's view page for the user to read.
### Plugin icon ### Plugin icon
The plugin icon is displayed next to its title, it is an SVG file intended to The plugin icon is displayed next to its title, it is an SVG file intended to

View File

@ -39,6 +39,8 @@ abstract class BasePlugin implements PluginInterface
protected ?string $readmeHTML; protected ?string $readmeHTML;
protected ?string $licenseHTML;
public function __construct( public function __construct(
protected string $vendor, protected string $vendor,
protected string $package, protected string $package,
@ -56,7 +58,9 @@ abstract class BasePlugin implements PluginInterface
$this->iconSrc = $this->loadIcon($directory . '/icon.svg'); $this->iconSrc = $this->loadIcon($directory . '/icon.svg');
$this->readmeHTML = $this->loadReadme($directory . '/README.md'); $this->readmeHTML = $this->loadMarkdownAsHTML($directory . '/README.md');
$this->licenseHTML = $this->loadMarkdownAsHTML($directory . '/LICENSE.md');
} }
/** /**
@ -270,6 +274,11 @@ abstract class BasePlugin implements PluginInterface
return $this->manifest->license ?? 'UNLICENSED'; return $this->manifest->license ?? 'UNLICENSED';
} }
final public function getLicenseHTML(): ?string
{
return $this->licenseHTML;
}
/** /**
* @param PluginStatus::ACTIVE|PluginStatus::INACTIVE $value * @param PluginStatus::ACTIVE|PluginStatus::INACTIVE $value
*/ */
@ -313,7 +322,7 @@ abstract class BasePlugin implements PluginInterface
); );
} }
private function loadReadme(string $path): ?string private function loadMarkdownAsHTML(string $path): ?string
{ {
// TODO: cache readme // TODO: cache readme
$readmeMD = @file_get_contents($path); $readmeMD = @file_get_contents($path);

View File

@ -40,6 +40,7 @@
"@github/hotkey": "^3.1.1", "@github/hotkey": "^3.1.1",
"@github/markdown-toolbar-element": "^2.2.3", "@github/markdown-toolbar-element": "^2.2.3",
"@github/relative-time-element": "^4.4.2", "@github/relative-time-element": "^4.4.2",
"@patternfly/elements": "^3.0.2",
"@tailwindcss/nesting": "0.0.0-insiders.565cd3e", "@tailwindcss/nesting": "0.0.0-insiders.565cd3e",
"@vime/core": "^5.4.1", "@vime/core": "^5.4.1",
"choices.js": "^10.2.0", "choices.js": "^10.2.0",

47
pnpm-lock.yaml generated
View File

@ -43,6 +43,9 @@ importers:
"@github/relative-time-element": "@github/relative-time-element":
specifier: ^4.4.2 specifier: ^4.4.2
version: 4.4.2 version: 4.4.2
"@patternfly/elements":
specifier: ^3.0.2
version: 3.0.2
"@tailwindcss/nesting": "@tailwindcss/nesting":
specifier: 0.0.0-insiders.565cd3e specifier: 0.0.0-insiders.565cd3e
version: 0.0.0-insiders.565cd3e(postcss@8.4.39) version: 0.0.0-insiders.565cd3e(postcss@8.4.39)
@ -2125,6 +2128,12 @@ packages:
integrity: sha512-yWJKmpGE6lUURKAaIltoPIE/wrbY3TEkqQt+X0m+7fQNnAv0keydnYvbiJFP1PnMhizmIWRWOG5KLhYyc/xl+g==, integrity: sha512-yWJKmpGE6lUURKAaIltoPIE/wrbY3TEkqQt+X0m+7fQNnAv0keydnYvbiJFP1PnMhizmIWRWOG5KLhYyc/xl+g==,
} }
"@lit/context@1.1.2":
resolution:
{
integrity: sha512-S0nw2C6Tkm7fVX5TGYqeROGD+Z9Coa2iFpW+ysYBDH3YvCqOY3wVQvSgwbaliLJkjTnSEYCBe9qFqKV8WUFpVw==,
}
"@lit/reactive-element@2.0.4": "@lit/reactive-element@2.0.4":
resolution: resolution:
{ {
@ -2233,6 +2242,24 @@ packages:
integrity: sha512-Y73oOAzRBAUzR/iRAbGULzpNkX8vaxKCqEtg6K74Ff3w9f5apFnWtE/2nade7dMWWW3bS5Kkd6DJS4HF04xreg==, integrity: sha512-Y73oOAzRBAUzR/iRAbGULzpNkX8vaxKCqEtg6K74Ff3w9f5apFnWtE/2nade7dMWWW3bS5Kkd6DJS4HF04xreg==,
} }
"@patternfly/elements@3.0.2":
resolution:
{
integrity: sha512-YsmDu0XP7YyWdwIKXQIvtI81JfQ9+R3QszKQyFlEuhiS1ufA86f7L/1toQvOhZgmEBfAitnJBejndYi5s13EGw==,
}
"@patternfly/icons@1.0.3":
resolution:
{
integrity: sha512-8BARaCFBUZU2/TxuOQb8R2/VIpxGMnFwdw5ddT1AMnR2KSifdo+d05SgZtVmFkOIAOA0oCo/YKRgSORDA47wig==,
}
"@patternfly/pfe-core@3.0.0":
resolution:
{
integrity: sha512-zxJ2dksvTsurQ74EHlNWv03P1HH/ZO+axX0XPyjDdkOWpbyL4UDK6x5VXDRRtiZ3CrRs7VX3RbBfB5EQ1gBZ5A==,
}
"@pkgjs/parseargs@0.11.0": "@pkgjs/parseargs@0.11.0":
resolution: resolution:
{ {
@ -10781,6 +10808,10 @@ snapshots:
"@lit-labs/ssr-dom-shim@1.2.0": {} "@lit-labs/ssr-dom-shim@1.2.0": {}
"@lit/context@1.1.2":
dependencies:
"@lit/reactive-element": 2.0.4
"@lit/reactive-element@2.0.4": "@lit/reactive-element@2.0.4":
dependencies: dependencies:
"@lit-labs/ssr-dom-shim": 1.2.0 "@lit-labs/ssr-dom-shim": 1.2.0
@ -10855,6 +10886,22 @@ snapshots:
dependencies: dependencies:
"@octokit/openapi-types": 22.1.0 "@octokit/openapi-types": 22.1.0
"@patternfly/elements@3.0.2":
dependencies:
"@lit/context": 1.1.2
"@patternfly/icons": 1.0.3
"@patternfly/pfe-core": 3.0.0
lit: 3.1.4
tslib: 2.6.2
"@patternfly/icons@1.0.3": {}
"@patternfly/pfe-core@3.0.0":
dependencies:
"@floating-ui/dom": 1.6.7
"@lit/context": 1.1.2
lit: 3.1.4
"@pkgjs/parseargs@0.11.0": "@pkgjs/parseargs@0.11.0":
optional: true optional: true

View File

@ -116,17 +116,32 @@
</ul> </ul>
<?php endif; ?> <?php endif; ?>
</aside> </aside>
<pf-tabs class="w-full max-w-3xl border rounded-t-lg rounded-b-lg xl:-mt-8 xl:rounded-t-none bg-elevated border-subtle" style="--pf-c-tabs__item--m-current__link--after--BorderColor:#009486">
<pf-tab slot="tab"><?= icon('article-line', [
'slot' => 'icon',
]) ?>README.md</pf-tab>
<?php if($plugin->getReadmeHTML()): ?> <?php if($plugin->getReadmeHTML()): ?>
<section class="w-full max-w-3xl p-4 prose border rounded-t-lg rounded-b-lg xl:rounded-t-none xl:-mt-12 md:p-6 xl:p-12 prose-headings:font-display bg-elevated border-subtle"> <pf-tab-panel class="p-4 prose md:p-6 xl:p-12 prose-headings:font-display">
<?= $plugin->getReadmeHTML() ?> <?= $plugin->getReadmeHTML() ?>
</section> </pf-tab-panel>
<?php else: ?> <?php else: ?>
<section class="flex flex-col items-center justify-center w-full max-w-3xl p-4 border rounded-t-lg rounded-b-lg xl:rounded-t-none xl:-mt-12 md:p-6 xl:p-12 bg-elevated border-subtle min-h-96"> <pf-tab-panel class="p-4 md:p-6 xl:p-12">
<div class="flex flex-col items-center justify-center min-h-96">
<?= icon('article-line', [ <?= icon('article-line', [
'class' => 'text-gray-300 text-6xl', 'class' => 'text-gray-300 text-6xl',
]) ?> ]) ?>
<p class="mt-2 font-semibold text-skin-muted"><?= lang('Plugins.noReadme') ?></p> <p class="mt-2 font-semibold text-skin-muted"><?= lang('Plugins.noReadme') ?></p>
</section> </div>
</pf-tab-panel>
<?php endif; ?> <?php endif; ?>
<?php if($plugin->getLicenseHTML()): ?>
<pf-tab slot="tab"><?= icon('scales-3-fill', [
'slot' => 'icon',
]) ?>LICENSE.md</pf-tab>
<pf-tab-panel class="p-4 prose md:p-6 xl:p-12 prose-headings:font-display">
<?= $plugin->getLicenseHTML() ?>
</pf-tab-panel>
<?php endif; ?>
</pf-tabs>
</div> </div>
<?= $this->endSection() ?> <?= $this->endSection() ?>