Compare commits
66 commits
feature/up
...
2.x
Author | SHA1 | Date | |
---|---|---|---|
|
2e96b7bd09 | ||
|
768e7a6576 | ||
|
431eafb2b6 | ||
|
d2184eef0a | ||
|
fbd050d4e4 | ||
|
5d67f570a9 | ||
|
7d016cdaa6 | ||
|
6e954a355d | ||
|
60faccad27 | ||
|
1f5493ac98 | ||
|
9c117b7946 | ||
|
c72fee9644 | ||
|
0999bebcb4 | ||
|
1c41e3d1ef | ||
|
ed3cd79c92 | ||
|
192002f898 | ||
|
18f7306b2c | ||
|
e9754519be | ||
|
1c276fbfc2 | ||
|
cefe07d218 | ||
|
cd4b522935 | ||
|
1ad5603c3e | ||
|
302e04bb12 | ||
|
49dab6e72b | ||
|
c5d0769afb | ||
|
4005894c16 | ||
|
a4022ce517 | ||
|
cd07d47445 | ||
|
df70dcc521 | ||
|
9e6321e500 | ||
|
0d9850c1c7 | ||
|
4d3083886e | ||
|
52f59afe63 | ||
|
aa886e4f77 | ||
|
3c9f361f5f | ||
|
5eb1f55b82 | ||
|
d910f8e4f7 | ||
|
751b23a5e4 | ||
|
a4fa490fb4 | ||
|
662f6ac3eb | ||
|
11257a272e | ||
|
6b93f8ed5c | ||
|
8f9b2959b2 | ||
|
45cc84c99c | ||
|
52620bc331 | ||
|
bd76efc613 | ||
|
6dead1c529 | ||
|
bb5a078f35 | ||
|
2ee5d07e48 | ||
|
d30edb6749 | ||
|
a53192beeb | ||
|
ef1ffe880d | ||
|
877b31f947 | ||
|
827088df76 | ||
|
a12c1d559d | ||
|
f0b60fc19a | ||
|
7c4619adb9 | ||
|
aa49a5fb42 | ||
|
7565bd4028 | ||
|
181b7564e8 | ||
|
0d3640b67a | ||
|
82b209d4b5 | ||
|
f576a82803 | ||
|
bb07ba5964 | ||
|
9aaa900a3e | ||
|
07f07449b9 |
2130 changed files with 271826 additions and 13043 deletions
|
@ -9,6 +9,13 @@ LOG_CHANNEL=daily
|
|||
DB_CONNECTION=sqlite
|
||||
DB_DATABASE=app.sqlite
|
||||
|
||||
#DB_CONNECTION=<mysql | pgsql>
|
||||
#DB_HOST=<hostname | ip>
|
||||
#DB_PORT=<port number>
|
||||
#DB_DATABASE=<database>
|
||||
#DB_USERNAME=<user>
|
||||
#DB_PASSWORD=<password>
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
QUEUE_CONNECTION=sync
|
||||
|
|
3
.eslintignore
Normal file
3
.eslintignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
huebee.js
|
||||
jquery-ui.min.js
|
||||
bootstrap.js
|
13
.eslintrc
Normal file
13
.eslintrc
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"extends": ["airbnb-base", "prettier"],
|
||||
"plugins": ["prettier"],
|
||||
"rules": {
|
||||
"prettier/prettier": ["error"]
|
||||
},
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
"globals": {
|
||||
"$": true
|
||||
}
|
||||
}
|
16
.github/workflows/call_issue_pr_tracker.yml
vendored
Normal file
16
.github/workflows/call_issue_pr_tracker.yml
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
name: Issue & PR Tracker
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened,reopened,labeled,unlabeled,closed]
|
||||
pull_request_target:
|
||||
types: [opened,reopened,review_requested,review_request_removed,labeled,unlabeled,closed]
|
||||
pull_request_review:
|
||||
types: [submitted,edited,dismissed]
|
||||
|
||||
jobs:
|
||||
manage-project:
|
||||
permissions:
|
||||
issues: write
|
||||
uses: linuxserver/github-workflows/.github/workflows/issue-pr-tracker.yml@v1
|
||||
secrets: inherit
|
13
.github/workflows/call_issues_cron.yml
vendored
Normal file
13
.github/workflows/call_issues_cron.yml
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
name: Mark stale issues and pull requests
|
||||
on:
|
||||
schedule:
|
||||
- cron: '35 15 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
uses: linuxserver/github-workflows/.github/workflows/issues-cron.yml@v1
|
||||
secrets: inherit
|
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
|
@ -40,11 +40,17 @@ jobs:
|
|||
- name: Run yarn
|
||||
run: yarn && yarn dev
|
||||
|
||||
- name: Run ESLint
|
||||
run: yarn lint
|
||||
|
||||
- name: Run tests
|
||||
run: ./vendor/bin/phpunit
|
||||
run: php artisan test
|
||||
env:
|
||||
APP_ENV: testing
|
||||
|
||||
- name: Php code sniffer
|
||||
run: ./vendor/bin/phpcs
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@master
|
||||
if: failure()
|
||||
|
|
2080
.phpstorm.meta.php
Normal file
2080
.phpstorm.meta.php
Normal file
File diff suppressed because it is too large
Load diff
20867
_ide_helper.php
Normal file
20867
_ide_helper.php
Normal file
File diff suppressed because it is too large
Load diff
|
@ -2,9 +2,43 @@
|
|||
|
||||
namespace App;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* App\Application
|
||||
*
|
||||
* @property string $appid
|
||||
* @property string $name
|
||||
* @property string|null $sha
|
||||
* @property string|null $icon
|
||||
* @property string|null $website
|
||||
* @property string|null $license
|
||||
* @property string|null $description
|
||||
* @property int $enhanced
|
||||
* @property string $tile_background
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property string|null $class
|
||||
* @method static Builder|Application newModelQuery()
|
||||
* @method static Builder|Application newQuery()
|
||||
* @method static Builder|Application query()
|
||||
* @method static Builder|Application whereAppid($value)
|
||||
* @method static Builder|Application whereClass($value)
|
||||
* @method static Builder|Application whereCreatedAt($value)
|
||||
* @method static Builder|Application whereDescription($value)
|
||||
* @method static Builder|Application whereEnhanced($value)
|
||||
* @method static Builder|Application whereIcon($value)
|
||||
* @method static Builder|Application whereLicense($value)
|
||||
* @method static Builder|Application whereName($value)
|
||||
* @method static Builder|Application whereSha($value)
|
||||
* @method static Builder|Application whereTileBackground($value)
|
||||
* @method static Builder|Application whereUpdatedAt($value)
|
||||
* @method static Builder|Application whereWebsite($value)
|
||||
*/
|
||||
class Application extends Model
|
||||
{
|
||||
/**
|
||||
|
@ -61,16 +95,14 @@ class Application extends Model
|
|||
$name = $this->name;
|
||||
$name = preg_replace('/[^\p{L}\p{N}]/u', '', $name);
|
||||
|
||||
$class = '\App\SupportedApps\\'.$name.'\\'.$name;
|
||||
|
||||
return $class;
|
||||
return '\App\SupportedApps\\'.$name.'\\'.$name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return string
|
||||
*/
|
||||
public static function classFromName($name)
|
||||
public static function classFromName($name): string
|
||||
{
|
||||
$name = preg_replace('/[^\p{L}\p{N}]/u', '', $name);
|
||||
|
||||
|
@ -80,9 +112,9 @@ class Application extends Model
|
|||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection
|
||||
* @return Collection
|
||||
*/
|
||||
public static function apps(): \Illuminate\Support\Collection
|
||||
public static function apps(): Collection
|
||||
{
|
||||
$json = json_decode(file_get_contents(storage_path('app/supportedapps.json'))) ?? [];
|
||||
$apps = collect($json->apps);
|
||||
|
@ -110,6 +142,7 @@ class Application extends Model
|
|||
/**
|
||||
* @param $appid
|
||||
* @return mixed|null
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public static function getApp($appid)
|
||||
{
|
||||
|
@ -121,13 +154,12 @@ class Application extends Model
|
|||
$application = ($localapp) ? $localapp : new self;
|
||||
|
||||
// Files missing? || app not in db || old sha version
|
||||
if (
|
||||
! file_exists(app_path('SupportedApps/'.className($app->name))) ||
|
||||
if (! file_exists(app_path('SupportedApps/'.className($app->name))) ||
|
||||
! $localapp ||
|
||||
$localapp->sha !== $app->sha
|
||||
) {
|
||||
$gotFiles = SupportedApps::getFiles($app);
|
||||
if($gotFiles) {
|
||||
if ($gotFiles) {
|
||||
$app = SupportedApps::saveApp($app, $application);
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +179,7 @@ class Application extends Model
|
|||
if ($app === null) {
|
||||
// Try in db for Private App
|
||||
$appModel = self::where('appid', $appid)->first();
|
||||
if($appModel) {
|
||||
if ($appModel) {
|
||||
$app = json_decode($appModel->toJson());
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +208,7 @@ class Application extends Model
|
|||
// Check for private apps in the db
|
||||
$appsListFromDB = self::all(['appid', 'name']);
|
||||
|
||||
foreach($appsListFromDB as $app) {
|
||||
foreach ($appsListFromDB as $app) {
|
||||
// Already existing keys are overwritten,
|
||||
// only private apps should be added at the end
|
||||
$list[$app->appid] = $app->name;
|
||||
|
|
|
@ -36,7 +36,7 @@ class RegisterApp extends Command
|
|||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
@ -54,7 +54,12 @@ class RegisterApp extends Command
|
|||
}
|
||||
}
|
||||
|
||||
public function addApp($folder, $remove = false)
|
||||
/**
|
||||
* @param $folder
|
||||
* @param bool $remove
|
||||
* @return void
|
||||
*/
|
||||
public function addApp($folder, bool $remove = false)
|
||||
{
|
||||
$json = app_path('SupportedApps/'.$folder.'/app.json');
|
||||
|
||||
|
@ -88,7 +93,13 @@ class RegisterApp extends Command
|
|||
$this->info('Application Added - ' . $app->name . ' - ' . $app->appid);
|
||||
}
|
||||
|
||||
private function saveIcon($appFolder, $icon) {
|
||||
/**
|
||||
* @param $appFolder
|
||||
* @param $icon
|
||||
* @return void
|
||||
*/
|
||||
private function saveIcon($appFolder, $icon)
|
||||
{
|
||||
$iconPath = app_path('SupportedApps/' . $appFolder . '/' . $icon);
|
||||
$contents = file_get_contents($iconPath);
|
||||
Storage::disk('public')->put('icons/'.$icon, $contents);
|
||||
|
|
|
@ -19,7 +19,7 @@ class Kernel extends ConsoleKernel
|
|||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @param Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
|
|
|
@ -2,43 +2,61 @@
|
|||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
function format_bytes($bytes, $is_drive_size = true, $beforeunit = '', $afterunit = '')
|
||||
/**
|
||||
* @param $bytes
|
||||
* @param bool $is_drive_size
|
||||
* @param string $beforeunit
|
||||
* @param string $afterunit
|
||||
* @return string
|
||||
*/
|
||||
function format_bytes($bytes, bool $is_drive_size = true, string $beforeunit = '', string $afterunit = ''): string
|
||||
{
|
||||
$btype = ($is_drive_size === true) ? 1000 : 1024;
|
||||
$labels = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
for ($x = 0; $bytes >= $btype && $x < (count($labels) - 1); $bytes /= $btype, $x++); // use 1000 rather than 1024 to simulate HD size not real size
|
||||
// use 1000 rather than 1024 to simulate HD size not real size
|
||||
for ($x = 0; $bytes >= $btype && $x < (count($labels) - 1); $bytes /= $btype, $x++) ;
|
||||
if ($labels[$x] == 'TB') {
|
||||
return round($bytes, 3).$beforeunit.$labels[$x].$afterunit;
|
||||
return round($bytes, 3) . $beforeunit . $labels[$x] . $afterunit;
|
||||
} elseif ($labels[$x] == 'GB') {
|
||||
return round($bytes, 2).$beforeunit.$labels[$x].$afterunit;
|
||||
return round($bytes, 2) . $beforeunit . $labels[$x] . $afterunit;
|
||||
} elseif ($labels[$x] == 'MB') {
|
||||
return round($bytes, 2).$beforeunit.$labels[$x].$afterunit;
|
||||
return round($bytes, 2) . $beforeunit . $labels[$x] . $afterunit;
|
||||
} else {
|
||||
return round($bytes, 0).$beforeunit.$labels[$x].$afterunit;
|
||||
return round($bytes, 0) . $beforeunit . $labels[$x] . $afterunit;
|
||||
}
|
||||
}
|
||||
|
||||
function str_slug($title, $separator = '-', $language = 'en')
|
||||
/**
|
||||
* @param $title
|
||||
* @param string $separator
|
||||
* @param string $language
|
||||
* @return string
|
||||
*/
|
||||
function str_slug($title, string $separator = '-', string $language = 'en'): string
|
||||
{
|
||||
return Str::slug($title, $separator, $language);
|
||||
}
|
||||
|
||||
if (! function_exists('str_is')) {
|
||||
if (!function_exists('str_is')) {
|
||||
/**
|
||||
* Determine if a given string matches a given pattern.
|
||||
*
|
||||
* @param string|array $pattern
|
||||
* @param string $value
|
||||
* @param string|array $pattern
|
||||
* @param string $value
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated Str::is() should be used directly instead. Will be removed in Laravel 6.0.
|
||||
*/
|
||||
function str_is($pattern, $value)
|
||||
function str_is($pattern, string $value): bool
|
||||
{
|
||||
return Str::is($pattern, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $hex
|
||||
* @return float|int
|
||||
*/
|
||||
function get_brightness($hex)
|
||||
{
|
||||
// returns brightness value from 0 to 255
|
||||
|
@ -46,7 +64,7 @@ function get_brightness($hex)
|
|||
// $hex = str_replace('#', '', $hex);
|
||||
$hex = preg_replace("/[^0-9A-Fa-f]/", '', $hex);
|
||||
if (strlen($hex) == 3) {
|
||||
$hex = $hex[0].$hex[0].$hex[1].$hex[1].$hex[2].$hex[2];
|
||||
$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
|
||||
}
|
||||
|
||||
$c_r = hexdec(substr($hex, 0, 2));
|
||||
|
@ -56,7 +74,11 @@ function get_brightness($hex)
|
|||
return (($c_r * 299) + ($c_g * 587) + ($c_b * 114)) / 1000;
|
||||
}
|
||||
|
||||
function title_color($hex)
|
||||
/**
|
||||
* @param $hex
|
||||
* @return string
|
||||
*/
|
||||
function title_color($hex): string
|
||||
{
|
||||
if (get_brightness($hex) > 130) {
|
||||
return ' black';
|
||||
|
@ -65,20 +87,52 @@ function title_color($hex)
|
|||
}
|
||||
}
|
||||
|
||||
function getLinkTargetAttribute()
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function getLinkTargetAttribute(): string
|
||||
{
|
||||
$target = \App\Setting::fetch('window_target');
|
||||
|
||||
if ($target === 'current') {
|
||||
return '';
|
||||
} else {
|
||||
return ' target="'.$target.'"';
|
||||
return ' target="' . $target . '"';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return array|string|string[]|null
|
||||
*/
|
||||
function className($name)
|
||||
{
|
||||
$name = preg_replace('/[^\p{L}\p{N}]/u', '', $name);
|
||||
|
||||
return $name;
|
||||
return preg_replace('/[^\p{L}\p{N}]/u', '', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param string $extension
|
||||
* @return bool
|
||||
*/
|
||||
function isImage(string $file, string $extension): bool
|
||||
{
|
||||
$allowedExtensions = ['jpg', 'jpeg', 'png', 'bmp', 'gif', 'svg', 'webp'];
|
||||
|
||||
if (!in_array($extension, $allowedExtensions)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$tempFileName = @tempnam("/tmp", "image-check-");
|
||||
$handle = fopen($tempFileName, "w");
|
||||
|
||||
fwrite($handle, $file);
|
||||
fclose($handle);
|
||||
|
||||
if ($extension == 'svg') {
|
||||
return 'image/svg+xml' === mime_content_type($tempFileName);
|
||||
}
|
||||
|
||||
$size = @getimagesize($tempFileName);
|
||||
return is_array($size) && str_starts_with($size['mime'], 'image');
|
||||
}
|
||||
|
|
|
@ -4,11 +4,17 @@ namespace App\Http\Controllers\Auth;
|
|||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\User;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
|
@ -30,7 +36,7 @@ class LoginController extends Controller
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/';
|
||||
protected string $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
|
@ -40,10 +46,13 @@ class LoginController extends Controller
|
|||
public function __construct()
|
||||
{
|
||||
Session::put('backUrl', URL::previous());
|
||||
$this->middleware('guest')->except('logout');
|
||||
$this->middleware('guest')->except(['logout','autologin']);
|
||||
}
|
||||
|
||||
public function username()
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function username(): string
|
||||
{
|
||||
return 'username';
|
||||
}
|
||||
|
@ -51,12 +60,12 @@ class LoginController extends Controller
|
|||
/**
|
||||
* Handle a login request to the application.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function login(Request $request)
|
||||
public function login(Request $request): Response
|
||||
{
|
||||
$current_user = User::currentUser();
|
||||
$request->merge(['username' => $current_user->username, 'remember' => true]);
|
||||
|
@ -88,7 +97,11 @@ class LoginController extends Controller
|
|||
{
|
||||
}
|
||||
|
||||
public function setUser(User $user)
|
||||
/**
|
||||
* @param User $user
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function setUser(User $user): RedirectResponse
|
||||
{
|
||||
Auth::logout();
|
||||
session(['current_user' => $user]);
|
||||
|
@ -96,10 +109,22 @@ class LoginController extends Controller
|
|||
return redirect()->route('dash');
|
||||
}
|
||||
|
||||
public function autologin($uuid)
|
||||
/**
|
||||
* @param $uuid
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function autologin($uuid): RedirectResponse
|
||||
{
|
||||
Auth::logout();
|
||||
|
||||
$user = User::where('autologin', $uuid)->first();
|
||||
|
||||
if (!$user) {
|
||||
return redirect()->route('dash');
|
||||
}
|
||||
|
||||
Auth::login($user, true);
|
||||
|
||||
session(['current_user' => $user]);
|
||||
|
||||
return redirect()->route('dash');
|
||||
|
@ -108,18 +133,26 @@ class LoginController extends Controller
|
|||
/**
|
||||
* Show the application's login form.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return Application|Factory|View
|
||||
*/
|
||||
public function showLoginForm()
|
||||
{
|
||||
return view('auth.login');
|
||||
}
|
||||
|
||||
protected function authenticated(Request $request, $user)
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param $user
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
protected function authenticated(Request $request, $user): RedirectResponse
|
||||
{
|
||||
return back();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function redirectTo()
|
||||
{
|
||||
return Session::get('url.intended') ? Session::get('url.intended') : $this->redirectTo;
|
||||
|
|
|
@ -27,7 +27,7 @@ class RegisterController extends Controller
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/';
|
||||
protected string $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
|
@ -45,7 +45,7 @@ class RegisterController extends Controller
|
|||
* @param array $data
|
||||
* @return \Illuminate\Contracts\Validation\Validator
|
||||
*/
|
||||
protected function validator(array $data)
|
||||
protected function validator(array $data): \Illuminate\Contracts\Validation\Validator
|
||||
{
|
||||
return Validator::make($data, [
|
||||
'name' => 'required|string|max:255',
|
||||
|
@ -58,7 +58,7 @@ class RegisterController extends Controller
|
|||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \App\User
|
||||
* @return User
|
||||
*/
|
||||
protected function create(array $data)
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@ class ResetPasswordController extends Controller
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/';
|
||||
protected string $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
|
|
58
app/Http/Controllers/HealthController.php
Normal file
58
app/Http/Controllers/HealthController.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Item;
|
||||
use App\User;
|
||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
|
||||
class HealthController extends Controller
|
||||
{
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
private static function getUsers(): int
|
||||
{
|
||||
return User::count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
private static function getItems(): int
|
||||
{
|
||||
return Item::select('id')
|
||||
->where('deleted_at', null)
|
||||
->where('type', '0')
|
||||
->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return JsonResponse|Response
|
||||
* @throws BindingResolutionException
|
||||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
$REQUESTS_MAX_PER_MIN = 30;
|
||||
$STATUS_TOO_MANY_REQUESTS = 429;
|
||||
|
||||
if (RateLimiter::remaining('health', $REQUESTS_MAX_PER_MIN) < 1) {
|
||||
return response()->make('Too many attempts.', $STATUS_TOO_MANY_REQUESTS);
|
||||
}
|
||||
|
||||
RateLimiter::hit('health');
|
||||
|
||||
return response()->json([
|
||||
'status' => 'ok',
|
||||
'items' => self::getItems(),
|
||||
'users' => self::getUsers(),
|
||||
]);
|
||||
}
|
||||
}
|
31
app/Http/Controllers/ImportController.php
Normal file
31
app/Http/Controllers/ImportController.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ImportController extends Controller
|
||||
{
|
||||
/**
|
||||
* Instantiate a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware('allowed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return View
|
||||
*/
|
||||
public function __invoke(Request $request): View
|
||||
{
|
||||
return view('items.import');
|
||||
}
|
||||
}
|
|
@ -6,17 +6,21 @@ use App\Application;
|
|||
use App\Item;
|
||||
use App\Jobs\ProcessApps;
|
||||
use App\User;
|
||||
use Artisan;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Exception\ServerException;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Redirector;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
class ItemController extends Controller
|
||||
{
|
||||
|
@ -104,13 +108,21 @@ class ItemController extends Controller
|
|||
$new = !(((bool)$item->pinned === true));
|
||||
$item->pinned = $new;
|
||||
$item->save();
|
||||
|
||||
if ($ajax) {
|
||||
if (is_numeric($tag) && $tag > 0) {
|
||||
$item = Item::whereId($tag)->first();
|
||||
$data['apps'] = $item->children()->pinned()->orderBy('order', 'asc')->get();
|
||||
} else {
|
||||
$data['apps'] = Item::pinned()->orderBy('order', 'asc')->get();
|
||||
$item = Item::whereId($tag)->first();
|
||||
|
||||
$data['apps'] = new Collection;
|
||||
|
||||
if ((int)$tag === 0) {
|
||||
$tags = Item::where('type', 1)->pinned()->orderBy('order', 'asc')->get();
|
||||
$data['apps'] = $data['apps']->merge($tags);
|
||||
}
|
||||
|
||||
$apps = $item->children()->pinned()->orderBy('order', 'asc')->get();
|
||||
$data['apps'] = $data['apps']->merge($apps);
|
||||
|
||||
|
||||
$data['ajax'] = true;
|
||||
|
||||
return view('sortable', $data);
|
||||
|
@ -124,11 +136,12 @@ class ItemController extends Controller
|
|||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$trash = (bool) $request->input('trash');
|
||||
$trash = (bool)$request->input('trash');
|
||||
|
||||
$data['apps'] = Item::ofType('item')->orderBy('title', 'asc')->get();
|
||||
$data['trash'] = Item::ofType('item')->onlyTrashed()->get();
|
||||
|
@ -182,15 +195,17 @@ class ItemController extends Controller
|
|||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param $id
|
||||
* @return void
|
||||
* @param null $id
|
||||
* @return Item
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function storelogic(Request $request, $id = null)
|
||||
public static function storelogic(Request $request, $id = null): Item
|
||||
{
|
||||
$application = Application::single($request->input('appid'));
|
||||
$validatedData = $request->validate([
|
||||
'title' => 'required|max:255',
|
||||
'url' => 'required',
|
||||
'file' => 'image'
|
||||
]);
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
|
@ -199,29 +214,30 @@ class ItemController extends Controller
|
|||
'icon' => $path,
|
||||
]);
|
||||
} elseif (strpos($request->input('icon'), 'http') === 0) {
|
||||
$options=array(
|
||||
"ssl"=>array(
|
||||
"verify_peer"=>false,
|
||||
"verify_peer_name"=>false,
|
||||
$options = array(
|
||||
"ssl" => array(
|
||||
"verify_peer" => false,
|
||||
"verify_peer_name" => false,
|
||||
),
|
||||
);
|
||||
);
|
||||
|
||||
$file = $request->input('icon');
|
||||
$path_parts = pathinfo($file);
|
||||
$extension = $path_parts['extension'];
|
||||
|
||||
$contents = file_get_contents($request->input('icon'), false, stream_context_create($options));
|
||||
|
||||
if ($application) {
|
||||
$icon = $application->icon;
|
||||
} else {
|
||||
$file = $request->input('icon');
|
||||
$path_parts = pathinfo($file);
|
||||
$icon = md5($contents);
|
||||
$icon .= '.'.$path_parts['extension'];
|
||||
if (!isImage($contents, $extension)) {
|
||||
throw ValidationException::withMessages(['file' => 'Icon must be an image.']);
|
||||
}
|
||||
$path = 'icons/'.$icon;
|
||||
|
||||
$path = 'icons/' . ($application ? $application->icon : md5($contents) . '.' . $extension);
|
||||
|
||||
// Private apps could have here duplicated icons folder
|
||||
if (strpos($path, 'icons/icons/') !== false) {
|
||||
$path = str_replace('icons/icons/','icons/',$path);
|
||||
$path = str_replace('icons/icons/', 'icons/', $path);
|
||||
}
|
||||
if(! Storage::disk('public')->exists($path)) {
|
||||
if (!Storage::disk('public')->exists($path)) {
|
||||
Storage::disk('public')->put($path, $contents);
|
||||
}
|
||||
$request->merge([
|
||||
|
@ -266,6 +282,7 @@ class ItemController extends Controller
|
|||
}
|
||||
|
||||
$item->parents()->sync($request->tags);
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -276,7 +293,7 @@ class ItemController extends Controller
|
|||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
$this->storelogic($request);
|
||||
self::storelogic($request);
|
||||
|
||||
$route = route('dash', []);
|
||||
|
||||
|
@ -304,7 +321,7 @@ class ItemController extends Controller
|
|||
*/
|
||||
public function update(Request $request, int $id): RedirectResponse
|
||||
{
|
||||
$this->storelogic($request, $id);
|
||||
self::storelogic($request, $id);
|
||||
$route = route('dash', []);
|
||||
|
||||
return redirect($route)
|
||||
|
@ -321,7 +338,7 @@ class ItemController extends Controller
|
|||
public function destroy(Request $request, int $id): RedirectResponse
|
||||
{
|
||||
//
|
||||
$force = (bool) $request->input('force');
|
||||
$force = (bool)$request->input('force');
|
||||
if ($force) {
|
||||
Item::withTrashed()
|
||||
->where('id', $id)
|
||||
|
@ -346,8 +363,8 @@ class ItemController extends Controller
|
|||
{
|
||||
//
|
||||
Item::withTrashed()
|
||||
->where('id', $id)
|
||||
->restore();
|
||||
->where('id', $id)
|
||||
->restore();
|
||||
|
||||
$route = route('items.index', []);
|
||||
|
||||
|
@ -360,6 +377,7 @@ class ItemController extends Controller
|
|||
*
|
||||
* @param Request $request
|
||||
* @return string|null
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function appload(Request $request): ?string
|
||||
{
|
||||
|
@ -374,32 +392,36 @@ class ItemController extends Controller
|
|||
$output['custom'] = null;
|
||||
|
||||
$app = Application::single($appid);
|
||||
$output = (array) $app;
|
||||
$output = (array)$app;
|
||||
|
||||
$appdetails = Application::getApp($appid);
|
||||
|
||||
if ((bool) $app->enhanced === true) {
|
||||
if ((bool)$app->enhanced === true) {
|
||||
// if(!isset($app->config)) { // class based config
|
||||
$output['custom'] = className($appdetails->name).'.config';
|
||||
$output['custom'] = className($appdetails->name) . '.config';
|
||||
// }
|
||||
}
|
||||
|
||||
$output['colour'] = ($app->tile_background == 'light') ? '#fafbfc' : '#161b1f';
|
||||
|
||||
if(strpos($app->icon, '://') !== false) {
|
||||
if (strpos($app->icon, '://') !== false) {
|
||||
$output['iconview'] = $app->icon;
|
||||
} elseif(strpos($app->icon, 'icons/') !== false) {
|
||||
} elseif (strpos($app->icon, 'icons/') !== false) {
|
||||
// Private apps have the icon locally
|
||||
$output['iconview'] = URL::to('/').'/storage/'.$app->icon;
|
||||
$output['iconview'] = URL::to('/') . '/storage/' . $app->icon;
|
||||
$output['icon'] = str_replace('icons/', '', $output['icon']);
|
||||
} else {
|
||||
$output['iconview'] = config('app.appsource').'icons/'.$app->icon;
|
||||
$output['iconview'] = config('app.appsource') . 'icons/' . $app->icon;
|
||||
}
|
||||
|
||||
|
||||
return json_encode($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function testConfig(Request $request)
|
||||
{
|
||||
$data = $request->input('data');
|
||||
|
@ -408,7 +430,10 @@ class ItemController extends Controller
|
|||
$app = $single->class;
|
||||
|
||||
// If password is not resubmitted fill it from the database when in edit mode
|
||||
if ($data['password'] === null && array_key_exists('id', $data)) {
|
||||
if (array_key_exists('password', $data) &&
|
||||
$data['password'] === null &&
|
||||
array_key_exists('id', $data)
|
||||
) {
|
||||
$item = Item::find($data['id']);
|
||||
if ($item) {
|
||||
$itemConfig = $item->getConfig();
|
||||
|
@ -417,21 +442,26 @@ class ItemController extends Controller
|
|||
}
|
||||
|
||||
$app_details = new $app();
|
||||
$app_details->config = (object) $data;
|
||||
$app_details->config = (object)$data;
|
||||
$app_details->test();
|
||||
}
|
||||
|
||||
public function execute($url, $attrs = [], $overridevars = false)
|
||||
/**
|
||||
* @param $url
|
||||
* @param array $attrs
|
||||
* @param array|bool $overridevars
|
||||
* @return ResponseInterface|null
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function execute($url, array $attrs = [], $overridevars = false): ?ResponseInterface
|
||||
{
|
||||
$res = null;
|
||||
|
||||
$vars = ($overridevars !== false) ?
|
||||
$overridevars : [
|
||||
'http_errors' => false,
|
||||
'timeout' => 15,
|
||||
'connect_timeout' => 15,
|
||||
'verify' => false,
|
||||
];
|
||||
$overridevars : [
|
||||
'http_errors' => false,
|
||||
'timeout' => 15,
|
||||
'connect_timeout' => 15,
|
||||
'verify' => false,
|
||||
];
|
||||
|
||||
$client = new Client($vars);
|
||||
|
||||
|
@ -446,10 +476,15 @@ class ItemController extends Controller
|
|||
Log::debug($e->getMessage());
|
||||
}
|
||||
|
||||
return $res;
|
||||
return null;
|
||||
}
|
||||
|
||||
public function websitelookup($url)
|
||||
/**
|
||||
* @param $url
|
||||
* @return StreamInterface
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function websitelookup($url): StreamInterface
|
||||
{
|
||||
$url = base64_decode($url);
|
||||
$data = $this->execute($url);
|
||||
|
@ -457,6 +492,10 @@ class ItemController extends Controller
|
|||
return $data->getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @return void
|
||||
*/
|
||||
public function getStats($id)
|
||||
{
|
||||
$item = Item::find($id);
|
||||
|
@ -469,6 +508,9 @@ class ItemController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Contracts\Foundation\Application|RedirectResponse|Redirector
|
||||
*/
|
||||
public function checkAppList()
|
||||
{
|
||||
ProcessApps::dispatch();
|
||||
|
|
111
app/Http/Controllers/ItemRestController.php
Normal file
111
app/Http/Controllers/ItemRestController.php
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Item;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class ItemRestController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware('allowed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$columns = [
|
||||
'title',
|
||||
'colour',
|
||||
'url',
|
||||
'description',
|
||||
'appid',
|
||||
'appdescription',
|
||||
];
|
||||
|
||||
return Item::select($columns)
|
||||
->where('deleted_at', null)
|
||||
->where('type', '0')
|
||||
->orderBy('order', 'asc')
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return object
|
||||
*/
|
||||
public function store(Request $request): object
|
||||
{
|
||||
$item = ItemController::storelogic($request);
|
||||
|
||||
if ($item) {
|
||||
return (object) ['status' => 'OK'];
|
||||
}
|
||||
|
||||
return (object) ['status' => 'FAILED'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param Item $item
|
||||
* @return Response
|
||||
*/
|
||||
public function show(Item $item)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param Item $item
|
||||
* @return Response
|
||||
*/
|
||||
public function edit(Item $item)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Item $item
|
||||
* @return Response
|
||||
*/
|
||||
public function update(Request $request, Item $item)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param Item $item
|
||||
* @return Response
|
||||
*/
|
||||
public function destroy(Item $item)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -3,10 +3,17 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Search;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Redirector;
|
||||
|
||||
class SearchController extends Controller
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return Application|RedirectResponse|Redirector|mixed|void
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$requestprovider = $request->input('provider');
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
|||
|
||||
use App\Setting;
|
||||
use App\SettingGroup;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
@ -53,7 +54,7 @@ class SettingsController extends Controller
|
|||
|
||||
return redirect($route)
|
||||
->with([
|
||||
'error' => __('app.alert.error.not_exist'),
|
||||
'errors' => collect([__('app.alert.error.not_exist')]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -68,37 +69,48 @@ class SettingsController extends Controller
|
|||
{
|
||||
$setting = Setting::find($id);
|
||||
$user = $this->user();
|
||||
$route = route('settings.index', []);
|
||||
|
||||
if (! is_null($setting)) {
|
||||
$data = Setting::getInput($request);
|
||||
try {
|
||||
if (is_null($setting)) {
|
||||
throw new Exception('not_exists');
|
||||
}
|
||||
|
||||
$setting_value = null;
|
||||
if ($setting->type === 'image') {
|
||||
$validatedData = $request->validate([
|
||||
'value' => 'image'
|
||||
]);
|
||||
|
||||
if ($setting->type == 'image') {
|
||||
if ($request->hasFile('value')) {
|
||||
$path = $request->file('value')->store('backgrounds');
|
||||
$setting_value = $path;
|
||||
if (!$request->hasFile('value')) {
|
||||
throw new \Exception(
|
||||
'file_too_big'
|
||||
);
|
||||
}
|
||||
|
||||
$path = $request->file('value')->store('backgrounds');
|
||||
|
||||
if ($path === null) {
|
||||
throw new \Exception('file_not_stored');
|
||||
}
|
||||
|
||||
$setting_value = $path;
|
||||
} else {
|
||||
$data = Setting::getInput($request);
|
||||
$setting_value = $data->value;
|
||||
}
|
||||
|
||||
$user->settings()->detach($setting->id);
|
||||
$user->settings()->save($setting, ['uservalue' => $setting_value]);
|
||||
|
||||
$route = route('settings.index', []);
|
||||
|
||||
return redirect($route)
|
||||
->with([
|
||||
'success' => __('app.alert.success.setting_updated'),
|
||||
]);
|
||||
} else {
|
||||
$route = route('settings.index', []);
|
||||
|
||||
->with([
|
||||
'success' => __('app.alert.success.setting_updated'),
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
return redirect($route)
|
||||
->with([
|
||||
'error' => __('app.alert.error.not_exist'),
|
||||
]);
|
||||
->with([
|
||||
'errors' => collect([__('app.alert.error.'.$e->getMessage())]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@ namespace App\Http\Controllers;
|
|||
|
||||
use App\Item;
|
||||
use App\User;
|
||||
use DB;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class TagController extends Controller
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ class TagController extends Controller
|
|||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Response
|
||||
* @return Application|Factory|View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ class TagController extends Controller
|
|||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return Response
|
||||
* @return Application|Factory|View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
|
@ -57,6 +57,7 @@ class TagController extends Controller
|
|||
{
|
||||
$validatedData = $request->validate([
|
||||
'title' => 'required|max:255',
|
||||
'file' => 'image'
|
||||
]);
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
|
@ -66,7 +67,7 @@ class TagController extends Controller
|
|||
]);
|
||||
}
|
||||
|
||||
$slug = str_slug($request->title, '-');
|
||||
$slug = str_slug($request->title, '-', 'en_US');
|
||||
|
||||
$current_user = User::currentUser();
|
||||
|
||||
|
@ -129,6 +130,7 @@ class TagController extends Controller
|
|||
{
|
||||
$validatedData = $request->validate([
|
||||
'title' => 'required|max:255',
|
||||
'file' => 'image'
|
||||
]);
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
|
@ -138,7 +140,7 @@ class TagController extends Controller
|
|||
]);
|
||||
}
|
||||
|
||||
$slug = str_slug($request->title, '-');
|
||||
$slug = str_slug($request->title, '-', 'en_US');
|
||||
// set item type to tag
|
||||
$request->merge([
|
||||
'url' => $slug,
|
||||
|
@ -155,6 +157,7 @@ class TagController extends Controller
|
|||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param int $id
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
|
|
|
@ -62,7 +62,7 @@ class UserController extends Controller
|
|||
'email' => 'required|email',
|
||||
'password' => 'nullable|confirmed',
|
||||
'password_confirmation' => 'nullable',
|
||||
|
||||
'file' => 'image'
|
||||
]);
|
||||
$user = new User;
|
||||
$user->username = $request->input('username');
|
||||
|
@ -129,6 +129,7 @@ class UserController extends Controller
|
|||
'email' => 'required|email',
|
||||
'password' => 'nullable|confirmed',
|
||||
'password_confirmation' => 'nullable',
|
||||
'file' => 'image'
|
||||
]);
|
||||
//die(print_r($request->all()));
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ namespace App\Http\Middleware;
|
|||
|
||||
use App\User;
|
||||
use Closure;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Session;
|
||||
|
@ -13,11 +15,12 @@ class CheckAllowed
|
|||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param Request $request
|
||||
* @param Closure $next
|
||||
* @return mixed
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$route = Route::currentRouteName();
|
||||
$current_user = User::currentUser();
|
||||
|
@ -30,9 +33,7 @@ class CheckAllowed
|
|||
}
|
||||
|
||||
// Public access to frontpage
|
||||
if ($route == 'dash') {
|
||||
//print_r(User::all());
|
||||
//die("here".var_dump($current_user->password));
|
||||
if ($route === 'dash' || $route === 'tags.show') {
|
||||
if ((bool)$current_user->public_front === true) {
|
||||
return $next($request);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
|
@ -10,12 +11,12 @@ class RedirectIfAuthenticated
|
|||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null $guard
|
||||
* @param Request $request
|
||||
* @param Closure $next
|
||||
* @param string|null $guard
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next, $guard = null)
|
||||
public function handle(Request $request, Closure $next, string $guard = null)
|
||||
{
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect()->intended();
|
||||
|
|
|
@ -18,5 +18,4 @@ class VerifyCsrfToken extends Middleware
|
|||
'test_config',
|
||||
//'get_stats'
|
||||
];
|
||||
|
||||
}
|
||||
|
|
203
app/Item.php
203
app/Item.php
|
@ -2,15 +2,83 @@
|
|||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Contracts\Routing\UrlGenerator;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use stdClass;
|
||||
use Symfony\Component\ClassLoader\ClassMapGenerator;
|
||||
|
||||
// @codingStandardsIgnoreStart
|
||||
/**
|
||||
* App\Item
|
||||
*
|
||||
* @property int $id
|
||||
* @property string $title
|
||||
* @property string|null $colour
|
||||
* @property string|null $icon
|
||||
* @property string $url
|
||||
* @property string|null $description
|
||||
* @property int $pinned
|
||||
* @property int $order
|
||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property int $type
|
||||
* @property int $user_id
|
||||
* @property string|null $class
|
||||
* @property string|null $appid
|
||||
* @property string|null $appdescription
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|Item[] $children
|
||||
* @property-read int|null $children_count
|
||||
* @property-read string $droppable
|
||||
* @property-read \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\UrlGenerator|mixed|string $link
|
||||
* @property-read string $link_icon
|
||||
* @property-read string $link_target
|
||||
* @property-read string $link_type
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|Item[] $parents
|
||||
* @property-read int|null $parents_count
|
||||
* @property-read \App\User|null $user
|
||||
* @method static \Database\Factories\ItemFactory factory(...$parameters)
|
||||
* @method static Builder|Item newModelQuery()
|
||||
* @method static Builder|Item newQuery()
|
||||
* @method static Builder|Item ofType($type)
|
||||
* @method static \Illuminate\Database\Query\Builder|Item onlyTrashed()
|
||||
* @method static Builder|Item pinned()
|
||||
* @method static Builder|Item query()
|
||||
* @method static Builder|Item whereAppdescription($value)
|
||||
* @method static Builder|Item whereAppid($value)
|
||||
* @method static Builder|Item whereClass($value)
|
||||
* @method static Builder|Item whereColour($value)
|
||||
* @method static Builder|Item whereCreatedAt($value)
|
||||
* @method static Builder|Item whereDeletedAt($value)
|
||||
* @method static Builder|Item whereDescription($value)
|
||||
* @method static Builder|Item whereIcon($value)
|
||||
* @method static Builder|Item whereId($value)
|
||||
* @method static Builder|Item whereOrder($value)
|
||||
* @method static Builder|Item wherePinned($value)
|
||||
* @method static Builder|Item whereTitle($value)
|
||||
* @method static Builder|Item whereType($value)
|
||||
* @method static Builder|Item whereUpdatedAt($value)
|
||||
* @method static Builder|Item whereUrl($value)
|
||||
* @method static Builder|Item whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|Item withTrashed()
|
||||
* @method static \Illuminate\Database\Query\Builder|Item withoutTrashed()
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
// @codingStandardsIgnoreEnd
|
||||
class Item extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
@ -25,9 +93,20 @@ class Item extends Model
|
|||
});
|
||||
}
|
||||
|
||||
//
|
||||
protected $fillable = [
|
||||
'title', 'url', 'colour', 'icon', 'appdescription', 'description', 'pinned', 'order', 'type', 'class', 'user_id', 'tag_id', 'appid',
|
||||
'title',
|
||||
'url',
|
||||
'colour',
|
||||
'icon',
|
||||
'appdescription',
|
||||
'description',
|
||||
'pinned',
|
||||
'order',
|
||||
'type',
|
||||
'class',
|
||||
'user_id',
|
||||
'tag_id',
|
||||
'appid',
|
||||
];
|
||||
|
||||
|
||||
|
@ -35,10 +114,10 @@ class Item extends Model
|
|||
/**
|
||||
* Scope a query to only include pinned items.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
* @param Builder $query
|
||||
* @return Builder
|
||||
*/
|
||||
public function scopePinned($query)
|
||||
public function scopePinned(Builder $query): Builder
|
||||
{
|
||||
return $query->where('pinned', 1);
|
||||
}
|
||||
|
@ -74,16 +153,42 @@ class Item extends Model
|
|||
return $tagdetails;
|
||||
}
|
||||
|
||||
public function parents()
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTagClass(): string
|
||||
{
|
||||
return $this->belongsToMany(\App\Item::class, 'item_tag', 'item_id', 'tag_id');
|
||||
$tags = $this->tags();
|
||||
$slugs = [];
|
||||
|
||||
foreach ($tags as $tag) {
|
||||
if ($tag->url) {
|
||||
$slugs[] = 'tag-'.$tag->url;
|
||||
}
|
||||
}
|
||||
|
||||
return implode(' ', $slugs);
|
||||
}
|
||||
|
||||
public function children()
|
||||
/**
|
||||
* @return BelongsToMany
|
||||
*/
|
||||
public function parents(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(\App\Item::class, 'item_tag', 'tag_id', 'item_id');
|
||||
return $this->belongsToMany(Item::class, 'item_tag', 'item_id', 'tag_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsToMany
|
||||
*/
|
||||
public function children(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Item::class, 'item_tag', 'tag_id', 'item_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Contracts\Foundation\Application|UrlGenerator|mixed|string
|
||||
*/
|
||||
public function getLinkAttribute()
|
||||
{
|
||||
if ((int) $this->type === 1) {
|
||||
|
@ -93,7 +198,10 @@ class Item extends Model
|
|||
}
|
||||
}
|
||||
|
||||
public function getDroppableAttribute()
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDroppableAttribute(): string
|
||||
{
|
||||
if ((int) $this->type === 1) {
|
||||
return ' droppable';
|
||||
|
@ -102,7 +210,10 @@ class Item extends Model
|
|||
}
|
||||
}
|
||||
|
||||
public function getLinkTargetAttribute()
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLinkTargetAttribute(): string
|
||||
{
|
||||
$target = Setting::fetch('window_target');
|
||||
|
||||
|
@ -113,7 +224,10 @@ class Item extends Model
|
|||
}
|
||||
}
|
||||
|
||||
public function getLinkIconAttribute()
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLinkIconAttribute(): string
|
||||
{
|
||||
if ((int) $this->type === 1) {
|
||||
return 'fa-tag';
|
||||
|
@ -122,7 +236,10 @@ class Item extends Model
|
|||
}
|
||||
}
|
||||
|
||||
public function getLinkTypeAttribute()
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLinkTypeAttribute(): string
|
||||
{
|
||||
if ((int) $this->type === 1) {
|
||||
return 'tags';
|
||||
|
@ -131,6 +248,10 @@ class Item extends Model
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $class
|
||||
* @return false|mixed|string
|
||||
*/
|
||||
public static function nameFromClass($class)
|
||||
{
|
||||
$explode = explode('\\', $class);
|
||||
|
@ -139,6 +260,11 @@ class Item extends Model
|
|||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $query
|
||||
* @param $type
|
||||
* @return mixed
|
||||
*/
|
||||
public function scopeOfType($query, $type)
|
||||
{
|
||||
switch ($type) {
|
||||
|
@ -153,7 +279,10 @@ class Item extends Model
|
|||
return $query->where('type', $typeid);
|
||||
}
|
||||
|
||||
public function enhanced()
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function enhanced(): bool
|
||||
{
|
||||
/*if(isset($this->class) && !empty($this->class)) {
|
||||
$app = new $this->class;
|
||||
|
@ -164,16 +293,24 @@ class Item extends Model
|
|||
return $this->description !== null;
|
||||
}
|
||||
|
||||
public static function isEnhanced($class)
|
||||
/**
|
||||
* @param $class
|
||||
* @return bool
|
||||
*/
|
||||
public static function isEnhanced($class): bool
|
||||
{
|
||||
if (!class_exists($class, false) || $class === null || $class === 'null') {
|
||||
return false;
|
||||
}
|
||||
$app = new $class;
|
||||
|
||||
return (bool) ($app instanceof \App\EnhancedApps);
|
||||
return (bool) ($app instanceof EnhancedApps);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $class
|
||||
* @return false|mixed
|
||||
*/
|
||||
public static function isSearchProvider($class)
|
||||
{
|
||||
if (!class_exists($class, false) || $class === null || $class === 'null') {
|
||||
|
@ -181,10 +318,13 @@ class Item extends Model
|
|||
}
|
||||
$app = new $class;
|
||||
|
||||
return ((bool) ($app instanceof \App\SearchInterface)) ? $app : false;
|
||||
return ((bool) ($app instanceof SearchInterface)) ? $app : false;
|
||||
}
|
||||
|
||||
public function enabled()
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function enabled(): bool
|
||||
{
|
||||
if ($this->enhanced()) {
|
||||
$config = $this->getconfig();
|
||||
|
@ -196,12 +336,15 @@ class Item extends Model
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|stdClass
|
||||
*/
|
||||
public function getconfig()
|
||||
{
|
||||
// $explode = explode('\\', $this->class);
|
||||
|
||||
if (! isset($this->description) || empty($this->description)) {
|
||||
$config = new \stdClass;
|
||||
$config = new stdClass;
|
||||
// $config->name = end($explode);
|
||||
$config->enabled = false;
|
||||
$config->override_url = null;
|
||||
|
@ -224,7 +367,11 @@ class Item extends Model
|
|||
return $config;
|
||||
}
|
||||
|
||||
public static function applicationDetails($class)
|
||||
/**
|
||||
* @param $class
|
||||
* @return Application|null
|
||||
*/
|
||||
public static function applicationDetails($class): ?Application
|
||||
{
|
||||
if (! empty($class)) {
|
||||
$name = self::nameFromClass($class);
|
||||
|
@ -234,13 +381,17 @@ class Item extends Model
|
|||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getApplicationDescription($class)
|
||||
/**
|
||||
* @param $class
|
||||
* @return string
|
||||
*/
|
||||
public static function getApplicationDescription($class): string
|
||||
{
|
||||
$details = self::applicationDetails($class);
|
||||
if ($details !== false) {
|
||||
if ($details !== null) {
|
||||
return $details->description.' - '.$details->license;
|
||||
}
|
||||
|
||||
|
@ -249,9 +400,11 @@ class Item extends Model
|
|||
|
||||
/**
|
||||
* Get the user that owns the item.
|
||||
*
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function user()
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(\App\User::class);
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,26 @@
|
|||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||
|
||||
/**
|
||||
* App\ItemTag
|
||||
*
|
||||
* @property int $item_id
|
||||
* @property int $tag_id
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ItemTag newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ItemTag newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ItemTag query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ItemTag whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ItemTag whereItemId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ItemTag whereTagId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ItemTag whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class ItemTag extends Pivot
|
||||
{
|
||||
use HasFactory;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace App\Jobs;
|
|||
use App\Application;
|
||||
use App\Item;
|
||||
use App\SupportedApps;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
|
@ -32,6 +33,7 @@ class ProcessApps implements ShouldQueue, ShouldBeUnique
|
|||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Jobs;
|
||||
|
||||
use App\Application;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
|
@ -30,6 +31,7 @@ class UpdateApps implements ShouldQueue, ShouldBeUnique
|
|||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
|
|
@ -7,10 +7,13 @@ use App\Jobs\ProcessApps;
|
|||
use App\Jobs\UpdateApps;
|
||||
use App\Setting;
|
||||
use App\User;
|
||||
use Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
@ -40,6 +43,9 @@ class AppServiceProvider extends ServiceProvider
|
|||
ProcessApps::dispatch();
|
||||
}
|
||||
|
||||
$lang = Setting::fetch('language');
|
||||
\App::setLocale($lang);
|
||||
|
||||
// User specific settings need to go here as session isn't available at this point in the app
|
||||
view()->composer('*', function ($view) {
|
||||
if (isset($_SERVER['HTTP_AUTHORIZATION']) && ! empty($_SERVER['HTTP_AUTHORIZATION'])) {
|
||||
|
@ -67,17 +73,21 @@ class AppServiceProvider extends ServiceProvider
|
|||
}
|
||||
|
||||
$alt_bg = '';
|
||||
if ($bg_image = Setting::fetch('background_image')) {
|
||||
$trianglify = 'false';
|
||||
$trianglify_seed = null;
|
||||
if (Setting::fetch('trianglify')) {
|
||||
$trianglify = 'true';
|
||||
$trianglify_seed = Setting::fetch('trianglify_seed');
|
||||
} elseif ($bg_image = Setting::fetch('background_image')) {
|
||||
$alt_bg = ' style="background-image: url(storage/'.$bg_image.')"';
|
||||
}
|
||||
|
||||
$allusers = User::all();
|
||||
$current_user = User::currentUser();
|
||||
|
||||
$lang = Setting::fetch('language');
|
||||
\App::setLocale($lang);
|
||||
|
||||
$view->with('alt_bg', $alt_bg);
|
||||
$view->with('trianglify', $trianglify);
|
||||
$view->with('trianglify_seed', $trianglify_seed);
|
||||
$view->with('allusers', $allusers);
|
||||
$view->with('current_user', $current_user);
|
||||
});
|
||||
|
@ -114,6 +124,10 @@ class AppServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function register()
|
||||
{
|
||||
if ($this->app->isLocal()) {
|
||||
$this->app->register(IdeHelperServiceProvider::class);
|
||||
}
|
||||
|
||||
$this->app->singleton('settings', function () {
|
||||
return new Setting();
|
||||
});
|
||||
|
@ -123,13 +137,18 @@ class AppServiceProvider extends ServiceProvider
|
|||
* Check if database needs an update or do first time database setup
|
||||
*
|
||||
* @return void
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function setupDatabase(): void
|
||||
{
|
||||
$db_type = config()->get('database.default');
|
||||
|
||||
if ($db_type == 'sqlite' && ! is_file(database_path('app.sqlite'))) {
|
||||
touch(database_path('app.sqlite'));
|
||||
if ($db_type == 'sqlite') {
|
||||
$db_file = database_path(env('DB_DATABASE', 'app.sqlite'));
|
||||
if (! is_file($db_file)) {
|
||||
touch($db_file);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->needsDBUpdate()) {
|
||||
|
|
|
@ -12,9 +12,9 @@ class RouteServiceProvider extends ServiceProvider
|
|||
*
|
||||
* In addition, it is set as the URL generator's root namespace.
|
||||
*
|
||||
* @var string
|
||||
* REMOVED WITH LARAVEL 8 UPGRADE
|
||||
*/
|
||||
protected $namespace = 'App\Http\Controllers';
|
||||
// protected $namespace = 'App\Http\Controllers';
|
||||
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, etc.
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace App;
|
|||
|
||||
use Cache;
|
||||
use Form;
|
||||
use Illuminate\Support\Collection;
|
||||
use Yaml;
|
||||
|
||||
abstract class Search
|
||||
|
@ -11,9 +12,9 @@ abstract class Search
|
|||
/**
|
||||
* List of all search providers
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
* @return Collection
|
||||
*/
|
||||
public static function providers()
|
||||
public static function providers(): Collection
|
||||
{
|
||||
$providers = self::standardProviders();
|
||||
$providers = $providers + self::appProviders();
|
||||
|
@ -61,7 +62,7 @@ abstract class Search
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function appProviders()
|
||||
public static function appProviders(): array
|
||||
{
|
||||
$providers = [];
|
||||
$userapps = Item::all();
|
||||
|
@ -121,7 +122,15 @@ abstract class Search
|
|||
$output .= '<option value="'.$key.'"'.$selected.'>'.$searchprovider['name'].'</option>';
|
||||
}
|
||||
$output .= '</select>';
|
||||
$output .= Form::text('q', null, ['class' => 'homesearch', 'autofocus' => 'autofocus', 'placeholder' => __('app.settings.search').'...']);
|
||||
$output .= Form::text(
|
||||
'q',
|
||||
null,
|
||||
[
|
||||
'class' => 'homesearch',
|
||||
'autofocus' => 'autofocus',
|
||||
'placeholder' => __('app.settings.search').'...'
|
||||
]
|
||||
);
|
||||
$output .= '<button type="submit">'.ucwords(__('app.settings.search')).'</button>';
|
||||
$output .= '</div>';
|
||||
$output .= '</form>';
|
||||
|
|
|
@ -3,10 +3,46 @@
|
|||
namespace App;
|
||||
|
||||
use Form;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Session\SessionManager;
|
||||
use Illuminate\Session\Store;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
|
||||
/**
|
||||
* App\Setting
|
||||
*
|
||||
* @mixin Builder
|
||||
* @property int $id
|
||||
* @property int $group_id
|
||||
* @property string $key
|
||||
* @property string $type
|
||||
* @property string|null $options
|
||||
* @property string $label
|
||||
* @property string|null $value
|
||||
* @property string $order
|
||||
* @property int $system
|
||||
* @property-read mixed $edit_value
|
||||
* @property-read mixed $list_value
|
||||
* @property-read \App\SettingGroup|null $group
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\User[] $users
|
||||
* @property-read int|null $users_count
|
||||
* @method static Builder|Setting newModelQuery()
|
||||
* @method static Builder|Setting newQuery()
|
||||
* @method static Builder|Setting query()
|
||||
* @method static Builder|Setting whereGroupId($value)
|
||||
* @method static Builder|Setting whereId($value)
|
||||
* @method static Builder|Setting whereKey($value)
|
||||
* @method static Builder|Setting whereLabel($value)
|
||||
* @method static Builder|Setting whereOptions($value)
|
||||
* @method static Builder|Setting whereOrder($value)
|
||||
* @method static Builder|Setting whereSystem($value)
|
||||
* @method static Builder|Setting whereType($value)
|
||||
* @method static Builder|Setting whereValue($value)
|
||||
*/
|
||||
class Setting extends Model
|
||||
{
|
||||
/**
|
||||
|
@ -57,7 +93,11 @@ class Setting extends Model
|
|||
switch ($this->type) {
|
||||
case 'image':
|
||||
if (! empty($this->value)) {
|
||||
$value = '<a href="'.asset('storage/'.$this->value).'" title="'.__('app.settings.view').'" target="_blank">'.__('app.settings.view').'</a>';
|
||||
$value = '<a href="'.asset('storage/'.$this->value).'" title="'.
|
||||
__('app.settings.view').
|
||||
'" target="_blank">'.
|
||||
__('app.settings.view').
|
||||
'</a>';
|
||||
} else {
|
||||
$value = __('app.options.none');
|
||||
}
|
||||
|
@ -75,7 +115,9 @@ class Setting extends Model
|
|||
if ($this->key === 'search_provider') {
|
||||
$options = Search::providers()->pluck('name', 'id')->toArray();
|
||||
}
|
||||
$value = (array_key_exists($this->value, $options)) ? __($options[$this->value]) : __('app.options.none');
|
||||
$value = (array_key_exists($this->value, $options))
|
||||
? __($options[$this->value])
|
||||
: __('app.options.none');
|
||||
} else {
|
||||
$value = __('app.options.none');
|
||||
}
|
||||
|
@ -100,11 +142,24 @@ class Setting extends Model
|
|||
case 'image':
|
||||
$value = '';
|
||||
if (isset($this->value) && ! empty($this->value)) {
|
||||
$value .= '<a class="setting-view-image" href="'.asset('storage/'.$this->value).'" title="'.__('app.settings.view').'" target="_blank"><img src="'.asset('storage/'.$this->value).'" /></a>';
|
||||
$value .= '<a class="setting-view-image" href="'.
|
||||
asset('storage/'.$this->value).
|
||||
'" title="'.
|
||||
__('app.settings.view').
|
||||
'" target="_blank"><img src="'.
|
||||
asset('storage/'.
|
||||
$this->value).
|
||||
'" /></a>';
|
||||
}
|
||||
$value .= Form::file('value', ['class' => 'form-control']);
|
||||
if (isset($this->value) && ! empty($this->value)) {
|
||||
$value .= '<a class="settinglink" href="'.route('settings.clear', $this->id).'" title="'.__('app.settings.remove').'">'.__('app.settings.reset').'</a>';
|
||||
$value .= '<a class="settinglink" href="'.
|
||||
route('settings.clear', $this->id).
|
||||
'" title="'.
|
||||
__('app.settings.remove').
|
||||
'">'.
|
||||
__('app.settings.reset').
|
||||
'</a>';
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -143,7 +198,10 @@ class Setting extends Model
|
|||
return $value;
|
||||
}
|
||||
|
||||
public function group()
|
||||
/**
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function group(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(\App\SettingGroup::class, 'group_id');
|
||||
}
|
||||
|
@ -153,13 +211,14 @@ class Setting extends Model
|
|||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function fetch($key)
|
||||
public static function fetch(string $key)
|
||||
{
|
||||
$user = self::user();
|
||||
|
||||
return self::_fetch($key, $user);
|
||||
}
|
||||
|
||||
// @codingStandardsIgnoreStart
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
|
@ -167,6 +226,7 @@ class Setting extends Model
|
|||
*/
|
||||
public static function _fetch($key, $user = null)
|
||||
{
|
||||
// @codingStandardsIgnoreEnd
|
||||
//$cachekey = ($user === null) ? $key : $key.'-'.$user->id;
|
||||
//if (Setting::cached($cachekey)) {
|
||||
// return Setting::$cache[$cachekey];
|
||||
|
@ -220,7 +280,7 @@ class Setting extends Model
|
|||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function cached($key)
|
||||
public static function cached($key): bool
|
||||
{
|
||||
return array_key_exists($key, self::$cache);
|
||||
}
|
||||
|
@ -228,11 +288,14 @@ class Setting extends Model
|
|||
/**
|
||||
* The users that belong to the setting.
|
||||
*/
|
||||
public function users()
|
||||
public function users(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(\App\User::class)->using(\App\SettingUser::class)->withPivot('uservalue');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Contracts\Foundation\Application|SessionManager|Store|mixed
|
||||
*/
|
||||
public static function user()
|
||||
{
|
||||
return User::currentUser();
|
||||
|
|
|
@ -3,7 +3,24 @@
|
|||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
/**
|
||||
* App\SettingGroup
|
||||
*
|
||||
* @property int $id
|
||||
* @property string $title
|
||||
* @property int $order
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Setting[] $settings
|
||||
* @property-read int|null $settings_count
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|SettingGroup newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|SettingGroup newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|SettingGroup query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|SettingGroup whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|SettingGroup whereOrder($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|SettingGroup whereTitle($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class SettingGroup extends Model
|
||||
{
|
||||
/**
|
||||
|
@ -20,7 +37,10 @@ class SettingGroup extends Model
|
|||
*/
|
||||
public $timestamps = false;
|
||||
|
||||
public function settings()
|
||||
/**
|
||||
* @return HasMany
|
||||
*/
|
||||
public function settings(): HasMany
|
||||
{
|
||||
return $this->hasMany(\App\Setting::class, 'group_id');
|
||||
}
|
||||
|
|
|
@ -4,6 +4,20 @@ namespace App;
|
|||
|
||||
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||
|
||||
/**
|
||||
* App\SettingUser
|
||||
*
|
||||
* @property int $setting_id
|
||||
* @property int $user_id
|
||||
* @property string|null $uservalue
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|SettingUser newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|SettingUser newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|SettingUser query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|SettingUser whereSettingId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|SettingUser whereUserId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|SettingUser whereUservalue($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class SettingUser extends Pivot
|
||||
{
|
||||
//
|
||||
|
|
|
@ -3,7 +3,11 @@
|
|||
namespace App;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Exception\ServerException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
abstract class SupportedApps
|
||||
{
|
||||
|
@ -13,7 +17,13 @@ abstract class SupportedApps
|
|||
|
||||
protected $error;
|
||||
|
||||
public function appTest($url, $attrs = [], $overridevars = false)
|
||||
/**
|
||||
* @param $url
|
||||
* @param array $attrs
|
||||
* @return object
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function appTest($url, array $attrs = []): object
|
||||
{
|
||||
if (empty($this->config->url)) {
|
||||
return (object) [
|
||||
|
@ -52,28 +62,41 @@ abstract class SupportedApps
|
|||
];
|
||||
}
|
||||
|
||||
public function execute($url, $attrs = [], $overridevars = false, $overridemethod = false)
|
||||
{
|
||||
/**
|
||||
* @param $url
|
||||
* @param array $attrs
|
||||
* @param array|bool|null $overridevars
|
||||
* @param string|bool|null $overridemethod
|
||||
* @return ResponseInterface|null
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function execute(
|
||||
$url,
|
||||
array $attrs = [],
|
||||
$overridevars = null,
|
||||
$overridemethod = null
|
||||
): ?ResponseInterface {
|
||||
$res = null;
|
||||
|
||||
$vars = ($overridevars !== false) ?
|
||||
$overridevars : [
|
||||
$vars = ($overridevars === null || $overridevars === false) ?
|
||||
[
|
||||
'http_errors' => false,
|
||||
'timeout' => 15,
|
||||
'connect_timeout' => 15,
|
||||
];
|
||||
] : $overridevars;
|
||||
|
||||
$client = new Client($vars);
|
||||
|
||||
$method = ($overridemethod !== false) ? $overridemethod : $this->method;
|
||||
$method = ($overridemethod === null || $overridemethod === false) ? $this->method : $overridemethod;
|
||||
|
||||
|
||||
try {
|
||||
return $client->request($method, $url, $attrs);
|
||||
} catch (\GuzzleHttp\Exception\ConnectException $e) {
|
||||
} catch (ConnectException $e) {
|
||||
Log::error('Connection refused');
|
||||
Log::debug($e->getMessage());
|
||||
$this->error = 'Connection refused - '.(string) $e->getMessage();
|
||||
} catch (\GuzzleHttp\Exception\ServerException $e) {
|
||||
} catch (ServerException $e) {
|
||||
Log::debug($e->getMessage());
|
||||
$this->error = (string) $e->getResponse()->getBody();
|
||||
}
|
||||
|
@ -82,11 +105,19 @@ abstract class SupportedApps
|
|||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function login()
|
||||
{
|
||||
}
|
||||
|
||||
public function normaliseurl($url, $addslash = true)
|
||||
/**
|
||||
* @param string $url
|
||||
* @param bool $addslash
|
||||
* @return string
|
||||
*/
|
||||
public function normaliseurl(string $url, bool $addslash = true): string
|
||||
{
|
||||
$url = rtrim($url, '/');
|
||||
if ($addslash) {
|
||||
|
@ -96,6 +127,11 @@ abstract class SupportedApps
|
|||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $status
|
||||
* @param $data
|
||||
* @return false|string
|
||||
*/
|
||||
public function getLiveStats($status, $data)
|
||||
{
|
||||
$className = get_class($this);
|
||||
|
@ -108,7 +144,11 @@ abstract class SupportedApps
|
|||
//return
|
||||
}
|
||||
|
||||
public static function getList()
|
||||
/**
|
||||
* @return ResponseInterface
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public static function getList(): ResponseInterface
|
||||
{
|
||||
// $list_url = 'https://apps.heimdall.site/list';
|
||||
$list_url = config('app.appsource').'list.json';
|
||||
|
@ -129,7 +169,7 @@ abstract class SupportedApps
|
|||
/**
|
||||
* @param $app
|
||||
* @return bool|false
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public static function getFiles($app): bool
|
||||
{
|
||||
|
@ -165,6 +205,11 @@ abstract class SupportedApps
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $details
|
||||
* @param $app
|
||||
* @return mixed
|
||||
*/
|
||||
public static function saveApp($details, $app)
|
||||
{
|
||||
$app->appid = $details->appid;
|
||||
|
|
39
app/User.php
39
app/User.php
|
@ -2,15 +2,54 @@
|
|||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
// @codingStandardsIgnoreStart
|
||||
/**
|
||||
* App\User
|
||||
*
|
||||
* @property int $id
|
||||
* @property string $username
|
||||
* @property string $email
|
||||
* @property string|null $avatar
|
||||
* @property string|null $password
|
||||
* @property string|null $autologin
|
||||
* @property int $public_front
|
||||
* @property string|null $remember_token
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Item[] $items
|
||||
* @property-read int|null $items_count
|
||||
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection|\Illuminate\Notifications\DatabaseNotification[] $notifications
|
||||
* @property-read int|null $notifications_count
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Setting[] $settings
|
||||
* @property-read int|null $settings_count
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereAutologin($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereAvatar($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereEmail($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User wherePassword($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User wherePublicFront($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereRememberToken($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereUsername($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
// @codingStandardsIgnoreEnd
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use Notifiable;
|
||||
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
|
|
|
@ -23,10 +23,12 @@
|
|||
"ext-intl": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-ide-helper": "^2.12",
|
||||
"filp/whoops": "~2.0",
|
||||
"fzaninotto/faker": "~1.4",
|
||||
"mockery/mockery": "~1.0",
|
||||
"phpunit/phpunit": "~9.0",
|
||||
"squizlabs/php_codesniffer": "3.*",
|
||||
"symfony/thanks": "^1.0"
|
||||
},
|
||||
"autoload": {
|
||||
|
@ -51,6 +53,7 @@
|
|||
"extra": {
|
||||
"laravel": {
|
||||
"dont-discover": [
|
||||
"barryvdh/laravel-ide-helper"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -64,6 +67,11 @@
|
|||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
"@php artisan package:discover"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
|
||||
"@php artisan ide-helper:generate",
|
||||
"@php artisan ide-helper:meta"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
|
|
766
composer.lock
generated
766
composer.lock
generated
|
@ -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": "5ec4ff397b3937979b48679da0338808",
|
||||
"content-hash": "23969e2624fec1e93e31a8fa1e94c471",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
|
@ -1770,16 +1770,16 @@
|
|||
},
|
||||
{
|
||||
"name": "laravel/tinker",
|
||||
"version": "v2.7.2",
|
||||
"version": "v2.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/tinker.git",
|
||||
"reference": "dff39b661e827dae6e092412f976658df82dbac5"
|
||||
"reference": "5062061b4924af3392225dd482ca7b4d85d8b8ef"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/tinker/zipball/dff39b661e827dae6e092412f976658df82dbac5",
|
||||
"reference": "dff39b661e827dae6e092412f976658df82dbac5",
|
||||
"url": "https://api.github.com/repos/laravel/tinker/zipball/5062061b4924af3392225dd482ca7b4d85d8b8ef",
|
||||
"reference": "5062061b4924af3392225dd482ca7b4d85d8b8ef",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1832,9 +1832,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/tinker/issues",
|
||||
"source": "https://github.com/laravel/tinker/tree/v2.7.2"
|
||||
"source": "https://github.com/laravel/tinker/tree/v2.7.3"
|
||||
},
|
||||
"time": "2022-03-23T12:38:24+00:00"
|
||||
"time": "2022-11-09T15:11:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/ui",
|
||||
|
@ -2513,25 +2513,25 @@
|
|||
},
|
||||
{
|
||||
"name": "nette/schema",
|
||||
"version": "v1.2.2",
|
||||
"version": "v1.2.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nette/schema.git",
|
||||
"reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df"
|
||||
"reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nette/schema/zipball/9a39cef03a5b34c7de64f551538cbba05c2be5df",
|
||||
"reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df",
|
||||
"url": "https://api.github.com/repos/nette/schema/zipball/abbdbb70e0245d5f3bf77874cea1dfb0c930d06f",
|
||||
"reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"nette/utils": "^2.5.7 || ^3.1.5 || ^4.0",
|
||||
"php": ">=7.1 <8.2"
|
||||
"php": ">=7.1 <8.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"nette/tester": "^2.3 || ^2.4",
|
||||
"phpstan/phpstan-nette": "^0.12",
|
||||
"phpstan/phpstan-nette": "^1.0",
|
||||
"tracy/tracy": "^2.7"
|
||||
},
|
||||
"type": "library",
|
||||
|
@ -2569,9 +2569,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nette/schema/issues",
|
||||
"source": "https://github.com/nette/schema/tree/v1.2.2"
|
||||
"source": "https://github.com/nette/schema/tree/v1.2.3"
|
||||
},
|
||||
"time": "2021-10-15T11:40:02+00:00"
|
||||
"time": "2022-10-13T01:24:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nette/utils",
|
||||
|
@ -7100,6 +7100,562 @@
|
|||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "barryvdh/laravel-ide-helper",
|
||||
"version": "v2.12.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/barryvdh/laravel-ide-helper.git",
|
||||
"reference": "3ba1e2573b38f72107b8aacc4ee177fcab30a550"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/3ba1e2573b38f72107b8aacc4ee177fcab30a550",
|
||||
"reference": "3ba1e2573b38f72107b8aacc4ee177fcab30a550",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"barryvdh/reflection-docblock": "^2.0.6",
|
||||
"composer/pcre": "^1 || ^2 || ^3",
|
||||
"doctrine/dbal": "^2.6 || ^3",
|
||||
"ext-json": "*",
|
||||
"illuminate/console": "^8 || ^9",
|
||||
"illuminate/filesystem": "^8 || ^9",
|
||||
"illuminate/support": "^8 || ^9",
|
||||
"nikic/php-parser": "^4.7",
|
||||
"php": "^7.3 || ^8.0",
|
||||
"phpdocumentor/type-resolver": "^1.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-pdo_sqlite": "*",
|
||||
"friendsofphp/php-cs-fixer": "^2",
|
||||
"illuminate/config": "^8 || ^9",
|
||||
"illuminate/view": "^8 || ^9",
|
||||
"mockery/mockery": "^1.4",
|
||||
"orchestra/testbench": "^6 || ^7",
|
||||
"phpunit/phpunit": "^8.5 || ^9",
|
||||
"spatie/phpunit-snapshot-assertions": "^3 || ^4",
|
||||
"vimeo/psalm": "^3.12"
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/events": "Required for automatic helper generation (^6|^7|^8|^9)."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.12-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Barryvdh\\LaravelIdeHelper\\IdeHelperServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Barryvdh\\LaravelIdeHelper\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Barry vd. Heuvel",
|
||||
"email": "barryvdh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.",
|
||||
"keywords": [
|
||||
"autocomplete",
|
||||
"codeintel",
|
||||
"helper",
|
||||
"ide",
|
||||
"laravel",
|
||||
"netbeans",
|
||||
"phpdoc",
|
||||
"phpstorm",
|
||||
"sublime"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/barryvdh/laravel-ide-helper/issues",
|
||||
"source": "https://github.com/barryvdh/laravel-ide-helper/tree/v2.12.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://fruitcake.nl",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/barryvdh",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-06T14:33:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "barryvdh/reflection-docblock",
|
||||
"version": "v2.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/barryvdh/ReflectionDocBlock.git",
|
||||
"reference": "bf44b757feb8ba1734659029357646466ded673e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/bf44b757feb8ba1734659029357646466ded673e",
|
||||
"reference": "bf44b757feb8ba1734659029357646466ded673e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5.14|^9"
|
||||
},
|
||||
"suggest": {
|
||||
"dflydev/markdown": "~1.0",
|
||||
"erusev/parsedown": "~1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Barryvdh": [
|
||||
"src/"
|
||||
]
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mike van Riel",
|
||||
"email": "mike.vanriel@naenius.com"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/barryvdh/ReflectionDocBlock/tree/v2.1.0"
|
||||
},
|
||||
"time": "2022-10-31T15:35:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/pcre",
|
||||
"version": "3.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/pcre.git",
|
||||
"reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
|
||||
"reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.3",
|
||||
"phpstan/phpstan-strict-rules": "^1.1",
|
||||
"symfony/phpunit-bridge": "^5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\Pcre\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
}
|
||||
],
|
||||
"description": "PCRE wrapping library that offers type-safe preg_* replacements.",
|
||||
"keywords": [
|
||||
"PCRE",
|
||||
"preg",
|
||||
"regex",
|
||||
"regular expression"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/composer/pcre/issues",
|
||||
"source": "https://github.com/composer/pcre/tree/3.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://packagist.com",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/composer",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-17T09:50:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/cache",
|
||||
"version": "2.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/cache.git",
|
||||
"reference": "1ca8f21980e770095a31456042471a57bc4c68fb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb",
|
||||
"reference": "1ca8f21980e770095a31456042471a57bc4c68fb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "~7.1 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/common": ">2.2,<2.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"cache/integration-tests": "dev-master",
|
||||
"doctrine/coding-standard": "^9",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
|
||||
"psr/cache": "^1.0 || ^2.0 || ^3.0",
|
||||
"symfony/cache": "^4.4 || ^5.4 || ^6",
|
||||
"symfony/var-exporter": "^4.4 || ^5.4 || ^6"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
|
||||
"homepage": "https://www.doctrine-project.org/projects/cache.html",
|
||||
"keywords": [
|
||||
"abstraction",
|
||||
"apcu",
|
||||
"cache",
|
||||
"caching",
|
||||
"couchdb",
|
||||
"memcached",
|
||||
"php",
|
||||
"redis",
|
||||
"xcache"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/cache/issues",
|
||||
"source": "https://github.com/doctrine/cache/tree/2.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.doctrine-project.org/sponsorship.html",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/phpdoctrine",
|
||||
"type": "patreon"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-05-20T20:07:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/dbal",
|
||||
"version": "3.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/dbal.git",
|
||||
"reference": "f38ee8aaca2d58ee88653cb34a6a3880c23f38a5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/f38ee8aaca2d58ee88653cb34a6a3880c23f38a5",
|
||||
"reference": "f38ee8aaca2d58ee88653cb34a6a3880c23f38a5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-runtime-api": "^2",
|
||||
"doctrine/cache": "^1.11|^2.0",
|
||||
"doctrine/deprecations": "^0.5.3|^1",
|
||||
"doctrine/event-manager": "^1|^2",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"psr/cache": "^1|^2|^3",
|
||||
"psr/log": "^1|^2|^3"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "10.0.0",
|
||||
"jetbrains/phpstorm-stubs": "2022.2",
|
||||
"phpstan/phpstan": "1.8.10",
|
||||
"phpstan/phpstan-strict-rules": "^1.4",
|
||||
"phpunit/phpunit": "9.5.25",
|
||||
"psalm/plugin-phpunit": "0.17.0",
|
||||
"squizlabs/php_codesniffer": "3.7.1",
|
||||
"symfony/cache": "^5.4|^6.0",
|
||||
"symfony/console": "^4.4|^5.4|^6.0",
|
||||
"vimeo/psalm": "4.29.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/console": "For helpful console commands such as SQL execution and import of files."
|
||||
},
|
||||
"bin": [
|
||||
"bin/doctrine-dbal"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\DBAL\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.",
|
||||
"homepage": "https://www.doctrine-project.org/projects/dbal.html",
|
||||
"keywords": [
|
||||
"abstraction",
|
||||
"database",
|
||||
"db2",
|
||||
"dbal",
|
||||
"mariadb",
|
||||
"mssql",
|
||||
"mysql",
|
||||
"oci8",
|
||||
"oracle",
|
||||
"pdo",
|
||||
"pgsql",
|
||||
"postgresql",
|
||||
"queryobject",
|
||||
"sasql",
|
||||
"sql",
|
||||
"sqlite",
|
||||
"sqlserver",
|
||||
"sqlsrv"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/dbal/issues",
|
||||
"source": "https://github.com/doctrine/dbal/tree/3.5.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.doctrine-project.org/sponsorship.html",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/phpdoctrine",
|
||||
"type": "patreon"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-10-24T07:26:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/deprecations",
|
||||
"version": "v1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/deprecations.git",
|
||||
"reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
|
||||
"reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^9",
|
||||
"phpunit/phpunit": "^7.5|^8.5|^9.5",
|
||||
"psr/log": "^1|^2|^3"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/log": "Allows logging deprecations via PSR-3 logger implementation"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
|
||||
"homepage": "https://www.doctrine-project.org/",
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/deprecations/issues",
|
||||
"source": "https://github.com/doctrine/deprecations/tree/v1.0.0"
|
||||
},
|
||||
"time": "2022-05-02T15:47:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/event-manager",
|
||||
"version": "1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/event-manager.git",
|
||||
"reference": "95aa4cb529f1e96576f3fda9f5705ada4056a520"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/event-manager/zipball/95aa4cb529f1e96576f3fda9f5705ada4056a520",
|
||||
"reference": "95aa4cb529f1e96576f3fda9f5705ada4056a520",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/deprecations": "^0.5.3 || ^1",
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/common": "<2.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^9 || ^10",
|
||||
"phpstan/phpstan": "~1.4.10 || ^1.8.8",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
|
||||
"vimeo/psalm": "^4.24"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Common\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Marco Pivetta",
|
||||
"email": "ocramius@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.",
|
||||
"homepage": "https://www.doctrine-project.org/projects/event-manager.html",
|
||||
"keywords": [
|
||||
"event",
|
||||
"event dispatcher",
|
||||
"event manager",
|
||||
"event system",
|
||||
"events"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/event-manager/issues",
|
||||
"source": "https://github.com/doctrine/event-manager/tree/1.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.doctrine-project.org/sponsorship.html",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/phpdoctrine",
|
||||
"type": "patreon"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-10-12T20:51:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/instantiator",
|
||||
"version": "1.4.1",
|
||||
|
@ -7519,17 +8075,125 @@
|
|||
"time": "2022-02-21T01:04:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "9.2.18",
|
||||
"name": "phpdocumentor/reflection-common",
|
||||
"version": "2.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "12fddc491826940cf9b7e88ad9664cf51f0f6d0a"
|
||||
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
|
||||
"reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/12fddc491826940cf9b7e88ad9664cf51f0f6d0a",
|
||||
"reference": "12fddc491826940cf9b7e88ad9664cf51f0f6d0a",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
|
||||
"reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-2.x": "2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"phpDocumentor\\Reflection\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jaap van Otterdijk",
|
||||
"email": "opensource@ijaap.nl"
|
||||
}
|
||||
],
|
||||
"description": "Common reflection classes used by phpdocumentor to reflect the code structure",
|
||||
"homepage": "http://www.phpdoc.org",
|
||||
"keywords": [
|
||||
"FQSEN",
|
||||
"phpDocumentor",
|
||||
"phpdoc",
|
||||
"reflection",
|
||||
"static analysis"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
|
||||
"source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
|
||||
},
|
||||
"time": "2020-06-27T09:03:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/type-resolver",
|
||||
"version": "1.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpDocumentor/TypeResolver.git",
|
||||
"reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d",
|
||||
"reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0",
|
||||
"phpdocumentor/reflection-common": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-tokenizer": "*",
|
||||
"phpstan/extension-installer": "^1.1",
|
||||
"phpstan/phpstan": "^1.8",
|
||||
"phpstan/phpstan-phpunit": "^1.1",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"rector/rector": "^0.13.9",
|
||||
"vimeo/psalm": "^4.25"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-1.x": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"phpDocumentor\\Reflection\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mike van Riel",
|
||||
"email": "me@mikevanriel.com"
|
||||
}
|
||||
],
|
||||
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
|
||||
"source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2"
|
||||
},
|
||||
"time": "2022-10-14T12:47:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "9.2.19",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c77b56b63e3d2031bd8997fcec43c1925ae46559",
|
||||
"reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -7585,7 +8249,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.18"
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.19"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -7593,7 +8257,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-10-27T13:35:33+00:00"
|
||||
"time": "2022-11-18T07:47:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
|
@ -8902,6 +9566,62 @@
|
|||
],
|
||||
"time": "2020-09-28T06:39:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "squizlabs/php_codesniffer",
|
||||
"version": "3.7.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
|
||||
"reference": "1359e176e9307e906dc3d890bcc9603ff6d90619"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619",
|
||||
"reference": "1359e176e9307e906dc3d890bcc9603ff6d90619",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-simplexml": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
|
||||
},
|
||||
"bin": [
|
||||
"bin/phpcs",
|
||||
"bin/phpcbf"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Greg Sherwood",
|
||||
"role": "lead"
|
||||
}
|
||||
],
|
||||
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
|
||||
"homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
|
||||
"keywords": [
|
||||
"phpcs",
|
||||
"standards"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
|
||||
"source": "https://github.com/squizlabs/PHP_CodeSniffer",
|
||||
"wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
|
||||
},
|
||||
"time": "2022-06-18T07:21:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/thanks",
|
||||
"version": "v1.2.10",
|
||||
|
|
|
@ -14,7 +14,7 @@ return [
|
|||
*/
|
||||
|
||||
'name' => env('APP_NAME', 'Heimdall'),
|
||||
'version' => '2.5.0',
|
||||
'version' => '2.5.8',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
|
@ -49,4 +49,4 @@ return [
|
|||
'time' => 2,
|
||||
],
|
||||
|
||||
];
|
||||
];
|
||||
|
|
|
@ -17,7 +17,7 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'default' => env('LOG_CHANNEL', 'stack'),
|
||||
'default' => env('LOG_CHANNEL', 'daily'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
|
@ -33,4 +33,4 @@ return [
|
|||
realpath(storage_path('framework/views'))
|
||||
),
|
||||
|
||||
];
|
||||
];
|
||||
|
|
29
database/factories/ItemFactory.php
Normal file
29
database/factories/ItemFactory.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Item;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class ItemFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = Item::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'title' => $this->faker->unique()->text(),
|
||||
'url' => $this->faker->unique()->url(),
|
||||
];
|
||||
}
|
||||
}
|
27
database/factories/ItemTagFactory.php
Normal file
27
database/factories/ItemTagFactory.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Item;
|
||||
use App\ItemTag;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class ItemTagFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = ItemTag::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
|
@ -2,11 +2,19 @@
|
|||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class UserFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = User::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
|
@ -15,10 +23,10 @@ class UserFactory extends Factory
|
|||
public function definition()
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->name(),
|
||||
'username' => $this->faker->name(),
|
||||
'email' => $this->faker->unique()->safeEmail(),
|
||||
'email_verified_at' => now(),
|
||||
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
|
||||
'public_front' => 1,
|
||||
'remember_token' => Str::random(10),
|
||||
];
|
||||
}
|
||||
|
@ -36,4 +44,4 @@ class UserFactory extends Factory
|
|||
];
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,11 @@ class SettingsSeeder extends Seeder
|
|||
|
||||
foreach ($languageDirectories as $languageDirectory) {
|
||||
$language = self::getLanguageFromDirectory($languageDirectory);
|
||||
$resultNative = mb_convert_case(Locale::getDisplayLanguage($language.'-', $language), MB_CASE_TITLE, 'UTF-8');
|
||||
$resultNative = mb_convert_case(
|
||||
Locale::getDisplayLanguage($language.'-', $language),
|
||||
MB_CASE_TITLE,
|
||||
'UTF-8'
|
||||
);
|
||||
$resultEn = ucfirst(Locale::getDisplayLanguage($language, 'en'));
|
||||
$result[$language] = "$resultNative ($resultEn)";
|
||||
}
|
||||
|
@ -176,6 +180,33 @@ class SettingsSeeder extends Seeder
|
|||
$setting->value = 'en';
|
||||
$setting->save();
|
||||
}
|
||||
|
||||
if (! $setting = Setting::find(12)) {
|
||||
$setting = new Setting;
|
||||
$setting->id = 12;
|
||||
$setting->group_id = 2;
|
||||
$setting->key = 'trianglify';
|
||||
$setting->type = 'boolean';
|
||||
$setting->label = 'app.settings.trianglify';
|
||||
$setting->save();
|
||||
} else {
|
||||
$setting->label = 'app.settings.trianglify';
|
||||
$setting->save();
|
||||
}
|
||||
|
||||
if (! $setting = Setting::find(13)) {
|
||||
$setting = new Setting;
|
||||
$setting->id = 13;
|
||||
$setting->group_id = 2;
|
||||
$setting->key = 'trianglify_seed';
|
||||
$setting->type = 'text';
|
||||
$setting->value = 'heimdall';
|
||||
$setting->label = 'app.settings.trianglify_seed';
|
||||
$setting->save();
|
||||
} else {
|
||||
$setting->label = 'app.settings.trianglify_seed';
|
||||
$setting->save();
|
||||
}
|
||||
|
||||
$window_target_options = json_encode([
|
||||
'current' => 'app.settings.window_target.current',
|
||||
|
@ -201,7 +232,12 @@ class SettingsSeeder extends Seeder
|
|||
|
||||
if ($support = Setting::find(8)) {
|
||||
$support->label = 'app.settings.support';
|
||||
$support->value = '<a rel="noopener" target="_blank" href="https://discord.gg/CCjHKn4">Discord</a> | <a rel="noopener" target="_blank" href="https://github.com/linuxserver/Heimdall">Github</a> | <a rel="noopener" target="_blank" href="https://blog.heimdall.site/">Blog</a>';
|
||||
$support->value =
|
||||
'<a rel="noopener" target="_blank" href="https://discord.gg/CCjHKn4">Discord</a>'.
|
||||
' | '.
|
||||
'<a rel="noopener" target="_blank" href="https://github.com/linuxserver/Heimdall">Github</a>'.
|
||||
' | '.
|
||||
'<a rel="noopener" target="_blank" href="https://blog.heimdall.site/">Blog</a>';
|
||||
$support->save();
|
||||
} else {
|
||||
$setting = new Setting;
|
||||
|
@ -210,7 +246,11 @@ class SettingsSeeder extends Seeder
|
|||
$setting->key = 'support';
|
||||
$setting->type = 'text';
|
||||
$setting->label = 'app.settings.support';
|
||||
$setting->value = '<a rel="noopener" target="_blank" href="https://discord.gg/CCjHKn4">Discord</a> | <a rel="noopener" target="_blank" href="https://github.com/linuxserver/Heimdall">Github</a> | <a rel="noopener" target="_blank" href="https://blog.heimdall.site/">Blog</a>';
|
||||
$setting->value = '<a rel="noopener" target="_blank" href="https://discord.gg/CCjHKn4">Discord</a>'.
|
||||
' | '.
|
||||
'<a rel="noopener" target="_blank" href="https://github.com/linuxserver/Heimdall">Github</a>'.
|
||||
' | '.
|
||||
'<a rel="noopener" target="_blank" href="https://blog.heimdall.site/">Blog</a>';
|
||||
$setting->system = true;
|
||||
$setting->save();
|
||||
}
|
||||
|
@ -275,7 +315,7 @@ class SettingsSeeder extends Seeder
|
|||
$home_tag->save();
|
||||
$home_tag_id = $home_tag->id;
|
||||
|
||||
if($home_tag_id != 0) {
|
||||
if ($home_tag_id != 0) {
|
||||
Log::info("Home Tag returned with id $home_tag_id from db! Changing to 0.");
|
||||
|
||||
DB::update('update items set id = 0 where id = ?', [$home_tag_id]);
|
||||
|
|
|
@ -15,7 +15,7 @@ class UsersSeeder extends Seeder
|
|||
public function run()
|
||||
{
|
||||
// Groups
|
||||
if (! $user = User::find(1)) {
|
||||
if (!User::find(1)) {
|
||||
$user = new User;
|
||||
$user->username = 'admin';
|
||||
$user->email = 'admin@test.com';
|
||||
|
@ -24,13 +24,11 @@ class UsersSeeder extends Seeder
|
|||
|
||||
$user_id = $user->id;
|
||||
|
||||
if($user_id != 1) {
|
||||
if ($user_id != 1) {
|
||||
Log::info("First User returned with id $user_id from db! Changing to 1.");
|
||||
|
||||
DB::update('update users set id = 1 where id = ?', [$user_id]);
|
||||
}
|
||||
} else {
|
||||
//$user->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
16155
package-lock.json
generated
16155
package-lock.json
generated
File diff suppressed because it is too large
Load diff
31
package.json
31
package.json
|
@ -2,22 +2,29 @@
|
|||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npm run development",
|
||||
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"watch-poll": "npm run watch -- --watch-poll",
|
||||
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"development": "mix",
|
||||
"watch": "mix watch",
|
||||
"watch-poll": "mix watch -- --watch-options-poll=1000",
|
||||
"hot": "mix watch --hot",
|
||||
"prod": "npm run production",
|
||||
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||
"production": "mix --production",
|
||||
"lint": "eslint 'resources/assets/js/*'"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bootstrap-sass": "^3.4.1",
|
||||
"cross-env": "^5.2.0",
|
||||
"jquery": "^3.4.1",
|
||||
"laravel-mix": "^4.0.16",
|
||||
"sass": "^1.21.0",
|
||||
"sass-loader": "7.*"
|
||||
"bootstrap-sass": "^3.4.3",
|
||||
"eslint": "^8.28.0",
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"jquery": "^3.6.3",
|
||||
"laravel-mix": "^6.0.49",
|
||||
"prettier": "^2.8.1",
|
||||
"sass": "^1.56.1",
|
||||
"sass-loader": "13.*"
|
||||
},
|
||||
"dependencies": {
|
||||
"select2": "^4.0.7"
|
||||
"select2": "^4.0.13",
|
||||
"sortablejs": "^1.15.0"
|
||||
}
|
||||
}
|
||||
|
|
24
phpcs.xml
Normal file
24
phpcs.xml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0"?>
|
||||
<ruleset name="PHP_CodeSniffer">
|
||||
<description>The coding standard for our project.</description>
|
||||
<rule ref="PSR2"/>
|
||||
|
||||
<file>app</file>
|
||||
<file>bootstrap</file>
|
||||
<file>config</file>
|
||||
<file>database</file>
|
||||
<file>resources</file>
|
||||
<file>routes</file>
|
||||
|
||||
<exclude-pattern>bootstrap/cache/*</exclude-pattern>
|
||||
<exclude-pattern>app/SupportedApps/*</exclude-pattern>
|
||||
<exclude-pattern>resources/lang/*</exclude-pattern>
|
||||
<exclude-pattern>bootstrap/autoload.php</exclude-pattern>
|
||||
<exclude-pattern>*/migrations/*</exclude-pattern>
|
||||
<exclude-pattern>*/seeds/*</exclude-pattern>
|
||||
<exclude-pattern>*.blade.php</exclude-pattern>
|
||||
<exclude-pattern>*.js</exclude-pattern>
|
||||
|
||||
<!-- Show progression -->
|
||||
<arg value="p"/>
|
||||
</ruleset>
|
4
public/css/app.css
vendored
4
public/css/app.css
vendored
File diff suppressed because one or more lines are too long
2
public/js/app.js
vendored
2
public/js/app.js
vendored
File diff suppressed because one or more lines are too long
4
public/js/fontawesome.js
vendored
4
public/js/fontawesome.js
vendored
|
@ -483,10 +483,14 @@ var icons = {
|
|||
"arrow-rotate-right": [512, 512, [8635, "arrow-right-rotate", "arrow-rotate-forward", "redo"], "f01e", "M496 48V192c0 17.69-14.31 32-32 32H320c-17.69 0-32-14.31-32-32s14.31-32 32-32h63.39c-29.97-39.7-77.25-63.78-127.6-63.78C167.7 96.22 96 167.9 96 256s71.69 159.8 159.8 159.8c34.88 0 68.03-11.03 95.88-31.94c14.22-10.53 34.22-7.75 44.81 6.375c10.59 14.16 7.75 34.22-6.375 44.81c-39.03 29.28-85.36 44.86-134.2 44.86C132.5 479.9 32 379.4 32 256s100.5-223.9 223.9-223.9c69.15 0 134 32.47 176.1 86.12V48c0-17.69 14.31-32 32-32S496 30.31 496 48z"],
|
||||
"ban": [512, 512, [], "f05e", "M256 8C119.034 8 8 119.033 8 256s111.034 248 248 248 248-111.034 248-248S392.967 8 256 8zm130.108 117.892c65.448 65.448 70 165.481 20.677 235.637L150.47 105.216c70.204-49.356 170.226-44.735 235.638 20.676zM125.892 386.108c-65.448-65.448-70-165.481-20.677-235.637L361.53 406.784c-70.203 49.356-170.226 44.736-235.638-20.676z"],
|
||||
"check": [512, 512, [], "f00c", "M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"],
|
||||
"circle-check": [512, 512, [61533, "check-circle"], "f058", ["M0 256C0 114.6 114.6 0 256 0C397.4 0 512 114.6 512 256C512 397.4 397.4 512 256 512C114.6 512 0 397.4 0 256zM371.8 211.8C382.7 200.9 382.7 183.1 371.8 172.2C360.9 161.3 343.1 161.3 332.2 172.2L224 280.4L179.8 236.2C168.9 225.3 151.1 225.3 140.2 236.2C129.3 247.1 129.3 264.9 140.2 275.8L204.2 339.8C215.1 350.7 232.9 350.7 243.8 339.8L371.8 211.8z", "M371.8 172.2C382.7 183.1 382.7 200.9 371.8 211.8L243.8 339.8C232.9 350.7 215.1 350.7 204.2 339.8L140.2 275.8C129.3 264.9 129.3 247.1 140.2 236.2C151.1 225.3 168.9 225.3 179.8 236.2L224 280.4L332.2 172.2C343.1 161.3 360.9 161.3 371.8 172.2V172.2z"]],
|
||||
"circle-xmark": [512, 512, [61532, "times-circle", "xmark-circle"], "f057", ["M0 256C0 114.6 114.6 0 256 0C397.4 0 512 114.6 512 256C512 397.4 397.4 512 256 512C114.6 512 0 397.4 0 256zM175 208.1L222.1 255.1L175 303C165.7 312.4 165.7 327.6 175 336.1C184.4 346.3 199.6 346.3 208.1 336.1L255.1 289.9L303 336.1C312.4 346.3 327.6 346.3 336.1 336.1C346.3 327.6 346.3 312.4 336.1 303L289.9 255.1L336.1 208.1C346.3 199.6 346.3 184.4 336.1 175C327.6 165.7 312.4 165.7 303 175L255.1 222.1L208.1 175C199.6 165.7 184.4 165.7 175 175C165.7 184.4 165.7 199.6 175 208.1V208.1z", "M255.1 222.1L303 175C312.4 165.7 327.6 165.7 336.1 175C346.3 184.4 346.3 199.6 336.1 208.1L289.9 255.1L336.1 303C346.3 312.4 346.3 327.6 336.1 336.1C327.6 346.3 312.4 346.3 303 336.1L255.1 289.9L208.1 336.1C199.6 346.3 184.4 346.3 175 336.1C165.7 327.6 165.7 312.4 175 303L222.1 255.1L175 208.1C165.7 199.6 165.7 184.4 175 175C184.4 165.7 199.6 165.7 208.1 175L255.1 222.1z"]],
|
||||
"cloud-download": [640, 512, [], "f0ed", "M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4zm-139.9 93L305 412.3c-9.4 9.4-24.6 9.4-33.9 0l-92.7-92.7c-9.4-9.4-9.4-24.6 0-33.9l10.8-10.8c9.6-9.6 25.2-9.3 34.5.5l32.4 34.5V184c0-13.3 10.7-24 24-24h16c13.3 0 24 10.7 24 24v125.9l32.4-34.5c9.3-9.9 24.9-10.1 34.5-.5l10.8 10.8c9.2 9.3 9.2 24.5-.1 33.9z"],
|
||||
"cogs": [640, 512, [], "f085", "M512.1 191l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0L552 6.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zm-10.5-58.8c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.7-82.4 14.3-52.8 52.8zM386.3 286.1l33.7 16.8c10.1 5.8 14.5 18.1 10.5 29.1-8.9 24.2-26.4 46.4-42.6 65.8-7.4 8.9-20.2 11.1-30.3 5.3l-29.1-16.8c-16 13.7-34.6 24.6-54.9 31.7v33.6c0 11.6-8.3 21.6-19.7 23.6-24.6 4.2-50.4 4.4-75.9 0-11.5-2-20-11.9-20-23.6V418c-20.3-7.2-38.9-18-54.9-31.7L74 403c-10 5.8-22.9 3.6-30.3-5.3-16.2-19.4-33.3-41.6-42.2-65.7-4-10.9.4-23.2 10.5-29.1l33.3-16.8c-3.9-20.9-3.9-42.4 0-63.4L12 205.8c-10.1-5.8-14.6-18.1-10.5-29 8.9-24.2 26-46.4 42.2-65.8 7.4-8.9 20.2-11.1 30.3-5.3l29.1 16.8c16-13.7 34.6-24.6 54.9-31.7V57.1c0-11.5 8.2-21.5 19.6-23.5 24.6-4.2 50.5-4.4 76-.1 11.5 2 20 11.9 20 23.6v33.6c20.3 7.2 38.9 18 54.9 31.7l29.1-16.8c10-5.8 22.9-3.6 30.3 5.3 16.2 19.4 33.2 41.6 42.1 65.8 4 10.9.1 23.2-10 29.1l-33.7 16.8c3.9 21 3.9 42.5 0 63.5zm-117.6 21.1c59.2-77-28.7-164.9-105.7-105.7-59.2 77 28.7 164.9 105.7 105.7zm243.4 182.7l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0l8.2-14.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zM501.6 431c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.6-82.4 14.3-52.8 52.8z"],
|
||||
"edit": [576, 512, [], "f044", "M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z"],
|
||||
"exchange": [512, 512, [], "f0ec", "M0 168v-16c0-13.255 10.745-24 24-24h381.97l-30.467-27.728c-9.815-9.289-10.03-24.846-.474-34.402l10.84-10.84c9.373-9.373 24.568-9.373 33.941 0l82.817 82.343c12.497 12.497 12.497 32.758 0 45.255l-82.817 82.343c-9.373 9.373-24.569 9.373-33.941 0l-10.84-10.84c-9.556-9.556-9.341-25.114.474-34.402L405.97 192H24c-13.255 0-24-10.745-24-24zm488 152H106.03l30.467-27.728c9.815-9.289 10.03-24.846.474-34.402l-10.84-10.84c-9.373-9.373-24.568-9.373-33.941 0L9.373 329.373c-12.497 12.497-12.497 32.758 0 45.255l82.817 82.343c9.373 9.373 24.569 9.373 33.941 0l10.84-10.84c9.556-9.556 9.341-25.113-.474-34.402L106.03 384H488c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z"],
|
||||
"file-arrow-down": [384, 512, ["file-download"], "f56d", ["M256 128V0H48C21.49 0 0 21.49 0 48v416C0 490.5 21.49 512 48 512h288c26.51 0 48-21.49 48-48V128H256zM288.1 360.1l-80 80c-9.375 9.375-24.56 9.375-33.94 0l-80-80c-9.375-9.375-9.375-24.56 0-33.94C99.72 322.3 105.8 320 112 320s12.28 2.344 16.97 7.031L168 366.1V248C168 234.8 178.8 224 192 224s24 10.75 24 24v118.1l39.03-39.03c9.375-9.375 24.56-9.375 33.94 0S298.3 351.6 288.1 360.1z", "M256 0v128h128L256 0zM255 327L216 366.1V248C216 234.8 205.3 224 192 224S168 234.8 168 248v118.1l-39.03-39.03C124.3 322.3 118.2 320 112 320s-12.28 2.344-16.97 7.031c-9.375 9.375-9.375 24.56 0 33.94l80 80c9.375 9.375 24.56 9.375 33.94 0l80-80c9.375-9.375 9.375-24.56 0-33.94S264.4 317.7 255 327z"]],
|
||||
"file-arrow-up": [384, 512, ["file-upload"], "f574", ["M256 128V0H48C21.49 0 0 21.49 0 48v416C0 490.5 21.49 512 48 512h288c26.51 0 48-21.49 48-48V128H256zM288.1 344.1C284.3 349.7 278.2 352 272 352s-12.28-2.344-16.97-7.031L216 305.9V424c0 13.25-10.75 24-24 24s-24-10.75-24-24V305.9l-39.03 39.03c-9.375 9.375-24.56 9.375-33.94 0s-9.375-24.56 0-33.94l80-80c9.375-9.375 24.56-9.375 33.94 0l80 80C298.3 320.4 298.3 335.6 288.1 344.1z", "M256 0v128h128L256 0zM208.1 231c-9.375-9.375-24.56-9.375-33.94 0l-80 80c-9.375 9.375-9.375 24.56 0 33.94s24.56 9.375 33.94 0L168 305.9V424C168 437.3 178.8 448 192 448s24-10.75 24-24V305.9l39.03 39.03C259.7 349.7 265.8 352 272 352s12.28-2.344 16.97-7.031c9.375-9.375 9.375-24.56 0-33.94L208.1 231z"]],
|
||||
"list": [512, 512, [], "f03a", "M128 116V76c0-8.837 7.163-16 16-16h352c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H144c-8.837 0-16-7.163-16-16zm16 176h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 144h64c8.837 0 16-7.163 16-16V64c0-8.837-7.163-16-16-16H16C7.163 48 0 55.163 0 64v64c0 8.837 7.163 16 16 16zm0 160h64c8.837 0 16-7.163 16-16v-64c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v64c0 8.837 7.163 16 16 16zm0 160h64c8.837 0 16-7.163 16-16v-64c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v64c0 8.837 7.163 16 16 16z"],
|
||||
"pencil": [512, 512, [], "f040", "M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"],
|
||||
"plus": [448, 512, [], "f067", "M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"],
|
||||
|
|
2
public/js/jquery-3.6.0.min.js
vendored
2
public/js/jquery-3.6.0.min.js
vendored
File diff suppressed because one or more lines are too long
13
public/js/jquery-ui.min.js
vendored
13
public/js/jquery-ui.min.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/jquery.min.js
vendored
Normal file
2
public/js/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/js/trianglify.js
vendored
Normal file
1
public/js/trianglify.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
public/mix-manifest.json
generated
4
public/mix-manifest.json
generated
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"/css/app.css": "/css/app.css?id=cdbee4d3b17bce4786a2",
|
||||
"/js/app.js": "/js/app.js?id=bf17db5adf00db2c59ef"
|
||||
"/css/app.css": "/css/app.css?id=55e02812d34a73b4386802d27fbcd6e8",
|
||||
"/js/app.js": "/js/app.js?id=3377b9b80073713e4dc54937c94aa6ad"
|
||||
}
|
||||
|
|
40
readme.md
40
readme.md
|
@ -22,10 +22,10 @@ Why not use it as your browser start page? It even has the ability to include a
|
|||
![Heimdall demo animation](https://i.imgur.com/MrC4QpN.gif)
|
||||
|
||||
## Video
|
||||
If you want to see a quick video of it in use, go to https://youtu.be/GXnnMAxPzMc
|
||||
If you want to see a quick video of Heimdall in use, go to https://youtu.be/GXnnMAxPzMc
|
||||
|
||||
## Supported applications
|
||||
You can use the app to link to any site or application, but Foundation apps will auto fill in the icon for the app and supply a default color for the tile. In addition Enhanced apps allow you provide details to an apps API, allowing you to view live stats directly on the dashboad. For example, the NZBGet and Sabnzbd Enhanced apps will display the queue size and download speed while something is downloading.
|
||||
You can use the app to link to any site or application, but Foundation apps will auto fill in the icon for the app and supply a default color for the tile. In addition, Enhanced apps allow you provide details to an apps API, allowing you to view live stats directly on the dashboad. For example, the NZBGet and Sabnzbd Enhanced apps will display the queue size, and download speed while something is downloading.
|
||||
|
||||
Supported applications are recognized by the title of the application as entered in the title field when adding an application. For example, to add a link to pfSense, begin by typing "p" in the title field and then select "pfSense" from the list of supported applications.
|
||||
|
||||
|
@ -36,7 +36,7 @@ Supported applications are recognized by the title of the application as entered
|
|||
## Installing
|
||||
Apart from the Laravel 8 dependencies, namely PHP >= 7.4.32, BCMath PHP Extension, INTL PHP Extension, Ctype PHP Extension, Fileinfo PHP extension, JSON PHP Extension, Mbstring PHP Extension, OpenSSL PHP Extension, PDO PHP Extension, Tokenizer PHP Extension, XML PHP Extension, the only other thing Heimdall needs is sqlite support and zip support (php-zip).
|
||||
|
||||
If you find you can't change the background make sure `php_fileinfo` is enabled in your php.ini. I believe it should be by default, but one user came across the issue on a windows system.
|
||||
If you find you can't change the background make sure `php_fileinfo` is enabled in your php.ini. I believe `php_fileinfo` should be enabled by default, but one user came across the issue on a windows system.
|
||||
|
||||
Installation is as simple as cloning the repository somewhere, or downloading and extracting the zip/tar and pointing your httpd document root to the `/public` folder then creating the .env file and generating an encryption key (this is all taken care of for you with the docker).
|
||||
|
||||
|
@ -62,10 +62,10 @@ Options are stored in `/storage/app/searchproviders.yaml` (`/config/www/searchpr
|
|||
|
||||
Consider contributing to https://github.com/linuxserver/Heimdall/discussions/categories/search-providers to help others add new ones.
|
||||
|
||||
The item at the top of the list `Tiles` allows you to search for apps on your dashboard by name, helpful when you have lots of icons.
|
||||
The item at the top of the list `Tiles` allows you to search for apps on your dashboard by name, this can be helpful when you have lots of icons.
|
||||
|
||||
## New background image not being set
|
||||
If you are using the docker image or a default php install you may find images over 2MB wont get set as the background image, you just need to change the `upload_max_filesize` in the php.ini.
|
||||
If you are using the docker image or a default php install you may find images over 2MB won't get set as the background image, you just need to change the `upload_max_filesize` in the php.ini.
|
||||
|
||||
If you are using the linuxserver.io docker image simply edit `/path/to/config/php/php-local.ini` and add `upload_max_filesize = 30M` to the end.
|
||||
|
||||
|
@ -75,7 +75,7 @@ If you are running the docker and the EnhancedApps you are using are also in doc
|
|||
You can do this by using `http(s)://docker_name:port` in the config section. Instead of the name you can use the internal docker ip, this usually starts with `172.`
|
||||
|
||||
## Languages
|
||||
The app has been translated into several languages; however, the quality of the translations could do with work. If you would like to improve them, or help with other translations, they are stored in `/resources/lang/`.
|
||||
The app has been translated into several languages; however, the quality of the translations could benefit from some work. If you would like to improve them, or help with other translations, they are stored in `/resources/lang/`.
|
||||
|
||||
To create a new language translation, make a new folder with the ISO 3166-1 alpha-2 code as the name, copy `app.php` from `/resources/lang/en/app.php` into your new folder and replace the English strings.
|
||||
|
||||
|
@ -83,27 +83,28 @@ When you are finished, create a pull request.
|
|||
|
||||
Currently added languages are
|
||||
|
||||
- English
|
||||
- Breton
|
||||
- Chinese
|
||||
- Danish
|
||||
- German
|
||||
- Greek
|
||||
- Spanish
|
||||
- Dutch
|
||||
- English
|
||||
- Finnish
|
||||
- French
|
||||
- German
|
||||
- Greek
|
||||
- Hungarian
|
||||
- Italian
|
||||
- Japanese
|
||||
- Korean
|
||||
- Lombard
|
||||
- Dutch
|
||||
- Norwegian
|
||||
- Polish
|
||||
- Portuguese
|
||||
- Russian
|
||||
- Slovenian
|
||||
- Spanish
|
||||
- Swedish
|
||||
- Turkish
|
||||
- Chinese
|
||||
|
||||
## Web Server Configuration
|
||||
|
||||
|
@ -144,15 +145,15 @@ location / {
|
|||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
```
|
||||
Someone was using the same nginx setup to both run this and reverse proxy Plex, Plex is served from `/web` so their location was interfering with the `/webfonts`.
|
||||
Someone was using the same Nginx setup to both run this and reverse proxy Plex. Plex is served from `/web` so their location was interfering with the `/webfonts`.
|
||||
|
||||
Therefore, if your fonts aren't showing because you have a location for `/web`, add the following
|
||||
Therefore, if your fonts aren't showing because you have a location for `/web`, add the following:
|
||||
```
|
||||
location /webfonts {
|
||||
try_files $uri $uri/;
|
||||
}
|
||||
```
|
||||
If there are any other locations which might interfere with any of the folders in the `/public` folder, you might have to do the same for those as well, but it's a super fringe case.
|
||||
If there are any other locations that might interfere with any of the folders in the `/public` folder, you might have to do the same for those as well, however it's a super fringe case.
|
||||
|
||||
### Reverse proxy
|
||||
If you'd like to reverse proxy this app, we recommend using our letsencrypt/nginx docker image: [SWAG - Secure Web Application Gateway](https://hub.docker.com/r/linuxserver/swag)
|
||||
|
@ -180,12 +181,12 @@ Per default Heimdall uses the standard certificate bundle file (`ca-certificates
|
|||
openssl.cafile = /config/heimdall.pem
|
||||
```
|
||||
|
||||
Restart the container and the enhanced apps should now be able to access your local HTTP websites. This configuration will survive updating or recreating the Heimdall container.
|
||||
Restart the container and the Enhanced apps should now be able to access your local HTTP websites. This configuration will survive updating or recreating the Heimdall container.
|
||||
|
||||
## Running offline
|
||||
The apps list is hosted on github, you have a couple of options if you want to run without a connection to the outside world:
|
||||
1) Clone the repository and host it yourself, look at the .github actions file to see how to generate the apps list.
|
||||
2) Download the apps list and store it as a json accessible to heimdall named `list.json`
|
||||
2) Download the apps list and store it as a JSON accessible to Heimdall named `list.json`
|
||||
|
||||
With both options all you need to do is add the following to your `.env`
|
||||
`APP_SOURCE=http://localhost/` Where `http://localhost/` is the path to the apps list without the name of the file, so if your file is stored at `https://heimdall.local/list.json` you would put `APP_SOURCE=https://heimdall.local/`
|
||||
|
@ -204,12 +205,13 @@ If you would like to show your appreciation, feel free to use the link below.
|
|||
- JavaScript - [jQuery](https://jquery.com/)
|
||||
- Colour picker - [Huebee](http://huebee.buzz/)
|
||||
- Background image - [pexels](https://www.pexels.com)
|
||||
- Trianglify library - [Trianglify](https://github.com/qrohlf/trianglify)
|
||||
- Everyone at Linuxserver.io that has helped with the app and let's not forget IronicBadger for the following question that started it all:
|
||||
```
|
||||
you know, i would love something like this landing page for all my servers apps
|
||||
You know, I would love something like this landing page for all my servers' apps
|
||||
that gives me the ability to pin favourites
|
||||
and / or search
|
||||
@Stark @Kode do either of you think you'd be able to rustle something like this up ?
|
||||
@Stark @Kode do either of you think you'd be able to rustle something like this up?
|
||||
```
|
||||
|
||||
## License
|
||||
|
|
|
@ -1,120 +1,41 @@
|
|||
$.when( $.ready ).then(function() {
|
||||
/* eslint-disable func-names */
|
||||
$.when($.ready).then(() => {
|
||||
const base = (document.querySelector("base") || {}).href;
|
||||
|
||||
var base = (document.querySelector('base') || {}).href;
|
||||
const itemID = $("form[data-item-id]").data("item-id");
|
||||
const fakePassword = "*****";
|
||||
|
||||
var itemID = $('form[data-item-id]').data('item-id');
|
||||
var fakePassword = '*****';
|
||||
// If in edit mode and password field is present, fill it with stars
|
||||
if (itemID) {
|
||||
const passwordField = $('input[name="config[password]"]').first();
|
||||
|
||||
// If in edit mode and password field is present, fill it with stars
|
||||
if (itemID) {
|
||||
var passwordField = $('input[name="config[password]"]').first();
|
||||
|
||||
if (passwordField.length > 0) {
|
||||
passwordField.attr('value', fakePassword);
|
||||
}
|
||||
if (passwordField.length > 0) {
|
||||
passwordField.attr("value", fakePassword);
|
||||
}
|
||||
}
|
||||
|
||||
if($('.message-container').length) {
|
||||
setTimeout(
|
||||
function()
|
||||
{
|
||||
$('.message-container').fadeOut();
|
||||
}, 3500);
|
||||
if ($(".message-container").length) {
|
||||
setTimeout(() => {
|
||||
$(".message-container").fadeOut();
|
||||
}, 3500);
|
||||
}
|
||||
|
||||
function readURL(input) {
|
||||
if (input.files && input.files[0]) {
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = function (e) {
|
||||
$("#appimage img").attr("src", e.target.result);
|
||||
};
|
||||
|
||||
reader.readAsDataURL(input.files[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// from https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
|
||||
// Set the name of the hidden property and the change event for visibility
|
||||
var hidden, visibilityChange;
|
||||
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
|
||||
hidden = "hidden";
|
||||
visibilityChange = "visibilitychange";
|
||||
} else if (typeof document.msHidden !== "undefined") {
|
||||
hidden = "msHidden";
|
||||
visibilityChange = "msvisibilitychange";
|
||||
} else if (typeof document.webkitHidden !== "undefined") {
|
||||
hidden = "webkitHidden";
|
||||
visibilityChange = "webkitvisibilitychange";
|
||||
}
|
||||
|
||||
var livestatsRefreshTimeouts = [];
|
||||
var livestatsFuncs = [];
|
||||
var livestatsContainers = $('.livestats-container');
|
||||
function stopLivestatsRefresh() {
|
||||
for (var timeoutId of livestatsRefreshTimeouts) {
|
||||
window.clearTimeout(timeoutId);
|
||||
}
|
||||
}
|
||||
function startLivestatsRefresh() {
|
||||
for (var fun of livestatsFuncs) {
|
||||
fun();
|
||||
}
|
||||
}
|
||||
|
||||
if (livestatsContainers.length > 0) {
|
||||
if (typeof document.addEventListener === "undefined" || hidden === undefined) {
|
||||
console.log("This browser does not support visibilityChange");
|
||||
} else {
|
||||
document.addEventListener(visibilityChange, function() {
|
||||
if (document[hidden]) {
|
||||
stopLivestatsRefresh();
|
||||
} else {
|
||||
startLivestatsRefresh();
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
livestatsContainers.each(function(index){
|
||||
var id = $(this).data('id');
|
||||
var dataonly = $(this).data('dataonly');
|
||||
var increaseby = (dataonly == 1) ? 20000 : 1000;
|
||||
var container = $(this);
|
||||
var max_timer = 30000;
|
||||
var timer = 5000;
|
||||
var fun = function worker() {
|
||||
$.ajax({
|
||||
url: base+'get_stats/'+id,
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
container.html(data.html);
|
||||
if(data.status == 'active') timer = increaseby;
|
||||
else {
|
||||
if(timer < max_timer) timer += 2000;
|
||||
}
|
||||
},
|
||||
complete: function(jqXHR) {
|
||||
if (jqXHR.status > 299) {
|
||||
// Stop polling when we get errors
|
||||
return;
|
||||
}
|
||||
|
||||
// Schedule the next request when the current one's complete
|
||||
livestatsRefreshTimeouts[index] = window.setTimeout(worker, timer);
|
||||
}
|
||||
});
|
||||
};
|
||||
livestatsFuncs[index] = fun;
|
||||
fun();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function readURL(input) {
|
||||
|
||||
if (input.files && input.files[0]) {
|
||||
var reader = new FileReader();
|
||||
|
||||
reader.onload = function(e) {
|
||||
$('#appimage img').attr('src', e.target.result);
|
||||
};
|
||||
|
||||
reader.readAsDataURL(input.files[0]);
|
||||
}
|
||||
}
|
||||
|
||||
$('#upload').change(function() {
|
||||
readURL(this);
|
||||
});
|
||||
/*$(".droppable").droppable({
|
||||
$("#upload").change(function () {
|
||||
readURL(this);
|
||||
});
|
||||
/* $(".droppable").droppable({
|
||||
tolerance: "intersect",
|
||||
drop: function( event, ui ) {
|
||||
var tag = $( this ).data('id');
|
||||
|
@ -129,153 +50,195 @@ $.when( $.ready ).then(function() {
|
|||
});
|
||||
|
||||
}
|
||||
});*/
|
||||
|
||||
$( '#sortable' ).sortable({
|
||||
stop: function (event, ui) {
|
||||
var idsInOrder = $('#sortable').sortable('toArray', {
|
||||
attribute: 'data-id'
|
||||
});
|
||||
$.post(
|
||||
base+'order',
|
||||
{ order:idsInOrder }
|
||||
);
|
||||
}
|
||||
}); */
|
||||
|
||||
const sortableEl = document.getElementById("sortable");
|
||||
let sortable;
|
||||
if (sortableEl !== null) {
|
||||
// eslint-disable-next-line no-undef
|
||||
sortable = Sortable.create(sortableEl, {
|
||||
disabled: true,
|
||||
animation: 150,
|
||||
forceFallback: !(
|
||||
navigator.userAgent.toLowerCase().indexOf("firefox") > -1
|
||||
),
|
||||
draggable: ".item-container",
|
||||
onEnd() {
|
||||
const idsInOrder = sortable.toArray();
|
||||
$.post(`${base}order`, { order: idsInOrder });
|
||||
},
|
||||
});
|
||||
$('#sortable').sortable('disable');
|
||||
// prevent Firefox drag behavior
|
||||
if (navigator.userAgent.toLowerCase().indexOf("firefox") > -1) {
|
||||
sortable.option("setData", (dataTransfer) => {
|
||||
dataTransfer.setData("Text", "");
|
||||
});
|
||||
|
||||
$('#main').on('mouseenter', '#sortable.ui-sortable-disabled .item', function () {
|
||||
$(this).siblings('.tooltip').addClass('active')
|
||||
$('.refresh', this).addClass('active')
|
||||
}).on('mouseleave', '.item', function () {
|
||||
$(this).siblings('.tooltip').removeClass('active')
|
||||
$('.refresh', this).removeClass('active')
|
||||
})
|
||||
$('#config-buttons').on('mouseenter', 'a', function () {
|
||||
$('.tooltip', this).addClass('active');
|
||||
}).on('mouseleave', 'a', function () {
|
||||
$('.tooltip', this).removeClass('active');
|
||||
})
|
||||
|
||||
$('.searchform > form').on('submit', function (event) {
|
||||
if ($('#search-container select[name=provider]').val() === 'tiles') {
|
||||
event.preventDefault();
|
||||
sortableEl.addEventListener("dragstart", (event) => {
|
||||
const { target } = event;
|
||||
if (target.nodeName.toLowerCase() === "a") {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
event.dataTransfer.setData("Text", "");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$("#main")
|
||||
.on("mouseenter", "#sortable .item", function () {
|
||||
$(this).siblings(".tooltip").addClass("active");
|
||||
$(".refresh", this).addClass("active");
|
||||
})
|
||||
.on("mouseleave", ".item", function () {
|
||||
$(this).siblings(".tooltip").removeClass("active");
|
||||
$(".refresh", this).removeClass("active");
|
||||
});
|
||||
$("#config-buttons")
|
||||
.on("mouseenter", "a", function () {
|
||||
$(".tooltip", this).addClass("active");
|
||||
})
|
||||
.on("mouseleave", "a", function () {
|
||||
$(".tooltip", this).removeClass("active");
|
||||
});
|
||||
|
||||
$('#search-container').on('input', 'input[name=q]', function () {
|
||||
const search = this.value
|
||||
const items = $('#sortable').children('.item-container')
|
||||
if($('#search-container select[name=provider]').val() === 'tiles') {
|
||||
if(search.length > 0) {
|
||||
items.hide()
|
||||
items.filter(function () {
|
||||
const name = $(this).data('name').toLowerCase();
|
||||
return name.includes(search.toLowerCase())
|
||||
}).show()
|
||||
} else {
|
||||
items.show()
|
||||
}
|
||||
$(".searchform > form").on("submit", (event) => {
|
||||
if ($("#search-container select[name=provider]").val() === "tiles") {
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
$("#search-container")
|
||||
.on("input", "input[name=q]", function () {
|
||||
const search = this.value;
|
||||
const items = $("#sortable").children(".item-container");
|
||||
if ($("#search-container select[name=provider]").val() === "tiles") {
|
||||
if (search.length > 0) {
|
||||
items.hide();
|
||||
items
|
||||
.filter(function () {
|
||||
const name = $(this).data("name").toLowerCase();
|
||||
return name.includes(search.toLowerCase());
|
||||
})
|
||||
.show();
|
||||
} else {
|
||||
items.show()
|
||||
}
|
||||
}).on('change', 'select[name=provider]', function () {
|
||||
const items = $('#sortable').children('.item-container')
|
||||
if($(this).val() === 'tiles') {
|
||||
$('#search-container button').hide()
|
||||
const search = $('#search-container input[name=q]').val()
|
||||
if(search.length > 0) {
|
||||
items.hide()
|
||||
items.filter(function () {
|
||||
const name = $(this).data('name').toLowerCase();
|
||||
return name.includes(search.toLowerCase())
|
||||
}).show()
|
||||
} else {
|
||||
items.show()
|
||||
}
|
||||
} else {
|
||||
$('#search-container button').show()
|
||||
items.show()
|
||||
items.show();
|
||||
}
|
||||
} else {
|
||||
items.show();
|
||||
}
|
||||
})
|
||||
|
||||
$('#app').on('click', '#config-button', function(e) {
|
||||
e.preventDefault();
|
||||
var app = $('#app');
|
||||
var active = (app.hasClass('header'));
|
||||
app.toggleClass('header');
|
||||
if(active) {
|
||||
$('.add-item').hide();
|
||||
$('.item-edit').hide();
|
||||
$('#app').removeClass('sidebar');
|
||||
$('#sortable .tooltip').css('display', '')
|
||||
$('#sortable').sortable('disable');
|
||||
.on("change", "select[name=provider]", function () {
|
||||
const items = $("#sortable").children(".item-container");
|
||||
if ($(this).val() === "tiles") {
|
||||
$("#search-container button").hide();
|
||||
const search = $("#search-container input[name=q]").val();
|
||||
if (search.length > 0) {
|
||||
items.hide();
|
||||
items
|
||||
.filter(function () {
|
||||
const name = $(this).data("name").toLowerCase();
|
||||
return name.includes(search.toLowerCase());
|
||||
})
|
||||
.show();
|
||||
} else {
|
||||
$('#sortable .tooltip').css('display', 'none')
|
||||
$('#sortable').sortable('enable');
|
||||
setTimeout(function() {
|
||||
$('.add-item').fadeIn();
|
||||
$('.item-edit').fadeIn();
|
||||
}, 350);
|
||||
|
||||
items.show();
|
||||
}
|
||||
}).on('click', '#add-item, #pin-item', function(e) {
|
||||
e.preventDefault();
|
||||
var app = $('#app');
|
||||
var active = (app.hasClass('sidebar'));
|
||||
app.toggleClass('sidebar');
|
||||
|
||||
}).on('click', '.close-sidenav', function(e) {
|
||||
e.preventDefault();
|
||||
var app = $('#app');
|
||||
app.removeClass('sidebar');
|
||||
|
||||
}).on('click', '#test_config', function(e) {
|
||||
e.preventDefault();
|
||||
var apiurl = $('#create input[name=url]').val();
|
||||
|
||||
var override_url = $('#sapconfig input[name="config[override_url]"]').val();
|
||||
if(override_url.length && override_url != '') {
|
||||
apiurl = override_url;
|
||||
}
|
||||
|
||||
var data = {};
|
||||
data['url'] = apiurl;
|
||||
$('.config-item').each(function(index){
|
||||
var config = $(this).data('config');
|
||||
data[config] = $(this).val();
|
||||
});
|
||||
|
||||
data['id'] = $('form[data-item-id]').data('item-id');
|
||||
|
||||
if (data.password && data.password === fakePassword) {
|
||||
data.password = '';
|
||||
}
|
||||
|
||||
$.post(base+'test_config', { data: data }, function(data) {
|
||||
alert(data);
|
||||
});
|
||||
|
||||
} else {
|
||||
$("#search-container button").show();
|
||||
items.show();
|
||||
}
|
||||
});
|
||||
$('#pinlist').on('click', 'a', function(e) {
|
||||
e.preventDefault();
|
||||
var current = $(this);
|
||||
var id = current.data('id');
|
||||
var tag = current.data('tag');
|
||||
$.get(base+'items/pintoggle/'+id+'/true/'+tag, function(data) {
|
||||
var inner = $(data).filter('#sortable').html();
|
||||
$('#sortable').html(inner);
|
||||
current.toggleClass('active');
|
||||
|
||||
$("#app")
|
||||
.on("click", "#config-button", (e) => {
|
||||
e.preventDefault();
|
||||
const app = $("#app");
|
||||
const active = app.hasClass("header");
|
||||
app.toggleClass("header");
|
||||
if (active) {
|
||||
$(".add-item").hide();
|
||||
$(".item-edit").hide();
|
||||
$("#app").removeClass("sidebar");
|
||||
$("#sortable .tooltip").css("display", "");
|
||||
if (sortable !== undefined) sortable.option("disabled", true);
|
||||
} else {
|
||||
$("#sortable .tooltip").css("display", "none");
|
||||
if (sortable !== undefined) sortable.option("disabled", false);
|
||||
setTimeout(() => {
|
||||
$(".add-item").fadeIn();
|
||||
$(".item-edit").fadeIn();
|
||||
}, 350);
|
||||
}
|
||||
})
|
||||
.on("click", "#add-item, #pin-item", (e) => {
|
||||
e.preventDefault();
|
||||
const app = $("#app");
|
||||
// const active = app.hasClass("sidebar");
|
||||
app.toggleClass("sidebar");
|
||||
})
|
||||
.on("click", ".close-sidenav", (e) => {
|
||||
e.preventDefault();
|
||||
const app = $("#app");
|
||||
app.removeClass("sidebar");
|
||||
})
|
||||
.on("click", "#test_config", (e) => {
|
||||
e.preventDefault();
|
||||
let apiurl = $("#create input[name=url]").val();
|
||||
|
||||
const overrideUrl = $(
|
||||
'#sapconfig input[name="config[override_url]"]'
|
||||
).val();
|
||||
|
||||
if (typeof overrideUrl === "string" && overrideUrl !== "") {
|
||||
apiurl = overrideUrl;
|
||||
}
|
||||
|
||||
const data = {};
|
||||
data.url = apiurl;
|
||||
$(".config-item").each(function () {
|
||||
const config = $(this).data("config");
|
||||
data[config] = $(this).val();
|
||||
});
|
||||
|
||||
data.id = $("form[data-item-id]").data("item-id");
|
||||
|
||||
if (data.password && data.password === fakePassword) {
|
||||
data.password = "";
|
||||
}
|
||||
|
||||
$.post(`${base}test_config`, { data })
|
||||
.done((responseData) => {
|
||||
// eslint-disable-next-line no-alert
|
||||
alert(responseData);
|
||||
})
|
||||
.fail((responseData) => {
|
||||
// eslint-disable-next-line no-alert
|
||||
alert(
|
||||
`Something went wrong: ${responseData.responseText.substring(
|
||||
0,
|
||||
100
|
||||
)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
$('#itemform').on('submit', function(e) {
|
||||
var passwordField = $('input[name="config[password]"]').first();
|
||||
if (passwordField.length > 0) {
|
||||
if (passwordField.attr('value') === fakePassword) {
|
||||
passwordField.attr('value', '');
|
||||
}
|
||||
}
|
||||
$("#pinlist").on("click", "a", function (e) {
|
||||
e.preventDefault();
|
||||
const current = $(this);
|
||||
const id = current.data("id");
|
||||
const tag = current.data("tag");
|
||||
$.get(`${base}items/pintoggle/${id}/true/${tag}`, (data) => {
|
||||
const inner = $(data).filter("#sortable").html();
|
||||
$("#sortable").html(inner);
|
||||
current.toggleClass("active");
|
||||
});
|
||||
|
||||
});
|
||||
$("#itemform").on("submit", () => {
|
||||
const passwordField = $('input[name="config[password]"]').first();
|
||||
if (passwordField.length > 0) {
|
||||
if (passwordField.attr("value") === fakePassword) {
|
||||
passwordField.attr("value", "");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
49
resources/assets/js/itemExport.js
vendored
Normal file
49
resources/assets/js/itemExport.js
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
const EXPORT_FILE_NAME = "HeimdallExport.json";
|
||||
const EXPORT_API_URL = "api/item";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} fileName
|
||||
* @param {string} data
|
||||
*/
|
||||
function triggerFileDownload(fileName, data) {
|
||||
const a = document.createElement("a");
|
||||
|
||||
const file = new Blob([data], {
|
||||
type: "text/plain",
|
||||
});
|
||||
|
||||
a.href = URL.createObjectURL(file);
|
||||
a.download = EXPORT_FILE_NAME;
|
||||
|
||||
a.click();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Event} event
|
||||
*/
|
||||
const exportItems = (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
fetch(EXPORT_API_URL)
|
||||
.then((response) => {
|
||||
if (response.status !== 200) {
|
||||
// eslint-disable-next-line no-alert
|
||||
window.alert("An error occurred while exporting...");
|
||||
}
|
||||
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
const exportedJson = JSON.stringify(data, null, 2);
|
||||
|
||||
triggerFileDownload(EXPORT_FILE_NAME, exportedJson);
|
||||
});
|
||||
};
|
||||
|
||||
const exportButton = document.querySelector("#item-export");
|
||||
|
||||
if (exportButton) {
|
||||
exportButton.addEventListener("click", exportItems);
|
||||
}
|
178
resources/assets/js/itemImport.js
vendored
Normal file
178
resources/assets/js/itemImport.js
vendored
Normal file
|
@ -0,0 +1,178 @@
|
|||
const IMPORT_API_URL = "api/item";
|
||||
const APP_LOAD_URL = "appload";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {object} item
|
||||
* @param {array} errors
|
||||
*/
|
||||
const updateStatus = ({ item, errors }) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(item, errors);
|
||||
let statusLine;
|
||||
if (errors.length === 0) {
|
||||
statusLine = `<li class="success"><i class="fas fa-circle-check"></i> Imported: ${item.title} </li>`;
|
||||
} else {
|
||||
statusLine = `<li class="fail"><i class="fas fa-circle-xmark"></i> Failed: ${item.title} - ${errors[0]} </li>`;
|
||||
}
|
||||
document.querySelector(".import-status").innerHTML += statusLine;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function clearStatus() {
|
||||
const statusContainer = document.querySelector(".import-status");
|
||||
statusContainer.innerHTML = "";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {object} data
|
||||
* @param {string} csrfToken
|
||||
*/
|
||||
const postToApi = (data, csrfToken) =>
|
||||
fetch(IMPORT_API_URL, {
|
||||
method: "POST",
|
||||
cache: "no-cache",
|
||||
redirect: "follow",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRF-TOKEN": csrfToken,
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
const getCSRFToken = () => {
|
||||
const tokenSelector = 'input[name="_token"]';
|
||||
return document.querySelector(tokenSelector).value;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {object} item
|
||||
* @param {object} appDetails
|
||||
* @returns {object}
|
||||
*/
|
||||
const mergeItemWithAppDetails = (item, appDetails) => ({
|
||||
pinned: 1,
|
||||
tags: [0],
|
||||
|
||||
appid: item.appid,
|
||||
title: item.title,
|
||||
colour: item.colour,
|
||||
url: item.url,
|
||||
appdescription: item.appdescription
|
||||
? item.appdescription
|
||||
: appDetails.description,
|
||||
|
||||
website: appDetails.website,
|
||||
|
||||
icon: appDetails.iconview,
|
||||
config: item.description ? JSON.parse(item.description) : null,
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string|null} appId
|
||||
* @returns {Promise<{}>|Promise<any>}
|
||||
*/
|
||||
const fetchAppDetails = (appId) => {
|
||||
if (appId === null || appId === "null") {
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
return fetch(APP_LOAD_URL, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ app: appId }),
|
||||
}).then((response) => response.json());
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {array} items
|
||||
*/
|
||||
const importItems = (items) => {
|
||||
items.forEach((item) => {
|
||||
const errors = [];
|
||||
|
||||
fetchAppDetails(item.appid)
|
||||
.catch(() =>
|
||||
errors.push(new Error(`Failed to find app id: ${item.appid}`))
|
||||
)
|
||||
.then((appDetails) => {
|
||||
const itemWithAppDetails = mergeItemWithAppDetails(item, appDetails);
|
||||
const csrfToken = getCSRFToken();
|
||||
|
||||
return postToApi(itemWithAppDetails, csrfToken);
|
||||
})
|
||||
.catch(() =>
|
||||
errors.push(new Error(`Failed to create item: ${item.title}`))
|
||||
)
|
||||
.finally(() => {
|
||||
updateStatus({
|
||||
item,
|
||||
errors,
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Blob} file
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
const readJSON = (file) =>
|
||||
new Promise((resolve, reject) => {
|
||||
try {
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = (event) => {
|
||||
const contents = event.target.result;
|
||||
resolve(JSON.parse(contents));
|
||||
};
|
||||
|
||||
reader.readAsText(file);
|
||||
} catch (e) {
|
||||
reject(new Error("Unable to read file"));
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Blob} file
|
||||
*/
|
||||
const openFileForImport = (file) => {
|
||||
clearStatus();
|
||||
|
||||
return readJSON(file)
|
||||
.catch((error) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
})
|
||||
.then(importItems);
|
||||
};
|
||||
|
||||
const fileInput = document.querySelector("input[name='import']");
|
||||
const importButtons = document.querySelectorAll(".import-button");
|
||||
|
||||
if (fileInput && importButtons) {
|
||||
importButtons.forEach((importButton) => {
|
||||
importButton.addEventListener("click", () => {
|
||||
const file = fileInput.files[0];
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
openFileForImport(file);
|
||||
});
|
||||
});
|
||||
fileInput.addEventListener("change", openFileForImport, false);
|
||||
}
|
7
resources/assets/js/jquery-ui.min.js
vendored
7
resources/assets/js/jquery-ui.min.js
vendored
File diff suppressed because one or more lines are too long
60
resources/assets/js/keyBindings.js
vendored
60
resources/assets/js/keyBindings.js
vendored
|
@ -1,35 +1,45 @@
|
|||
const focusSearch = event => {
|
||||
const searchInput = document.querySelector('input[name="q"]');
|
||||
if (searchInput) {
|
||||
event.preventDefault();
|
||||
searchInput.focus();
|
||||
}
|
||||
const focusSearch = (event) => {
|
||||
const searchInput = document.querySelector('input[name="q"]');
|
||||
if (searchInput) {
|
||||
event.preventDefault();
|
||||
searchInput.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const openFirstNonHiddenItem = event => {
|
||||
if (event.target !== document.querySelector('input[name="q"]')) {
|
||||
return;
|
||||
}
|
||||
const openFirstNonHiddenItem = (event) => {
|
||||
if (event.target !== document.querySelector('input[name="q"]')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const item = document.querySelector('#sortable section.item-container:not([style="display: none;"]) a');
|
||||
const providerSelect = document.querySelector(
|
||||
"#search-container select[name=provider]"
|
||||
);
|
||||
|
||||
if ('href' in item) {
|
||||
event.preventDefault();
|
||||
window.open(item.href);
|
||||
}
|
||||
if (providerSelect.value !== "tiles") {
|
||||
return;
|
||||
}
|
||||
|
||||
const item = document.querySelector(
|
||||
'#sortable section.item-container:not([style="display: none;"]) a'
|
||||
);
|
||||
|
||||
if ("href" in item) {
|
||||
event.preventDefault();
|
||||
window.open(item.href);
|
||||
}
|
||||
};
|
||||
|
||||
const KEY_BINDINGS = {
|
||||
'/': focusSearch,
|
||||
'Enter': openFirstNonHiddenItem
|
||||
"/": focusSearch,
|
||||
Enter: openFirstNonHiddenItem,
|
||||
};
|
||||
|
||||
document.addEventListener('keydown', function (event) {
|
||||
try {
|
||||
if (event.key in KEY_BINDINGS) {
|
||||
KEY_BINDINGS[event.key](event);
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
document.addEventListener("keydown", (event) => {
|
||||
try {
|
||||
if (event.key in KEY_BINDINGS) {
|
||||
KEY_BINDINGS[event.key](event);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
// Nothing to do
|
||||
}
|
||||
});
|
||||
|
|
101
resources/assets/js/liveStatRefresh.js
vendored
Normal file
101
resources/assets/js/liveStatRefresh.js
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
const REFRESH_INTERVAL_SMALL = 5000;
|
||||
const REFRESH_INTERVAL_BIG = 30000;
|
||||
const QUEUE_PROCESSING_INTERVAL = 1000;
|
||||
const CONTAINER_SELECTOR = ".livestats-container";
|
||||
|
||||
/**
|
||||
* @returns {*[]}
|
||||
*/
|
||||
function createQueue() {
|
||||
const queue = [];
|
||||
let suspended = false;
|
||||
|
||||
function processQueue() {
|
||||
if (queue.length === 0 || suspended === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
const next = queue.shift();
|
||||
next();
|
||||
}
|
||||
|
||||
document.addEventListener("visibilitychange", () => {
|
||||
suspended = document.hidden;
|
||||
});
|
||||
|
||||
setInterval(processQueue, QUEUE_PROCESSING_INTERVAL);
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {NodeListOf<Element>}
|
||||
*/
|
||||
function getContainers() {
|
||||
return document.querySelectorAll(CONTAINER_SELECTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {boolean} dataOnly
|
||||
* @param {boolean} active
|
||||
* @returns {number}
|
||||
*/
|
||||
function getQueueInterval(dataOnly, active) {
|
||||
if (dataOnly) {
|
||||
return REFRESH_INTERVAL_BIG;
|
||||
}
|
||||
|
||||
if (active) {
|
||||
return REFRESH_INTERVAL_SMALL;
|
||||
}
|
||||
|
||||
return REFRESH_INTERVAL_BIG;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} container
|
||||
* @param {array} queue
|
||||
* @returns {function(): Promise<Response>}
|
||||
*/
|
||||
function createUpdateJob(container, queue) {
|
||||
const id = container.getAttribute("data-id");
|
||||
// Data only attribute seems to indicate that the item should not be updated that often
|
||||
const isDataOnly = container.getAttribute("data-dataonly") === "1";
|
||||
|
||||
return () =>
|
||||
fetch(`get_stats/${id}`)
|
||||
.then((response) => {
|
||||
if (response.ok) {
|
||||
return response.json();
|
||||
}
|
||||
|
||||
throw new Error(`Network response was not ok: ${response.status}`);
|
||||
})
|
||||
.then((data) => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
container.innerHTML = data.html;
|
||||
|
||||
const isActive = data.status === "active";
|
||||
|
||||
if (queue) {
|
||||
setTimeout(() => {
|
||||
queue.push(createUpdateJob(container, queue));
|
||||
}, getQueueInterval(isDataOnly, isActive));
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
const livestatContainers = getContainers();
|
||||
|
||||
if (livestatContainers.length > 0) {
|
||||
const myQueue = createQueue();
|
||||
|
||||
livestatContainers.forEach((container) => {
|
||||
createUpdateJob(container, myQueue)();
|
||||
});
|
||||
}
|
|
@ -1125,6 +1125,16 @@ select:-webkit-autofill:focus {
|
|||
color: $app-text!important;
|
||||
}
|
||||
|
||||
.sortable-drag {
|
||||
opacity: 1!important;
|
||||
}
|
||||
|
||||
#sortable {
|
||||
.sortable-ghost:not(.sortable-drag) {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#sortable:focus-within {
|
||||
.item:focus-within {
|
||||
outline: 1px solid #ffffff91;
|
||||
|
@ -1141,4 +1151,22 @@ select:-webkit-autofill:focus {
|
|||
a:not(:focus-within) {
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
.import-status {
|
||||
list-style: none;
|
||||
li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 6px 0;
|
||||
svg {
|
||||
margin-right: 8px;
|
||||
}
|
||||
&.success svg {
|
||||
color: $app-green;
|
||||
}
|
||||
&.fail svg {
|
||||
color: $app-red;
|
||||
}
|
||||
}
|
||||
}
|
2
resources/assets/sass/app.scss
vendored
2
resources/assets/sass/app.scss
vendored
|
@ -9,7 +9,7 @@
|
|||
@import "normalise";
|
||||
|
||||
// Bootstrap
|
||||
@import "app";
|
||||
@import "_app";
|
||||
@import "rune";
|
||||
|
||||
// Huebee
|
||||
|
|
|
@ -17,6 +17,8 @@ return [
|
|||
|
||||
'settings.version' => 'Versão',
|
||||
'settings.background_image' => 'Imagem de fundo',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Link é aberto em',
|
||||
'settings.window_target.current' => 'Abra nesta aba',
|
||||
'settings.window_target.one' => 'Abra na mesma aba',
|
||||
|
@ -28,6 +30,9 @@ return [
|
|||
'settings.remove' => 'Remover',
|
||||
'settings.search' => 'busca',
|
||||
'settings.no_items' => 'Nenhum item encontrado',
|
||||
'settings.advanced' => 'Avançado',
|
||||
'settings.custom_css' => 'CSS Customizado',
|
||||
'settings.custom_js' => 'JavaScript Customizado',
|
||||
|
||||
'settings.label' => 'Rótulo',
|
||||
'settings.value' => 'Valor',
|
||||
|
@ -42,11 +47,18 @@ return [
|
|||
'options.startpage' => 'Página inicial',
|
||||
'options.yes' => 'Sim',
|
||||
'options.no' => 'Não',
|
||||
'options.nzbhydra' => 'NZBHydra',
|
||||
'options.jackett' => 'Jackett',
|
||||
|
||||
'buttons.save' => 'Salvar',
|
||||
'buttons.cancel' => 'Cancelar',
|
||||
'buttons.add' => 'Adicionar',
|
||||
'buttons.upload' => 'Carregar um arquivo',
|
||||
'buttons.downloadapps' => 'Atualizar lista de Apps',
|
||||
|
||||
'dashboard' => 'Página Inicial do dashboard',
|
||||
'dashboard.reorder' => 'Reordenar e fixar itens',
|
||||
'dashboard.settings' => 'Configurações',
|
||||
|
||||
'dash.pin_item' => 'Fixar o item na dashboard',
|
||||
'dash.no_apps' => 'Atualmente não há aplicativos fixados, :link1 ou :link2',
|
||||
|
@ -60,6 +72,7 @@ return [
|
|||
'apps.application_name' => 'Nome do aplicativo',
|
||||
'apps.colour' => 'Cor',
|
||||
'apps.icon' => 'Ícone',
|
||||
'app.import' => 'Importar',
|
||||
'apps.pinned' => 'Fixado',
|
||||
'apps.title' => 'Título',
|
||||
'apps.hex' => 'Cor hexadecimal',
|
||||
|
@ -73,6 +86,13 @@ return [
|
|||
'apps.tag_name' => 'Nome da tag',
|
||||
'apps.tags' => 'Tags',
|
||||
'apps.override' => 'Se diferente do URL principal',
|
||||
'apps.preview' => 'Vizualizar',
|
||||
'apps.apptype' => 'Tipo de Aplicativo',
|
||||
'apps.website' => 'Website',
|
||||
'apps.description' => 'Descrição',
|
||||
'apps.only_admin_account' => 'Somente se tiver conta admin!',
|
||||
'apps.autologin_url' => 'URL de login automático',
|
||||
'apps.show_deleted' => 'Mostrando Aplicativos Apagados',
|
||||
|
||||
'user.user_list' => 'Comercial',
|
||||
'user.add_user' => 'Adicionar usuários',
|
||||
|
@ -88,6 +108,8 @@ return [
|
|||
'delete' => 'Apagar',
|
||||
'optional' => 'Opcional',
|
||||
'restore' => 'Restaurar',
|
||||
'export' => 'Exportar',
|
||||
'import' => 'Importar',
|
||||
|
||||
'alert.success.item_created' => 'Item criado com sucesso',
|
||||
'alert.success.item_updated' => 'Item atualizado com sucesso',
|
||||
|
@ -98,9 +120,10 @@ return [
|
|||
'alert.success.tag_updated' => 'Tag atualizada com sucesso',
|
||||
'alert.success.tag_deleted' => 'Tag apagada com sucesso',
|
||||
'alert.success.tag_restored' => 'Tag restaurada com sucesso',
|
||||
|
||||
'alert.success.updating'=> 'Atualizando lista de apps',
|
||||
'alert.success.setting_updated' => 'Você editou com sucesso essa configuração',
|
||||
'alert.error.not_exist' => 'Essa configuração não existe.',
|
||||
'alert.success.updating' => 'Atualizando lista de Apps',
|
||||
|
||||
'alert.success.user_created' => 'Usuário criado com sucesso',
|
||||
'alert.success.user_updated' => 'Usuário atualizado com sucesso',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Podpořte nás',
|
||||
'settings.version' => 'Verze',
|
||||
'settings.background_image' => 'Obrázek pozadí',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Odkazy otevírat v',
|
||||
'settings.window_target.current' => 'Otevřít v této záložce',
|
||||
'settings.window_target.one' => 'Otevřít ve stejné záložce',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Doner',
|
||||
'settings.version' => 'Version',
|
||||
'settings.background_image' => 'Baggrundsbillede',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Link opens in',
|
||||
'settings.window_target.current' => 'Åbn i denne fane',
|
||||
'settings.window_target.one' => 'Åbn i den samme fane',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Spende',
|
||||
'settings.version' => 'Version',
|
||||
'settings.background_image' => 'Hintergrundbild',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Link öffnen in',
|
||||
'settings.window_target.current' => 'In diesem Tab öffnen',
|
||||
'settings.window_target.one' => 'Im selben Tab öffnen',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Δωρεά',
|
||||
'settings.version' => 'Έκδοση',
|
||||
'settings.background_image' => 'Εικόνα Παρασκηνίου',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Ο Σύνδεσμος ανοίγει σε',
|
||||
'settings.window_target.current' => 'Άνοιγμα σε αυτή την καρτέλα',
|
||||
'settings.window_target.one' => 'Άνοιγμα στην ίδια καρτέλα',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Donate',
|
||||
'settings.version' => 'Version',
|
||||
'settings.background_image' => 'Background Image',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Link opens in',
|
||||
'settings.window_target.current' => 'Open in this tab',
|
||||
'settings.window_target.one' => 'Open in the same tab',
|
||||
|
@ -72,6 +74,7 @@ return array (
|
|||
'apps.only_admin_account' => 'Only if you have admin-account!',
|
||||
'apps.autologin_url' => 'Auto login url',
|
||||
'apps.show_deleted' => 'Showing Deleted Applications',
|
||||
'app.import' => 'Import',
|
||||
'dashboard' => 'Home dashboard',
|
||||
'user.user_list' => 'Users',
|
||||
'user.add_user' => 'Add user',
|
||||
|
@ -86,6 +89,8 @@ return array (
|
|||
'delete' => 'Delete',
|
||||
'optional' => 'Optional',
|
||||
'restore' => 'Restore',
|
||||
'export' => 'Export',
|
||||
'import' => 'Import',
|
||||
'alert.success.item_created' => 'Item created successfully',
|
||||
'alert.success.item_updated' => 'Item updated successfully',
|
||||
'alert.success.item_deleted' => 'Item deleted successfully',
|
||||
|
@ -97,6 +102,8 @@ return array (
|
|||
'alert.success.tag_restored' => 'Tag restored successfully',
|
||||
'alert.success.setting_updated' => 'You have successfully edited this setting',
|
||||
'alert.error.not_exist' => 'This setting does not exist.',
|
||||
'alert.error.file_too_big' => 'File is too big.',
|
||||
'alert.error.file_not_stored' => 'File could not be stored.',
|
||||
'alert.success.user_created' => 'User created successfully',
|
||||
'alert.success.user_updated' => 'User updated successfully',
|
||||
'alert.success.user_deleted' => 'User deleted successfully',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Donar',
|
||||
'settings.version' => 'Versión',
|
||||
'settings.background_image' => 'Imagen de Fondo',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Vínculo abre en',
|
||||
'settings.window_target.current' => 'Abrir en ésta pestaña',
|
||||
'settings.window_target.one' => 'Abrir en la misma pestaña',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Lahjoita',
|
||||
'settings.version' => 'Versio',
|
||||
'settings.background_image' => 'Taustakuva',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Linkit aukeaa',
|
||||
'settings.window_target.current' => 'Avaa tässä välilehdessä',
|
||||
'settings.window_target.one' => 'Avaa samassa välilehdessä',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Contribuer',
|
||||
'settings.version' => 'Version',
|
||||
'settings.background_image' => 'Image d\'arrière-plan',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Ouverture des liens',
|
||||
'settings.window_target.current' => 'Dans l\'onglet courant',
|
||||
'settings.window_target.one' => 'Dans le même nouvel onglet',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Adomány',
|
||||
'settings.version' => 'Verzió',
|
||||
'settings.background_image' => 'Háttérkép',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Link megnyitása',
|
||||
'settings.window_target.current' => 'Ezen a lapon',
|
||||
'settings.window_target.one' => 'Azonos lapon',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Dona',
|
||||
'settings.version' => 'Versione',
|
||||
'settings.background_image' => 'Immagine di sfondo',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Apri link in',
|
||||
'settings.window_target.current' => 'Apri in questa scheda',
|
||||
'settings.window_target.one' => 'Apri nella stessa scheda',
|
||||
|
|
111
resources/lang/jp/app.php
Normal file
111
resources/lang/jp/app.php
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'settings.system' => 'システム',
|
||||
'settings.appearance' => '外観',
|
||||
'settings.miscellaneous' => 'その他',
|
||||
'settings.advanced' => '高度な設定',
|
||||
'settings.support' => 'サポート',
|
||||
'settings.donate' => '寄付',
|
||||
'settings.version' => 'バージョン',
|
||||
'settings.background_image' => '背景画像',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'リンクを開く',
|
||||
'settings.window_target.current' => 'このタブで開く',
|
||||
'settings.window_target.one' => '同じタブで開く',
|
||||
'settings.window_target.new' => '新しいタブで開く',
|
||||
'settings.homepage_search' => 'ホームページ検索',
|
||||
'settings.search_provider' => 'デフォルトの検索プロバイダー',
|
||||
'settings.language' => '言語',
|
||||
'settings.reset' => 'デフォルトにリセット',
|
||||
'settings.remove' => '削除する',
|
||||
'settings.search' => '検索する',
|
||||
'settings.no_items' => '項目は見つかりませんでした',
|
||||
'settings.label' => 'ラベル',
|
||||
'settings.value' => '値',
|
||||
'settings.edit' => '編集',
|
||||
'settings.view' => '観る',
|
||||
'settings.custom_css' => 'カスタム CSS',
|
||||
'settings.custom_js' => 'カスタム JavaScript',
|
||||
'options.none' => '- 設定されていません -',
|
||||
'options.google' => 'Google',
|
||||
'options.ddg' => 'DuckDuckGo',
|
||||
'options.bing' => 'Bing',
|
||||
'options.qwant' => 'Qwant',
|
||||
'options.startpage' => 'スタートページ',
|
||||
'options.yes' => 'はい',
|
||||
'options.no' => 'いいえ',
|
||||
'options.nzbhydra' => 'NZBHydra',
|
||||
'options.jackett' => 'Jackett',
|
||||
'buttons.save' => '保存',
|
||||
'buttons.cancel' => 'キャンセル',
|
||||
'buttons.add' => '追加',
|
||||
'buttons.upload' => 'アイコンをアップロード',
|
||||
'buttons.downloadapps' => 'アプリ一覧の更新',
|
||||
'dash.pin_item' => 'アイテムをダッシュボードにピン留め',
|
||||
'dash.no_apps' => '現在、ピン留めされたアプリケーション (:link1 または :link2) はありません',
|
||||
'dash.link1' => 'ここにアプリケーションを追加',
|
||||
'dash.link2' => 'アイテムをダッシュに固定する',
|
||||
'dash.pinned_items' => 'ピン留めされたアイテム',
|
||||
'apps.app_list' => 'アプリケーション一覧',
|
||||
'apps.view_trash' => 'ゴミ箱を表示',
|
||||
'apps.add_application' => 'アプリケーションを追加',
|
||||
'apps.application_name' => 'アプリケーション名',
|
||||
'apps.colour' => '色',
|
||||
'apps.icon' => 'アイコン',
|
||||
'apps.pinned' => 'ピン留め',
|
||||
'apps.title' => 'タイトル',
|
||||
'apps.hex' => '16 進数の色',
|
||||
'apps.username' => 'ユーザー名',
|
||||
'apps.password' => 'パスワード',
|
||||
'apps.config' => '設定',
|
||||
'apps.apikey' => 'APIキー',
|
||||
'apps.enable' => '有効',
|
||||
'apps.tag_list' => 'タグ一覧',
|
||||
'apps.add_tag' => 'タグ付けする',
|
||||
'apps.tag_name' => 'タグ名',
|
||||
'apps.tags' => 'タグ',
|
||||
'apps.override' => 'メインURLと異なる場合',
|
||||
'apps.preview' => 'プレビュー',
|
||||
'apps.apptype' => 'アプリケーションタイプ',
|
||||
'apps.website' => 'Webサイト',
|
||||
'apps.description' => '説明',
|
||||
'apps.only_admin_account' => 'あなたが管理者アカウントを持っている場合のみ!',
|
||||
'apps.autologin_url' => '自動ログイン URL',
|
||||
'apps.show_deleted' => '削除されたアプリケーションの表示',
|
||||
'app.import' => '読み込む',
|
||||
'dashboard' => 'ホームダッシュボード',
|
||||
'user.user_list' => 'ユーザー一覧',
|
||||
'user.add_user' => 'ユーザーを追加',
|
||||
'user.username' => 'ユーザー名',
|
||||
'user.avatar' => 'アバター',
|
||||
'user.email' => 'メールアドレス',
|
||||
'user.password_confirm' => 'パスワードを確認',
|
||||
'user.secure_front' => 'フロントへのパブリック アクセスを許可する - パスワードが設定されている場合にのみ適用されます。',
|
||||
'user.autologin' => '特定の URL からのログインを許可します。リンクを知っている人は誰でもログインできます。',
|
||||
'url' => 'URL',
|
||||
'title' => 'タイトル',
|
||||
'delete' => '消去',
|
||||
'optional' => 'オプション',
|
||||
'restore' => '復元',
|
||||
'export' => '書き出す',
|
||||
'import' => '読み込む',
|
||||
'alert.success.item_created' => 'アイテムが正常に作成されました',
|
||||
'alert.success.item_updated' => 'アイテムは正常に更新されました',
|
||||
'alert.success.item_deleted' => 'アイテムは正常に削除されました',
|
||||
'alert.success.item_restored' => 'アイテムは正常に復元されました',
|
||||
'alert.success.updating' => 'アプリ リストを更新中',
|
||||
'alert.success.tag_created' => 'タグが正常に作成されました',
|
||||
'alert.success.tag_updated' => 'タグが正常に更新されました',
|
||||
'alert.success.tag_deleted' => 'タグが正常に削除されました',
|
||||
'alert.success.tag_restored' => 'タグが正常に復元されました',
|
||||
'alert.success.setting_updated' => 'この設定の編集に成功しました',
|
||||
'alert.error.not_exist' => 'この設定は存在しません',
|
||||
'alert.success.user_created' => 'ユーザーが正常に作成されました',
|
||||
'alert.success.user_updated' => 'ユーザーが正常に更新されました',
|
||||
'alert.success.user_deleted' => 'ユーザーは正常に削除されました',
|
||||
'alert.success.user_restored' => 'ユーザーは正常に復元されました',
|
||||
'dashboard.reorder' => '項目の並べ替えと固定',
|
||||
'dashboard.settings' => '設定',
|
||||
);
|
6
resources/lang/jp/auth.php
Normal file
6
resources/lang/jp/auth.php
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'failed' => 'これらの認証情報は弊社の記録と一致しません。',
|
||||
'throttle' => 'ログイン試行回数が多すぎます。 :seconds 秒後にもう一度お試しください。',
|
||||
);
|
6
resources/lang/jp/pagination.php
Normal file
6
resources/lang/jp/pagination.php
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'previous' => '« 前',
|
||||
'next' => '次 »',
|
||||
);
|
9
resources/lang/jp/passwords.php
Normal file
9
resources/lang/jp/passwords.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'password' => 'パスワードは 6 文字以上で、確認と一致する必要があります。',
|
||||
'reset' => 'パスワードがリセットされました!',
|
||||
'sent' => 'パスワードのリセット リンクをメールで送信しました。',
|
||||
'token' => 'このパスワード リセット トークンは無効です。',
|
||||
'user' => 'その電子メール アドレスを持つユーザーが見つかりません。',
|
||||
);
|
128
resources/lang/jp/validation.php
Normal file
128
resources/lang/jp/validation.php
Normal file
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines contain the default error messages used by
|
||||
| the validator class. Some of these rules have multiple versions such
|
||||
| as the size rules. Feel free to tweak each of these messages here.
|
||||
|
|
||||
*/
|
||||
|
||||
'accepted' => ':attribute を受け入れる必要があります。',
|
||||
'active_url' => ':attribute は有効な URL ではありません。',
|
||||
'after' => ':attribute は :date より後の日付でなければなりません。',
|
||||
'after_or_equal' => ':attribute は :date 以降の日付でなければなりません。',
|
||||
'alpha' => ':attribute には文字のみを含めることができます。',
|
||||
'accepted' => ':attribute を受け入れる必要があります。',
|
||||
'active_url' => ':attribute は有効な URL ではありません。',
|
||||
'after' => ':attribute は :date より後の日付でなければなりません。',
|
||||
'after_or_equal' => ':attribute は :date 以降の日付でなければなりません。',
|
||||
'alpha' => ':attribute には文字のみを含めることができます。',
|
||||
'alpha_dash' => ':attribute には、文字、数字、およびダッシュのみを含めることができます。',
|
||||
'alpha_num' => ':attribute には、文字と数字のみを含めることができます。',
|
||||
'array' => ':attribute は配列でなければなりません。',
|
||||
'before' => ':attribute は :date より前の日付でなければなりません。',
|
||||
'before_or_equal' => ':attribute は :date より前または等しい日付でなければなりません。',
|
||||
'between' => [
|
||||
'numeric' => ':attribute は :min と :max の間でなければなりません。',
|
||||
'file' => ':attribute は :min から :max キロバイトの間でなければなりません。',
|
||||
'string' => ':attribute は :min から :max 文字の間でなければなりません.',
|
||||
'array' => ':attribute には :min と :max の項目が必要です。',
|
||||
],
|
||||
'boolean' => ':attribute フィールドは true または false でなければなりません。',
|
||||
'confirmed' => ':attribute の確認が一致しません。',
|
||||
'date' => ':attribute は有効な日付ではありません。',
|
||||
'date_format' => ':attribute がフォーマット :format と一致しません。',
|
||||
'different' => ':attribute と :other は異なる必要があります。',
|
||||
'digits' => ':attribute は :digits 桁でなければなりません。',
|
||||
'digits_between' => ':attribute は :min から :max 桁の間でなければなりません.',
|
||||
'dimensions' => ':attribute の画像サイズが無効です。',
|
||||
'distinct' => ':attribute フィールドの値が重複しています。',
|
||||
'email' => ':attribute は有効な電子メール アドレスでなければなりません。',
|
||||
'exists' => '選択された :attribute は無効です。',
|
||||
'file' => ':attribute はファイルでなければなりません。',
|
||||
'filled' => ':attribute フィールドには値が必要です。',
|
||||
'image' => ':attribute は画像でなければなりません。',
|
||||
'in' => '選択された :attribute は無効です。',
|
||||
'in_array' => ':attribute フィールドが :other に存在しません。',
|
||||
'integer' => ':attribute は整数でなければなりません。',
|
||||
'ip' => ':attribute は有効な IP アドレスでなければなりません。',
|
||||
'ipv4' => ':attribute は有効な IPv4 アドレスでなければなりません。',
|
||||
'ipv6' => ':attribute は有効な IPv6 アドレスでなければなりません。',
|
||||
'json' => ':attribute は有効な JSON 文字列でなければなりません。',
|
||||
'max' => [
|
||||
'numeric' => ':attribute は :max を超えることはできません。',
|
||||
'file' => ':attribute は :max キロバイトを超えることはできません。',
|
||||
'string' => ':attribute は :max 文字を超えることはできません.',
|
||||
'array' => ':attribute には :max 個を超えるアイテムを含めることはできません。',
|
||||
],
|
||||
'mimes' => ':attribute は、タイプ: :values のファイルでなければなりません。',
|
||||
'mimetypes' => ':attribute はタイプ: :values のファイルでなければなりません。',
|
||||
'min' => [
|
||||
'numeric' => ':attribute は少なくとも :min である必要があります。',
|
||||
'file' => ':attribute は、少なくとも :min キロバイトでなければなりません。',
|
||||
'string' => ':attribute は少なくとも :min 文字でなければなりません。',
|
||||
'array' => ':attribute には少なくとも :min 個のアイテムが必要です。',
|
||||
],
|
||||
'not_in' => '選択された :attribute は無効です。',
|
||||
'numeric' => ':attribute は数値でなければなりません。',
|
||||
'present' => ':attribute フィールドが存在する必要があります。',
|
||||
'regex' => ':attribute 形式が無効です。',
|
||||
'required' => ':attribute フィールドは必須です。',
|
||||
'required_if' => ':other が :value の場合、:attribute フィールドは必須です。',
|
||||
'required_unless' => ':values に :other がない限り、:attribute フィールドは必須です。',
|
||||
'required_with' => ':values が存在する場合、:attribute フィールドは必須です。',
|
||||
'required_with_all' => ':values が存在する場合、:attribute フィールドは必須です。',
|
||||
'required_without' => ':values が存在しない場合、:attribute フィールドは必須です。',
|
||||
'regex' => ':attribute 形式が無効です。',
|
||||
'required_without_all' => ':values が存在しない場合、:attribute フィールドは必須です。',
|
||||
'regex' => ':attribute 形式が無効です。',
|
||||
'same' => ':attribute と :other は一致する必要があります。',
|
||||
'size' => [
|
||||
'numeric' => ':attribute は :size でなければなりません。',
|
||||
'file' => ':attribute は :size キロバイトでなければなりません。',
|
||||
'string' => ':attribute は :size 文字でなければなりません。',
|
||||
'array' => ':attribute には :size 項目が含まれている必要があります。',
|
||||
],
|
||||
'string' => ':attribute は文字列でなければなりません。',
|
||||
'timezone' => ':attribute は有効なゾーンでなければなりません。',
|
||||
'unique' => ':attribute は既に取得されています。',
|
||||
'uploaded' => ':attribute のアップロードに失敗しました。',
|
||||
'url' => ':attribute 形式が無効です。'
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify custom validation messages for attributes using the
|
||||
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||
| specify a specific custom language line for a given attribute rule.
|
||||
|
|
||||
*/
|
||||
|
||||
'custom' => [
|
||||
'attribute-name' => [
|
||||
'rule-name' => 'custom-message',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Attributes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used to swap attribute place-holders
|
||||
| with something more reader friendly such as E-Mail Address instead
|
||||
| of "email". This simply helps us make messages a little cleaner.
|
||||
|
|
||||
*/
|
||||
|
||||
'attributes' => [],
|
||||
|
||||
];
|
|
@ -4,11 +4,13 @@ return array (
|
|||
'settings.system' => '시스템',
|
||||
'settings.appearance' => '외관',
|
||||
'settings.miscellaneous' => '잡동사니',
|
||||
'settings.advanced' => '고급의',
|
||||
'settings.advanced' => '고급',
|
||||
'settings.support' => '지원',
|
||||
'settings.donate' => '기부',
|
||||
'settings.version' => '버전',
|
||||
'settings.background_image' => '배경 이미지',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => '다음에서 링크 열기',
|
||||
'settings.window_target.current' => '현재 탭에서 열기',
|
||||
'settings.window_target.one' => '같은 탭에서 열기',
|
||||
|
@ -42,9 +44,9 @@ return array (
|
|||
'buttons.upload' => '아이콘 업로드',
|
||||
'buttons.downloadapps' => '앱 목록 업데이트',
|
||||
'dash.pin_item' => '대시보드에 항목 고정',
|
||||
'dash.no_apps' => '현재 고정된 응용 프로그램 없음, :link1 혹은 :link2',
|
||||
'dash.link1' => '여기에 앱 추가',
|
||||
'dash.link2' => '대시에 항목 고정',
|
||||
'dash.no_apps' => '현재 고정된 앱이 없습니다. :link1하거나 :link2해야 합니다.',
|
||||
'dash.link1' => '여기에 앱을 추가',
|
||||
'dash.link2' => '대시보드에 항목을 고정',
|
||||
'dash.pinned_items' => '고정된 항목',
|
||||
'apps.app_list' => '앱 목록',
|
||||
'apps.view_trash' => '휴지통 보기',
|
||||
|
@ -69,9 +71,10 @@ return array (
|
|||
'apps.apptype' => '앱 형식',
|
||||
'apps.website' => '웹사이트',
|
||||
'apps.description' => '설명',
|
||||
'apps.only_admin_account' => '관리자 계정이 있는 경우에만!',
|
||||
'apps.only_admin_account' => '관리자 계정이 있는 경우에만 가능합니다!',
|
||||
'apps.autologin_url' => '자동 로그인 URL',
|
||||
'apps.show_deleted' => '삭제된 애플리케이션 표시',
|
||||
'app.import' => '가져오기',
|
||||
'dashboard' => '홈 대시보드',
|
||||
'user.user_list' => '사용자',
|
||||
'user.add_user' => '사용자 추가',
|
||||
|
@ -79,13 +82,15 @@ return array (
|
|||
'user.avatar' => '아바타',
|
||||
'user.email' => '전자 메일',
|
||||
'user.password_confirm' => '암호 확인',
|
||||
'user.secure_front' => 'Allow public access to front - Only enforced if a password is set.',
|
||||
'user.autologin' => 'Allow logging in from a specific URL. Anyone with the link can login.',
|
||||
'user.secure_front' => '전방에 대한 공개 액세스 허용 - 암호가 설정된 경우에만 적용됩니다.',
|
||||
'user.autologin' => '지정된 URL에서 로그인을 허용합니다. 해당 링크을 소유한 사람이라면 누구나 로그인할 수 있습니다.',
|
||||
'url' => 'URL',
|
||||
'title' => '제목',
|
||||
'delete' => '제거',
|
||||
'optional' => '선택적',
|
||||
'restore' => '복원',
|
||||
'export' => '내보내기',
|
||||
'import' => '가져오기',
|
||||
'alert.success.item_created' => '항목을 성공적으로 만들었습니다',
|
||||
'alert.success.item_updated' => '항목을 성공적으로 업데이트했습니다',
|
||||
'alert.success.item_deleted' => '항목을 성공적으로 제거했습니다',
|
||||
|
@ -97,10 +102,12 @@ return array (
|
|||
'alert.success.tag_restored' => '태그를 성공적으로 복원했습니다',
|
||||
'alert.success.setting_updated' => '설정을 성공적으로 수정했습니다',
|
||||
'alert.error.not_exist' => '이 설정은 존재하지 않습니다.',
|
||||
'alert.error.file_too_big' => '파일이 너무 큽니다.',
|
||||
'alert.error.file_not_stored' => '파일을 저장할 수 없습니다.',
|
||||
'alert.success.user_created' => '사용자를 성공적으로 만들었습니다',
|
||||
'alert.success.user_updated' => '사용자를 성공적으로 업데이트했습니다',
|
||||
'alert.success.user_deleted' => '사용자를 성공적으로 제거했습니다',
|
||||
'alert.success.user_restored' => '사용자를 성공적으로 복원했습니다',
|
||||
'dashboard.reorder' => '항목 재정렬 및 고정',
|
||||
'dashboard.settings' => '설정',
|
||||
);
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'failed' => 'These credentials do not match our records.',
|
||||
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
|
||||
);
|
||||
'failed' => '이 자격 증명은 우리 기록과 일치하지 않습니다.',
|
||||
'throttle' => '로그인 시도 횟수가 너무 많습니다. :seconds 초 후에 다시 시도하십시오.',
|
||||
);
|
||||
|
|
|
@ -30,6 +30,10 @@ return [
|
|||
|
||||
'settings.background_image' => 'Imagin dedree',
|
||||
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
|
||||
'settings.window_target' => 'I link se derven...',
|
||||
|
||||
'settings.window_target.current' => 'In quella scheda chi',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Doneren',
|
||||
'settings.version' => 'Versie',
|
||||
'settings.background_image' => 'Achtergrondafbeelding',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Link opent in',
|
||||
'settings.window_target.current' => 'In de huidige tab openen',
|
||||
'settings.window_target.one' => 'In dezelfde tab openen',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Donere',
|
||||
'settings.version' => 'Versjon',
|
||||
'settings.background_image' => 'Bakgrunnsbilde',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Link åpnes inn',
|
||||
'settings.window_target.current' => 'Åpne i denne fanen',
|
||||
'settings.window_target.one' => 'Åpne i samme fane',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Podarować',
|
||||
'settings.version' => 'Wersja',
|
||||
'settings.background_image' => 'Tapeta Pulpitu',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Link otwiera się w',
|
||||
'settings.window_target.current' => 'Otwórz w tej zakładce',
|
||||
'settings.window_target.one' => 'Otwórz w tej samej zakładce',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Doar',
|
||||
'settings.version' => 'Versão',
|
||||
'settings.background_image' => 'Imagem de fundo',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'O link abre em',
|
||||
'settings.window_target.current' => 'Abrir neste separador',
|
||||
'settings.window_target.one' => 'Abrir no mesmo separador',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Пожертвования',
|
||||
'settings.version' => 'Версия',
|
||||
'settings.background_image' => 'Фоновое изображение',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Открывать ссылки в',
|
||||
'settings.window_target.current' => 'Открывать в этой же закладке',
|
||||
'settings.window_target.one' => 'Открывать в той же закладке',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Doniraj',
|
||||
'settings.version' => 'Verzija',
|
||||
'settings.background_image' => 'Slika za ozadje',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Povezava se odpre v',
|
||||
'settings.window_target.current' => 'Odpri v tem zavihku',
|
||||
'settings.window_target.one' => 'Odpri v istem zavihku',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Donera',
|
||||
'settings.version' => 'Version',
|
||||
'settings.background_image' => 'Bakgrundsbild',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Länken öppnas i',
|
||||
'settings.window_target.current' => 'Öppna i denna flik',
|
||||
'settings.window_target.one' => 'Öppna i samma flik',
|
||||
|
|
|
@ -9,6 +9,8 @@ return array (
|
|||
'settings.donate' => 'Bağış yapmak',
|
||||
'settings.version' => 'Versiyon',
|
||||
'settings.background_image' => 'Arkaplan Resmi',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Bağlantı açılır',
|
||||
'settings.window_target.current' => 'Bu sekmede aç',
|
||||
'settings.window_target.one' => 'Aynı sekmede aç',
|
||||
|
|
113
resources/lang/uk/app.php
Normal file
113
resources/lang/uk/app.php
Normal file
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'settings.system' => 'Система',
|
||||
'settings.appearance' => 'Зовнішній вигляд',
|
||||
'settings.miscellaneous' => 'Різне',
|
||||
'settings.advanced' => 'Просунуті',
|
||||
'settings.support' => 'Підтримка',
|
||||
'settings.donate' => 'Пожертви',
|
||||
'settings.version' => 'Версія',
|
||||
'settings.background_image' => 'Фонове зображення',
|
||||
'settings.trianglify' => 'Trianglify',
|
||||
'settings.trianglify_seed' => 'Trianglify Random Seed',
|
||||
'settings.window_target' => 'Відкривати посилання в',
|
||||
'settings.window_target.current' => 'Відкривати в цій вкладці',
|
||||
'settings.window_target.one' => 'Відкривати у тій самій вкладці',
|
||||
'settings.window_target.new' => 'Відкривати у новій вкладці',
|
||||
'settings.homepage_search' => 'Сторінка пошуку',
|
||||
'settings.search_provider' => 'Пошукова система',
|
||||
'settings.language' => 'Мова',
|
||||
'settings.reset' => 'Повернутися до початкових значень',
|
||||
'settings.remove' => 'Видалити',
|
||||
'settings.search' => 'знайти',
|
||||
'settings.no_items' => 'Нічого не знайдено',
|
||||
'settings.label' => 'Мітка',
|
||||
'settings.value' => 'Значення',
|
||||
'settings.edit' => 'Редагувати',
|
||||
'settings.view' => 'Перегляд',
|
||||
'settings.custom_css' => 'Кастомний CSS',
|
||||
'settings.custom_js' => 'Кастомний JavaScript',
|
||||
'options.none' => '- не задано -',
|
||||
'options.google' => 'Google',
|
||||
'options.ddg' => 'DuckDuckGo',
|
||||
'options.bing' => 'Bing',
|
||||
'options.qwant' => 'Qwant',
|
||||
'options.startpage' => 'Початкова сторінка',
|
||||
'options.yes' => 'Так',
|
||||
'options.no' => 'Ні',
|
||||
'options.nzbhydra' => 'NZBHydra',
|
||||
'options.jackett' => 'Jackett',
|
||||
'buttons.save' => 'Зберегти',
|
||||
'buttons.cancel' => 'Скасувати',
|
||||
'buttons.add' => 'Додати',
|
||||
'buttons.upload' => 'Завантажити картинку',
|
||||
'buttons.downloadapps' => 'Оновити список додатків',
|
||||
'dash.pin_item' => 'Прикріпити до панелі',
|
||||
'dash.no_apps' => 'Немає прикріплених додатків, :link1 або :link2',
|
||||
'dash.link1' => 'Дотайте додаток',
|
||||
'dash.link2' => 'Прикріпіть на дошку',
|
||||
'dash.pinned_items' => 'Прикріплені елементи',
|
||||
'apps.app_list' => 'Список додатків',
|
||||
'apps.view_trash' => 'Показати кошик',
|
||||
'apps.add_application' => 'Дотати додаток',
|
||||
'apps.application_name' => 'Ім\'я додатку',
|
||||
'apps.colour' => 'Колір',
|
||||
'apps.icon' => 'Зображення',
|
||||
'apps.pinned' => 'Прикріплено',
|
||||
'apps.title' => 'Заголовок',
|
||||
'apps.hex' => 'Колір в Hex',
|
||||
'apps.username' => 'Ім\'я користувача',
|
||||
'apps.password' => 'Пароль',
|
||||
'apps.config' => 'Налаштування',
|
||||
'apps.apikey' => 'Ключ API',
|
||||
'apps.enable' => 'Увімкнено',
|
||||
'apps.tag_list' => 'Список тегів',
|
||||
'apps.add_tag' => 'Додати тег',
|
||||
'apps.tag_name' => 'Назва тега',
|
||||
'apps.tags' => 'Теги',
|
||||
'apps.override' => 'Якщо відрізняється від основного url',
|
||||
'apps.preview' => 'Попередній перегляд',
|
||||
'apps.apptype' => 'Тип додатку',
|
||||
'apps.website' => 'Вебсайт',
|
||||
'apps.description' => 'Опис',
|
||||
'apps.only_admin_account' => 'Тільки з адмін аккаунтом!',
|
||||
'apps.autologin_url' => 'Автоматичний логін',
|
||||
'apps.show_deleted' => 'Показати видалені додатки',
|
||||
'app.import' => 'Імпорт',
|
||||
'dashboard' => 'Основна панель',
|
||||
'user.user_list' => 'Користувачі',
|
||||
'user.add_user' => 'Додати користувача',
|
||||
'user.username' => 'Ім\'я користувача',
|
||||
'user.avatar' => 'Аватар',
|
||||
'user.email' => 'Email',
|
||||
'user.password_confirm' => 'Підтвердження пароля',
|
||||
'user.secure_front' => 'Дозволити публічний доступ - Можливо тільки якщо встановлено пароль.',
|
||||
'user.autologin' => 'Автоматичний вхід з визначеного URL. Хто завгодно зможе увійти за даним посиланням.',
|
||||
'url' => 'URL',
|
||||
'title' => 'Заголовок',
|
||||
'delete' => 'Видалити',
|
||||
'optional' => 'Опціонально',
|
||||
'restore' => 'Відновити',
|
||||
'export' => 'Експорт',
|
||||
'import' => 'Імпорт',
|
||||
'alert.success.item_created' => 'Елемент створено успішно',
|
||||
'alert.success.item_updated' => 'Елемент оновлено успішно',
|
||||
'alert.success.item_deleted' => 'Елемент видалено успішно',
|
||||
'alert.success.item_restored' => 'Елемент відновлено успішно',
|
||||
'alert.success.updating' => 'Обовлено список додатків',
|
||||
'alert.success.tag_created' => 'Тег створено успішно',
|
||||
'alert.success.tag_updated' => 'Тег оновлено успішно',
|
||||
'alert.success.tag_deleted' => 'Тег видалено успішно',
|
||||
'alert.success.tag_restored' => 'Тег відновлено успішно',
|
||||
'alert.success.setting_updated' => 'Ви успішно відредагували налаштування',
|
||||
'alert.error.not_exist' => 'Ваших налаштувань не існує.',
|
||||
'alert.error.file_too_big' => 'Файл занадто великий.',
|
||||
'alert.error.file_not_stored' => 'Не вдалося зберегти файл.',
|
||||
'alert.success.user_created' => 'Користувача створено успішно',
|
||||
'alert.success.user_updated' => 'Користувача оновлено успішно',
|
||||
'alert.success.user_deleted' => 'Користувача видалено успішно',
|
||||
'alert.success.user_restored' => 'Користувача відновлено успішно',
|
||||
'dashboard.reorder' => 'Змінити порядок та закріпити елементи',
|
||||
'dashboard.settings' => 'Налаштування',
|
||||
);
|
6
resources/lang/uk/auth.php
Normal file
6
resources/lang/uk/auth.php
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'failed' => 'Введені реквізити не співпадають з існуючими.',
|
||||
'throttle' => 'Забагато спроб авторизації. Спробуйте знову через :seconds секунд.',
|
||||
);
|
6
resources/lang/uk/pagination.php
Normal file
6
resources/lang/uk/pagination.php
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'previous' => '« Попередній',
|
||||
'next' => 'Наступний »',
|
||||
);
|
9
resources/lang/uk/passwords.php
Normal file
9
resources/lang/uk/passwords.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'password' => 'Довжина пароля мінімум 6 символів та він має співпадати з підтвердженням.',
|
||||
'reset' => 'Ваш пароль відновлено!',
|
||||
'sent' => 'Мы відправили вам посилання для відновлення пароля!',
|
||||
'token' => 'Некоректний токен для відновлення пароля.',
|
||||
'user' => 'Користувача з такою e-mail адресою не існує.',
|
||||
);
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue