Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preferred User and Browser Locales #78

Merged
merged 11 commits into from
Apr 1, 2024
2 changes: 1 addition & 1 deletion resources/dist/filament-language-switch.css

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions resources/views/components/flag.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,10 @@
src="{{ $src }}"
{{ $attributes
->class([
'object-cover object-center max-w-none',
'object-cover object-center',
'rounded-full' => $circular,
'rounded-lg' => ! $circular && ! $switch,
'rounded-md' => ! $circular && $switch,
''
])
}}
@class([

])
/>
2 changes: 1 addition & 1 deletion resources/views/language-switch.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<div>
@if ($isVisibleOutsidePanels)
<div @class([
'fls-display-on fixed w-full flex p-4 z-50',
'fls-display-on fixed w-fit flex p-4 z-50',
'top-0' => str_contains($outsidePanelsPlacement, 'top'),
'bottom-0' => str_contains($outsidePanelsPlacement, 'bottom'),
'justify-start' => str_contains($outsidePanelsPlacement, 'left'),
Expand Down
2 changes: 1 addition & 1 deletion resources/views/switch.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class="w-7 h-7"
:src="$languageSwitch->getFlag($locale)"
:circular="$isCircular"
:alt="$languageSwitch->getLabel($locale)"
class="p-0.5 w-7 h-7"
class="w-7 h-7"
/>
@else
<span
Expand Down
15 changes: 4 additions & 11 deletions src/Http/Livewire/FilamentLanguageSwitch.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,17 @@

namespace BezhanSalleh\FilamentLanguageSwitch\Http\Livewire;

use BezhanSalleh\FilamentLanguageSwitch\Events\LocaleChanged;
use BezhanSalleh\FilamentLanguageSwitch\LanguageSwitch;
use Illuminate\Contracts\View\View;
use Livewire\Attributes\On;
use Livewire\Component;

class FilamentLanguageSwitch extends Component
{
#[On('language-switched')]
public function changeLocale($locale)
{
session()->put('locale', $locale);

cookie()->queue(cookie()->forever('filament_language_switch_locale', $locale));

$this->dispatch('filament-language-changed');

event(new LocaleChanged($locale));

$this->redirect(request()->header('Referer'));

LanguageSwitch::trigger(locale: $locale);
}

public function render(): View
Expand Down
27 changes: 3 additions & 24 deletions src/Http/Middleware/SwitchLanguageLocale.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,10 @@ class SwitchLanguageLocale
{
public function handle(Request $request, Closure $next): mixed
{
$locale = session()->get('locale')
?? $request->get('locale')
?? $request->cookie('filament_language_switch_locale')
?? $this->getBrowserLocale($request)
?? config('app.locale', 'en');

if (in_array($locale, LanguageSwitch::make()->getLocales())) {
app()->setLocale($locale);
}
app()->setLocale(
locale: LanguageSwitch::make()->getPreferredLocale()
);

return $next($request);
}

private function getBrowserLocale(Request $request): ?string
{
$appLocales = LanguageSwitch::make()->getLocales();

$userLocales = preg_split('/[,;]/', $request->server('HTTP_ACCEPT_LANGUAGE'));

foreach ($userLocales as $locale) {
if (in_array($locale, $appLocales)) {
return $locale;
}
}

return null;
}
}
69 changes: 65 additions & 4 deletions src/LanguageSwitch.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace BezhanSalleh\FilamentLanguageSwitch;

use BezhanSalleh\FilamentLanguageSwitch\Enums\Placement;
use BezhanSalleh\FilamentLanguageSwitch\Events\LocaleChanged;
use Closure;
use Exception;
use Filament\Panel;
Expand All @@ -30,6 +31,8 @@ class LanguageSwitch extends Component

protected array | Closure $locales = [];

protected bool $nativeLabel = false;

protected ?Placement $outsidePanelPlacement = null;

protected bool | Closure $visibleInsidePanels = false;
Expand All @@ -38,6 +41,8 @@ class LanguageSwitch extends Component

protected Closure | string $renderHook = 'panels::global-search.after';

protected Closure | string | null $userPreferredLocale = null;

public static function make(): static
{
$static = app(static::class);
Expand Down Expand Up @@ -66,7 +71,7 @@ public static function boot(): void

if ($static->isVisibleOutsidePanels()) {
FilamentView::registerRenderHook(
name: 'panels::body.end',
name: 'panels::body.start',
hook: fn (): string => Blade::render('<livewire:filament-language-switch key=\'fls-outside-panels\' />')
);
}
Expand All @@ -86,6 +91,13 @@ public function displayLocale(?string $locale = null): static
return $this;
}

public function nativeLabel(bool $condition = true): static
{
$this->nativeLabel = $condition;

return $this;
}

public function outsidePanelRoutes(array | Closure | null $routes = null): static
{
$this->outsidePanelRoutes = $routes ?? [
Expand Down Expand Up @@ -146,6 +158,13 @@ public function renderHook(string $hook): static
return $this;
}

public function userPreferredLocale(Closure | string | null $locale): static
{
$this->userPreferredLocale = $locale;

return $this;
}

public function visible(bool | Closure $insidePanels = true, bool | Closure $outsidePanels = false): static
{
$this->visibleInsidePanels = $insidePanels;
Expand All @@ -155,9 +174,9 @@ public function visible(bool | Closure $insidePanels = true, bool | Closure $out
return $this;
}

public function getDisplayLocale(): string
public function getDisplayLocale(): ?string
{
return (string) $this->evaluate($this->displayLocale);
return $this->evaluate($this->displayLocale);
}

public function getExcludes(): array
Expand Down Expand Up @@ -219,6 +238,11 @@ public function getLocales(): array
return (array) $this->evaluate($this->locales);
}

public function getNativeLabel(): bool
{
return (bool) $this->evaluate($this->nativeLabel);
}

public function getOutsidePanelPlacement(): Placement
{
return $this->outsidePanelPlacement ?? Placement::TopRight;
Expand All @@ -229,6 +253,23 @@ public function getRenderHook(): string
return (string) $this->evaluate($this->renderHook);
}

public function getUserPreferredLocale(): ?string
{
return $this->evaluate($this->userPreferredLocale) ?? null;
}

public function getPreferredLocale(): string
{
$locale = session()->get('locale') ??
request()->get('locale') ??
request()->cookie('filament_language_switch_locale') ??
$this->getUserPreferredLocale() ??
config('app.locale', 'en') ??
request()->getPreferredLanguage();

return in_array($locale, $this->getLocales(), true) ? $locale : config('app.locale');
}

/**
* @return array<string, Panel>
*/
Expand All @@ -251,7 +292,16 @@ public function getFlag(string $locale): string

public function getLabel(string $locale): string
{
return $this->labels[$locale] ?? str(locale_get_display_name($locale, $this->getDisplayLocale()))
if (array_key_exists($locale, $this->labels) && ! $this->getNativeLabel()) {
return strval($this->labels[$locale]);
}

return str(
locale_get_display_name(
locale: $locale,
displayLocale: $this->getNativeLabel() ? $locale : $this->getDisplayLocale()
)
)
->title()
->toString();
}
Expand All @@ -267,4 +317,15 @@ public function getCharAvatar(string $locale): string
? str($locale)->substr(0, 2)->upper()->toString()
: str($locale)->upper()->toString();
}

public static function trigger(string $locale)
{
session()->put('locale', $locale);

cookie()->queue(cookie()->forever('filament_language_switch_locale', $locale));

event(new LocaleChanged($locale));

return redirect(request()->header('Referer'));
}
}
Loading