mirror of
https://github.com/filamentphp/filament.git
synced 2026-09-24 15:42:09 +08:00
wip
This commit is contained in:
@@ -20,10 +20,14 @@ body:
|
||||
- filament/forms
|
||||
- filament/tables
|
||||
- filament/notifications
|
||||
- filament/actions
|
||||
- filament/widgets
|
||||
- filament/spatie-laravel-google-fonts-plugin
|
||||
- filament/spatie-laravel-media-library-plugin
|
||||
- filament/spatie-laravel-settings-plugin
|
||||
- filament/spatie-laravel-tags-plugin
|
||||
- filament/spatie-laravel-translatable-plugin
|
||||
- filament/spark-billing-provider
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -16,6 +16,7 @@ jobs:
|
||||
- forms
|
||||
- notifications
|
||||
- spark-billing-provider
|
||||
- spatie-laravel-google-fonts-plugin
|
||||
- spatie-laravel-media-library-plugin
|
||||
- spatie-laravel-settings-plugin
|
||||
- spatie-laravel-tags-plugin
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
"Filament\\Actions\\": "packages/actions/src",
|
||||
"Filament\\Billing\\Providers\\": "packages/spark-billing-provider/src",
|
||||
"Filament\\Forms\\": "packages/forms/src",
|
||||
"Filament\\FontProviders\\": "packages/spatie-laravel-google-fonts-plugin/src",
|
||||
"Filament\\Notifications\\": "packages/notifications/src",
|
||||
"Filament\\Support\\": "packages/support/src",
|
||||
"Filament\\Tables\\": "packages/tables/src",
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -26,6 +26,8 @@ use Filament\Resources\Resource;
|
||||
use Filament\Support\Assets\Theme;
|
||||
use Filament\Support\Color;
|
||||
use Filament\Support\Facades\FilamentAsset;
|
||||
use Filament\Support\Facades\FilamentIcon;
|
||||
use Filament\Support\Icons\Icon;
|
||||
use Filament\Widgets\Widget;
|
||||
use Illuminate\Auth\EloquentUserProvider;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
@@ -59,6 +61,11 @@ class Context
|
||||
|
||||
protected string $homeUrl = '';
|
||||
|
||||
/**
|
||||
* @var array<string, Icon>
|
||||
*/
|
||||
protected array $icons = [];
|
||||
|
||||
protected bool $isNavigationMounted = false;
|
||||
|
||||
/**
|
||||
@@ -136,6 +143,11 @@ class Context
|
||||
*/
|
||||
protected ?array $secondaryColor = null;
|
||||
|
||||
/**
|
||||
* @var array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null
|
||||
*/
|
||||
protected ?array $grayColor = null;
|
||||
|
||||
/**
|
||||
* @var array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null
|
||||
*/
|
||||
@@ -221,7 +233,7 @@ class Context
|
||||
|
||||
protected string $fontProvider = BunnyFontProvider::class;
|
||||
|
||||
protected ?string $fontUrl = 'https://fonts.bunny.net/css?family=be-vietnam-pro:400,400i,500,500i,600,600i,700,700i&display=swap';
|
||||
protected ?string $fontUrl = 'https://fonts.bunny.net/css?family=be-vietnam-pro:400,500,700&display=swap';
|
||||
|
||||
/**
|
||||
* @var array<string, Plugin>
|
||||
@@ -260,6 +272,7 @@ class Context
|
||||
$plugin->boot($this);
|
||||
}
|
||||
|
||||
FilamentIcon::register($this->icons);
|
||||
$this->registerLivewireComponents();
|
||||
}
|
||||
|
||||
@@ -631,6 +644,16 @@ class Context
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, Icon> $icons
|
||||
*/
|
||||
public function icons(array $icons): static
|
||||
{
|
||||
$this->icons = array_merge($this->icons, $icons);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | string $color
|
||||
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | string
|
||||
@@ -684,6 +707,24 @@ class Context
|
||||
return $this->secondaryColor ?? Color::Gray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | string | null $color
|
||||
*/
|
||||
public function grayColor(array | string | null $color): static
|
||||
{
|
||||
$this->grayColor = $this->processColor($color);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string}
|
||||
*/
|
||||
public function getGrayColor(): array
|
||||
{
|
||||
return $this->grayColor ?? Color::Gray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | string | null $color
|
||||
*/
|
||||
@@ -824,6 +865,7 @@ class Context
|
||||
* @return array{
|
||||
* 'primary': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
* 'secondary': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
* 'gray': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
* 'danger': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
* 'warning': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
* 'success': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
@@ -834,6 +876,7 @@ class Context
|
||||
return [
|
||||
'primary' => $this->getPrimaryColor(),
|
||||
'secondary' => $this->getSecondaryColor(),
|
||||
'gray' => $this->getGrayColor(),
|
||||
'warning' => $this->getWarningColor(),
|
||||
'danger' => $this->getDangerColor(),
|
||||
'success' => $this->getSuccessColor(),
|
||||
@@ -1168,6 +1211,10 @@ class Context
|
||||
$tenant = Filament::getUserDefaultTenant($this->auth()->user());
|
||||
}
|
||||
|
||||
if ((! $tenant) && $this->hasRoutableTenancy()) {
|
||||
return $this->hasTenantRegistration() ? $this->getTenantRegistrationUrl() : null;
|
||||
}
|
||||
|
||||
if ($tenant && $this->hasRoutableTenancy()) {
|
||||
$originalTenant = Filament::getTenant();
|
||||
Filament::setTenant($tenant);
|
||||
@@ -1397,7 +1444,7 @@ class Context
|
||||
|
||||
public function getFontHtml(): Htmlable
|
||||
{
|
||||
return app($this->getFontProvider())->getHtml($this->getFontUrl());
|
||||
return app($this->getFontProvider())->getHtml($this->getFontUrl(), $this->getFontName());
|
||||
}
|
||||
|
||||
public function getFontName(): string
|
||||
|
||||
@@ -51,12 +51,14 @@ use Illuminate\Support\Facades\Facade;
|
||||
* @method static Plugin getPlugin(string $id)
|
||||
* @method static array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} getPrimaryColor()
|
||||
* @method static array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} getSecondaryColor()
|
||||
* @method static array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} getGrayColor()
|
||||
* @method static array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} getDangerColor()
|
||||
* @method static array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} getWarningColor()
|
||||
* @method static array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} getSuccessColor()
|
||||
* @method static array{
|
||||
* 'primary': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
* 'secondary': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
* 'gray': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
* 'danger': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
* 'warning': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
* 'success': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
|
||||
@@ -309,6 +309,14 @@ class FilamentManager
|
||||
return $this->getCurrentContext()->getSecondaryColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string}
|
||||
*/
|
||||
public function getGrayColor(): array
|
||||
{
|
||||
return $this->getCurrentContext()->getGrayColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string}
|
||||
*/
|
||||
@@ -337,6 +345,7 @@ class FilamentManager
|
||||
* @return array{
|
||||
* 'primary': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
* 'secondary': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
* 'gray': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
* 'danger': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
* 'warning': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
* 'success': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string} | null,
|
||||
|
||||
@@ -4,11 +4,15 @@ namespace Filament\FontProviders;
|
||||
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
use Illuminate\Support\HtmlString;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class BunnyFontProvider implements Contracts\FontProvider
|
||||
{
|
||||
public function getHtml(?string $url): Htmlable
|
||||
public function getHtml(?string $url, string $name): Htmlable
|
||||
{
|
||||
$name = Str::kebab($name);
|
||||
$url ??= "https://fonts.bunny.net/css?family={$name}:400,500,700&display=swap";
|
||||
|
||||
return new HtmlString("
|
||||
<link rel=\"preconnect\" href=\"https://fonts.bunny.net\">
|
||||
<link href=\"{$url}\" rel=\"stylesheet\" />
|
||||
|
||||
@@ -6,5 +6,5 @@ use Illuminate\Contracts\Support\Htmlable;
|
||||
|
||||
interface FontProvider
|
||||
{
|
||||
public function getHtml(?string $url): Htmlable;
|
||||
public function getHtml(?string $url, string $name): Htmlable;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Filament\FontProviders;
|
||||
|
||||
use Filament\FontProviders\Contracts;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
class GoogleFontProvider implements Contracts\FontProvider
|
||||
{
|
||||
public function getHtml(?string $url): Htmlable
|
||||
public function getHtml(?string $url, string $name): Htmlable
|
||||
{
|
||||
$name = urlencode($name);
|
||||
$url ??= "https://fonts.googleapis.com/css2?family={$name}:wght@400;500;700&display=swap";
|
||||
|
||||
return new HtmlString("
|
||||
<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">
|
||||
<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>
|
||||
|
||||
@@ -4,12 +4,12 @@ namespace Filament\Pages;
|
||||
|
||||
use Filament\Context;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Support\Facades\FilamentIcon;
|
||||
use Filament\Support\Icons\IconManager;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class Dashboard extends Page
|
||||
{
|
||||
protected static ?string $navigationIcon = 'heroicon-o-home';
|
||||
|
||||
protected static ?int $navigationSort = -2;
|
||||
|
||||
/**
|
||||
@@ -19,7 +19,16 @@ class Dashboard extends Page
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return static::$navigationLabel ?? static::$title ?? __('filament::pages/dashboard.title');
|
||||
return static::$navigationLabel ??
|
||||
static::$title ??
|
||||
__('filament::pages/dashboard.title');
|
||||
}
|
||||
|
||||
public static function getNavigationIcon(): string
|
||||
{
|
||||
return static::$navigationIcon ??
|
||||
FilamentIcon::resolve('app::pages.dashboard.navigation')?->name ??
|
||||
'heroicon-o-home';
|
||||
}
|
||||
|
||||
public static function routes(Context $context): void
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
const preset = require('./filament-preset')
|
||||
const preset = require('./tailwind.config.preset')
|
||||
|
||||
module.exports = {
|
||||
presets: [preset],
|
||||
content: preset.content,
|
||||
content: [
|
||||
'./packages/**/*.blade.php',
|
||||
],
|
||||
}
|
||||
|
||||
@@ -2,14 +2,7 @@ const defaultTheme = require('tailwindcss/defaultTheme')
|
||||
|
||||
module.exports = {
|
||||
content: [
|
||||
'./packages/actions/resources/**/*.blade.php',
|
||||
'./packages/app/resources/**/*.blade.php',
|
||||
'./packages/forms/resources/**/*.blade.php',
|
||||
'./packages/navigation/resources/**/*.blade.php',
|
||||
'./packages/notifications/resources/**/*.blade.php',
|
||||
'./packages/support/resources/**/*.blade.php',
|
||||
'./packages/tables/resources/**/*.blade.php',
|
||||
'./packages/widgets/resources/**/*.blade.php',
|
||||
'./vendor/filament/**/*.blade.php',
|
||||
],
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
@@ -51,6 +44,18 @@ module.exports = {
|
||||
800: 'rgba(var(--secondary-color-800), <alpha-value>)',
|
||||
900: 'rgba(var(--secondary-color-900), <alpha-value>)',
|
||||
},
|
||||
gray: {
|
||||
50: 'rgba(var(--gray-color-50), <alpha-value>)',
|
||||
100: 'rgba(var(--gray-color-100), <alpha-value>)',
|
||||
200: 'rgba(var(--gray-color-200), <alpha-value>)',
|
||||
300: 'rgba(var(--gray-color-300), <alpha-value>)',
|
||||
400: 'rgba(var(--gray-color-400), <alpha-value>)',
|
||||
500: 'rgba(var(--gray-color-500), <alpha-value>)',
|
||||
600: 'rgba(var(--gray-color-600), <alpha-value>)',
|
||||
700: 'rgba(var(--gray-color-700), <alpha-value>)',
|
||||
800: 'rgba(var(--gray-color-800), <alpha-value>)',
|
||||
900: 'rgba(var(--gray-color-900), <alpha-value>)',
|
||||
},
|
||||
success: {
|
||||
50: 'rgba(var(--success-color-50), <alpha-value>)',
|
||||
100: 'rgba(var(--success-color-100), <alpha-value>)',
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "filament/spatie-laravel-google-fonts-plugin",
|
||||
"description": "Filament support for `spatie/laravel-google-fonts`.",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/filamentphp/filament",
|
||||
"support": {
|
||||
"issues": "https://github.com/filamentphp/filament/issues",
|
||||
"source": "https://github.com/filamentphp/filament"
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.0",
|
||||
"illuminate/contracts": "^9.0",
|
||||
"illuminate/support": "^9.0",
|
||||
"spatie/laravel-google-fonts": "^1.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Filament\\FontProviders\\": "src"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
|
||||
use Filament\FontProviders\Contracts;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
class SpatieGoogleFontProvider implements Contracts\FontProvider
|
||||
{
|
||||
public function getHtml(?string $url, string $name): Htmlable
|
||||
{
|
||||
return new HtmlString(Blade::render('@googlefonts'));
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,7 @@
|
||||
@if ($icon)
|
||||
<x-filament::icon
|
||||
:name="$icon"
|
||||
alias="support::button.prefix"
|
||||
group="support::button.prefix"
|
||||
:size="$iconSize"
|
||||
:class="$iconClasses"
|
||||
:wire:loading.remove.delay="$hasLoadingIndicator"
|
||||
@@ -164,7 +164,7 @@
|
||||
@if ($icon)
|
||||
<x-filament::icon
|
||||
:name="$icon"
|
||||
alias="support::button.suffix"
|
||||
group="support::button.suffix"
|
||||
:size="$iconSize"
|
||||
:class="$iconClasses"
|
||||
:wire:loading.remove.delay="$hasLoadingIndicator"
|
||||
@@ -198,7 +198,7 @@
|
||||
@if ($icon && $iconPosition === 'before')
|
||||
<x-filament::icon
|
||||
:name="$icon"
|
||||
alias="support::button.prefix"
|
||||
group="support::button.prefix"
|
||||
:class="$iconClasses"
|
||||
/>
|
||||
@endif
|
||||
@@ -212,7 +212,7 @@
|
||||
@if ($icon && $iconPosition === 'after')
|
||||
<x-filament::icon
|
||||
:name="$icon"
|
||||
alias="support::button.suffix"
|
||||
group="support::button.suffix"
|
||||
:class="$iconClasses"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
'disabled' => false,
|
||||
'form' => null,
|
||||
'icon' => null,
|
||||
'iconAlias' => null,
|
||||
'iconSize' => null,
|
||||
'indicator' => null,
|
||||
'indicatorColor' => 'primary',
|
||||
@@ -96,7 +97,8 @@
|
||||
|
||||
<x-filament::icon
|
||||
:name="$icon"
|
||||
alias="support::icon-button"
|
||||
:alias="$iconAlias"
|
||||
group="support::icon-button"
|
||||
:size="$iconSize"
|
||||
:class="$iconClasses"
|
||||
:wire:loading.remove.delay="$hasLoadingIndicator"
|
||||
|
||||
@@ -1,30 +1,33 @@
|
||||
@props([
|
||||
'alias',
|
||||
'alias' => null,
|
||||
'class' => [],
|
||||
'color' => null,
|
||||
'group' => null,
|
||||
'name' => null,
|
||||
'size',
|
||||
])
|
||||
|
||||
@php
|
||||
$customIcon = \Filament\Support\Facades\FilamentIcon::resolve($alias);
|
||||
$icon = $alias ? \Filament\Support\Facades\FilamentIcon::resolve($alias) : null;
|
||||
$group = $group ? \Filament\Support\Facades\FilamentIcon::resolve($group) : null;
|
||||
|
||||
if ($customIcon) {
|
||||
$name = $customIcon->name;
|
||||
if ($icon?->name) {
|
||||
$name = $icon->name;
|
||||
}
|
||||
|
||||
$class = array_merge(
|
||||
$group?->class ?? [],
|
||||
$icon?->class ?? [],
|
||||
Arr::wrap($class),
|
||||
$customIcon?->class ?? [],
|
||||
);
|
||||
|
||||
$color = $customIcon?->color ?? $color;
|
||||
$color = $icon?->color ?? $group?->color ?? $color;
|
||||
|
||||
if ($color !== null) {
|
||||
$class[] = $color;
|
||||
}
|
||||
|
||||
$class[] = $customIcon?->size ?? $size;
|
||||
$class[] = $icon?->size ?? $group?->size ?? $size;
|
||||
@endphp
|
||||
|
||||
@if ($name)
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
@if ($icon && $iconPosition === 'before')
|
||||
<x-filament::icon
|
||||
:name="$icon"
|
||||
alias="support::link.prefix"
|
||||
group="support::link.prefix"
|
||||
:size="$iconSize"
|
||||
:class="$iconClasses"
|
||||
/>
|
||||
@@ -81,7 +81,7 @@
|
||||
@if ($icon && $iconPosition === 'after')
|
||||
<x-filament::icon
|
||||
:name="$icon"
|
||||
alias="support::link.suffix"
|
||||
group="support::link.suffix"
|
||||
:size="$iconSize"
|
||||
:class="$iconClasses"
|
||||
/>
|
||||
@@ -111,7 +111,7 @@
|
||||
@if ($icon)
|
||||
<x-filament::icon
|
||||
:name="$icon"
|
||||
alias="support::link.prefix"
|
||||
group="support::link.prefix"
|
||||
:size="$iconSize"
|
||||
:class="$iconClasses"
|
||||
:wire:loading.remove.delay="$hasLoadingIndicator"
|
||||
@@ -135,7 +135,7 @@
|
||||
@if ($icon)
|
||||
<x-filament::icon
|
||||
:name="$icon"
|
||||
alias="support::link.suffix"
|
||||
group="support::link.suffix"
|
||||
:size="$iconSize"
|
||||
:class="$iconClasses"
|
||||
:wire:loading.remove.delay="$hasLoadingIndicator"
|
||||
|
||||
Reference in New Issue
Block a user