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 VideoClipBuilder from "./modules/VideoClipBuilder";
import "./modules/xml-editor";
import "@patternfly/elements/pf-tabs/pf-tabs.js";
Dropdown();
Tooltip();

View File

@ -17,6 +17,7 @@ Plugins are ways to extend Castopod's core features.
- …
- icon.svg
- manifest.json // required
- LICENSE.md
- Plugin.php // required
- README.md
@ -97,6 +98,12 @@ through.
It should be used for any additional information to help guide the user in using
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
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 $licenseHTML;
public function __construct(
protected string $vendor,
protected string $package,
@ -56,7 +58,9 @@ abstract class BasePlugin implements PluginInterface
$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';
}
final public function getLicenseHTML(): ?string
{
return $this->licenseHTML;
}
/**
* @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
$readmeMD = @file_get_contents($path);

View File

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

47
pnpm-lock.yaml generated
View File

@ -43,6 +43,9 @@ importers:
"@github/relative-time-element":
specifier: ^4.4.2
version: 4.4.2
"@patternfly/elements":
specifier: ^3.0.2
version: 3.0.2
"@tailwindcss/nesting":
specifier: 0.0.0-insiders.565cd3e
version: 0.0.0-insiders.565cd3e(postcss@8.4.39)
@ -2125,6 +2128,12 @@ packages:
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":
resolution:
{
@ -2233,6 +2242,24 @@ packages:
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":
resolution:
{
@ -10781,6 +10808,10 @@ snapshots:
"@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":
dependencies:
"@lit-labs/ssr-dom-shim": 1.2.0
@ -10855,6 +10886,22 @@ snapshots:
dependencies:
"@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":
optional: true

View File

@ -116,17 +116,32 @@
</ul>
<?php endif; ?>
</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()): ?>
<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() ?>
</section>
</pf-tab-panel>
<?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">
<?= icon('article-line', [
'class' => 'text-gray-300 text-6xl',
]) ?>
<p class="mt-2 font-semibold text-skin-muted"><?= lang('Plugins.noReadme') ?></p>
</section>
<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', [
'class' => 'text-gray-300 text-6xl',
]) ?>
<p class="mt-2 font-semibold text-skin-muted"><?= lang('Plugins.noReadme') ?></p>
</div>
</pf-tab-panel>
<?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>
<?= $this->endSection() ?>