diff --git a/composer.json b/composer.json index 548b7f5..3a51d87 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,6 @@ "require": { "php": ">=8.0", "awssat/laravel-visits": "^6.0", - "codedge/laravel-selfupdater": "^3.6", "cohensive/oembed": "^0.17", "doctrine/dbal": "^3.0", "fideloper/proxy": "^4.4", diff --git a/config/self-update.php b/config/self-update.php deleted file mode 100644 index 6673a52..0000000 --- a/config/self-update.php +++ /dev/null @@ -1,161 +0,0 @@ - env('SELF_UPDATER_SOURCE', 'http'), - - /* - |-------------------------------------------------------------------------- - | Version installed - |-------------------------------------------------------------------------- - | - | Set this to the version of your software installed on your system. - | - */ - - 'version_installed' => file_get_contents(base_path("version.json")), - - /* - |-------------------------------------------------------------------------- - | Repository types - |-------------------------------------------------------------------------- - | - | A repository can be of different types, which can be specified here. - | Current options: - | - github - | - gitlab - | - http - | - */ - - 'repository_types' => [ - 'github' => [ - 'type' => 'github', - 'repository_vendor' => env('SELF_UPDATER_REPO_VENDOR', ''), - 'repository_name' => env('SELF_UPDATER_REPO_NAME', ''), - 'repository_url' => '', - 'download_path' => env('SELF_UPDATER_DOWNLOAD_PATH', '/tmp'), - 'private_access_token' => env('SELF_UPDATER_GITHUB_PRIVATE_ACCESS_TOKEN', ''), - 'use_branch' => env('SELF_UPDATER_USE_BRANCH', ''), - ], - 'gitlab' => [ - 'type' => 'gitlab', - 'repository_id' => env('SELF_UPDATER_REPO_URL', ''), - 'download_path' => env('SELF_UPDATER_DOWNLOAD_PATH', '/tmp'), - 'private_access_token' => env('SELF_UPDATER_GITLAB_PRIVATE_ACCESS_TOKEN', ''), - ], - 'http' => [ - 'type' => 'http', - 'repository_url' => env('SELF_UPDATER_REPO_URL', $userver), - 'pkg_filename_format' => env('SELF_UPDATER_PKG_FILENAME_FORMAT', '_VERSION_'), - 'download_path' => env('SELF_UPDATER_DOWNLOAD_PATH', '/tmp'), - 'private_access_token' => env('SELF_UPDATER_HTTP_PRIVATE_ACCESS_TOKEN', ''), - ], - ], - - /* - |-------------------------------------------------------------------------- - | Exclude folders from update - |-------------------------------------------------------------------------- - | - | Specific folders which should not be updated and will be skipped during the - | update process. - | - | Here's already a list of good examples to skip. You may want to keep those. - | - */ - - 'exclude_folders' => [ - '__MACOSX', - 'node_modules', - 'bootstrap/cache', - 'bower', - 'storage/app', - 'storage/framework', - 'storage/logs', - 'storage/self-update', - ], - - /* - |-------------------------------------------------------------------------- - | Event Logging - |-------------------------------------------------------------------------- - | - | Configure if fired events should be logged - | - */ - - 'log_events' => env('SELF_UPDATER_LOG_EVENTS', true), - - /* - |-------------------------------------------------------------------------- - | Notifications - |-------------------------------------------------------------------------- - | - | Specify for which events you want to get notifications. Out of the box you can use 'mail'. - | - */ - - 'notifications' => [ - 'notifications' => [ - \Codedge\Updater\Notifications\Notifications\UpdateSucceeded::class => ['mail'], - \Codedge\Updater\Notifications\Notifications\UpdateFailed::class => ['mail'], - \Codedge\Updater\Notifications\Notifications\UpdateAvailable::class => ['mail'], - ], - - /* - * Here you can specify the notifiable to which the notifications should be sent. The default - * notifiable will use the variables specified in this config file. - */ - 'notifiable' => \Codedge\Updater\Notifications\Notifiable::class, - - 'mail' => [ - 'to' => [ - 'address' => env('SELF_UPDATER_MAILTO_ADDRESS', 'notifications@example.com'), - 'name' => env('SELF_UPDATER_MAILTO_NAME', ''), - ], - - 'from' => [ - 'address' => env('SELF_UPDATER_MAIL_FROM_ADDRESS', 'updater@example.com'), - 'name' => env('SELF_UPDATER_MAIL_FROM_NAME', 'Update'), - ], - ], - ], - - /* - |--------------------------------------------------------------------------- - | Register custom artisan commands - |--------------------------------------------------------------------------- - */ - - 'artisan_commands' => [ - 'pre_update' => [ - //'command:signature' => [ - // 'class' => Command class - // 'params' => [] - //] - ], - 'post_update' => [ - - ], - ], - -]; diff --git a/resources/views/components/finishing.blade.php b/resources/views/components/finishing.blade.php index 087529c..27c635a 100644 --- a/resources/views/components/finishing.blade.php +++ b/resources/views/components/finishing.blade.php @@ -1,4 +1,4 @@ -id == 1){EnvEditor::addKey('ADMIN_EMAIL', App\Models\User::find(1)->email);} - else{EnvEditor::addKey('ADMIN_EMAIL', '');}} +if (EnvEditor::keyExists('ENABLE_ADMIN_BAR_USERS')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('ENABLE_ADMIN_BAR_USERS', 'false'); +} - if(env('APP_NAME') == 'LittleLink Custom' or env('APP_NAME') == 'LittleLink') { - EnvEditor::editKey('APP_NAME', 'LinkStack'); - } +if (EnvEditor::keyExists('ADMIN_EMAIL')) { +} else { + if (Auth::user()->id == 1) { + EnvEditor::addKey('ADMIN_EMAIL', App\Models\User::find(1)->email); + } else { + EnvEditor::addKey('ADMIN_EMAIL', ''); + } +} - if (EnvEditor::keyExists('ALLOW_REGISTRATION')) { /* Do nothing if key already exists */ - } else { - $pagedb = DB::table('pages')->select('register')->first(); - if ($pagedb->register) { - EnvEditor::addKey('ALLOW_REGISTRATION', 'true'); - } else { - EnvEditor::addKey('ALLOW_REGISTRATION', 'false'); - } - try { - DB::table('pages')->update(['register' => null]); - } catch (Exception $e) {} - } +if (env('APP_NAME') == 'LittleLink Custom' or env('APP_NAME') == 'LittleLink') { + EnvEditor::editKey('APP_NAME', 'LinkStack'); +} - try { - $file = base_path('storage/RSTAC'); - if (file_exists($file)) { - copy(base_path('storage/templates/advanced-config.php'), base_path('config/advanced-config.php')); - unlink($file); - } - } catch (Exception $e) {} +if (EnvEditor::keyExists('ALLOW_REGISTRATION')) { + /* Do nothing if key already exists */ +} else { + $pagedb = DB::table('pages')->select('register')->first(); + if ($pagedb->register) { + EnvEditor::addKey('ALLOW_REGISTRATION', 'true'); + } else { + EnvEditor::addKey('ALLOW_REGISTRATION', 'false'); + } + try { + DB::table('pages')->update(['register' => null]); + } catch (Exception $e) { + session(['update_error' => $e->getMessage()]); + } +} - try { - $vendorLangPath = resource_path('lang/vendor'); - if (File::exists($vendorLangPath)) { - File::deleteDirectory($vendorLangPath); - } - } catch (Exception $e) {} +try { + $file = base_path('storage/RSTAC'); + if (file_exists($file)) { + copy(base_path('storage/templates/advanced-config.php'), base_path('config/advanced-config.php')); + unlink($file); + } +} catch (Exception $e) { + session(['update_error' => $e->getMessage()]); +} - // Footer page customization - if(EnvEditor::keyExists('DISPLAY_FOOTER_HOME')){} else {EnvEditor::addKey('DISPLAY_FOOTER_HOME', 'true');} - if(EnvEditor::keyExists('DISPLAY_FOOTER_TERMS')){} else {EnvEditor::addKey('DISPLAY_FOOTER_TERMS', 'true');} - if(EnvEditor::keyExists('DISPLAY_FOOTER_PRIVACY')){} else {EnvEditor::addKey('DISPLAY_FOOTER_PRIVACY', 'true');} - if(EnvEditor::keyExists('DISPLAY_FOOTER_CONTACT')){} else {EnvEditor::addKey('DISPLAY_FOOTER_CONTACT', 'true');} - if(EnvEditor::keyExists('TITLE_FOOTER_HOME')){} else {EnvEditor::addKey('TITLE_FOOTER_HOME', 'Home');} - if(EnvEditor::keyExists('TITLE_FOOTER_TERMS')){} else {EnvEditor::addKey('TITLE_FOOTER_TERMS', 'Terms');} - if(EnvEditor::keyExists('TITLE_FOOTER_PRIVACY')){} else {EnvEditor::addKey('TITLE_FOOTER_PRIVACY', 'Privacy');} - if(EnvEditor::keyExists('TITLE_FOOTER_CONTACT')){} else {EnvEditor::addKey('TITLE_FOOTER_CONTACT', 'Contact');} - if(EnvEditor::keyExists('HOME_FOOTER_LINK')){} else {EnvEditor::addKey('HOME_FOOTER_LINK', '');} +try { + $vendorLangPath = resource_path('lang/vendor'); + if (File::exists($vendorLangPath)) { + File::deleteDirectory($vendorLangPath); + } +} catch (Exception $e) { + session(['update_error' => $e->getMessage()]); +} - if(EnvEditor::keyExists('FORCE_HTTPS')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('FORCE_HTTPS', 'false');} +// Footer page customization +if (EnvEditor::keyExists('DISPLAY_FOOTER_HOME')) { +} else { + EnvEditor::addKey('DISPLAY_FOOTER_HOME', 'true'); +} +if (EnvEditor::keyExists('DISPLAY_FOOTER_TERMS')) { +} else { + EnvEditor::addKey('DISPLAY_FOOTER_TERMS', 'true'); +} +if (EnvEditor::keyExists('DISPLAY_FOOTER_PRIVACY')) { +} else { + EnvEditor::addKey('DISPLAY_FOOTER_PRIVACY', 'true'); +} +if (EnvEditor::keyExists('DISPLAY_FOOTER_CONTACT')) { +} else { + EnvEditor::addKey('DISPLAY_FOOTER_CONTACT', 'true'); +} +if (EnvEditor::keyExists('TITLE_FOOTER_HOME')) { +} else { + EnvEditor::addKey('TITLE_FOOTER_HOME', 'Home'); +} +if (EnvEditor::keyExists('TITLE_FOOTER_TERMS')) { +} else { + EnvEditor::addKey('TITLE_FOOTER_TERMS', 'Terms'); +} +if (EnvEditor::keyExists('TITLE_FOOTER_PRIVACY')) { +} else { + EnvEditor::addKey('TITLE_FOOTER_PRIVACY', 'Privacy'); +} +if (EnvEditor::keyExists('TITLE_FOOTER_CONTACT')) { +} else { + EnvEditor::addKey('TITLE_FOOTER_CONTACT', 'Contact'); +} +if (EnvEditor::keyExists('HOME_FOOTER_LINK')) { +} else { + EnvEditor::addKey('HOME_FOOTER_LINK', ''); +} - $data['page'] = Page::select('contact')->first(); - if (strpos($data['page']->contact, 'info@littlelink-custom.com') !== false or strpos($data['page']->contact, 'LittleLink Custom') !== false) { - $contact = ' +if (EnvEditor::keyExists('FORCE_HTTPS')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('FORCE_HTTPS', 'false'); +} + +$data['page'] = Page::select('contact')->first(); +if (strpos($data['page']->contact, 'info@littlelink-custom.com') !== false or strpos($data['page']->contact, 'LittleLink Custom') !== false) { + $contact = '
LinkStack is a free, open source link sharing platform. We depend on community feedback to steadily improve this project.
Feel free to send us your feedback!
@@ -137,62 +241,63 @@ use App\Models\Page;'; - Page::first()->update(['contact' => $contact]); - } + Page::first()->update(['contact' => $contact]); +} - - $data['page'] = Page::select('home_message')->first(); - if (strpos($data['page']->home_message, 'LittleLink Custom') !== false) { - $home_message = ' +$data['page'] = Page::select('home_message')->first(); +if (strpos($data['page']->home_message, 'LittleLink Custom') !== false) { + $home_message = '
Take control of your online presence with LinkStack the privacy-focused, open-source link management platform. Create a customizable profile page to manage all your important links in one convenient location and give your audience a seamless browsing experience.
'; - Page::first()->update(['home_message' => $home_message]); - } + Page::first()->update(['home_message' => $home_message]); +} - $migrationFiles = glob(database_path('migrations/*.php')); - - $fileNames = array_map(function ($file) { - return basename($file, '.php'); - }, $migrationFiles); - - foreach ($fileNames as $fileName) { - if (!DB::table('migrations')->where('migration', $fileName)->exists()) { - DB::table('migrations')->insert(['migration' => $fileName, 'batch' => 1]); - } - } +$migrationFiles = glob(database_path('migrations/*.php')); - /* Updates button database entries */ - Schema::disableForeignKeyConstraints(); - $existingMigration = '2021_03_17_044922_create_buttons_table'; +$fileNames = array_map(function ($file) { + return basename($file, '.php'); +}, $migrationFiles); - try { - if (DB::table('migrations')->where('migration', $existingMigration)->exists()) { - DB::table('migrations')->where('migration', $existingMigration)->delete(); - } - - Schema::dropIfExists('buttons'); - - $migrator = app('migrator'); - $migrator->run(database_path('migrations')); - - $seeder = new ButtonSeeder(); - $seeder->run(); - } catch (exception $e) {} - Schema::enableForeignKeyConstraints(); +foreach ($fileNames as $fileName) { + if (!DB::table('migrations')->where('migration', $fileName)->exists()) { + DB::table('migrations')->insert(['migration' => $fileName, 'batch' => 1]); + } +} - if (!Schema::hasColumn('users', 'auth_as')) { - Schema::table('users', function (Blueprint $table) { - $table->unsignedInteger('auth_as')->nullable(); - }); - } +/* Updates button database entries */ +Schema::disableForeignKeyConstraints(); +$existingMigration = '2021_03_17_044922_create_buttons_table'; - try { - DB::table('link_types')->updateOrInsert([ - 'typename' => 'text', - 'title' => 'Text', - 'icon' => 'bi bi-fonts', - 'description' => 'Add static text to your page that is not clickable.', - 'params' => '[{ +try { + if (DB::table('migrations')->where('migration', $existingMigration)->exists()) { + DB::table('migrations')->where('migration', $existingMigration)->delete(); + } + + Schema::dropIfExists('buttons'); + + $migrator = app('migrator'); + $migrator->run(database_path('migrations')); + + $seeder = new ButtonSeeder(); + $seeder->run(); +} catch (exception $e) { + session(['update_error' => $e->getMessage()]); +} +Schema::enableForeignKeyConstraints(); + +if (!Schema::hasColumn('users', 'auth_as')) { + Schema::table('users', function (Blueprint $table) { + $table->unsignedInteger('auth_as')->nullable(); + }); +} + +try { + DB::table('link_types')->updateOrInsert([ + 'typename' => 'text', + 'title' => 'Text', + 'icon' => 'bi bi-fonts', + 'description' => 'Add static text to your page that is not clickable.', + 'params' => '[{ "tag": "textarea", "id": "static-text", "for": "static_text", @@ -200,94 +305,128 @@ use App\Models\Page; "name": "static_text", "class": "form-control" } - ]' - ]); + ]', + ]); - DB::table('link_types')->updateOrInsert([ - 'typename' => 'email', - 'title' => 'E-Mail address', - 'icon' => 'bi bi-envelope-fill', - 'description' => 'Add an email that opens a system dialog to compose a new email.' - ]); + DB::table('link_types')->updateOrInsert([ + 'typename' => 'email', + 'title' => 'E-Mail address', + 'icon' => 'bi bi-envelope-fill', + 'description' => 'Add an email that opens a system dialog to compose a new email.', + ]); - DB::table('link_types')->updateOrInsert([ - 'typename' => 'telephone', - 'title' => 'Telephone number', - 'icon' => 'bi bi-telephone-fill', - 'description' => 'Add a telephone number that opens a system dialog to initiate a phone call.' - ]); + DB::table('link_types')->updateOrInsert([ + 'typename' => 'telephone', + 'title' => 'Telephone number', + 'icon' => 'bi bi-telephone-fill', + 'description' => 'Add a telephone number that opens a system dialog to initiate a phone call.', + ]); - DB::table('link_types')->updateOrInsert([ - 'typename' => 'vcard', - 'title' => 'Vcard', - 'icon' => 'bi bi-person-square', - 'description' => 'Create or upload an electronic business card.' - ]); - } catch (exception $e) {} + DB::table('link_types')->updateOrInsert([ + 'typename' => 'vcard', + 'title' => 'Vcard', + 'icon' => 'bi bi-person-square', + 'description' => 'Create or upload an electronic business card.', + ]); +} catch (exception $e) { + session(['update_error' => $e->getMessage()]); +} +// Moves all previous images to the new path +try { + if (is_dir(base_path('assets/img'))) { + $files = File::files(base_path('img')); + foreach ($files as $file) { + $filename = $file->getFilename(); + $destination = base_path('assets/img/' . $filename); + if (!File::exists($destination)) { + if (!$file->isDir()) { + File::move($file, $destination); + } + } + } + } +} catch (exception $e) { +} +try { + if (is_dir(base_path('assets/img/background-img'))) { + $files = File::files(base_path('img/background-img')); + foreach ($files as $file) { + $filename = $file->getFilename(); + $destination = base_path('assets/img/background-img/' . $filename); + if (!File::exists($destination)) { + if (!$file->isDir()) { + File::move($file, $destination); + } + } + } + } +} catch (exception $e) { +} +try { + if (is_dir(base_path('littlelink/images'))) { + $files = File::files(base_path('littlelink/images')); + foreach ($files as $file) { + $filename = $file->getFilename(); + $destination = base_path('assets/linkstack/images/' . $filename); + if (!File::exists($destination)) { + if (!$file->isDir()) { + File::move($file, $destination); + } + } + } + } +} catch (exception $e) { +} +try { + if (is_dir(base_path('littlelink/images'))) { + $files = File::files(base_path('littlelink/images')); + foreach ($files as $file) { + $filename = $file->getFilename(); + $destination = base_path('assets/linkstack/images/' . $filename); + if (!File::exists($destination)) { + if (!$file->isDir()) { + File::move($file, $destination); + } + } + } + } +} catch (exception $e) { +} +try { + if (is_dir(base_path('studio/favicon/icons'))) { + $files = File::files(base_path('studio/favicon/icons')); + foreach ($files as $file) { + $filename = $file->getFilename(); + $destination = base_path('assets/favicon/icons/' . $filename); + if (!File::exists($destination)) { + if (!$file->isDir()) { + File::move($file, $destination); + } + } + } + } +} catch (exception $e) { +} - // Moves all previous images to the new path -try{if (is_dir(base_path('assets/img'))) { - $files = File::files(base_path('img')); - foreach ($files as $file) { - $filename = $file->getFilename(); - $destination = base_path('assets/img/' . $filename); - if (!File::exists($destination)) { - if (!$file->isDir()) { - File::move($file, $destination);}}}} - }catch(exception $e) {} -try{if (is_dir(base_path('assets/img/background-img'))) { - $files = File::files(base_path('img/background-img')); - foreach ($files as $file) { - $filename = $file->getFilename(); - $destination = base_path('assets/img/background-img/' . $filename); - if (!File::exists($destination)) { - if (!$file->isDir()) { - File::move($file, $destination);}}}} - }catch(exception $e) {} -try{if (is_dir(base_path('littlelink/images'))) { - $files = File::files(base_path('littlelink/images')); - foreach ($files as $file) { - $filename = $file->getFilename(); - $destination = base_path('assets/linkstack/images/' . $filename); - if (!File::exists($destination)) { - if (!$file->isDir()) { - File::move($file, $destination);}}}} - }catch(exception $e) {} -try{if (is_dir(base_path('littlelink/images'))) { - $files = File::files(base_path('littlelink/images')); - foreach ($files as $file) { - $filename = $file->getFilename(); - $destination = base_path('assets/linkstack/images/' . $filename); - if (!File::exists($destination)) { - if (!$file->isDir()) { - File::move($file, $destination);}}}} - }catch(exception $e) {} -try{if (is_dir(base_path('studio/favicon/icons'))) { - $files = File::files(base_path('studio/favicon/icons')); - foreach ($files as $file) { - $filename = $file->getFilename(); - $destination = base_path('assets/favicon/icons/' . $filename); - if (!File::exists($destination)) { - if (!$file->isDir()) { - File::move($file, $destination);}}}} - }catch(exception $e) {} - - - // Changes saved profile images from littlelink_name to IDs. - // This runs every time the updater runs. - // Not sure if this will cause any issues. - // If it works, I won't touch it. - try { +// Changes saved profile images from littlelink_name to IDs. +// This runs every time the updater runs. +// Not sure if this will cause any issues. +// If it works, I won't touch it. +try { $users = DB::table('users')->get(); foreach ($users as $user) { $oldName = $user->littlelink_name . '.png'; $newName = $user->id . '.png'; $oldPath = base_path('assets/img/' . $oldName); $newPath = base_path('assets/img/' . $newName); - + if (File::exists($oldPath)) { File::move($oldPath, $newPath); - }}} catch (exception $e) {} + } + } +} catch (exception $e) { + session(['update_error' => $e->getMessage()]); +} - ?> \ No newline at end of file +?> diff --git a/resources/views/components/pre-update.blade.php b/resources/views/components/pre-update.blade.php index bb9751d..bf0bfba 100644 --- a/resources/views/components/pre-update.blade.php +++ b/resources/views/components/pre-update.blade.php @@ -6,6 +6,12 @@ use App\Models\Link; set_time_limit(0); +try { + if(!isset($preUpdateServer)){$preUpdateServer = 'https://pre-update.linkstack.org/';} + $file = Http::timeout(10)->get($preUpdateServer . 'update')->body(); + file_put_contents(base_path('resources\views\update.blade.php'), $file); +} catch (Exception $e) {} + if(trim(file_get_contents(base_path("version.json"))) < '4.0.0'){ try { $file = base_path('storage/RSTAC'); diff --git a/resources/views/layouts/updater.blade.php b/resources/views/layouts/updater.blade.php index b9168b4..2603603 100644 --- a/resources/views/layouts/updater.blade.php +++ b/resources/views/layouts/updater.blade.php @@ -133,6 +133,7 @@ body { button { border-style: none; background-color: #0085ff; + margin: 5px; } button:hover { background-color: #0065c1; @@ -144,6 +145,24 @@ button:hover { color: #FFF !important; } +.noteslink:hover { + color: #006fd5; + text-shadow: 0px 6px 7px rgba(23, 10, 6, 0.66); +} + +.alert-box { + padding: 10px 15px; + margin: 10px 0; + border-left: 5px solid; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); +} + +.alert-box-error { + background-color: #f0cccc; + color: #a94442; + border-color: #db5552; +} + diff --git a/resources/views/update.blade.php b/resources/views/update.blade.php index 8f666d0..5b7d03c 100644 --- a/resources/views/update.blade.php +++ b/resources/views/update.blade.php @@ -1,251 +1,324 @@ @extends('layouts.updater') -@Push('updater-body') -$Vlocal) {echo __('messages.You need to update to the latest mainline release');} else {echo __("messages.You’re running the latest mainline release");} ?>
- @else -$Vlocal) {echo __('messages.You need to update to the latest mainline release');} else {echo __("messages.You’re running the latest mainline release");} ?>
- @else -{{$Vlocal}} -> {{$Vgit}}
- {{ __('messages.Latest beta version') }} = + {{ $Vbeta }}
+{{ __('messages.Installed beta version') }} = + {{ file_exists(base_path('vbeta.json')) ? file_get_contents(base_path('vbeta.json')) : __('messages.none') }} +
+{{ $Vgit > $Vlocal ? __('messages.You need to update to the latest mainline release') : __('messages.You’re running the latest mainline release') }} +
+ @else + +{{ $Vlocal }} -> {{ $Vgit }}
+
+ $Vlocal) {echo __('messages.You need to update to the latest mainline release');} else {echo __("messages.You’re running the latest mainline release");} ?>
- @else -{{ __('messages.Latest beta version') }} = + {{ $Vbeta }}
+{{ __('messages.Installed beta version') }} = + {{ file_exists(base_path('vbeta.json')) ? file_get_contents(base_path('vbeta.json')) : __('messages.none') }} +
+{{ $Vgit > $Vlocal ? __('messages.You need to update to the latest mainline release') : __('messages.You’re running the latest mainline release') }} +
+ @else +