-
-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
133 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<x-filament::widget> | ||
<x-filament::section :heading="__('cachet::cachet.feed.section_heading')"> | ||
<div class="relative"> | ||
<ul role="list" class="gap-4 flex flex-col"> | ||
@forelse ($items as $post) | ||
<li> | ||
<a class="flex items-center justify-between text-sm" href="{{ $post['link'] }}" target="_blank"> | ||
<div class="overflow-hidden text-sm leading-6 text-gray-500 dark:text-gray-400"> | ||
<h3 class="text-base font-medium text-gray-950 dark:text-white">{{ $post['title'] }}</h3> | ||
<time class="text-muted text-xs" datetime="{{ $post['date']->toW3cString() }}" title="{{ $post['date']->toDateTimeString() }}"> | ||
{{ __('cachet::cachet.feed.posted_at', ['date' => $post['date']->diffForHumans()]) }} | ||
</time> | ||
<p class="break-words truncate">{{ $post['description'] }}</p> | ||
</div> | ||
<div class=""> | ||
<x-heroicon-o-chevron-right class="w-5 h-5 text-gray-400" /> | ||
</div> | ||
</a> | ||
</li> | ||
@empty | ||
<li class="text-center filament-tables-text-column"> | ||
<p class="text-sm text-gray-500">{!! $noItems !!}</p> | ||
</li> | ||
@endforelse | ||
</ul> | ||
</div> | ||
</x-filament::section> | ||
</x-filament::widget> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
<?php | ||
|
||
namespace Cachet\Filament\Widgets; | ||
|
||
use Filament\Widgets\Concerns\CanPoll; | ||
use Filament\Widgets\Widget; | ||
use Illuminate\Support\Carbon; | ||
use Illuminate\Support\Facades\Blade; | ||
use Illuminate\Support\Facades\Cache; | ||
use Illuminate\Support\Str; | ||
use Illuminate\Support\Uri; | ||
use Throwable; | ||
|
||
class Feed extends Widget | ||
{ | ||
use CanPoll; | ||
|
||
protected int|string|array $columnSpan = 'full'; | ||
|
||
protected static string $view = 'cachet::filament.widgets.feed'; | ||
|
||
protected static ?int $sort = 10; | ||
|
||
protected function getViewData(): array | ||
{ | ||
return [ | ||
'items' => $this->getFeed(), | ||
'noItems' => Blade::render($this->getEmptyBlock()), | ||
]; | ||
} | ||
|
||
/** | ||
* Get the generated empty block text. | ||
*/ | ||
public function getEmptyBlock(): string | ||
{ | ||
return preg_replace( | ||
'/\*(.*?)\*/', | ||
'<x-filament::link href="'.config('cachet.feed.uri').'" target="_blank" rel="nofollow noopener">$1</x-filament::link>', | ||
__('cachet::cachet.feed.empty') | ||
); | ||
} | ||
|
||
/** | ||
* Get the feed from the cache or fetch it fresh. | ||
*/ | ||
protected function getFeed(): array | ||
{ | ||
return Cache::flexible('cachet-feed', [ | ||
Check failure on line 49 in src/Filament/Widgets/Feed.php
|
||
60 * 15, | ||
60 * 60, | ||
], fn () => $this->fetchFeed( | ||
config('cachet.feed.uri') | ||
)); | ||
} | ||
|
||
/** | ||
* Fetch the data from the given RSS feed. | ||
*/ | ||
protected function fetchFeed(string $uri, int $maxPosts = 5): array | ||
{ | ||
try { | ||
$xml = simplexml_load_string(file_get_contents($uri)); | ||
|
||
$posts = []; | ||
|
||
$feedItems = $xml->channel->item ?? $xml->entry ?? []; | ||
$feedIndex = 0; | ||
|
||
foreach ($feedItems as $item) { | ||
if ($feedIndex >= $maxPosts) { | ||
break; | ||
} | ||
|
||
$posts[] = [ | ||
'title' => (string)($item->title ?? ''), | ||
'link' => Uri::of((string)($item->link ?? ''))->withQuery([ | ||
Check failure on line 77 in src/Filament/Widgets/Feed.php
|
||
'ref' => 'cachet-dashboard', | ||
]), | ||
'description' => Str::of($item->description ?? $item->summary ?? '')->limit(preserveWords: true), | ||
'date' => Carbon::parse((string)($item->pubDate ?? $item->updated ?? '')), | ||
]; | ||
|
||
$feedIndex++; | ||
} | ||
|
||
return $posts; | ||
} catch (Throwable $e) { | ||
return []; | ||
} | ||
} | ||
} |