diff --git a/app/Http/Controllers/ShowDocumentationController.php b/app/Http/Controllers/ShowDocumentationController.php index 9e6b852f..bae2ce42 100644 --- a/app/Http/Controllers/ShowDocumentationController.php +++ b/app/Http/Controllers/ShowDocumentationController.php @@ -238,7 +238,7 @@ protected function extractTableOfContents(string $document): array ->map(function (string $line) { return [ 'level' => strlen(trim(Str::before($line, '# '))) + 1, - 'title' => $title = trim(Str::after($line, '# ')), + 'title' => $title = htmlspecialchars_decode(trim(Str::after($line, '# '))), 'anchor' => Str::slug(Str::replace('`', 'code', $title)), ]; }) diff --git a/app/Support/GitHub.php b/app/Support/GitHub.php index d0aa6763..0006f3e9 100644 --- a/app/Support/GitHub.php +++ b/app/Support/GitHub.php @@ -2,6 +2,8 @@ namespace App\Support; +use App\Support\GitHub\Release; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Http; @@ -27,18 +29,25 @@ public static function laravel(): static public function latestVersion() { - $version = Cache::remember( + $release = Cache::remember( $this->getCacheKey('latest-version'), now()->addHour(), - function () { - return $this->fetchLatestVersion(); - } + fn () => $this->fetchLatestVersion() ); - return $version['name'] ?? 'Unknown'; + return $release?->name ?? 'Unknown'; } - private function fetchLatestVersion() + public function releases(): Collection + { + return Cache::remember( + $this->getCacheKey('releases'), + now()->addHour(), + fn () => $this->fetchReleases() + ) ?? collect(); + } + + private function fetchLatestVersion(): ?Release { // Make a request to GitHub $response = Http::get('https://api.github.com/repos/'.$this->package.'/releases/latest'); @@ -48,11 +57,24 @@ private function fetchLatestVersion() return null; } - return $response->json(); + return new Release($response->json()); } private function getCacheKey(string $string): string { return sprintf('%s-%s', $this->package, $string); } + + private function fetchReleases(): ?Collection + { + // Make a request to GitHub + $response = Http::get('https://api.github.com/repos/'.$this->package.'/releases'); + + // Check if the request was successful + if ($response->failed()) { + return collect(); + } + + return collect($response->json())->map(fn (array $release) => new Release($release)); + } } diff --git a/app/Support/GitHub/Release.php b/app/Support/GitHub/Release.php new file mode 100644 index 00000000..30130478 --- /dev/null +++ b/app/Support/GitHub/Release.php @@ -0,0 +1,92 @@ +data[$name] ?? null; + } + + public function __isset(string $name): bool + { + return isset($this->data[$name]); + } + + public function getBodyForMarkdown(): string + { + $body = $this->body; + + // Convert any URLs to Markdown links + if ($this->convertLinks) { + $body = preg_replace( + '/https?:\/\/[^\s]+\/pull\/(\d+)/', + '[#$1]($0)', + $body + ); + + $body = preg_replace( + '/(https?:\/\/(?![^\s]+\/pull\/\d+)[^\s]+)/', + '[$1]($1)', + $body + ); + } + + // Change any @ tags to markdown links to GitHub + if ($this->withUserLinks) { + $body = preg_replace( + '/@([a-zA-Z0-9_]+)/', + '[@$1](https://github.com/$1)', + $body + ); + } + + return preg_replace('/^#/m', '###', $body); + } + + public function withoutUserLinks(bool $withoutUserLinks = true): static + { + $this->withUserLinks = ! $withoutUserLinks; + + return $this; + } + + public function withoutLinkConversion(bool $convertLinks = true): static + { + $this->convertLinks = ! $convertLinks; + + return $this; + } +} diff --git a/resources/views/docs/desktop/1/getting-started/releasenotes.md b/resources/views/docs/desktop/1/getting-started/releasenotes.md new file mode 100644 index 00000000..831a6c6a --- /dev/null +++ b/resources/views/docs/desktop/1/getting-started/releasenotes.md @@ -0,0 +1,15 @@ +--- +title: Release Notes +order: 1100 +--- + +@forelse (\App\Support\GitHub::electron()->releases()->take(10) as $release) +## {{ $release->name }} +**Released: {{ \Carbon\Carbon::parse($release->published_at)->format('F j, Y') }}** + +{{ $release->getBodyForMarkdown() }} +--- +@empty +## We couldn't show you the latest release notes at this time. +Not to worry, you can head over to GitHub to see the [latest release notes](https://github.com/NativePHP/electron/releases). +@endforelse