diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cf80a9ae..7ef365e6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,6 +10,8 @@ jobs: - uses: actions/checkout@v1 - name: Install dependencies run: composer install --prefer-dist --no-progress --no-suggest + - name: Validate Twig templates + run: php artisan twig:lint -v frontend: name: JavaScript Check runs-on: ubuntu-latest diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php index 32a7107f..7f5e1ca7 100644 --- a/app/Http/Controllers/AdminController.php +++ b/app/Http/Controllers/AdminController.php @@ -21,6 +21,18 @@ use Illuminate\Support\Facades\Redis; class AdminController extends Controller { + public function index() + { + return view('admin.index', [ + 'sum' => [ + 'users' => User::count(), + 'players' => Player::count(), + 'textures' => Texture::count(), + 'storage' => Texture::select('size')->sum('size'), + ], + ]); + } + public function chartData() { $today = Carbon::today()->timestamp; @@ -105,7 +117,7 @@ class AdminController extends Controller return redirect('/admin'); } - public function customize(Request $request) + public function customize(Request $request, \App\Services\Webpack $webpack) { $homepage = Option::form('homepage', OptionForm::AUTO_DETECT, function ($form) { $form->text('home_pic_url')->hint(); @@ -142,7 +154,14 @@ class AdminController extends Controller option(['color_scheme' => $color]); } - return view('admin.customize', ['forms' => compact('homepage', 'customJsCss')]); + return view('admin.customize', [ + 'colors' => ['blue', 'yellow', 'green', 'purple', 'red', 'black'], + 'skins_css' => $webpack->url('skins/_all-skins.min.css'), + 'forms' => [ + 'homepage' => $homepage, + 'custom_js_css' => $customJsCss, + ], + ]); } public function score() diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index f4aaa527..71976160 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -41,21 +41,26 @@ class UserController extends Controller $user = Auth::user(); [$from, $to] = explode(',', option('sign_score')); - $scoreIntro = nl2br(trans('user.score-intro.introduction', [ + $scoreIntro = trans('user.score-intro.introduction', [ 'initial_score' => option('user_initial_score'), 'score-from' => $from, 'score-to' => $to, 'return-score' => option('return_score') ? trans('user.score-intro.will-return-score') : trans('user.score-intro.no-return-score'), - ])); + ]); return view('user.index')->with([ 'statistics' => [ 'players' => $this->calculatePercentageUsed($user->players->count(), option('score_per_player')), 'storage' => $this->calculatePercentageUsed($this->getStorageUsed($user), option('score_per_storage')), ], - 'scoreIntro' => $scoreIntro, + 'score_intro' => $scoreIntro, + 'rates' => [ + 'storage' => option('score_per_storage'), + 'player' => option('score_per_player'), + 'closet' => option('score_per_closet_item'), + ], 'announcement' => app('parsedown')->text(option_localized('announcement')), 'extra' => ['unverified' => option('require_verification') && ! $user->verified], ]); diff --git a/app/Http/View/Composers/FootComposer.php b/app/Http/View/Composers/FootComposer.php new file mode 100644 index 00000000..78e9c3d3 --- /dev/null +++ b/app/Http/View/Composers/FootComposer.php @@ -0,0 +1,70 @@ +request = $request; + $this->webpack = $webpack; + $this->javascript = $javascript; + $this->dispatcher = $dispatcher; + } + + public function compose(View $view) + { + $this->injectJavaScript($view); + $this->addExtra($view); + } + + public function injectJavaScript(View $view) + { + $scripts = []; + + $locale = app()->getLocale(); + $scripts[] = $this->javascript->generate($locale); + if ($pluginI18n = $this->javascript->plugin($locale)) { + $scripts[] = $pluginI18n; + } + if ($this->request->is('admin*') && auth()->user()->permission >= User::SUPER_ADMIN) { + $scripts[] = $this->webpack->url('check-updates.js'); + } + $scripts[] = $this->webpack->url('index.js'); + + $view->with([ + 'scripts' => $scripts, + 'inline_js' => option('custom_js'), + ]); + } + + public function addExtra(View $view) + { + $content = []; + $this->dispatcher->dispatch(new \App\Events\RenderingFooter($content)); + $view->with('extra_foot', $content); + } +} diff --git a/app/Http/View/Composers/HeadComposer.php b/app/Http/View/Composers/HeadComposer.php new file mode 100644 index 00000000..28f09c15 --- /dev/null +++ b/app/Http/View/Composers/HeadComposer.php @@ -0,0 +1,79 @@ +webpack = $webpack; + $this->dispatcher = $dispatcher; + } + + public function compose(View $view) + { + $this->addFavicon($view); + $this->applyThemeColor($view); + $this->seo($view); + $this->injectStyles($view); + $this->addExtra($view); + } + + public function addFavicon(View $view) + { + $url = option('favicon_url', config('options.favicon_url')); + $url = Str::startsWith($url, 'http') ? $url : url($url); + $view->with('favicon', $url); + } + + public function applyThemeColor(View $view) + { + $colors = [ + 'blue' => '#3c8dbc', + 'yellow' => '#f39c12', + 'green' => '#00a65a', + 'purple' => '#605ca8', + 'red' => '#dd4b39', + 'black' => '#ffffff', + ]; + preg_match('/skin-(\w+)?(?:-light)?/', option('color_scheme'), $matches); + $view->with('theme_color', Arr::get($colors, $matches[1])); + } + + public function seo(View $view) + { + $view->with('seo', [ + 'keywords' => option('meta_keywords'), + 'description' => option('meta_description'), + 'extra' => option('meta_extras'), + ]); + } + + public function injectStyles(View $view) + { + $view->with('styles', [ + $this->webpack->url('style.css'), + $this->webpack->url('skins/'.option('color_scheme').'.min.css'), + ]); + $view->with('inline_css', option('custom_css')); + } + + public function addExtra(View $view) + { + $content = []; + $this->dispatcher->dispatch(new \App\Events\RenderingHeader($content)); + $view->with('extra_head', $content); + } +} diff --git a/app/Http/View/Composers/LanguagesMenuComposer.php b/app/Http/View/Composers/LanguagesMenuComposer.php new file mode 100644 index 00000000..d0dc26b0 --- /dev/null +++ b/app/Http/View/Composers/LanguagesMenuComposer.php @@ -0,0 +1,40 @@ +request = $request; + } + + public function compose(View $view) + { + $query = $this->request->query(); + $url = $this->request->url(); + + $langs = collect(config('locales')) + ->reject(function ($locale) { + return Arr::has($locale, 'alias'); + }) + ->map(function ($locale, $id) use ($query, $url) { + $query = array_merge($query, ['lang' => $id]); + $locale['url'] = $url.'?'.http_build_query($query); + + return $locale; + }); + + $view->with([ + 'current' => config('locales.'.app()->getLocale().'.short_name'), + 'langs' => $langs, + ]); + } +} diff --git a/app/Http/View/Composers/SideMenuComposer.php b/app/Http/View/Composers/SideMenuComposer.php new file mode 100644 index 00000000..b6a1cb1a --- /dev/null +++ b/app/Http/View/Composers/SideMenuComposer.php @@ -0,0 +1,101 @@ +request = $request; + } + + public function compose(View $view) + { + $type = $view->gatherData()['type']; + + $menu = config('menu'); + switch ($type) { + case 'user': + event(new Events\ConfigureUserMenu($menu)); + break; + case 'explore': + event(new Events\ConfigureExploreMenu($menu)); + break; + case 'admin': + event(new Events\ConfigureAdminMenu($menu)); + $menu['admin'] = $this->collectPluginConfigs($menu['admin']); + break; + } + + $view->with('items', array_map(function ($item) { + return $this->transform($item); + }, $menu[$type])); + } + + public function transform(array $item): array + { + $isActive = $this->request->is(Arr::get($item, 'link')); + foreach (Arr::get($item, 'children', []) as $k => $v) { + if ($this->request->is(Arr::get($v, 'link'))) { + $isActive = true; + break; + } + } + + $classes = []; + if ($isActive) { + $classes[] = 'active menu-open'; + } + + if (Arr::has($item, 'children')) { + $classes[] = 'treeview'; + $item['children'] = array_map(function ($item) { + return $this->transform($item); + }, $item['children']); + } + + $item['classes'] = $classes; + + return $item; + } + + public function collectPluginConfigs(array &$menu) + { + $menu = array_map(function ($item) { + if (Arr::get($item, 'id') === 'plugin-configs') { + $pluginConfigs = resolve(PluginManager::class) + ->getEnabledPlugins() + ->filter(function ($plugin) { + return $plugin->hasConfigView(); + }) + ->map(function ($plugin) { + return [ + 'title' => trans($plugin->title), + 'link' => 'admin/plugins/config/'.$plugin->name, + 'icon' => 'fa-circle', + ]; + }); + + // Don't display this menu item when no plugin config is available + if ($pluginConfigs->isNotEmpty()) { + $item['children'] = array_merge($item['children'], $pluginConfigs->values()->all()); + + return $item; + } + } else { + return $item; + } + }, $menu); + + return array_filter($menu); // Remove empty items + } +} diff --git a/app/Http/View/Composers/UserMenuComposer.php b/app/Http/View/Composers/UserMenuComposer.php new file mode 100644 index 00000000..d59063ca --- /dev/null +++ b/app/Http/View/Composers/UserMenuComposer.php @@ -0,0 +1,35 @@ +request = $request; + } + + public function compose(View $view) + { + $user = auth()->user(); + $view->with('user', $user); + + if ($this->request->is('skinlib*') || $this->request->is('/')) { + $view->with( + 'tiny_avatar', + url('avatar/25/'.base64_encode($user->email).'.png?tid='.$user->avatar) + ); + } + + $view->with( + 'avatar', + url('avatar/128/'.base64_encode($user->email).'.png?tid='.$user->avatar) + ); + } +} diff --git a/app/Http/View/Composers/UserPanelComposer.php b/app/Http/View/Composers/UserPanelComposer.php new file mode 100644 index 00000000..6ba1efc3 --- /dev/null +++ b/app/Http/View/Composers/UserPanelComposer.php @@ -0,0 +1,41 @@ +dispatcher = $dispatcher; + } + + public function compose(View $view) + { + $user = auth()->user(); + $roles = [ + User::BANNED => 'banned', + User::NORMAL => 'normal', + User::ADMIN => 'admin', + User::SUPER_ADMIN => 'super-admin', + ]; + $role = $roles[$user->permission]; + $avatar = url('avatar/45/'.base64_encode($user->email).'.png?tid='.$user->avatar); + + $badges = []; + $this->dispatcher->dispatch(new \App\Events\RenderingBadges($badges)); + + $view->with([ + 'user' => $user, + 'role' => trans("admin.users.status.$role"), + 'avatar' => $avatar, + 'badges' => $badges, + ]); + } +} diff --git a/app/Providers/ViewServiceProvider.php b/app/Providers/ViewServiceProvider.php new file mode 100644 index 00000000..4e09009b --- /dev/null +++ b/app/Providers/ViewServiceProvider.php @@ -0,0 +1,54 @@ +with([ + 'site_name' => option_localized('site_name'), + 'color_scheme' => option('color_scheme'), + ]); + }); + + View::composer('shared.head', Composers\HeadComposer::class); + + View::composer('shared.notifications', function ($view) { + $notifications = auth()->user()->unreadNotifications; + $view->with([ + 'notifications' => $notifications, + 'amount' => count($notifications), + ]); + }); + + View::composer('shared.languages', Composers\LanguagesMenuComposer::class); + + View::composer('shared.user-menu', Composers\UserMenuComposer::class); + + View::composer('shared.side-menu', Composers\SideMenuComposer::class); + + View::composer('shared.user-panel', Composers\UserPanelComposer::class); + + View::composer('shared.footer', function ($view) { + $customCopyright = get_string_replaced( + option_localized('copyright_text'), + [ + '{site_name}' => option_localized('site_name'), + '{site_url}' => option('site_url'), + ] + ); + $view->with([ + 'copyright' => option_localized('copyright_prefer', 0), + 'custom_copyright' => $customCopyright, + ]); + }); + + View::composer('shared.foot', Composers\FootComposer::class); + } +} diff --git a/app/helpers.php b/app/helpers.php index 153bc7bd..e93e7c57 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -77,102 +77,6 @@ if (! function_exists('bs_header_extra')) { } } -if (! function_exists('bs_menu')) { - function bs_menu(string $type): string - { - $menu = config('menu'); - - switch ($type) { - case 'user': - event(new App\Events\ConfigureUserMenu($menu)); - break; - case 'explore': - event(new App\Events\ConfigureExploreMenu($menu)); - break; - case 'admin': - event(new App\Events\ConfigureAdminMenu($menu)); - break; - } - - if (! isset($menu[$type])) { - throw new InvalidArgumentException; - } - - $menu[$type] = array_map(function ($item) { - if (Arr::get($item, 'id') === 'plugin-configs') { - $pluginConfigs = app('plugins')->getEnabledPlugins() - ->filter(function ($plugin) { - return $plugin->hasConfigView(); - }) - ->map(function ($plugin) { - return [ - 'title' => trans($plugin->title), - 'link' => 'admin/plugins/config/'.$plugin->name, - 'icon' => 'fa-circle', - ]; - }); - - // Don't display this menu item when no plugin config is available - if ($pluginConfigs->isNotEmpty()) { - $item['children'] = array_merge($item['children'], $pluginConfigs->values()->all()); - - return $item; - } - } else { - return $item; - } - }, $menu[$type]); - - return bs_menu_render($menu[$type]); - } - - function bs_menu_render(array $data): string - { - $content = ''; - - foreach ($data as $key => $value) { - $active = app('request')->is(@$value['link']); - - // also set parent as active if any child is active - foreach ((array) @$value['children'] as $childKey => $childValue) { - if (app('request')->is(@$childValue['link'])) { - $active = true; - } - } - - $classes = []; - $active ? ($classes[] = 'active menu-open') : null; - isset($value['children']) ? ($classes[] = 'treeview') : null; - - $attr = count($classes) ? sprintf(' class="%s"', implode(' ', $classes)) : ''; - - $content .= ""; - - if (isset($value['children'])) { - $content .= sprintf('  %s', $value['icon'], trans($value['title'])); - - // recurse - $content .= ''; - } else { - if ($value) { - $content .= sprintf( - '  %s', - url((string) $value['link']), - Arr::get($value, 'new-tab') ? 'target="_blank"' : '', - $value['icon'] == 'fa-circle' ? 'far' : 'fas', - (string) $value['icon'], - trans((string) $value['title']) - ); - } - } - - $content .= ''; - } - - return $content; - } -} - if (! function_exists('bs_copyright')) { function bs_copyright(): string { @@ -323,22 +227,6 @@ if (! function_exists('is_request_secure')) { } } -if (! function_exists('nl2p')) { - /** - * Wrap blocks of text (delimited by \n) in p tags (similar to nl2br). - * - * @param string $text - * @return string - */ - function nl2p(string $text): string - { - $parts = explode("\n", $text); - $result = '

'.implode('

', $parts).'

'; - // Remove empty paragraphs - return str_replace('

', '', $result); - } -} - if (! function_exists('png')) { function png($resource) { diff --git a/composer.json b/composer.json index 9bd58eaf..ad56831d 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,9 @@ "composer/ca-bundle": "^1.2", "facade/ignition": "^1.4", "spatie/laravel-translation-loader": "^2.4", - "symfony/yaml": "^4.3" + "symfony/yaml": "^4.3", + "twig/twig": "^2.11", + "rcrowe/twigbridge": "^0.11.1" }, "require-dev": { "fzaninotto/faker": "~1.8", diff --git a/composer.lock b/composer.lock index 9a9ecf50..6191f436 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e0bda645aa2fc04fc9dc1d6e0d711c50", + "content-hash": "5ac658b15e8a3bf5b2f92d73193abf8a", "packages": [ { "name": "composer/ca-bundle", @@ -2577,6 +2577,78 @@ ], "time": "2018-07-19T23:38:55+00:00" }, + { + "name": "rcrowe/twigbridge", + "version": "v0.11.1", + "source": { + "type": "git", + "url": "https://github.com/rcrowe/TwigBridge.git", + "reference": "2054abdbd8dcde573cd86d8d3856873e2388d47b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rcrowe/TwigBridge/zipball/2054abdbd8dcde573cd86d8d3856873e2388d47b", + "reference": "2054abdbd8dcde573cd86d8d3856873e2388d47b", + "shasum": "" + }, + "require": { + "illuminate/support": "5.5.*|5.6.*|5.7.*|5.8.x|6.0.*", + "illuminate/view": "5.5.*|5.6.*|5.7.*|5.8.x|6.0.*", + "php": ">=7.1", + "twig/twig": "~2.0" + }, + "require-dev": { + "laravel/framework": "5.5.*", + "mockery/mockery": "0.9.*", + "phpunit/phpunit": "~6.0", + "satooshi/php-coveralls": "~0.6", + "squizlabs/php_codesniffer": "~1.5" + }, + "suggest": { + "laravelcollective/html": "For bringing back html/form in Laravel 5.x", + "twig/extensions": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.11-dev" + }, + "laravel": { + "providers": [ + "TwigBridge\\ServiceProvider" + ], + "aliases": { + "Twig": "TwigBridge\\Facade\\Twig" + } + } + }, + "autoload": { + "psr-4": { + "TwigBridge\\": "src", + "TwigBridge\\Tests\\": "tests" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Crowe", + "email": "hello@vivalacrowe.com" + }, + { + "name": "Barry vd. Heuvel", + "email": "barryvdh@gmail.com" + } + ], + "description": "Adds the power of Twig to Laravel", + "keywords": [ + "laravel", + "twig" + ], + "time": "2019-09-05T11:59:53+00:00" + }, { "name": "scrivo/highlight.php", "version": "v9.15.10.0", @@ -4356,6 +4428,73 @@ "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", "time": "2017-11-27T11:13:29+00:00" }, + { + "name": "twig/twig", + "version": "v2.11.3", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "699ed2342557c88789a15402de5eb834dedd6792" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/699ed2342557c88789a15402de5eb834dedd6792", + "reference": "699ed2342557c88789a15402de5eb834dedd6792", + "shasum": "" + }, + "require": { + "php": "^7.0", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3" + }, + "require-dev": { + "psr/container": "^1.0", + "symfony/debug": "^2.7", + "symfony/phpunit-bridge": "^3.4.19|^4.1.8|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.11-dev" + } + }, + "autoload": { + "psr-0": { + "Twig_": "lib/" + }, + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + }, + { + "name": "Twig Team", + "homepage": "https://twig.symfony.com/contributors", + "role": "Contributors" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "time": "2019-06-18T15:37:11+00:00" + }, { "name": "tymon/jwt-auth", "version": "dev-develop", diff --git a/config/app.php b/config/app.php index 432e8353..f0e753a6 100644 --- a/config/app.php +++ b/config/app.php @@ -188,7 +188,7 @@ return [ App\Providers\PluginServiceProvider::class, App\Providers\RouteServiceProvider::class, App\Providers\ValidatorExtendServiceProvider::class, - + App\Providers\ViewServiceProvider::class, ], /* diff --git a/config/twigbridge.php b/config/twigbridge.php new file mode 100644 index 00000000..c3cc931c --- /dev/null +++ b/config/twigbridge.php @@ -0,0 +1,214 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Configuration options for Twig. + */ +return [ + + 'twig' => [ + /* + |-------------------------------------------------------------------------- + | Extension + |-------------------------------------------------------------------------- + | + | File extension for Twig view files. + | + */ + 'extension' => 'twig', + + /* + |-------------------------------------------------------------------------- + | Accepts all Twig environment configuration options + |-------------------------------------------------------------------------- + | + | http://twig.sensiolabs.org/doc/api.html#environment-options + | + */ + 'environment' => [ + + // When set to true, the generated templates have a __toString() method + // that you can use to display the generated nodes. + // default: false + 'debug' => env('APP_DEBUG', false), + + // The charset used by the templates. + // default: utf-8 + 'charset' => 'utf-8', + + // The base template class to use for generated templates. + // default: TwigBridge\Twig\Template + 'base_template_class' => 'TwigBridge\Twig\Template', + + // An absolute path where to store the compiled templates, or false to disable caching. If null + // then the cache file path is used. + // default: cache file storage path + 'cache' => null, + + // When developing with Twig, it's useful to recompile the template + // whenever the source code changes. If you don't provide a value + // for the auto_reload option, it will be determined automatically based on the debug value. + 'auto_reload' => true, + + // If set to false, Twig will silently ignore invalid variables + // (variables and or attributes/methods that do not exist) and + // replace them with a null value. When set to true, Twig throws an exception instead. + // default: false + 'strict_variables' => false, + + // If set to true, auto-escaping will be enabled by default for all templates. + // default: 'html' + 'autoescape' => 'html', + + // A flag that indicates which optimizations to apply + // (default to -1 -- all optimizations are enabled; set it to 0 to disable) + 'optimizations' => -1, + ], + + /* + |-------------------------------------------------------------------------- + | Global variables + |-------------------------------------------------------------------------- + | + | These will always be passed in and can be accessed as Twig variables. + | NOTE: these will be overwritten if you pass data into the view with the same key. + | + */ + 'globals' => [], + ], + + 'extensions' => [ + + /* + |-------------------------------------------------------------------------- + | Extensions + |-------------------------------------------------------------------------- + | + | Enabled extensions. + | + | `Twig\Extension\DebugExtension` is enabled automatically if twig.debug is TRUE. + | + */ + 'enabled' => [ + 'Twig\Extension\StringLoaderExtension', + + 'TwigBridge\Extension\Loader\Facades', + 'TwigBridge\Extension\Loader\Filters', + 'TwigBridge\Extension\Loader\Functions', + + 'TwigBridge\Extension\Laravel\Auth', + 'TwigBridge\Extension\Laravel\Config', + 'TwigBridge\Extension\Laravel\Dump', + // 'TwigBridge\Extension\Laravel\Input', + 'TwigBridge\Extension\Laravel\Session', + // 'TwigBridge\Extension\Laravel\Str', + 'TwigBridge\Extension\Laravel\Translator', + 'TwigBridge\Extension\Laravel\Url', + // 'TwigBridge\Extension\Laravel\Model', + // 'TwigBridge\Extension\Laravel\Gate', + + // 'TwigBridge\Extension\Laravel\Form', + // 'TwigBridge\Extension\Laravel\Html', + // 'TwigBridge\Extension\Laravel\Legacy\Facades', + ], + + /* + |-------------------------------------------------------------------------- + | Facades + |-------------------------------------------------------------------------- + | + | Available facades. Access like `{{ Config.get('foo.bar') }}`. + | + | Each facade can take an optional array of options. To mark the whole facade + | as safe you can set the option `'is_safe' => true`. Setting the facade as + | safe means that any HTML returned will not be escaped. + | + | It is advisable to not set the whole facade as safe and instead mark the + | each appropriate method as safe for security reasons. You can do that with + | the following syntax: + | + | + | 'Form' => [ + | 'is_safe' => [ + | 'open' + | ] + | ] + | + | + | The values of the `is_safe` array must match the called method on the facade + | in order to be marked as safe. + | + */ + 'facades' => [], + + /* + |-------------------------------------------------------------------------- + | Functions + |-------------------------------------------------------------------------- + | + | Available functions. Access like `{{ secure_url(...) }}`. + | + | Each function can take an optional array of options. These options are + | passed directly to `Twig\TwigFunction`. + | + | So for example, to mark a function as safe you can do the following: + | + | + | 'link_to' => [ + | 'is_safe' => ['html'] + | ] + | + | + | The options array also takes a `callback` that allows you to name the + | function differently in your Twig templates than what it's actually called. + | + | + | 'link' => [ + | 'callback' => 'link_to' + | ] + | + | + */ + 'functions' => [], + + /* + |-------------------------------------------------------------------------- + | Filters + |-------------------------------------------------------------------------- + | + | Available filters. Access like `{{ variable|filter }}`. + | + | Each filter can take an optional array of options. These options are + | passed directly to `Twig\TwigFilter`. + | + | So for example, to mark a filter as safe you can do the following: + | + | + | 'studly_case' => [ + | 'is_safe' => ['html'] + | ] + | + | + | The options array also takes a `callback` that allows you to name the + | filter differently in your Twig templates than what is actually called. + | + | + | 'snake' => [ + | 'callback' => 'snake_case' + | ] + | + | + */ + 'filters' => [ + 'get' => 'data_get', + ], + ], +]; diff --git a/resources/assets/src/styles/common.styl b/resources/assets/src/styles/common.styl index d211e743..b820fe63 100644 --- a/resources/assets/src/styles/common.styl +++ b/resources/assets/src/styles/common.styl @@ -57,6 +57,9 @@ body, h1, h2, h3, h4, h5, h6 .main-header .navbar .user-menu .user-image border-radius 10% +.navbar-nav > .user-menu > .dropdown-menu > li.user-header + height unset + #language-menu li a color #777 diff --git a/resources/lang/en/admin.yml b/resources/lang/en/admin.yml index 3d365e23..755be9b8 100644 --- a/resources/lang/en/admin.yml +++ b/resources/lang/en/admin.yml @@ -159,15 +159,16 @@ update: latest: "Latest Version:" current: "Current Version:" - check-github: Check GitHub Releases + check-github: Check GitHub Releases button: Update Now cautions: title: Cautions + link: check out this. text: | Please choose update source according to your host's network environment. Low-speed connection between update source and your host will cause long-time loading at checking and downloading page. - To change the default update source, please refer to this article. + To change the default update source, download: downloading: Downloading update package... diff --git a/resources/lang/zh_CN/admin.yml b/resources/lang/zh_CN/admin.yml index 5bcb3bd6..a173bd60 100644 --- a/resources/lang/zh_CN/admin.yml +++ b/resources/lang/zh_CN/admin.yml @@ -164,15 +164,16 @@ update: latest: 最新版本: current: 当前版本: - check-github: 查看 GitHub Releases + check-github: 查看 GitHub Releases button: 马上升级 cautions: title: 注意事项 + link: 点击了解详情 text: | 请根据你的主机所在位置(国内/国外)选择更新源。 如错选至相对于你的主机速度较慢的源,可能会造成检查与下载更新页面长时间无响应。 - 如何更换更新源?点击了解详情。 + 如何更换更新源? download: downloading: 正在下载更新包 diff --git a/resources/views/admin/base.twig b/resources/views/admin/base.twig new file mode 100644 index 00000000..3e745839 --- /dev/null +++ b/resources/views/admin/base.twig @@ -0,0 +1,25 @@ + + + + {{ include('shared.head') }} + {% block title %}{% endblock %} - {{ site_name }} + + + +
+ {{ include('shared.header') }} + {{ include('shared.sidebar', {scope: 'admin'}) }} +
+
+

{{ block('title') }}

+
+
+ {% block content %}{% endblock %} +
+
+ {{ include('shared.footer') }} +
+ {% block before_foot %}{% endblock %} + {{ include('shared.foot') }} + + diff --git a/resources/views/admin/customize.blade.php b/resources/views/admin/customize.blade.php deleted file mode 100644 index 3939cef4..00000000 --- a/resources/views/admin/customize.blade.php +++ /dev/null @@ -1,81 +0,0 @@ -@extends('admin.master') - -@section('title', trans('general.customize')) - -@section('style') - -@endsection - -@section('content') - - -
- -
-

- @lang('general.customize') -

-
- - -
- -
-
-
- @csrf -
-

- @lang('admin.customize.change-color.title') -

-
-
- - @php - $colors = ['blue', 'yellow', 'green', 'purple', 'red', 'black']; - @endphp - - @foreach ($colors as $color) - - - - - - - - - @endforeach - -
@lang('admin.customize.colors.'.$color) - -
@lang('admin.customize.colors.'.$color.'-light') - -
-
- -
-
- -
- {!! $forms['homepage']->render() !!} - - {!! $forms['customJsCss']->render() !!} -
- -
- -
-
-@endsection diff --git a/resources/views/admin/customize.twig b/resources/views/admin/customize.twig new file mode 100644 index 00000000..8011ac3d --- /dev/null +++ b/resources/views/admin/customize.twig @@ -0,0 +1,74 @@ +{% extends 'admin.base' %} + +{% block title %}{{ trans('general.customize') }}{% endblock %} + +{% block content %} +
+
+
+ {{ csrf_field() }} +
+

+ {{ trans('admin.customize.change-color.title') }} +

+
+
+ + + {% for color in colors %} + + + + + + + + + {% endfor %} + +
{{ trans("admin.customize.colors.#{color}") }} + +
{{ trans("admin.customize.colors.#{color}-light") }} + +
+
+ +
+
+
+ {{ forms.homepage|raw }} + {{ forms.custom_js_css|raw }} +
+
+{% endblock %} + +{% block before_foot %} + +{% endblock %} diff --git a/resources/views/admin/i18n.blade.php b/resources/views/admin/i18n.blade.php deleted file mode 100644 index d72d500b..00000000 --- a/resources/views/admin/i18n.blade.php +++ /dev/null @@ -1,67 +0,0 @@ -@extends('admin.master') - -@section('title', trans('general.i18n')) - -@section('content') -
-
-

@lang('general.i18n')

-
- -
-
-
-
-
-
-
-
-
-

@lang('admin.i18n.add')

-
-
- @if (session()->pull('success')) -
@lang('admin.i18n.added')
- @endif - @if ($errors->any()) -
{{ $errors->first() }}
- @endif - @csrf - - - - - - - - - - - - - - - -
@lang('admin.i18n.group') - -
@lang('admin.i18n.key') - -
@lang('admin.i18n.text') - -
-
- -
-
- -
-
-
-
-@endsection diff --git a/resources/views/admin/i18n.twig b/resources/views/admin/i18n.twig new file mode 100644 index 00000000..f07e038e --- /dev/null +++ b/resources/views/admin/i18n.twig @@ -0,0 +1,60 @@ +{% extends 'admin.base' %} + +{% block title %}{{ trans('general.i18n') }}{% endblock %} + +{% block content %} +
+
+
+
+
+
+

{{ trans('admin.i18n.add') }}

+
+
+ {% if errors.any %} +
{{ errors.first }}
+ {% elseif session_pull('success') %} +
{{ trans('admin.i18n.added') }}
+ {% endif %} + {{ csrf_field() }} + + + + + + + + + + + + + + + +
{{ trans('admin.i18n.group') }} + +
{{ trans('admin.i18n.key') }} + +
{{ trans('admin.i18n.text') }} + +
+
+ +
+
+ +
+
+{% endblock %} diff --git a/resources/views/admin/index.blade.php b/resources/views/admin/index.blade.php deleted file mode 100644 index ab806e6a..00000000 --- a/resources/views/admin/index.blade.php +++ /dev/null @@ -1,145 +0,0 @@ -@extends('admin.master') - -@section('title', trans('general.dashboard')) - -@section('content') - -
- -
-

- @lang('general.dashboard') -

-
- - -
- -
-
-
-
-
-
-

{{ resolve(\App\Models\User::class)->count() }}

-

@lang('admin.index.total-users')

-
-
- - @lang('general.user-manage') - -
-
- -
-
-
-

{{ App\Models\Player::count() }}

-

@lang('admin.index.total-players')

-
-
- - @lang('general.player-manage') - -
-
-
- -
-
-
-
-

{{ App\Models\Texture::count() }}

-

@lang('admin.index.total-textures')

-
-
-
-
- -
-
-
- @php - $size = DB::table('textures')->sum('size') ?: 0; - @endphp -

{{ $size > 1024 ? round($size / 1024, 1).'MB' : $size.'KB' }}

-

@lang('admin.index.disk-usage')

-
-
-
-
-
- -
-
-

@lang('admin.notifications.send.title')

-
-
- @csrf -
- @if ($errors->any()) -
{{ $errors->first() }}
- @endif - @if ($sentResult = Session::pull('sentResult')) -
{{ $sentResult }}
- @endif -
- -
- -
-
- -
-
- -
-
- -
-
-
- - -
-
- - -
-
- -
-
-
- -
-
-
-

@lang('admin.index.overview')

-
-
-
-
-
-
-
- -
-
-@endsection diff --git a/resources/views/admin/index.twig b/resources/views/admin/index.twig new file mode 100644 index 00000000..440664a5 --- /dev/null +++ b/resources/views/admin/index.twig @@ -0,0 +1,136 @@ +{% extends 'admin.base' %} + +{% block title %}{{ trans('general.dashboard') }}{% endblock %} + +{% block content %} +
+
+
+
+
+
+

{{ sum.users }}

+

{{ trans('admin.index.total-users') }}

+
+
+ + {{ trans('general.user-manage') }}  + + +
+
+ +
+
+
+

{{ sum.players }}

+

{{ trans('admin.index.total-players') }}

+
+
+ + {{ trans('general.player-manage') }}  + + +
+
+
+ +
+
+
+
+

{{ sum.textures }}

+

{{ trans('admin.index.total-textures') }}

+
+
+
+
+ +
+
+
+ {% if sum.storage > 1024 %} +

{{ (sum.storage / 1024)|round(1) }}MB

+ {% else %} +

{{ sum.storage }}KB

+ {% endif %} +

{{ trans('admin.index.disk-usage') }}

+
+
+
+
+
+ +
+
+

{{ trans('admin.notifications.send.title') }}

+
+
+ {{ csrf_field() }} +
+ {% if errors.any %} +
{{ errors.first }}
+ {% endif %} + {% set sent_result = session_pull('sentResult') %} + {% if sent_result %} +
{{ sent_result }}
+ {% endif %} +
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+
+ + +
+
+ + +
+
+ +
+
+
+ +
+
+
+

{{ trans('admin.index.overview') }}

+
+
+
+
+
+{% endblock %} diff --git a/resources/views/admin/market.blade.php b/resources/views/admin/market.blade.php deleted file mode 100644 index 6b1a0236..00000000 --- a/resources/views/admin/market.blade.php +++ /dev/null @@ -1,2 +0,0 @@ -@component('common.skeleton', ['parent' => 'admin', 'title' => trans('general.plugin-market')]) -@endcomponent diff --git a/resources/views/admin/market.twig b/resources/views/admin/market.twig new file mode 100644 index 00000000..5313a772 --- /dev/null +++ b/resources/views/admin/market.twig @@ -0,0 +1,3 @@ +{% extends 'admin.base' %} + +{% block title %}{{ trans('general.plugin-market') }}{% endblock %} diff --git a/resources/views/admin/master.blade.php b/resources/views/admin/master.blade.php index 8c0fba75..e75cf369 100644 --- a/resources/views/admin/master.blade.php +++ b/resources/views/admin/master.blade.php @@ -1,94 +1,20 @@ - + - - + @include('shared.head') @yield('title') - {{ option_localized('site_name') }} - @include('common.favicon') - - - - @include('common.theme-color') - - @include('common.dependencies.style') - @yield('style') -@php - $user = auth()->user(); -@endphp -
- - -
- - - - - - -
- - - + @include('shared.header') + @include('shared.sidebar', ['scope' => 'admin']) @yield('content') + @include('shared.footer') +
- - - - - - - @include('common.dependencies.script') - @if ($user->permission >= \App\Models\User::SUPER_ADMIN) - - @endif + @include('shared.foot') @yield('script') diff --git a/resources/views/admin/options.blade.php b/resources/views/admin/options.blade.php deleted file mode 100644 index 52e681a2..00000000 --- a/resources/views/admin/options.blade.php +++ /dev/null @@ -1,37 +0,0 @@ -@extends('admin.master') - -@section('title', trans('general.options')) - -@section('content') - - -
- -
-

- @lang('general.options') -

-
- - -
- -
-
- {!! $forms['general']->render() !!} -
- -
- {!! $forms['announ']->render() !!} - - {!! $forms['meta']->render() !!} - - {!! $forms['recaptcha']->render() !!} -
- -
- -
-
- -@endsection diff --git a/resources/views/admin/options.twig b/resources/views/admin/options.twig new file mode 100644 index 00000000..2edf9ce5 --- /dev/null +++ b/resources/views/admin/options.twig @@ -0,0 +1,16 @@ +{% extends 'admin.base' %} + +{% block title %}{{ trans('general.options') }}{% endblock %} + +{% block content %} +
+
+ {{ forms.general.render()|raw }} +
+
+ {{ forms.announ.render()|raw }} + {{ forms.meta.render()|raw }} + {{ forms.recaptcha.render()|raw }} +
+
+{% endblock %} diff --git a/resources/views/admin/players.blade.php b/resources/views/admin/players.blade.php deleted file mode 100644 index d9d5f996..00000000 --- a/resources/views/admin/players.blade.php +++ /dev/null @@ -1,2 +0,0 @@ -@component('common.skeleton', ['parent' => 'admin', 'title' => trans('general.player-manage')]) -@endcomponent diff --git a/resources/views/admin/players.twig b/resources/views/admin/players.twig new file mode 100644 index 00000000..1c9d5059 --- /dev/null +++ b/resources/views/admin/players.twig @@ -0,0 +1,3 @@ +{% extends 'admin.base' %} + +{% block title %}{{ trans('general.player-manage') }}{% endblock %} diff --git a/resources/views/admin/plugins.blade.php b/resources/views/admin/plugins.blade.php deleted file mode 100644 index 683d0492..00000000 --- a/resources/views/admin/plugins.blade.php +++ /dev/null @@ -1,2 +0,0 @@ -@component('common.skeleton', ['parent' => 'admin', 'title' => trans('general.plugin-manage')]) -@endcomponent diff --git a/resources/views/admin/plugins.twig b/resources/views/admin/plugins.twig new file mode 100644 index 00000000..a1b3883d --- /dev/null +++ b/resources/views/admin/plugins.twig @@ -0,0 +1,3 @@ +{% extends 'admin.base' %} + +{% block title %}{{ trans('general.plugin-manage') }}{% endblock %} diff --git a/resources/views/admin/reports.blade.php b/resources/views/admin/reports.blade.php deleted file mode 100644 index f50e41ce..00000000 --- a/resources/views/admin/reports.blade.php +++ /dev/null @@ -1,2 +0,0 @@ -@component('common.skeleton', ['parent' => 'admin', 'title' => trans('general.report-manage')]) -@endcomponent diff --git a/resources/views/admin/reports.twig b/resources/views/admin/reports.twig new file mode 100644 index 00000000..e81ce869 --- /dev/null +++ b/resources/views/admin/reports.twig @@ -0,0 +1,3 @@ +{% extends 'admin.base' %} + +{% block title %}{{ trans('general.report-manage') }}{% endblock %} diff --git a/resources/views/admin/resource.blade.php b/resources/views/admin/resource.blade.php deleted file mode 100644 index 15e27f6b..00000000 --- a/resources/views/admin/resource.blade.php +++ /dev/null @@ -1,41 +0,0 @@ -@extends('admin.master') - -@section('title', trans('general.res-options')) - -@section('content') - - -
- -
-

- @lang('general.res-options') -

-
- - -
- -
-
-
@lang('options.res-warning')
-
-
- -
-
- {!! $forms['resources']->render() !!} - - {!! $forms['redis']->render() !!} -
- -
- {!! $forms['cache']->render() !!} -
- -
- -
-
- -@endsection diff --git a/resources/views/admin/resource.twig b/resources/views/admin/resource.twig new file mode 100644 index 00000000..a99dbfe0 --- /dev/null +++ b/resources/views/admin/resource.twig @@ -0,0 +1,23 @@ +{% extends 'admin.base' %} + +{% block title %}{{ trans('general.res-options') }}{% endblock %} + +{% block content %} +
+
+
+ {{ trans('options.res-warning') }} +
+
+
+ +
+
+ {{ forms.resources.render()|raw }} + {{ forms.redis.render()|raw }} +
+
+ {{ forms.cache.render()|raw }} +
+
+{% endblock %} diff --git a/resources/views/admin/score.blade.php b/resources/views/admin/score.blade.php deleted file mode 100644 index 9f53c721..00000000 --- a/resources/views/admin/score.blade.php +++ /dev/null @@ -1,35 +0,0 @@ -@extends('admin.master') - -@section('title', trans('general.score-options')) - -@section('content') - - -
- -
-

- @lang('general.score-options') -

-
- - -
-
-
- {!! $forms['rate']->render() !!} - - {!! $forms['report']->render() !!} -
- -
- {!! $forms['sign']->render() !!} - - {!! $forms['sharing']->render() !!} -
- -
-
-
- -@endsection diff --git a/resources/views/admin/score.twig b/resources/views/admin/score.twig new file mode 100644 index 00000000..ae67cd7d --- /dev/null +++ b/resources/views/admin/score.twig @@ -0,0 +1,16 @@ +{% extends 'admin.base' %} + +{% block title %}{{ trans('general.score-options') }}{% endblock %} + +{% block content %} +
+
+ {{ forms.rate.render()|raw }} + {{ forms.report.render()|raw }} +
+
+ {{ forms.sign.render()|raw }} + {{ forms.sharing.render()|raw }} +
+
+{% endblock %} diff --git a/resources/views/admin/status.blade.php b/resources/views/admin/status.blade.php deleted file mode 100644 index ac6c613a..00000000 --- a/resources/views/admin/status.blade.php +++ /dev/null @@ -1,50 +0,0 @@ -@extends('admin.master') - -@section('title', trans('general.status')) - -@section('content') -
-
-

@lang('general.status')

-
- -
-
-
-
-
-

@lang('admin.status.info')

-
-
- - - @foreach ($detail as $category => $info) - - - - @foreach ($info as $key => $value) - - - - - @endforeach - @endforeach - - - - @foreach ($plugins as $plugin) - - - - - @endforeach - -
@lang("admin.status.$category.name")
@lang("admin.status.$category.$key"){{ $value }}
@lang('admin.status.plugins', ['amount' => $plugins->count()])
{{ $plugin['title'] }}{{ $plugin['version'] }}
-
-
-
-
-
-
-
-@endsection diff --git a/resources/views/admin/status.twig b/resources/views/admin/status.twig new file mode 100644 index 00000000..8da64aed --- /dev/null +++ b/resources/views/admin/status.twig @@ -0,0 +1,44 @@ +{% extends 'admin.base' %} + +{% block title %}{{ trans('general.status') }}{% endblock %} + +{% block content %} +
+
+
+
+

{{ trans('admin.status.info') }}

+
+
+ + + {% for category, info in detail %} + + + + {% for key, value in info %} + + + + + {% endfor %} + {% endfor %} + + + + {% for plugin in plugins %} + + + + + {% endfor %} + +
{{ trans("admin.status.#{category}.name") }}
{{ trans("admin.status.#{category}.#{key}") }}{{ value }}
+ {{ trans('admin.status.plugins', {amount: plugins|length}) }} +
{{ plugin.title }}{{ plugin.version }}
+
+
+
+
+
+{% endblock %} diff --git a/resources/views/admin/update.blade.php b/resources/views/admin/update.blade.php deleted file mode 100644 index 010bf38d..00000000 --- a/resources/views/admin/update.blade.php +++ /dev/null @@ -1,87 +0,0 @@ -@extends('admin.master') - -@section('title', trans('general.check-update')) - -@section('content') - - -
- -
-

- @lang('general.check-update') -

-
- - -
-
-
-
-
-

@lang('admin.update.info.title')

-
-
- @if ($extra['canUpdate']) -
@lang('admin.update.info.available')
- - - - - - - - - - - - -
@lang('admin.update.info.versions.latest') - v{{ $info['latest'] }} -
@lang('admin.update.info.versions.current') - v{{ $info['current'] }} -
- @else - - @if (is_string($error)) -
{{ trans('admin.update.errors.connection', ['error' => $error]) }}
- @else -
{{ trans('admin.update.info.up-to-date') }}
- @endif - - - - - - - - -
@lang('admin.update.info.versions.current') - v{{ $info['current'] }} -
- @endif -
- -
- -
-
-

@lang('admin.update.cautions.title')

-
-
- {!! nl2p(trans('admin.update.cautions.text')) !!} -
-
-
- -
-
-
- - -@endsection diff --git a/resources/views/admin/update.twig b/resources/views/admin/update.twig new file mode 100644 index 00000000..b7d3a049 --- /dev/null +++ b/resources/views/admin/update.twig @@ -0,0 +1,91 @@ +{% extends 'admin.base' %} + +{% block title %}{{ trans('general.check-update') }}{% endblock %} + +{% block content %} +
+
+
+
+

{{ trans('admin.update.info.title') }}

+
+
+ {% if extra.canUpdate %} +
+ {{ trans('admin.update.info.available') }} +
+ + + + + + + + + + + +
{{ trans('admin.update.info.versions.latest') }} + v{{ info.latest }} +
{{ trans('admin.update.info.versions.current') }} + v{{ info.current }} +
+ {% else %} + {% if error is not empty %} +
+ {{ trans('admin.update.errors.connection', {error: error}) }} +
+ {% else %} +
+ {{ trans('admin.update.info.up-to-date') }} +
+ {% endif %} + + + + + + + +
+ {{ trans('admin.update.info.versions.current') }} + v{{ info.current }} +
+ {% endif %} +
+ +
+ +
+
+

+ {{ trans('admin.update.cautions.title') }} +

+
+
+ {% for text in trans('admin.update.cautions.text')|split('\n') %} +

{{ text }}

+ {% endfor %} + + {{ trans('admin.update.cautions.link') }} + +
+
+
+
+{% endblock %} + +{% block before_foot %} + +{% endblock %} diff --git a/resources/views/admin/users.blade.php b/resources/views/admin/users.blade.php deleted file mode 100644 index 21d9eb78..00000000 --- a/resources/views/admin/users.blade.php +++ /dev/null @@ -1,2 +0,0 @@ -@component('common.skeleton', ['parent' => 'admin', 'title' => trans('general.user-manage')]) -@endcomponent diff --git a/resources/views/admin/users.twig b/resources/views/admin/users.twig new file mode 100644 index 00000000..421e4d0a --- /dev/null +++ b/resources/views/admin/users.twig @@ -0,0 +1,3 @@ +{% extends 'admin.base' %} + +{% block title %}{{ trans('general.user-manage') }}{% endblock %} diff --git a/resources/views/common/skeleton.blade.php b/resources/views/common/skeleton.blade.php deleted file mode 100644 index 0ec38144..00000000 --- a/resources/views/common/skeleton.blade.php +++ /dev/null @@ -1,14 +0,0 @@ -@extends("$parent.master") - -@section('title', $title) - -@section('content') -
-
-

{{ $title }}

-
-
-
- -{{ $bottom ?? '' }} -@endsection diff --git a/resources/views/index.blade.php b/resources/views/index.blade.php index 22305789..f8ce29a2 100644 --- a/resources/views/index.blade.php +++ b/resources/views/index.blade.php @@ -1,16 +1,8 @@ - - + @include('shared.head') {{ option_localized('site_name') }} - @include('common.favicon') - - - - @include('common.seo-meta-tags') - - @include('common.dependencies.style') +{{ extra_head|join('\n')|raw }} diff --git a/resources/views/shared/header.twig b/resources/views/shared/header.twig new file mode 100644 index 00000000..c13d7461 --- /dev/null +++ b/resources/views/shared/header.twig @@ -0,0 +1,26 @@ +
+ + + + + +
diff --git a/resources/views/shared/languages.twig b/resources/views/shared/languages.twig new file mode 100644 index 00000000..83ffd301 --- /dev/null +++ b/resources/views/shared/languages.twig @@ -0,0 +1,14 @@ + diff --git a/resources/views/shared/notifications.twig b/resources/views/shared/notifications.twig new file mode 100644 index 00000000..12fc4d61 --- /dev/null +++ b/resources/views/shared/notifications.twig @@ -0,0 +1,25 @@ + diff --git a/resources/views/shared/side-menu-item.twig b/resources/views/shared/side-menu-item.twig new file mode 100644 index 00000000..8a95fd66 --- /dev/null +++ b/resources/views/shared/side-menu-item.twig @@ -0,0 +1,27 @@ +
  • + {% if item.children %} + +   + {{ trans(item.title) }} + + + + + + {% else %} + + +  {{ trans(item.title) }} + + {% endif %} +
  • diff --git a/resources/views/shared/side-menu.twig b/resources/views/shared/side-menu.twig new file mode 100644 index 00000000..9a1388b0 --- /dev/null +++ b/resources/views/shared/side-menu.twig @@ -0,0 +1,3 @@ +{% for item in items %} + {{ include('shared.side-menu-item', {item: item}) }} +{% endfor %} diff --git a/resources/views/shared/sidebar.twig b/resources/views/shared/sidebar.twig new file mode 100644 index 00000000..3895eccd --- /dev/null +++ b/resources/views/shared/sidebar.twig @@ -0,0 +1,44 @@ + diff --git a/resources/views/shared/user-menu.twig b/resources/views/shared/user-menu.twig new file mode 100644 index 00000000..749b05f8 --- /dev/null +++ b/resources/views/shared/user-menu.twig @@ -0,0 +1,47 @@ + diff --git a/resources/views/shared/user-panel.twig b/resources/views/shared/user-panel.twig new file mode 100644 index 00000000..1ddb3aa4 --- /dev/null +++ b/resources/views/shared/user-panel.twig @@ -0,0 +1,20 @@ +
    +
    + User Image +
    +
    +

    {{ user.nickname ?? user.email }}

    + {{ role }} + {% if badges|length == 1 %} + {{ badges[0][0] }} + {% endif %} +
    +
    + +{% if badges|length > 1 %} +
    + {% for badge in badges %} + {{ badge[0] }} + {% endfor %} +
    +{% endif %} diff --git a/resources/views/skinlib/master.blade.php b/resources/views/skinlib/master.blade.php index 535ddc6b..480163ad 100644 --- a/resources/views/skinlib/master.blade.php +++ b/resources/views/skinlib/master.blade.php @@ -1,18 +1,8 @@ - - + @include('shared.head') @yield('title') - {{ option_localized('site_name') }} - @include('common.favicon') - - - - @include('common.theme-color') - @include('common.seo-meta-tags') - - @include('common.dependencies.style') - @yield('style') diff --git a/resources/views/user/base.twig b/resources/views/user/base.twig new file mode 100644 index 00000000..cef5cdf8 --- /dev/null +++ b/resources/views/user/base.twig @@ -0,0 +1,25 @@ + + + + {{ include('shared.head') }} + {% block title %}{% endblock %} - {{ site_name }} + + + +
    + {{ include('shared.header') }} + {{ include('shared.sidebar', {scope: 'user'}) }} +
    +
    +

    {{ block('title') }}

    +
    +
    + {% block content %}{% endblock %} +
    +
    + {{ include('shared.footer') }} +
    + {% block before_foot %}{% endblock %} + {{ include('shared.foot') }} + + diff --git a/resources/views/user/closet.blade.php b/resources/views/user/closet.blade.php deleted file mode 100644 index 8613cb66..00000000 --- a/resources/views/user/closet.blade.php +++ /dev/null @@ -1,25 +0,0 @@ -@extends('user.master') - -@section('title', trans('general.my-closet')) - -@section('content') - - -
    - -
    -

    - @lang('general.my-closet') -

    -
    - - -
    -
    - - -@endsection diff --git a/resources/views/user/closet.twig b/resources/views/user/closet.twig new file mode 100644 index 00000000..0ae3a79e --- /dev/null +++ b/resources/views/user/closet.twig @@ -0,0 +1,11 @@ +{% extends 'user.base' %} + +{% block title %}{{ trans('general.my-closet') }}{% endblock %} + +{% block before_foot %} + +{% endblock %} diff --git a/resources/views/user/index.blade.php b/resources/views/user/index.blade.php deleted file mode 100644 index 814d7987..00000000 --- a/resources/views/user/index.blade.php +++ /dev/null @@ -1,76 +0,0 @@ -@extends('user.master') - -@section('title', trans('general.dashboard')) - -@section('content') - - -
    - -
    -

    @lang('general.dashboard')

    -
    - - -
    -
    -
    -
    -
    - -
    -
    -
    -

    @lang('user.announcement')

    - @if (auth()->user()->isAdmin()) - - - - @endif -
    -
    - {!! $announcement !!} -
    -
    -
    - -
    - -
    -
    - - - - -@endsection diff --git a/resources/views/user/index.twig b/resources/views/user/index.twig new file mode 100644 index 00000000..72d9dd48 --- /dev/null +++ b/resources/views/user/index.twig @@ -0,0 +1,68 @@ +{% extends 'user.base' %} + +{% block title %}{{ trans('general.dashboard') }}{% endblock %} + +{% block content %} +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +

    {{ trans('user.announcement') }}

    + {% if auth_user().admin %} + + + + {% endif %} +
    +
    + {{ announcement|raw }} +
    +
    +
    +
    +{% endblock %} + +{% block before_foot %} + + + +{% endblock %} diff --git a/resources/views/user/master.blade.php b/resources/views/user/master.blade.php index 033535a7..7c3fd0b8 100644 --- a/resources/views/user/master.blade.php +++ b/resources/views/user/master.blade.php @@ -1,97 +1,20 @@ - + - - + @include('shared.head') @yield('title') - {{ option_localized('site_name') }} - @include('common.favicon') - - - - @include('common.theme-color') - - @include('common.dependencies.style') - @yield('style') -@php - $user = auth()->user(); -@endphp -
    - - -
    - - - - - - -
    - - - + @include('shared.header') + @include('shared.sidebar', ['scope' => 'user']) @yield('content') + @include('shared.footer') +
    - - - - - - - @include('common.dependencies.script') - + @include('shared.foot') @yield('script') diff --git a/resources/views/user/oauth.blade.php b/resources/views/user/oauth.blade.php deleted file mode 100644 index 5a2475f9..00000000 --- a/resources/views/user/oauth.blade.php +++ /dev/null @@ -1,2 +0,0 @@ -@component('common.skeleton', ['parent' => 'user', 'title' => trans('general.oauth-manage')]) -@endcomponent diff --git a/resources/views/user/oauth.twig b/resources/views/user/oauth.twig new file mode 100644 index 00000000..d4e8ee83 --- /dev/null +++ b/resources/views/user/oauth.twig @@ -0,0 +1,3 @@ +{% extends 'user.base' %} + +{% block title %}{{ trans('general.oauth-manage') }}{% endblock %} diff --git a/resources/views/user/player.blade.php b/resources/views/user/player.blade.php deleted file mode 100644 index 575a3cc3..00000000 --- a/resources/views/user/player.blade.php +++ /dev/null @@ -1,5 +0,0 @@ -@component('common.skeleton', ['parent' => 'user', 'title' => trans('general.player-manage')]) - @slot('bottom') - - @endslot -@endcomponent diff --git a/resources/views/user/player.twig b/resources/views/user/player.twig new file mode 100644 index 00000000..b4496ae3 --- /dev/null +++ b/resources/views/user/player.twig @@ -0,0 +1,7 @@ +{% extends 'user.base' %} + +{% block title %}{{ trans('general.player-manage') }}{% endblock %} + +{% block before_foot %} + +{% endblock %} diff --git a/resources/views/user/profile.blade.php b/resources/views/user/profile.blade.php deleted file mode 100644 index 69fa013d..00000000 --- a/resources/views/user/profile.blade.php +++ /dev/null @@ -1,10 +0,0 @@ -@component('common.skeleton', ['parent' => 'user', 'title' => trans('general.profile')]) - @slot('bottom') - - @endslot -@endcomponent diff --git a/resources/views/user/profile.twig b/resources/views/user/profile.twig new file mode 100644 index 00000000..b8cd6ad1 --- /dev/null +++ b/resources/views/user/profile.twig @@ -0,0 +1,12 @@ +{% extends 'user.base' %} + +{% block title %}{{ trans('general.profile') }}{% endblock %} + +{% block before_foot %} + +{% endblock %} diff --git a/resources/views/user/report.blade.php b/resources/views/user/report.blade.php deleted file mode 100644 index 4fdbba8e..00000000 --- a/resources/views/user/report.blade.php +++ /dev/null @@ -1,2 +0,0 @@ -@component('common.skeleton', ['parent' => 'user', 'title' => trans('general.my-reports')]) -@endcomponent diff --git a/resources/views/user/report.twig b/resources/views/user/report.twig new file mode 100644 index 00000000..c6906d63 --- /dev/null +++ b/resources/views/user/report.twig @@ -0,0 +1,3 @@ +{% extends 'user.base' %} + +{% block title %}{{ trans('general.my-reports') }}{% endblock %} diff --git a/routes/web.php b/routes/web.php index 01263523..4d4e1735 100644 --- a/routes/web.php +++ b/routes/web.php @@ -114,7 +114,7 @@ Route::group(['prefix' => 'skinlib'], function () { * Admin Panel */ Route::group(['middleware' => ['authorize', 'admin'], 'prefix' => 'admin'], function () { - Route::view('/', 'admin.index'); + Route::get('/', 'AdminController@index'); Route::get('/chart', 'AdminController@chartData'); Route::post('/notifications/send', 'AdminController@sendNotification'); diff --git a/tests/AdminConfigurationsTest.php b/tests/AdminConfigurationsTest.php index 92794bc2..e2b0be39 100644 --- a/tests/AdminConfigurationsTest.php +++ b/tests/AdminConfigurationsTest.php @@ -154,12 +154,12 @@ class AdminConfigurationsTest extends BrowserKitTestCase $this->visit('/admin/options') ->type('kw', 'meta_keywords') ->type('desc', 'meta_description') - ->type('', 'meta_extras') + ->type('', 'meta_extras') ->press('submit_meta'); $this->visit('/') ->see('') ->see('') - ->see(''); + ->see(''); $this->visit('/admin/options') ->type('key', 'recaptcha_sitekey') diff --git a/tests/HttpTest/ViewTest/ComposersTest/FootComposerTest.php b/tests/HttpTest/ViewTest/ComposersTest/FootComposerTest.php new file mode 100644 index 00000000..12069914 --- /dev/null +++ b/tests/HttpTest/ViewTest/ComposersTest/FootComposerTest.php @@ -0,0 +1,72 @@ + '"
    "