-
-
Notifications
You must be signed in to change notification settings - Fork 3
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
1 parent
78db2b6
commit 6f780fc
Showing
11 changed files
with
493 additions
and
4 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Console\Commands; | ||
|
||
use Exception; | ||
use Illuminate\Console\Command; | ||
use Illuminate\Contracts\Filesystem\FileNotFoundException; | ||
use Illuminate\Http\Client\RequestException; | ||
use Illuminate\Support\Facades\Cache; | ||
use Illuminate\Support\Facades\File; | ||
use Illuminate\Support\Facades\Http; | ||
use Symfony\Component\Console\Command\Command as CommandAlias; | ||
|
||
/** | ||
* Command to fetch new features from GitHub or a local file and store them in cache. | ||
*/ | ||
class FetchNewFeatures extends Command | ||
{ | ||
protected $signature = 'vanguard:fetch-new-features {--local : Fetch from local new_features.json file}'; | ||
|
||
protected $description = 'Fetch new features from GitHub or local file and store in cache'; | ||
|
||
/** | ||
* Handle the command execution. | ||
*/ | ||
public function handle(): int | ||
{ | ||
try { | ||
$features = $this->fetchFeatures(); | ||
|
||
if ($features === []) { | ||
$this->error('No new features found.'); | ||
|
||
return CommandAlias::FAILURE; | ||
} | ||
|
||
$this->storeLatestFeature($features); | ||
$this->info('New features fetched and stored successfully.'); | ||
|
||
return CommandAlias::SUCCESS; | ||
} catch (Exception $e) { | ||
$this->error($e->getMessage()); | ||
|
||
return CommandAlias::FAILURE; | ||
} | ||
} | ||
|
||
/** | ||
* Fetch features from either local or remote source. | ||
* | ||
* @return array<int, array<string, string>> | ||
*/ | ||
private function fetchFeatures(): array | ||
{ | ||
return $this->option('local') ? $this->fetchLocal() : $this->fetchRemote(); | ||
} | ||
|
||
/** | ||
* Fetch features from the remote GitHub repository. | ||
* | ||
* @return array<int, array<string, string>> | ||
* | ||
* @throws Exception | ||
*/ | ||
private function fetchRemote(): array | ||
{ | ||
try { | ||
$response = Http::get('https://raw.githubusercontent.com/vanguardbackup/vanguard/main/new_features.json'); | ||
$response->throw(); | ||
|
||
return $response->json(); | ||
} catch (RequestException $e) { | ||
throw new Exception("Failed to fetch new features from remote: {$e->getMessage()}", $e->getCode(), $e); | ||
} | ||
} | ||
|
||
/** | ||
* Fetch features from the local file. | ||
* | ||
* @return array<int, array<string, string>> | ||
* | ||
* @throws Exception | ||
*/ | ||
private function fetchLocal(): array | ||
{ | ||
$path = base_path('new_features.json'); | ||
|
||
if (! File::exists($path)) { | ||
throw new Exception('Local new_features.json file not found in project root.'); | ||
} | ||
|
||
$content = File::get($path); | ||
$features = json_decode($content, true); | ||
|
||
if (json_last_error() !== JSON_ERROR_NONE || ! is_array($features)) { | ||
throw new Exception('Failed to parse local new_features.json file.'); | ||
} | ||
|
||
return $features; | ||
} | ||
|
||
/** | ||
* Store the latest feature in the cache if available. | ||
* | ||
* @param array<int, array<string, string>> $features | ||
* | ||
* @throws FileNotFoundException | ||
*/ | ||
private function storeLatestFeature(array $features): void | ||
{ | ||
if ($features === []) { | ||
$this->info('No features to store.'); | ||
|
||
return; | ||
} | ||
|
||
$latestFeature = end($features); | ||
if ($latestFeature === false) { | ||
$this->error('Failed to retrieve the latest feature.'); | ||
|
||
return; | ||
} | ||
|
||
$latestFeature['current_version'] = $this->getCurrentVersion(); | ||
$latestFeature['github_url'] ??= 'https://github.com/vanguardbackup/vanguard'; | ||
|
||
Cache::put('latest_feature', $latestFeature, now()->addDay()); | ||
} | ||
|
||
/** | ||
* Get the current version from the VERSION file. | ||
* | ||
* @throws FileNotFoundException | ||
*/ | ||
private function getCurrentVersion(): string | ||
{ | ||
$versionFile = base_path('VERSION'); | ||
|
||
return File::exists($versionFile) ? trim(File::get($versionFile)) : '0.0.0'; | ||
} | ||
} |
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,56 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Livewire\Other; | ||
|
||
use Illuminate\Support\Facades\Cache; | ||
use Illuminate\Support\Facades\Log; | ||
use Illuminate\View\View; | ||
use Livewire\Component; | ||
|
||
/** | ||
* Displays a banner for new features in the application. | ||
* Fetches the latest feature from cache and allows users to dismiss it. | ||
*/ | ||
class NewFeatureBanner extends Component | ||
{ | ||
/** | ||
* The latest feature to display in the banner. | ||
* | ||
* @var array<string, string>|null | ||
*/ | ||
public ?array $latestFeature = null; | ||
|
||
/** | ||
* Initialize the component state. | ||
*/ | ||
public function mount(): void | ||
{ | ||
$cachedFeature = Cache::get('latest_feature'); | ||
|
||
if (is_array($cachedFeature)) { | ||
$this->latestFeature = $cachedFeature; | ||
} elseif ($cachedFeature !== null) { | ||
Log::warning('Unexpected data type for latest_feature in cache', ['type' => gettype($cachedFeature)]); | ||
$this->latestFeature = null; | ||
} | ||
} | ||
|
||
/** | ||
* Render the component. | ||
*/ | ||
public function render(): View | ||
{ | ||
return view('livewire.other.new-feature-banner'); | ||
} | ||
|
||
/** | ||
* Dismiss the feature banner. | ||
*/ | ||
public function dismiss(): void | ||
{ | ||
$this->latestFeature = null; | ||
$this->dispatch('featureDismissed'); | ||
} | ||
} |
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,8 @@ | ||
[ | ||
{ | ||
"title": "New Feature Banner!", | ||
"description": "We have added a new feature banner to Vanguard.", | ||
"version": "1.4.2", | ||
"github_url": "https://github.com/vanguardbackup/vanguard/releases/tag/1.4.2" | ||
} | ||
] |
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
69 changes: 69 additions & 0 deletions
69
resources/views/livewire/other/new-feature-banner.blade.php
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,69 @@ | ||
<div> | ||
@php | ||
$currentVersion = obtain_vanguard_version(); | ||
$featureVersion = $latestFeature['version'] ?? '0.0.0'; | ||
$showBanner = version_compare($currentVersion, $featureVersion, '>='); | ||
@endphp | ||
|
||
@if ($latestFeature && $showBanner) | ||
<div | ||
x-data="{ | ||
show: true, | ||
copied: false, | ||
copyFeatureDetails() { | ||
const details = `${this.$refs.title.textContent}\n${this.$refs.description.textContent}`; | ||
navigator.clipboard.writeText(details); | ||
this.copied = true; | ||
setTimeout(() => this.copied = false, 2000); | ||
} | ||
}" | ||
x-show="show" | ||
x-transition:enter="transition ease-out duration-300" | ||
x-transition:enter-start="opacity-0 transform -translate-y-2" | ||
x-transition:enter-end="opacity-100 transform translate-y-0" | ||
x-transition:leave="transition ease-in duration-300" | ||
x-transition:leave-start="opacity-100 transform translate-y-0" | ||
x-transition:leave-end="opacity-0 transform -translate-y-2" | ||
class="bg-gradient-to-r from-blue-500/90 to-blue-600/90 text-white relative shadow-lg" | ||
role="alert" | ||
aria-live="assertive" | ||
> | ||
<div class="max-w-7xl mx-auto py-4 px-4 sm:px-6 lg:px-8"> | ||
<div class="flex flex-col sm:flex-row items-center justify-between"> | ||
<div class="flex items-center w-full sm:w-auto mb-4 sm:mb-0"> | ||
<span class="flex p-2 rounded-full bg-blue-700/50 backdrop-blur-sm"> | ||
@svg('heroicon-o-sparkles', 'h-6 w-6 text-white') | ||
</span> | ||
<p class="ml-3 font-medium text-base sm:text-lg"> | ||
{{ __('New Feature!') }} | ||
</p> | ||
</div> | ||
<div class="flex flex-col sm:flex-row items-stretch sm:items-center space-y-2 sm:space-y-0 sm:space-x-3 w-full sm:w-auto"> | ||
<div class="flex-grow sm:flex-grow-0"> | ||
<p x-ref="title" class="font-bold text-sm sm:text-base">{{ $latestFeature['title'] }}</p> | ||
<p x-ref="description" class="text-sm text-white/80">{{ $latestFeature['description'] }}</p> | ||
</div> | ||
<div class="flex space-x-2"> | ||
<a | ||
href="{{ $latestFeature['github_url'] ?? 'https://github.com/vanguardbackup/vanguard' }}" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
class="bg-white/10 hover:bg-white/20 backdrop-blur-sm px-3 py-1 text-sm font-medium text-white rounded-full border border-white/25 focus:outline-none focus:ring-2 focus:ring-white/50 focus:ring-offset-2 focus:ring-offset-blue-600 transition-all duration-150 ease-out hover:shadow-lg hover:-translate-y-0.5" | ||
> | ||
@svg('heroicon-o-code-bracket', 'h-4 w-4 inline mr-1') | ||
{{ __('View on GitHub') }} | ||
</a> | ||
<button | ||
wire:click="dismiss" | ||
@click="show = false" | ||
class="bg-white/10 hover:bg-white/20 backdrop-blur-sm px-3 py-1 text-sm font-medium text-white rounded-full border border-white/25 focus:outline-none focus:ring-2 focus:ring-white/50 focus:ring-offset-2 focus:ring-offset-blue-600 transition-all duration-150 ease-out hover:shadow-lg hover:-translate-y-0.5" | ||
> | ||
{{ __('Dismiss') }} | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
@endif | ||
</div> |
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
Oops, something went wrong.