mirror of
https://github.com/Kovah/LinkAce.git
synced 2025-01-16 20:58:22 +01:00
Merge branch 'main' into dev-v2
# Conflicts: # .github/workflows/build-docker.yml # app/Actions/ImportHtmlBookmarks.php # app/Helper/functions.php # app/Http/Controllers/Guest/LinkController.php # app/Http/Controllers/Guest/ListController.php # app/Http/Controllers/Guest/TagController.php # app/Http/Controllers/Models/LinkController.php # app/Http/Controllers/Models/ListController.php # app/Http/Controllers/Models/TagController.php # app/Http/Controllers/Traits/SearchesLinks.php # app/Http/Middleware/TrustProxies.php # composer.json # composer.lock # config/app.php # resources/views/partials/configure-darkmode.blade.php # tests/Controller/Models/LinkControllerTest.php # tests/Controller/Models/ListControllerTest.php # tests/Controller/Models/TagControllerTest.php
This commit is contained in:
commit
c084752b95
6
.codeclimate.yml
Normal file
6
.codeclimate.yml
Normal file
@ -0,0 +1,6 @@
|
||||
engines:
|
||||
sonar-php:
|
||||
enabled: true
|
||||
checks:
|
||||
php:S1192:
|
||||
enabled: false
|
@ -14,7 +14,7 @@ APP_DEBUG=true
|
||||
|
||||
## Configuration of the database connection
|
||||
## Attention: Those settings are configured during the web setup, please do not modify them now.
|
||||
# Set the database driver (mysql, pgsql, sqlsrv)
|
||||
# Set the database driver (mysql, pgsql, sqlsrv, sqlite)
|
||||
DB_CONNECTION=mysql
|
||||
# Set the host of your database here
|
||||
DB_HOST=db
|
||||
|
@ -10,7 +10,7 @@ APP_KEY=someRandomStringWith32Characters
|
||||
|
||||
## Configuration of the database connection
|
||||
## Attention: Those settings are configured during the web setup, please do not modify them now.
|
||||
# Set the database driver (mysql, pgsql, sqlsrv)
|
||||
# Set the database driver (mysql, pgsql, sqlsrv, sqlite)
|
||||
DB_CONNECTION=mysql
|
||||
# Set the host of your database here
|
||||
DB_HOST=db
|
||||
|
@ -6,7 +6,7 @@ APP_KEY=someRandomStringWith32Characters
|
||||
|
||||
## Configuration of the database connection
|
||||
## Attention: Those settings are configured during the web setup, please do not modify them now.
|
||||
# Set the database driver (mysql, pgsql, sqlsrv)
|
||||
# Set the database driver (mysql, pgsql, sqlsrv, sqlite)
|
||||
DB_CONNECTION=mysql
|
||||
# Set the host of your database here
|
||||
DB_HOST=127.0.0.1
|
||||
|
6
.github/workflows/analyze.yml
vendored
6
.github/workflows/analyze.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Use Node.js 18.x
|
||||
uses: actions/setup-node@v2
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
@ -50,7 +50,7 @@ jobs:
|
||||
run: composer install --prefer-dist --no-progress --no-suggest
|
||||
|
||||
- name: Test & publish code coverage
|
||||
uses: paambaati/codeclimate-action@v2.6.0
|
||||
uses: paambaati/codeclimate-action@v3.2.0
|
||||
env:
|
||||
CC_TEST_REPORTER_ID: ${{secrets.CC_TEST_REPORTER_ID}}
|
||||
with:
|
||||
|
18
.github/workflows/build-docker.yml
vendored
18
.github/workflows/build-docker.yml
vendored
@ -26,6 +26,22 @@ jobs:
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_TOKEN }}
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Prepare tags
|
||||
id: prep
|
||||
run: |
|
||||
DOCKER_IMAGE=linkace/linkace
|
||||
DOCKER_IMAGE_GITUHB=ghcr.io/kovah/linkace
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
TAGS="${DOCKER_IMAGE}:${VERSION},${DOCKER_IMAGE}:latest,${DOCKER_IMAGE_GITUHB}:${VERSION},${DOCKER_IMAGE_GITUHB}:latest"
|
||||
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build and push advanced image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
@ -42,7 +58,7 @@ jobs:
|
||||
DOCKER_IMAGE_GITHUB=ghcr.io/kovah/linkace
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
TAGS="${DOCKER_IMAGE}:${VERSION}-php-nginx,${DOCKER_IMAGE}:php-nginx,${DOCKER_IMAGE}:${VERSION}-simple,${DOCKER_IMAGE}:simple,${DOCKER_IMAGE_GITHUB}:${VERSION}-php-nginx,${DOCKER_IMAGE_GITHUB}:php-nginx,${DOCKER_IMAGE_GITHUB}:${VERSION}-simple,${DOCKER_IMAGE_GITHUB}:simple"
|
||||
echo ::set-output name=tags::${TAGS}
|
||||
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build and push simple image
|
||||
uses: docker/build-push-action@v5
|
||||
|
16
.github/workflows/build-package.yml
vendored
16
.github/workflows/build-package.yml
vendored
@ -29,13 +29,13 @@ jobs:
|
||||
npm run production
|
||||
|
||||
- name: Upload built assets
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: assets
|
||||
path: public/assets/dist
|
||||
|
||||
- name: Upload mix manifest
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: mix-manifest
|
||||
path: public/mix-manifest.json
|
||||
@ -47,12 +47,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: assets
|
||||
path: public/assets/dist
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: mix-manifest
|
||||
path: public
|
||||
@ -65,7 +65,7 @@ jobs:
|
||||
- id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- uses: actions/cache@v1
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
@ -91,7 +91,7 @@ jobs:
|
||||
filename: linkace.zip
|
||||
exclusions: '*.git*'
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: linkace-package
|
||||
path: linkace.zip
|
||||
@ -112,7 +112,7 @@ jobs:
|
||||
with:
|
||||
args: zip -qq linkace-package-docker-simple.zip docker-compose.yml .env LICENSE.md README.md
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: linkace-package-docker-simple
|
||||
path: linkace-package-docker-simple.zip
|
||||
@ -124,7 +124,7 @@ jobs:
|
||||
with:
|
||||
args: zip -qq linkace-package-docker-advanced.zip docker-compose.yml .env nginx.conf nginx-ssl.conf LICENSE.md README.md
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: linkace-package-docker-advanced
|
||||
path: linkace-package-docker-advanced.zip
|
||||
|
18
.github/workflows/test.yml
vendored
18
.github/workflows/test.yml
vendored
@ -10,10 +10,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Use Node.js 18 LTS
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
@ -23,13 +23,13 @@ jobs:
|
||||
npm run production
|
||||
|
||||
- name: Upload built assets
|
||||
uses: actions/upload-artifact@v1
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: assets
|
||||
path: public/assets/dist
|
||||
|
||||
- name: Upload mix manifest
|
||||
uses: actions/upload-artifact@v1
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: mix-manifest
|
||||
path: public/mix-manifest.json
|
||||
@ -47,12 +47,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/download-artifact@v1
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: assets
|
||||
path: public/assets/dist
|
||||
|
||||
- uses: actions/download-artifact@v1
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: mix-manifest
|
||||
path: public
|
||||
@ -68,7 +68,7 @@ jobs:
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
@ -89,13 +89,13 @@ jobs:
|
||||
- name: Run PHPunit
|
||||
run: composer run test
|
||||
|
||||
- uses: actions/upload-artifact@v1
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: application-logs
|
||||
path: storage/logs
|
||||
|
||||
- uses: actions/upload-artifact@v1
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: application-public
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -16,6 +16,10 @@ Homestead.yaml
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
.env
|
||||
.env.*
|
||||
!.env.docker
|
||||
!.env.docker.production
|
||||
!.env.example
|
||||
.phpunit.result.cache
|
||||
_ide_helper.php
|
||||
_ide_helper_models.php
|
||||
|
@ -17,10 +17,7 @@ class ImportHtmlBookmarks
|
||||
|
||||
public function run(string $data, string $userId, bool $generateMeta = true): bool
|
||||
{
|
||||
$parser = new NetscapeBookmarkParser(
|
||||
defaultPub: usersettings('links_private_default'),
|
||||
logDir: storage_path('logs')
|
||||
);
|
||||
$parser = new NetscapeBookmarkParser(logger: Log::channel('import'));
|
||||
|
||||
try {
|
||||
$links = $parser->parseString($data);
|
||||
@ -30,29 +27,30 @@ class ImportHtmlBookmarks
|
||||
}
|
||||
|
||||
foreach ($links as $link) {
|
||||
if (Link::whereUrl($link['uri'])->first()) {
|
||||
if (Link::whereUrl($link['url'])->first()) {
|
||||
$this->skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($generateMeta) {
|
||||
$linkMeta = (new HtmlMeta)->getFromUrl($link['uri']);
|
||||
$title = $link['title'] ?: $linkMeta['title'];
|
||||
$description = $link['note'] ?: $linkMeta['description'];
|
||||
$linkMeta = (new HtmlMeta)->getFromUrl($link['url']);
|
||||
$title = $link['name'] ?: $linkMeta['title'];
|
||||
$description = $link['description'] ?: $linkMeta['description'];
|
||||
} else {
|
||||
$title = $link['title'];
|
||||
$description = $link['note'];
|
||||
$title = $link['name'];
|
||||
$description = $link['description'];
|
||||
}
|
||||
|
||||
$isPublic = $link['public'] ?? true;
|
||||
$newLink = new Link([
|
||||
'user_id' => $userId,
|
||||
'url' => $link['uri'],
|
||||
'url' => $link['url'],
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'icon' => LinkIconMapper::getIconForUrl($link['uri']),
|
||||
'is_private' => $link['pub']
|
||||
'is_private' => usersettings('tags_private_default') === '1' ? true : $isPublic,
|
||||
]);
|
||||
$newLink->created_at = Carbon::createFromTimestamp($link['time']);
|
||||
$newLink->created_at = Carbon::createFromTimestamp($link['dateCreated']);
|
||||
$newLink->updated_at = Carbon::now();
|
||||
$newLink->timestamps = false;
|
||||
$newLink->save();
|
||||
|
@ -72,7 +72,7 @@ class HtmlMeta
|
||||
$this->fallback = [
|
||||
'success' => false,
|
||||
'title' => parse_url($this->url, PHP_URL_HOST) ?? $this->url,
|
||||
'description' => false,
|
||||
'description' => null,
|
||||
'thumbnail' => null,
|
||||
];
|
||||
}
|
||||
|
@ -261,3 +261,13 @@ function bookmarkletUrl(): string
|
||||
|
||||
return str_replace('##URL##', route('bookmarklet-add'), $bmCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all routes that are accessible by guests.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
function guestRoutes(): array
|
||||
{
|
||||
return ['guest/*', 'login', 'forgot-password', 'reset-password/*', 'two-factor-challenge', 'email/verify'];
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ class SearchController extends Controller
|
||||
'only_lists' => '',
|
||||
'only_tags' => '',
|
||||
'order_by' => $this->orderByOptions[0],
|
||||
'performed_search' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
@ -49,6 +50,7 @@ class SearchController extends Controller
|
||||
'empty_tags' => $this->emptyTags,
|
||||
'empty_lists' => $this->emptyLists,
|
||||
'order_by' => $this->searchOrderBy,
|
||||
'performed_search' => true,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -3,24 +3,35 @@
|
||||
namespace App\Http\Controllers\Guest;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\Traits\HandlesQueryOrder;
|
||||
use App\Models\Link;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class LinkController extends Controller
|
||||
{
|
||||
use HandlesQueryOrder;
|
||||
|
||||
/**
|
||||
* Display an overview of all links.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return View
|
||||
*/
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$links = Link::publicOnly()
|
||||
->with(['tags' => fn ($query) => $query->publicOnly()])
|
||||
->orderBy(
|
||||
$request->input('orderBy', 'created_at'),
|
||||
$request->input('orderDir', 'desc')
|
||||
)
|
||||
->paginate(getPaginationLimit());
|
||||
$links = Link::publicOnly()->with(['tags' => fn ($query) => $query->publicOnly()]);
|
||||
|
||||
$orderBy = $request->input('orderBy', 'created_at');
|
||||
$orderDir = $this->getOrderDirection($request);
|
||||
if ($orderBy === 'random') {
|
||||
$links->inRandomOrder();
|
||||
} else {
|
||||
$links->orderBy($orderBy, $orderDir);
|
||||
}
|
||||
|
||||
return view('guest.links.index', [
|
||||
'links' => $links,
|
||||
'links' => $links->paginate(getPaginationLimit()),
|
||||
'route' => $request->getBaseUrl(),
|
||||
'orderBy' => $request->input('orderBy', 'created_at'),
|
||||
'orderDir' => $request->input('orderDir', 'desc'),
|
||||
|
@ -3,26 +3,29 @@
|
||||
namespace App\Http\Controllers\Guest;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\Traits\HandlesQueryOrder;
|
||||
use App\Models\LinkList;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ListController extends Controller
|
||||
{
|
||||
use HandlesQueryOrder;
|
||||
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$lists = LinkList::publicOnly()
|
||||
->withCount(['links' => fn ($query) => $query->publicOnly()])
|
||||
->orderBy(
|
||||
$request->input('orderBy', 'name'),
|
||||
$request->input('orderDir', 'asc')
|
||||
$this->getOrderDirection($request, 'asc')
|
||||
)
|
||||
->paginate(getPaginationLimit());
|
||||
|
||||
return view('guest.lists.index', [
|
||||
'lists' => $lists,
|
||||
'orderBy' => $request->input('orderBy', 'name'),
|
||||
'orderDir' => $request->input('orderDir', 'asc'),
|
||||
'orderDir' => $this->getOrderDirection($request, 'asc'),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -34,7 +37,7 @@ class ListController extends Controller
|
||||
->publicOnly()
|
||||
->orderBy(
|
||||
$request->input('orderBy', 'title'),
|
||||
$request->input('orderDir', 'asc')
|
||||
$this->getOrderDirection($request, 'asc')
|
||||
)->paginate(getPaginationLimit());
|
||||
|
||||
return view('guest.lists.show', [
|
||||
@ -42,7 +45,7 @@ class ListController extends Controller
|
||||
'listLinks' => $links,
|
||||
'route' => $request->getBaseUrl(),
|
||||
'orderBy' => $request->input('orderBy', 'title'),
|
||||
'orderDir' => $request->input('orderDir', 'asc'),
|
||||
'orderDir' => $this->getOrderDirection($request, 'asc'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -3,19 +3,22 @@
|
||||
namespace App\Http\Controllers\Guest;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\Traits\HandlesQueryOrder;
|
||||
use App\Models\Tag;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TagController extends Controller
|
||||
{
|
||||
use HandlesQueryOrder;
|
||||
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$tags = Tag::publicOnly()
|
||||
->withCount(['links' => fn ($query) => $query->publicOnly()])
|
||||
->orderBy(
|
||||
$request->input('orderBy', 'name'),
|
||||
$request->input('orderDir', 'asc')
|
||||
$this->getOrderDirection($request, 'asc')
|
||||
)
|
||||
->paginate(getPaginationLimit());
|
||||
|
||||
@ -23,7 +26,7 @@ class TagController extends Controller
|
||||
'tags' => $tags,
|
||||
'route' => $request->getBaseUrl(),
|
||||
'orderBy' => $request->input('orderBy', 'name'),
|
||||
'orderDir' => $request->input('orderDir', 'asc'),
|
||||
'orderDir' => $this->getOrderDirection($request, 'asc'),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -4,9 +4,9 @@ namespace App\Http\Controllers\Models;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\Traits\ChecksOrdering;
|
||||
use App\Http\Controllers\Traits\HandlesQueryOrder;
|
||||
use App\Http\Requests\Models\LinkStoreRequest;
|
||||
use App\Http\Requests\Models\LinkUpdateRequest;
|
||||
use App\Http\Requests\Models\MarkLinkWorkingRequest;
|
||||
use App\Http\Requests\Models\ToggleLinkCheckRequest;
|
||||
use App\Models\Link;
|
||||
use App\Repositories\LinkRepository;
|
||||
@ -17,6 +17,7 @@ use Illuminate\Http\Request;
|
||||
class LinkController extends Controller
|
||||
{
|
||||
use ChecksOrdering;
|
||||
use HandlesQueryOrder;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@ -26,8 +27,8 @@ class LinkController extends Controller
|
||||
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$this->orderBy = $request->input('orderBy', session()->get('links.index.orderBy', 'created_at'));
|
||||
$this->orderDir = $request->input('orderDir', session()->get('links.index.orderDir', 'desc'));
|
||||
$orderBy = $request->input('orderBy', session()->get('links.index.orderBy', 'created_at'));
|
||||
$orderDir = $this->getOrderDirection($request, session()->get('links.index.orderDir', 'desc'));
|
||||
|
||||
$this->checkOrdering();
|
||||
|
||||
@ -36,12 +37,16 @@ class LinkController extends Controller
|
||||
|
||||
$links = Link::query()
|
||||
->visibleForUser()
|
||||
->with('tags')
|
||||
->orderBy($this->orderBy, $this->orderDir)
|
||||
->paginate(getPaginationLimit());
|
||||
->with('tags');
|
||||
|
||||
if ($orderBy === 'random') {
|
||||
$links->inRandomOrder();
|
||||
} else {
|
||||
$links->orderBy($orderBy, $orderDir);
|
||||
}
|
||||
|
||||
return view('models.links.index', [
|
||||
'links' => $links,
|
||||
'links' => $links->paginate(getPaginationLimit()),
|
||||
'route' => $request->getBaseUrl(),
|
||||
'orderBy' => $this->orderBy,
|
||||
'orderDir' => $this->orderDir,
|
||||
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers\Models;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\Traits\ChecksOrdering;
|
||||
use App\Http\Controllers\Traits\HandlesQueryOrder;
|
||||
use App\Http\Requests\Models\ListStoreRequest;
|
||||
use App\Http\Requests\Models\ListUpdateRequest;
|
||||
use App\Models\LinkList;
|
||||
@ -15,6 +16,7 @@ use Illuminate\Http\Request;
|
||||
class ListController extends Controller
|
||||
{
|
||||
use ChecksOrdering;
|
||||
use HandlesQueryOrder;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@ -24,13 +26,12 @@ class ListController extends Controller
|
||||
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$this->orderBy = $request->input('orderBy', session()->get('lists.index.orderBy', 'name'));
|
||||
$this->orderDir = $request->input('orderDir', session()->get('lists.index.orderDir', 'asc'));
|
||||
|
||||
$orderBy = $request->input('orderBy', session()->get('lists.index.orderBy', 'name'));
|
||||
$orderDir = $this->getOrderDirection($request, session()->get('lists.index.orderDir', 'asc'));
|
||||
$this->checkOrdering();
|
||||
|
||||
session()->put('lists.index.orderBy', $this->orderBy);
|
||||
session()->put('lists.index.orderDir', $this->orderDir);
|
||||
session()->put('lists.index.orderBy', $orderBy);
|
||||
session()->put('lists.index.orderDir', $orderDir);
|
||||
|
||||
$lists = LinkList::query()
|
||||
->visibleForUser()
|
||||
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers\Models;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\Traits\ChecksOrdering;
|
||||
use App\Http\Controllers\Traits\HandlesQueryOrder;
|
||||
use App\Http\Requests\Models\TagStoreRequest;
|
||||
use App\Http\Requests\Models\TagUpdateRequest;
|
||||
use App\Models\Link;
|
||||
@ -26,8 +27,8 @@ class TagController extends Controller
|
||||
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$this->orderBy = $request->input('orderBy', session()->get('tags.index.orderBy', 'name'));
|
||||
$this->orderDir = $request->input('orderDir', session()->get('tags.index.orderDir', 'asc'));
|
||||
$orderBy = $request->input('orderBy', session()->get('tags.index.orderBy', 'name'));
|
||||
$orderDir = $this->getOrderDirection($request, session()->get('tags.index.orderDir', 'asc'));
|
||||
|
||||
$this->checkOrdering();
|
||||
|
||||
@ -76,7 +77,7 @@ class TagController extends Controller
|
||||
{
|
||||
$this->allowedOrderBy = Link::$allowOrderBy;
|
||||
$this->orderBy = $request->input('orderBy', 'created_at');
|
||||
$this->orderDir = $request->input('orderDir', 'desc');
|
||||
$this->orderDir = $this->getOrderDirection($request);
|
||||
|
||||
$this->checkOrdering();
|
||||
|
||||
@ -90,7 +91,7 @@ class TagController extends Controller
|
||||
'tagLinks' => $links,
|
||||
'route' => $request->getBaseUrl(),
|
||||
'orderBy' => $request->input('orderBy', 'created_at'),
|
||||
'orderDir' => $request->input('orderDir', 'desc'),
|
||||
'orderDir' => $this->getOrderDirection($request),
|
||||
]);
|
||||
}
|
||||
|
||||
|
14
app/Http/Controllers/Traits/HandlesQueryOrder.php
Normal file
14
app/Http/Controllers/Traits/HandlesQueryOrder.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Traits;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
trait HandlesQueryOrder
|
||||
{
|
||||
protected function getOrderDirection(Request $request, $default = 'desc'): string
|
||||
{
|
||||
$dir = $request->input('orderDir');
|
||||
return in_array($dir, ['asc', 'desc']) ? $dir : $default;
|
||||
}
|
||||
}
|
@ -90,8 +90,12 @@ trait SearchesLinks
|
||||
|
||||
// Order the results if applicable and only allow predefined ordering
|
||||
if ($this->searchOrderBy = $request->input('order_by')) {
|
||||
$this->searchOrderBy = in_array($this->searchOrderBy, $this->orderByOptions)
|
||||
? $this->searchOrderBy : $this->orderByOptions[0];
|
||||
if ($this->searchOrderBy === 'random') {
|
||||
$search->inRandomOrder();
|
||||
} else {
|
||||
$this->searchOrderBy = in_array($this->searchOrderBy, $this->orderByOptions)
|
||||
? $this->searchOrderBy : $this->orderByOptions[0];
|
||||
}
|
||||
$search->orderBy(...explode(':', $this->searchOrderBy));
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Contracts\Config\Repository;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
@ -12,7 +13,12 @@ class TrustProxies extends Middleware
|
||||
*
|
||||
* @var array<int, string>|string|null
|
||||
*/
|
||||
protected $proxies = '*';
|
||||
protected $proxies = null;
|
||||
|
||||
public function __construct(Repository $config)
|
||||
{
|
||||
$this->proxies = config('app.trusted_proxies');
|
||||
}
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
|
@ -194,6 +194,11 @@ class LinkRepository
|
||||
{
|
||||
$newEntries = collect();
|
||||
|
||||
$privateSetting = match ($model) {
|
||||
Tag::class => usersettings('tags_private_default') === '1',
|
||||
LinkList::class => usersettings('lists_private_default') === '1',
|
||||
};
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
if ((int)$entry > 0) {
|
||||
$newEntry = $model::find($entry);
|
||||
@ -201,6 +206,10 @@ class LinkRepository
|
||||
$newEntry = $model::firstOrCreate([
|
||||
'user_id' => auth()->id(),
|
||||
'name' => trim($entry),
|
||||
], [
|
||||
'user_id' => auth()->id(),
|
||||
'name' => trim($entry),
|
||||
'is_private' => $privateSetting,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,7 @@ return [
|
||||
'it_IT' => 'Italiano',
|
||||
'no_NO' => 'Norsk',
|
||||
'pl_PL' => 'Polski',
|
||||
'ro_RO' => 'Română',
|
||||
'vi_VN' => 'Tiếng Việt',
|
||||
'zh_CN' => '简体中文',
|
||||
],
|
||||
@ -140,6 +141,19 @@ return [
|
||||
|
||||
'guest_access' => (bool)env('GUEST_ACCESS', false),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Trusted Proxies
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Specify which proxies should be trusted by default. As it's unknown which
|
||||
| proxy ist used in front of LinkAce, all are allowed by default.
|
||||
| Also see App\Http\Middleware\TrustProxies
|
||||
|
|
||||
*/
|
||||
|
||||
'trusted_proxies' => env('TRUSTED_PROXIES', '*'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Encryption Key
|
||||
|
@ -15,7 +15,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'driver' => 'bcrypt',
|
||||
'driver' => env('HASHING_DRIVER', 'bcrypt'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@ -29,7 +29,7 @@ return [
|
||||
*/
|
||||
|
||||
'bcrypt' => [
|
||||
'rounds' => env('BCRYPT_ROUNDS', 10),
|
||||
'rounds' => env('BCRYPT_ROUNDS', 12),
|
||||
],
|
||||
|
||||
/*
|
||||
|
@ -67,6 +67,12 @@ return [
|
||||
'days' => 14,
|
||||
],
|
||||
|
||||
'import' => [
|
||||
'driver' => 'single',
|
||||
'path' => storage_path('logs/import.log'),
|
||||
'level' => 'debug',
|
||||
],
|
||||
|
||||
'slack' => [
|
||||
'driver' => 'slack',
|
||||
'url' => env('LOG_SLACK_WEBHOOK_URL'),
|
||||
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'password' => 'Les contrasenyes han de tenir com a mínim sis caràcters i han de coincidir amb la confirmació.',
|
||||
'reset' => 'La contrasenya s\'ha restablert!',
|
||||
'sent' => 'T\'hem enviat un correu electrònic amb un enllaç per a reiniciar la teva contrasenya!',
|
||||
'sent' => 'Si existeix un compte amb la vostra adreça de correu electrònic, hem enviat per correu electrònic l\'enllaç de restabliment de la contrasenya.',
|
||||
'token' => 'Aquest codi de recuperació de contrasenya és invàlid.',
|
||||
'user' => "No hi ha cap usuari amb aquest correu.",
|
||||
|
||||
|
@ -14,14 +14,15 @@ return [
|
||||
'empty_lists' => 'sense Llistes',
|
||||
|
||||
'order_by' => 'Ordenar per',
|
||||
'order_by.title:asc' => 'Títol ascendent',
|
||||
'order_by.title:desc' => 'Títol descendent',
|
||||
'order_by.url:asc' => 'URL ascendent',
|
||||
'order_by.url:desc' => 'URL descendent',
|
||||
'order_by.created_at:asc' => 'Data de creació ascendent',
|
||||
'order_by.created_at:desc' => 'Data de creació descendent',
|
||||
'order_by.number_links:asc' => 'Nombre d\'enllaços ascendent',
|
||||
'order_by.number_links:desc' => 'Nombre d\'enllaços descendent',
|
||||
'order_by.title:asc' => 'Títol A-Z',
|
||||
'order_by.title:desc' => 'Títol Z-A',
|
||||
'order_by.url:asc' => 'URL A-Z',
|
||||
'order_by.url:desc' => 'URL Z-A',
|
||||
'order_by.created_at:asc' => 'Més antigues',
|
||||
'order_by.created_at:desc' => 'Més recents',
|
||||
'order_by.number_links:asc' => 'Menys enllaços',
|
||||
'order_by.number_links:desc' => 'La majoria d\'enllaços',
|
||||
'order_by.random' => 'Aleatori',
|
||||
|
||||
'no_results' => 'No s\'han trobat resultats.',
|
||||
|
||||
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'password' => 'Passwörter müssen mindestens sechs Zeichen lang sein und übereinstimmen.',
|
||||
'reset' => 'Ihr Passwort wurde zurückgesetzt!',
|
||||
'sent' => 'Wir haben Ihren Link zum Zurücksetzen des Passworts per E-Mail gesendet!',
|
||||
'sent' => 'Falls ein Konto mit der angegebenen E-Mail-Adresse existiert, wurde ein Link zum Zurücksetzen des Passworts per E-Mail verschickt.',
|
||||
'token' => 'Das Passwort Reset Token ist ungültig.',
|
||||
'user' => "Wir konnten keinen Benutzer mit dieser E-Mail-Adresse finden.",
|
||||
|
||||
|
@ -14,14 +14,15 @@ return [
|
||||
'empty_lists' => 'ohne Listen',
|
||||
|
||||
'order_by' => 'Sortieren nach',
|
||||
'order_by.title:asc' => 'Titel aufsteigend',
|
||||
'order_by.title:desc' => 'Titel absteigend',
|
||||
'order_by.url:asc' => 'URL aufsteigend',
|
||||
'order_by.url:desc' => 'URL absteigend',
|
||||
'order_by.created_at:asc' => 'Erstellungsdatum aufsteigend',
|
||||
'order_by.created_at:desc' => 'Erstellungsdatum absteigend',
|
||||
'order_by.number_links:asc' => 'Anzahl der Links aufsteigend',
|
||||
'order_by.number_links:desc' => 'Anzahl der Links absteigend',
|
||||
'order_by.title:asc' => 'Titel A-Z',
|
||||
'order_by.title:desc' => 'Title Z-A',
|
||||
'order_by.url:asc' => 'URL A-Z',
|
||||
'order_by.url:desc' => 'URL Z-A',
|
||||
'order_by.created_at:asc' => 'Älteste',
|
||||
'order_by.created_at:desc' => 'Neueste',
|
||||
'order_by.number_links:asc' => 'Wenigste Links',
|
||||
'order_by.number_links:desc' => 'Meiste Links',
|
||||
'order_by.random' => 'Zufällig',
|
||||
|
||||
'no_results' => 'Keine Ergebnisse gefunden.',
|
||||
|
||||
|
@ -14,14 +14,15 @@ return [
|
||||
'empty_lists' => 'without Lists',
|
||||
|
||||
'order_by' => 'Order by',
|
||||
'order_by.title:asc' => 'Title ascending',
|
||||
'order_by.title:desc' => 'Title descending',
|
||||
'order_by.url:asc' => 'URL ascending',
|
||||
'order_by.url:desc' => 'URL descending',
|
||||
'order_by.created_at:asc' => 'Creation Date ascending',
|
||||
'order_by.created_at:desc' => 'Creation Date descending',
|
||||
'order_by.number_links:asc' => 'Number of Links ascending',
|
||||
'order_by.number_links:desc' => 'Number of Links descending',
|
||||
'order_by.title:asc' => 'Title A-Z',
|
||||
'order_by.title:desc' => 'Title Z-A',
|
||||
'order_by.url:asc' => 'URL A-Z',
|
||||
'order_by.url:desc' => 'URL Z-A',
|
||||
'order_by.created_at:asc' => 'Oldest',
|
||||
'order_by.created_at:desc' => 'Newest',
|
||||
'order_by.number_links:asc' => 'Fewest Links',
|
||||
'order_by.number_links:desc' => 'Most Links',
|
||||
'order_by.random' => 'Random',
|
||||
|
||||
'no_results' => 'No results found.',
|
||||
|
||||
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'password' => 'Las contraseñas deben tener al menos seis caracteres y coincidir con la confirmación.',
|
||||
'reset' => '¡Tu contraseña ha sido restablecida!',
|
||||
'sent' => '¡Hemos enviado un correo electrónico a tu email para restablecer la contraseña!',
|
||||
'sent' => 'Si existe una cuenta con su dirección de correo electrónico, hemos enviado un correo electrónico a su enlace de restablecimiento de contraseña.',
|
||||
'token' => 'Este token de restablecimiento de contraseña no es válido.',
|
||||
'user' => "No podemos encontrar un usuario con esa dirección de correo electrónico.",
|
||||
|
||||
|
@ -14,14 +14,15 @@ return [
|
||||
'empty_lists' => 'sin listas',
|
||||
|
||||
'order_by' => 'Ordenar por',
|
||||
'order_by.title:asc' => 'Título ascendente',
|
||||
'order_by.title:desc' => 'Título descendente',
|
||||
'order_by.url:asc' => 'URL ascendente',
|
||||
'order_by.url:desc' => 'URL descendente',
|
||||
'order_by.created_at:asc' => 'Fecha de creación ascendente',
|
||||
'order_by.created_at:desc' => 'Fecha de creación descendente',
|
||||
'order_by.number_links:asc' => 'Número de enlaces ascendentes',
|
||||
'order_by.number_links:desc' => 'Número de enlaces descendente',
|
||||
'order_by.title:asc' => 'Título A-Z',
|
||||
'order_by.title:desc' => 'Título Z-A',
|
||||
'order_by.url:asc' => 'URL A-Z',
|
||||
'order_by.url:desc' => 'URL Z-A',
|
||||
'order_by.created_at:asc' => 'Más antiguos',
|
||||
'order_by.created_at:desc' => 'Más recientes',
|
||||
'order_by.number_links:asc' => 'Menos enlaces',
|
||||
'order_by.number_links:desc' => 'Más enlaces',
|
||||
'order_by.random' => 'Aleatorio',
|
||||
|
||||
'no_results' => 'No se han encontrado resultados.',
|
||||
|
||||
|
@ -30,7 +30,7 @@ return [
|
||||
'delete' => 'Supprimer',
|
||||
|
||||
'menu' => 'Menu',
|
||||
'entries' => 'Éntrées',
|
||||
'entries' => 'Entrées',
|
||||
'feed' => 'Feed',
|
||||
|
||||
'continue_adding' => 'Continuer l\'Ajout',
|
||||
|
@ -3,7 +3,7 @@ return [
|
||||
'list' => 'Liste',
|
||||
'lists' => 'Listes',
|
||||
'all_lists' => 'Toutes les Listes',
|
||||
'recent_lists' => 'Liens Récents',
|
||||
'recent_lists' => 'Listes Récentes',
|
||||
|
||||
'add' => 'Ajouter Liste',
|
||||
'show' => 'Afficher Liste',
|
||||
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'password' => 'Les mots de passe doivent comporter au moins six caractères et correspondre à la confirmation.',
|
||||
'reset' => 'Votre mot de passe a été réinitialisé !',
|
||||
'sent' => 'Nous avons envoyé votre lien de réinitialisation de mot de passe !',
|
||||
'sent' => 'Si un compte avec cette adresse e-mail existe, nous avons envoyé votre lien de réinitialisation de mot de passe.',
|
||||
'token' => 'Ce jeton de réinitialisation de mot de passe est invalide.',
|
||||
'user' => "Nous ne trouvons pas d'utilisateur avec cette adresse e-mail.",
|
||||
|
||||
|
@ -14,14 +14,15 @@ return [
|
||||
'empty_lists' => 'sans listes',
|
||||
|
||||
'order_by' => 'Trier par',
|
||||
'order_by.title:asc' => 'Titre ascendant',
|
||||
'order_by.title:desc' => 'Titre descendant',
|
||||
'order_by.url:asc' => 'URL ascendante',
|
||||
'order_by.url:desc' => 'URL descendante',
|
||||
'order_by.created_at:asc' => 'Date de Création ascendante',
|
||||
'order_by.created_at:desc' => 'Date de Création descendante',
|
||||
'order_by.number_links:asc' => 'Nombre de Liens ascendants',
|
||||
'order_by.number_links:desc' => 'Nombre de Liens descendants',
|
||||
'order_by.title:asc' => 'Titre A-Z',
|
||||
'order_by.title:desc' => 'Title Z-A',
|
||||
'order_by.url:asc' => 'URL A-Z',
|
||||
'order_by.url:desc' => 'URL Z-A',
|
||||
'order_by.created_at:asc' => 'Plus ancien',
|
||||
'order_by.created_at:desc' => 'Plus récent',
|
||||
'order_by.number_links:asc' => 'Moins de liens',
|
||||
'order_by.number_links:desc' => 'Plus de liens',
|
||||
'order_by.random' => 'Aléatoire',
|
||||
|
||||
'no_results' => 'Aucun résultat trouvé.',
|
||||
|
||||
|
@ -45,7 +45,7 @@ return [
|
||||
'sharing_toggle' => 'Activer/désactiver tout',
|
||||
|
||||
'darkmode' => 'Mode sombre',
|
||||
'darkmode_help' => 'Vous pouvez choisir d\'activer définitivement ou automatiquement en fonction des paramètres de votre appareil. (<small>Cocher <a href="https://caniuse.com/#search=prefers-color-scheme">ici</a> si votre navigateur prend en charge la détection automatique</small>)',
|
||||
'darkmode_help' => 'Vous pouvez choisir d\'activer définitivement ou automatiquement en fonction des paramètres de votre appareil. (<small>Vérifiez <a href="https://caniuse.com/#search=prefers-color-scheme">ici</a> si votre navigateur prend en charge la détection automatique</small>)',
|
||||
'darkmode_disabled' => 'Désactivé',
|
||||
'darkmode_auto' => 'Automatiquement',
|
||||
'darkmode_permanent' => 'Permanent',
|
||||
|
@ -15,7 +15,7 @@ return [
|
||||
'delete_warning' => 'Les entrées définitivement supprimées ne peuvent pas être restaurées !',
|
||||
'delete_no_entries' => 'Aucune entrée à supprimer.',
|
||||
|
||||
'delete_success.links' => 'Supprimer définitivement tous les liens.',
|
||||
'delete_success.links' => 'Tous les liens ont été définitivement supprimés.',
|
||||
'delete_success.lists' => 'Supprimer définitivement toutes les listes.',
|
||||
'delete_success.tags' => 'Supprimer définitivement toutes les étiquettes.',
|
||||
'delete_success.notes' => 'Supprimer définitivement toutes les notes.',
|
||||
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'password' => 'A jelszónak legalább hat karakterből kell állnia, és meg kell egyeznie a megerősítéssel.',
|
||||
'reset' => 'A jelszava visszaállításra került!',
|
||||
'sent' => 'Elküldtük e-mailben a jelszó-visszaállítási hivatkozást!',
|
||||
'sent' => 'Ha létezik fiók az Ön e-mail címével, e-mailben elküldtük a jelszó-visszaállítási linket.',
|
||||
'token' => 'Ez a jelszó-visszaállítási jogkivonat érvénytelen.',
|
||||
'user' => "Nem találtunk felhasználót ezzel az e-mail-címmel.",
|
||||
|
||||
|
@ -14,14 +14,15 @@ return [
|
||||
'empty_lists' => 'lista nélkül',
|
||||
|
||||
'order_by' => 'Rendezés:',
|
||||
'order_by.title:asc' => 'Növekvő sorrendben a cím szerint',
|
||||
'order_by.title:desc' => 'Csökkenő sorrendben a cím szerint',
|
||||
'order_by.url:asc' => 'Növekvő sorrendben az URL szerint',
|
||||
'order_by.url:desc' => 'Csökkenő sorrendben az URL szerint',
|
||||
'order_by.created_at:asc' => 'Növekvő sorrendben a létrehozás dátuma szerint',
|
||||
'order_by.created_at:desc' => 'Csökkenő sorrendben a létrehozás dátuma szerint',
|
||||
'order_by.number_links:asc' => 'Növekvő sorrendben a hivatkozások száma szerint',
|
||||
'order_by.number_links:desc' => 'Csökkenő sorrendben a hivatkozások száma szerint',
|
||||
'order_by.title:asc' => 'Cím A-Z',
|
||||
'order_by.title:desc' => 'Cím Z-A',
|
||||
'order_by.url:asc' => 'URL A-Z',
|
||||
'order_by.url:desc' => 'URL Z-A',
|
||||
'order_by.created_at:asc' => 'Legrégebbi',
|
||||
'order_by.created_at:desc' => 'Legújabb',
|
||||
'order_by.number_links:asc' => 'A legkevesebb link',
|
||||
'order_by.number_links:desc' => 'A legtöbb link',
|
||||
'order_by.random' => 'Véletlen',
|
||||
|
||||
'no_results' => 'Nincs találat.',
|
||||
|
||||
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'password' => 'Le password devono essere di almeno 6 caratteri e devono coincidere.',
|
||||
'reset' => 'La password è stata reimpostata!',
|
||||
'sent' => 'Abbiamo inviato una e-mail al tuo link per reimpostare la password!',
|
||||
'sent' => 'Se esiste un account con il tuo indirizzo e-mail, verrà inviata una e-mail con un link per reimpostare la password.',
|
||||
'token' => 'Questo token per la reimpostazione della password non è valido.',
|
||||
'user' => "Non esiste un utente associato a questo indirizzo e-mail.",
|
||||
|
||||
|
@ -14,14 +14,15 @@ return [
|
||||
'empty_lists' => 'senza Liste',
|
||||
|
||||
'order_by' => 'Ordina per',
|
||||
'order_by.title:asc' => 'Titolo ascendente',
|
||||
'order_by.title:desc' => 'Titolo discendente',
|
||||
'order_by.url:asc' => 'URL ascendente',
|
||||
'order_by.url:desc' => 'URL discendente',
|
||||
'order_by.created_at:asc' => 'Data creazione ascendente',
|
||||
'order_by.created_at:desc' => 'Data creazione discendente',
|
||||
'order_by.number_links:asc' => 'Numero di link ascendente',
|
||||
'order_by.number_links:desc' => 'Numero di link discendente',
|
||||
'order_by.title:asc' => 'Titolo A-Z',
|
||||
'order_by.title:desc' => 'Titolo Z-A',
|
||||
'order_by.url:asc' => 'URL A-Z',
|
||||
'order_by.url:desc' => 'URL Z-A',
|
||||
'order_by.created_at:asc' => 'Meno Recenti',
|
||||
'order_by.created_at:desc' => 'Più Recenti',
|
||||
'order_by.number_links:asc' => 'Minor numero di Link',
|
||||
'order_by.number_links:desc' => 'Maggior numero di Link',
|
||||
'order_by.random' => 'Casuale',
|
||||
|
||||
'no_results' => 'Nessun risultato trovato.',
|
||||
|
||||
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'password' => 'Passord må være minst seks tegn og stemme med bekreftelsen.',
|
||||
'reset' => 'Ditt passord har blitt tilbakestilt!',
|
||||
'sent' => 'Vi har sendt deg en lenke for tilbakestilling av passordet ditt!',
|
||||
'sent' => 'Hvis en konto med din e-postadresse finnes, har vi sendt en lenke for tilbakestilling av passordet ditt.',
|
||||
'token' => 'Denne resettingen av passordet er ugyldig.',
|
||||
'user' => "Vi finner ikke en bruker med denne e-postadressen.",
|
||||
|
||||
|
@ -14,14 +14,15 @@ return [
|
||||
'empty_lists' => 'uten lister',
|
||||
|
||||
'order_by' => 'Sorter etter',
|
||||
'order_by.title:asc' => 'Tittel stigende',
|
||||
'order_by.title:desc' => 'Tittel synkende',
|
||||
'order_by.url:asc' => 'Nettadresse stigende',
|
||||
'order_by.url:desc' => 'Nettadresse synkende',
|
||||
'order_by.created_at:asc' => 'Opprettet dato stigende',
|
||||
'order_by.created_at:desc' => 'Opprettet dato synkende',
|
||||
'order_by.number_links:asc' => 'Antall lenker stigende',
|
||||
'order_by.number_links:desc' => 'Antall lenker synkende',
|
||||
'order_by.title:asc' => 'Tittel A-Å',
|
||||
'order_by.title:desc' => 'Tittel Å-A',
|
||||
'order_by.url:asc' => 'Nettadresse A-Z',
|
||||
'order_by.url:desc' => 'Nettadresse Z-A',
|
||||
'order_by.created_at:asc' => 'Eldste',
|
||||
'order_by.created_at:desc' => 'Nyeste',
|
||||
'order_by.number_links:asc' => 'Færrest lenker',
|
||||
'order_by.number_links:desc' => 'Fleste lenker',
|
||||
'order_by.random' => 'Tilfeldig',
|
||||
|
||||
'no_results' => 'Ingen resultater.',
|
||||
|
||||
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'password' => 'Hasła muszą mieć co najmniej sześć znaków i muszą być zgodne z potwierdzeniem.',
|
||||
'reset' => 'Twoje hasło zostało zresetowane!',
|
||||
'sent' => 'Wysłaliśmy Twój link do resetowania hasła!',
|
||||
'sent' => 'Jeśli konto z Twoim adresem e-mail istnieje, wysłaliśmy wiadomość e-mail z linkiem do resetowania hasła.',
|
||||
'token' => 'Ten token resetowania hasła jest nieprawidłowy.',
|
||||
'user' => "Nie możemy znaleźć użytkownika z tym adresem email.",
|
||||
|
||||
|
@ -14,14 +14,15 @@ return [
|
||||
'empty_lists' => 'bez list',
|
||||
|
||||
'order_by' => 'Pokaż według',
|
||||
'order_by.title:asc' => 'Tytuł rosnąco',
|
||||
'order_by.title:desc' => 'Tytuł malejąco',
|
||||
'order_by.url:asc' => 'Adres URL rosnąco',
|
||||
'order_by.url:desc' => 'Adres URL malejąco',
|
||||
'order_by.created_at:asc' => 'Data utworzenia rosnąco',
|
||||
'order_by.created_at:desc' => 'Data utworzenia malejąco',
|
||||
'order_by.number_links:asc' => 'Liczba linków rosnąco',
|
||||
'order_by.number_links:desc' => 'Liczba linków malejąco',
|
||||
'order_by.title:asc' => 'Tytuł A-Z',
|
||||
'order_by.title:desc' => 'Tytuł Z-A',
|
||||
'order_by.url:asc' => 'Adres URL A-Z',
|
||||
'order_by.url:desc' => 'Adres URL Z-A',
|
||||
'order_by.created_at:asc' => 'Najstarsze',
|
||||
'order_by.created_at:desc' => 'Najnowsze',
|
||||
'order_by.number_links:asc' => 'Najmniej linków',
|
||||
'order_by.number_links:desc' => 'Najwięcej linków',
|
||||
'order_by.random' => 'Losowo',
|
||||
|
||||
'no_results' => 'Nie znaleziono wyników.',
|
||||
|
||||
|
27
lang/ro_RO/auth.php
Normal file
27
lang/ro_RO/auth.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used during authentication for various
|
||||
| messages that we need to display to the user. You are free to modify
|
||||
| these language lines according to your application's requirements.
|
||||
|
|
||||
*/
|
||||
|
||||
'failed' => 'Aceste date de autentificare nu se potrivesc cu înregistrările noastre.',
|
||||
'throttle' => 'Prea multe tentative de autentificare. Reîncearcă din nou în :seconds secunde.',
|
||||
|
||||
'confirm_title' => 'Confirmarea este necesară',
|
||||
'confirm' => 'Confirmă această acțiune prin folosirea parolei actuale.',
|
||||
'confirm_action' => 'Confirmă acțiunea',
|
||||
|
||||
'two_factor' => 'Autentificare în doi factori',
|
||||
'two_factor_check' => 'Introdu acum parola de unică folosință furnizată de aplicația de autentificare în doi factori.',
|
||||
'two_factor_with_recovery' => 'Autentifică-te cu codul de recuperare',
|
||||
|
||||
];
|
10
lang/ro_RO/export.php
Normal file
10
lang/ro_RO/export.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
return [
|
||||
'export' => 'Exportare',
|
||||
'start_export_html' => 'Exportare în HTML',
|
||||
'start_export_csv' => 'Exportare în CSV',
|
||||
|
||||
'export_help' => 'Executarea funcției de exportare va salva toate marcajele existente într-un fișier obișnuit compatibil cu marcajele sau într-un fișier CSV, dacă se dorește acest lucru.',
|
||||
|
||||
'export_csv_error' => 'A apărut o eroare la generarea unui fișier CSV. Examinează fișierele de jurnal pentru mai multe detalii.',
|
||||
];
|
14
lang/ro_RO/import.php
Normal file
14
lang/ro_RO/import.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
return [
|
||||
'import' => 'Importare',
|
||||
'start_import' => 'Pornire importare',
|
||||
'import_running' => 'Se importă...',
|
||||
'import_file' => 'Fișier pentru importat',
|
||||
|
||||
'import_help' => 'Aici îți poți importa marcajele de navigator existente. De regulă, marcajele sunt exportate într-un fișier .html de navigatorul tău. Selectează fișierul aici și pornește importarea.<br>Acest proces poate dura mai mult timp în funcție de numărul de marcaje.',
|
||||
|
||||
'import_networkerror' => 'A apărut o eroare la importarea marcajelor. Examinează consola navigatorului cu privire la detalii sau consultă jurnalele aplicației.',
|
||||
'import_error' => 'A apărut o eroare la importarea marcajelor. Consultă jurnalele aplicației.',
|
||||
'import_empty' => 'Niciun marcaj nu a putut fi importat. Fișierul încărcat este deteriorat sau gol.',
|
||||
'import_successfully' => ':imported legături importate, :skipped omise.',
|
||||
];
|
69
lang/ro_RO/link.php
Normal file
69
lang/ro_RO/link.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
return [
|
||||
'link' => 'Legătură',
|
||||
'links' => 'Legături',
|
||||
'all_links' => 'Toate legăturile',
|
||||
'recent_links' => 'Legături recente',
|
||||
'no_links' => 'Nicio legătură',
|
||||
|
||||
'add' => 'Adăugare legătură',
|
||||
'add_quick' => 'Adăugare rapid legătură',
|
||||
'show' => 'Afișare legătură',
|
||||
'details' => 'Detalii legătură',
|
||||
'edit' => 'Editare legătură',
|
||||
'update' => 'Actualizare legătură',
|
||||
'delete' => 'Ștergere legătură',
|
||||
|
||||
'private' => 'Legătură privată',
|
||||
|
||||
'history' => 'Istoric',
|
||||
'history_added' => 'S-a adăugat <code>:newvalue</code> la :fieldname.',
|
||||
'history_changed' => 'S-a modificat :fieldname de la <code>:oldvalue</code> la <code>:newvalue</code>',
|
||||
'history_removed' => 'S-a eliminat <code>:oldvalue</code> de la :fieldname.',
|
||||
'history_deleted' => 'Legătura a fost ștearsă',
|
||||
'history_restored' => 'Legătura a fost restaurată',
|
||||
'history_created' => 'Legătura a fost creată',
|
||||
|
||||
'url' => 'URL',
|
||||
'title' => 'Titlu',
|
||||
'description' => 'Descriere',
|
||||
'revtags' => 'Etichete',
|
||||
'revlists' => 'Liste',
|
||||
'is_private' => 'Stare privată',
|
||||
|
||||
'status' => 'Stare',
|
||||
'stati' => [
|
||||
'1' => 'Funcțională',
|
||||
'2' => 'Mutată',
|
||||
'3' => 'Nefuncțională',
|
||||
],
|
||||
|
||||
'author' => 'de :user',
|
||||
|
||||
'external_link' => 'Legătură externă',
|
||||
'wayback' => 'Arhiva legăturilor la Wayback Machine',
|
||||
|
||||
'check_disable' => 'Dezactivare verificare',
|
||||
'check_disabled' => 'Verificarea este dezactivată',
|
||||
'check_enable' => 'Activare verificare',
|
||||
'check_enabled' => 'Verificarea este activată',
|
||||
|
||||
'status_is_broken' => 'Legătura este marcată ca fiind nefuncțională',
|
||||
'status_mark_working' => 'Marchează ca în lucru',
|
||||
|
||||
'added_successfully' => 'Legătura a fost adăugată.',
|
||||
'added_connection_error' => 'Legătura a fost adăugată, dar a apărut o eroare de conexiune la accesarea URL-ului. Detaliile se regăsesc în jurnale.',
|
||||
'added_request_error' => 'Legătura a fost adăugată, dar a apărut o eroare de conexiune la solicitarea URL-ului, de exemplu, un certificat invalid. Detaliile se regăsesc în jurnale.',
|
||||
'updated_successfully' => 'Legătura a fost actualizată.',
|
||||
'deleted_successfully' => 'Legătura a fost ștearsă.',
|
||||
'deletion_error' => 'Legătura nu a putut fi ștearsă.',
|
||||
|
||||
'duplicates_found' => 'LinkAce a găsit dubluri posibile ale URL-ului trimis:',
|
||||
'existing_found' => 'Există deja o legătură cu acel URL.',
|
||||
|
||||
'notifications.linkcheck.errors' => 'LinkAce a descoperit erori la verificarea linkurilor tale.',
|
||||
'notifications.linkcheck.errors.moved' => '⚠ ️Următoarele legături au fost mutate într-o nouă locație:',
|
||||
'notifications.linkcheck.errors.broken' => '🚫 Următoarele legături nu mai sunt accesibile sau returnează o eroare:',
|
||||
|
||||
'happy_bookmarking' => 'La cât mai multe marcaje',
|
||||
];
|
54
lang/ro_RO/linkace.php
Normal file
54
lang/ro_RO/linkace.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
return [
|
||||
'linkace' => 'LinkAce',
|
||||
|
||||
'user' => 'Utilizator',
|
||||
'username' => 'Nume de utilizator',
|
||||
'email' => 'Poștă electronică',
|
||||
'password' => 'Parolă',
|
||||
'password_confirm' => 'Confirmare parolă',
|
||||
'login' => 'Autentificare',
|
||||
'logout' => 'Deconectare',
|
||||
'remember_me' => 'Ține-mă minte',
|
||||
'go_to_dashboard' => 'Deplasare la tabloul de bord',
|
||||
'system_logs' => 'Jurnale de sistem',
|
||||
|
||||
'reset_password' => 'Resetare parolă',
|
||||
'send_reset_email' => 'Trimite legătura de resetare a parolei',
|
||||
'forgot_password_link' => 'Ți-ai uitat parola? <a href=":reset_url">Reseteaz-o aici</a>',
|
||||
|
||||
'added' => 'Adăugat',
|
||||
'added_at' => 'Adăugat la',
|
||||
'updated_at' => 'Actualizat la',
|
||||
'last_update' => 'Ultima actualizare',
|
||||
'deleted_at' => 'Şters la',
|
||||
|
||||
'add' => 'Adăugare',
|
||||
'show' => 'Afișare',
|
||||
'edit' => 'Editare',
|
||||
'update' => 'Actualizare',
|
||||
'delete' => 'Ștergere',
|
||||
|
||||
'menu' => 'Meniu',
|
||||
'entries' => 'Înregistrări',
|
||||
'feed' => 'Flux',
|
||||
|
||||
'continue_adding' => 'Continuă să adaugi',
|
||||
|
||||
'private' => 'Privat',
|
||||
'is_private' => 'Este privat',
|
||||
|
||||
'yes' => 'Da',
|
||||
'no' => 'Nu',
|
||||
'more' => 'Mai mult',
|
||||
|
||||
'no_results_found' => 'Nicio :model găsită.',
|
||||
|
||||
'bookmarklet_close' => 'Această ferestră de marcaj-script se închide automat în <span class="bm-timer">5</span> secunde.',
|
||||
'open_linkace' => 'Deschidere LinkAce',
|
||||
|
||||
'demo_login_hint' => 'Te poți autentifica imediat. Reține că această demonstrație va fi resetată la fiecare 2 ore.',
|
||||
|
||||
'project_of' => 'LinkAce este un proiect realizat de',
|
||||
'version' => 'Versiunea actuală: :version',
|
||||
];
|
31
lang/ro_RO/list.php
Normal file
31
lang/ro_RO/list.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
return [
|
||||
'list' => 'Listă',
|
||||
'lists' => 'Liste',
|
||||
'all_lists' => 'Toate listele',
|
||||
'recent_lists' => 'Liste recente',
|
||||
|
||||
'add' => 'Adăugare listă',
|
||||
'show' => 'Afișare listă',
|
||||
'edit' => 'Editare listă',
|
||||
'update' => 'Actualizare listă',
|
||||
'delete' => 'Ștergere listă',
|
||||
|
||||
'filter_lists' => 'Filtrare liste...',
|
||||
|
||||
'private' => 'Listă privată',
|
||||
|
||||
'name' => 'Denumirea listei',
|
||||
'description' => 'Descrierea listei',
|
||||
|
||||
'author' => 'de :user',
|
||||
|
||||
'no_lists' => 'Nicio listă',
|
||||
|
||||
'number_links' => ':number legătură în această listă|:number legături în această listă',
|
||||
|
||||
'added_successfully' => 'Lista a fost adăugată.',
|
||||
'updated_successfully' => 'Lista a fost actualizată.',
|
||||
'deleted_successfully' => 'Lista a fost ștearsă.',
|
||||
'deletion_error' => 'Lista nu a putut fi ștearsă.',
|
||||
];
|
20
lang/ro_RO/note.php
Normal file
20
lang/ro_RO/note.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
return [
|
||||
'note' => 'Observație',
|
||||
'notes' => 'Observații',
|
||||
|
||||
'add' => 'Adăugare observație',
|
||||
'show' => 'Afișare observație',
|
||||
'edit' => 'Editare observație',
|
||||
'update' => 'Actualizare observație',
|
||||
'delete' => 'Ștergere observație',
|
||||
|
||||
'private' => 'Observație privată',
|
||||
|
||||
'note_content' => 'Conținutul observației',
|
||||
|
||||
'added_successfully' => 'Observația a fost adăugată.',
|
||||
'updated_successfully' => 'Observația a fost actualizată.',
|
||||
'deleted_successfully' => 'Observația a fost ștearsă.',
|
||||
'deletion_error' => 'Observația nu a putut fi ștearsă.',
|
||||
];
|
19
lang/ro_RO/pagination.php
Normal file
19
lang/ro_RO/pagination.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Pagination Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used by the paginator library to build
|
||||
| the simple pagination links. You are free to change them to anything
|
||||
| you want to customize your views to better match your application.
|
||||
|
|
||||
*/
|
||||
|
||||
'previous' => '« Anterior',
|
||||
'next' => 'Următoarea »',
|
||||
|
||||
];
|
22
lang/ro_RO/passwords.php
Normal file
22
lang/ro_RO/passwords.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are the default lines which match reasons
|
||||
| that are given by the password broker for a password update attempt
|
||||
| has failed, such as for an invalid token or invalid new password.
|
||||
|
|
||||
*/
|
||||
|
||||
'password' => 'Parolele trebuie să aibă cel puțin șase caractere și să coincidă.',
|
||||
'reset' => 'Parola a fost resetată!',
|
||||
'sent' => 'Dacă există un cont cu adresa ta de poștă electronică, ți-am trimis un mesaj cu legătura de resetare a parolei.',
|
||||
'token' => 'Acest token de resetare a parolei este invalid.',
|
||||
'user' => "Nu putem găsi un utilizator cu această adresă de poștă electronică.",
|
||||
|
||||
];
|
20
lang/ro_RO/placeholder.php
Normal file
20
lang/ro_RO/placeholder.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
return [
|
||||
'username' => 'ionpopescu',
|
||||
'email' => 'ion.popescu@exemplu.ro',
|
||||
'password' => 'Parolă',
|
||||
'password_confirmed' => 'Parolă confirmată',
|
||||
|
||||
'link_url' => 'https://github.com/Kovah/LinkAce',
|
||||
'link_title' => 'Titlul paginii de internet',
|
||||
|
||||
'list_select' => 'Selectează o listă',
|
||||
'tags_select' => 'Selectează câteva etichete',
|
||||
|
||||
'list_name' => 'Denumirea actuală a listei',
|
||||
'tag_name' => 'Denumirea actuală a etichetei',
|
||||
|
||||
'two_factor_otp' => 'Parolă de unică folosință',
|
||||
'two_factor_recovery_code' => 'Cod de recuperare',
|
||||
|
||||
];
|
30
lang/ro_RO/search.php
Normal file
30
lang/ro_RO/search.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
return [
|
||||
'search' => 'Căutare',
|
||||
'results' => 'rezultate',
|
||||
|
||||
'filter_by_list' => 'Filtrare după listă(e)',
|
||||
'filter_by_tag' => 'Filtrare după etichetă(e)',
|
||||
'query' => 'Căutare după...',
|
||||
'search_title' => 'Căutare titlu',
|
||||
'search_description' => 'Căutare descriere',
|
||||
'private_only' => 'Doar legături private',
|
||||
'broken_links' => 'Doar legături nefuncționale',
|
||||
'empty_tags' => 'fără etichete',
|
||||
'empty_lists' => 'fără liste',
|
||||
|
||||
'order_by' => 'Ordonare după',
|
||||
'order_by.title:asc' => 'Titlul A-Z',
|
||||
'order_by.title:desc' => 'Titlul Z-A',
|
||||
'order_by.url:asc' => 'URL A-Z',
|
||||
'order_by.url:desc' => 'URL Z-A',
|
||||
'order_by.created_at:asc' => 'Cele mai vechi',
|
||||
'order_by.created_at:desc' => 'Cele mai noi',
|
||||
'order_by.number_links:asc' => 'Link-uri cel mai puțin',
|
||||
'order_by.number_links:desc' => 'Cele mai multe link-uri',
|
||||
'order_by.random' => 'Aleatoriu',
|
||||
|
||||
'no_results' => 'Niciun rezultat găsit.',
|
||||
|
||||
'validation_query_missing' => 'Trebuie fie să introduci o interogare de căutare, fie să selectezi o listă, o etichetă sau să activezi căutarea pentru legături nefuncționale.',
|
||||
];
|
106
lang/ro_RO/settings.php
Normal file
106
lang/ro_RO/settings.php
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
return [
|
||||
'settings' => 'Setări',
|
||||
'user_settings' => 'Setări ale utilizatorului',
|
||||
'account_settings' => 'Setări ale contului',
|
||||
'app_settings' => 'Setări ale aplicației',
|
||||
'system_settings' => 'Setări ale sistemului',
|
||||
'guest_settings' => 'Setări pentru invitați',
|
||||
|
||||
'language' => 'Limbă',
|
||||
'timezone' => 'Fus orar',
|
||||
'date_format' => 'Format de dată',
|
||||
'time_format' => 'Format orar',
|
||||
'listitem_count' => 'Numărul de elemente din liste',
|
||||
|
||||
'links_new_tab' => 'Deschidere legături externe în file noi',
|
||||
|
||||
'markdown_for_text' => 'Activează Markdown pentru descrieri și note',
|
||||
|
||||
'privacy' => 'Confidențialitate',
|
||||
'links_private_default' => 'Legături private în mod implicit',
|
||||
'links_private_default_help' => 'Activarea acestei opțiuni va face ca toate legăturile noi să devină private în mod implicit',
|
||||
'notes_private_default' => 'Observații private în mod implicit',
|
||||
'notes_private_default_help' => 'Activarea acestei opțiuni va face ca toate observațiile noi să devină private în mod implicit',
|
||||
'tags_private_default' => 'Etichete private în mod implicit',
|
||||
'tags_private_default_help' => 'Activarea acestei opțiuni va face ca toate etichetele noi să devină private în mod implicit',
|
||||
'lists_private_default' => 'Liste private în mod implicit',
|
||||
'lists_private_default_help' => 'Activarea acestei opțiuni va face ca toate listele noi să devină private în mod implicit',
|
||||
|
||||
'archive_backups' => 'Copii de rezervă Wayback Machine',
|
||||
'archive_backups_help' => 'Dacă opțiunea este activată, LinkAce va transmite serviciului <a href="https://archive.org/">Wayback Machine</a> să creeze copii de rezervă pentru legăturile tale. Serviciul Wayback Machine este administrat de Internet Archive, o organizație non-profit. Te îndemnăm să <a href="https://archive.org/donate/">donezi către Internet Archive</a>.',
|
||||
'archive_backups_enabled' => 'Activare copii de rezervă',
|
||||
'archive_backups_enabled_help' => 'Dacă opțiunea este activată, legăturile neprivate vor fi salvate de Internet Archive.',
|
||||
'archive_private_backups_enabled' => 'Activare copii de rezervă pentru legături private',
|
||||
'archive_private_backups_enabled_help' => 'Dacă opțiunea este activată, legăturile private vor fi, de asemenea, salvate. Copiile de rezervă trebuie să fie activate.',
|
||||
|
||||
'display_mode' => 'Afișare legături ca',
|
||||
'display_mode_list_detailed' => 'listă cu multe detalii',
|
||||
'display_mode_list_simple' => 'listă cu mai puține detalii',
|
||||
'display_mode_cards' => 'cartonașe cu mai puține detalii',
|
||||
'display_mode_cards_detailed' => 'cartonașe cu multe detalii',
|
||||
|
||||
'sharing' => 'Distribuire legătură',
|
||||
'sharing_help' => 'Activează toate serviciile care dorești să fie afișate pentru legături, pentru a le putea distribui cu ușurință printr-un singur clic.',
|
||||
'sharing_toggle' => 'Comutare toate pornit/oprit',
|
||||
|
||||
'darkmode' => 'Mod întunecat',
|
||||
'darkmode_help' => 'Poți alege să se pornească permanent sau automat în funcție de setările dispozitivului tău. (<small>Vezi <a href="https://caniuse.com/#search=prefers-color-scheme">aici</a> dacă navigatorul tău este compatibil cu detectarea automată</small>)',
|
||||
'darkmode_disabled' => 'Dezactivat',
|
||||
'darkmode_auto' => 'Automat',
|
||||
'darkmode_permanent' => 'Permanent',
|
||||
|
||||
'save_settings' => 'Salvare setări',
|
||||
'settings_saved' => 'Setările au fost actualizate!',
|
||||
|
||||
'bookmarklet' => 'Marcaj-script',
|
||||
'bookmarklet_button' => 'Trage acest script în marcajele tale sau dă clic dreapta și salvează-l ca marcaj',
|
||||
'bookmarklet_help' => 'Adaugă acest marcaj-script în navigatorul tău pentru a adăuga rapid legături de pe paginile pe care le vizitezi, fără a fi nevoie să deschizi manual aplicația LinkAce.',
|
||||
|
||||
'change_password' => 'Modificare parolă',
|
||||
'old_password' => 'Parolă veche',
|
||||
'new_password' => 'Parolă nouă',
|
||||
'new_password2' => 'Repetă noua parolă',
|
||||
'password_updated' => 'Parola a fost modificată!',
|
||||
'old_password_invalid' => 'Parola veche nu este validă!',
|
||||
|
||||
'two_factor_auth' => 'Autentificare în doi factori',
|
||||
'two_factor_enable' => 'Activează autentificarea în doi factori',
|
||||
'two_factor_disable' => 'Dezactivează autentificarea în doi factori',
|
||||
'two_factor_setup_app' => 'Autentificarea în doi pași este activată. Configurează-ți acum dispozitivul de autentificare prin scanarea următorului cod QR.',
|
||||
'two_factor_setup_url' => 'Codul QR nu funcționează? Mai ai posibilitatea de a utiliza direct acest URL.',
|
||||
'two_factor_recovery_codes' => 'Stochează aceste coduri de recuperare într-un manager de parole securizat. Acestea pot fi utilizate pentru a-ți recupera accesul la cont în cazul în care ți-ai pierdut dispozitivul de autentificare în doi factori.',
|
||||
'two_factor_recovery_codes_view' => 'Vizualizare coduri de recuperare',
|
||||
'two_factor_regenerate_recovery_codes' => 'Generare coduri de recuperare noi',
|
||||
|
||||
'api_token' => 'Token API',
|
||||
'api_token_generate' => 'Generare token',
|
||||
'api_token_generate_confirm' => 'Sigur dorești să generezi un token nou?',
|
||||
'api_token_help' => 'Tokenul API poate fi utilizat pentru a accesa LinkAce din alte aplicații sau scripturi.',
|
||||
'api_token_generate_info' => 'Atenție: dacă ai deja un token API, generarea unuia nou va întrerupe toate integrările existente!',
|
||||
'api_token_generate_failure' => 'Un nou token API nu a putut fi generat. Examinează consola navigatorului și jurnalele aplicației cu privire la mai multe informații.',
|
||||
|
||||
'sys_page_title' => 'Titlul paginii',
|
||||
'sys_guest_access' => 'Activează accesul pentru invitați',
|
||||
'sys_guest_access_help' => 'Dacă opțiunea este activată, invitații vor putea să vadă toate legăturile care nu sunt private.',
|
||||
'sys_custom_header_content' => 'Conținut personalizat de antet',
|
||||
'sys_custom_header_content_help' => 'Conținutul introdus aici va fi plasat înaintea etichetei </head> pe toate paginile LinkAce. Această opțiune este utilă pentru a plasa scripturi de analiză sau personalizare. Atenție: conținutul nu este marcat cu secvențe escape și poate întrerupe paginile!',
|
||||
|
||||
'cron_token' => 'Token Cron',
|
||||
'cron_token_generate' => 'Generare token',
|
||||
'cron_token_generate_confirm' => 'Sigur dorești să generezi un token nou?',
|
||||
'cron_token_help' => 'Tokenul cron este necesar pentru a executa serviciul cron care verifică dacă există legături nefuncționale sau copii de rezervă în desfășurare.',
|
||||
'cron_token_url' => 'Direcționează-ți serviciul cron către următorul URL: <span class="cron-token-url">:route</span>',
|
||||
'cron_token_generate_info' => 'Atenție: dacă ai deja un token cron, generarea unuia nou va întrerupe serviciul cron existent!',
|
||||
'cron_token_generate_failure' => 'Un nou token cron nu a putut fi generat. Examinează consola navigatorului și jurnalele aplicației cu privire la mai multe informații.',
|
||||
'cron_token_auth_failure' => 'Tokenul cron furnizat este invalid',
|
||||
'cron_execute_successful' => 'Serviciul cron a fost executat',
|
||||
|
||||
'update_check' => 'Căutare actualizare',
|
||||
'update_check_running' => 'Se caută actualizări...',
|
||||
'update_check_version_found' => 'Actualizare găsită. Este disponibilă versiunea #VERSION#.',
|
||||
'update_check_success' => 'Nu s-a găsit nicio actualizare.',
|
||||
'update_check_failed' => 'Nu s-au putut căuta actualizări.',
|
||||
|
||||
'guest_settings_info' => 'Următoarele setări se vor aplica invitaților care îți vizitează pagina, dacă accesul pentru invitați este activat.',
|
||||
];
|
52
lang/ro_RO/setup.php
Normal file
52
lang/ro_RO/setup.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'setup' => 'Configurare',
|
||||
'continue' => 'Continuare',
|
||||
'try_again' => 'Încearcă din nou',
|
||||
|
||||
'welcome' => 'Bun venit la configurarea LinkAce',
|
||||
'intro' => 'În următorii pași vei configura LinkAce pentru a fi gata de utilizare.',
|
||||
'intro.step1' => 'Verifică dacă sunt îndeplinite toate cerințele.',
|
||||
'intro.step2' => 'Configurează o bază de date și verifică dacă se realizează conexiunea la aceasta.',
|
||||
'intro.step3' => 'Creează-ți contul de utilizator.',
|
||||
|
||||
'check_requirements' => 'Verificare cerințe',
|
||||
'requirements.php_version' => 'Versiune PHP >= 7.4.0',
|
||||
'requirements.extension_bcmath' => 'Extensie PHP: BCMath',
|
||||
'requirements.extension_ctype' => 'Extensie PHP: Ctype',
|
||||
'requirements.extension_json' => 'Extensie PHP: JSON',
|
||||
'requirements.extension_mbstring' => 'Extensie PHP: Mbstring',
|
||||
'requirements.extension_openssl' => 'Extensie PHP: OpenSSL',
|
||||
'requirements.extension_pdo_mysql' => 'Extensie PHP: PDO',
|
||||
'requirements.extension_tokenizer' => 'Extensie PHP: Tokenizer',
|
||||
'requirements.extension_xml' => 'Extensie PHP: XML',
|
||||
'requirements.env_writable' => 'Fișierul .env există și este inscripționabil',
|
||||
'requirements.storage_writable' => 'Directoarele /storage și /storage/logs sunt inscripționabile',
|
||||
|
||||
'database_configuration' => 'Configurarea bazei de date',
|
||||
'database_configure' => 'Configurare bază de date',
|
||||
'database.intro' => 'Dacă ai completat deja detaliile bazei de date în fișierul .env, atunci câmpurile de introducere ar trebui să fie completate în prealabil. În caz contrar, completează câmpurile cu informațiile corespunzătoare pentru baza ta de date.',
|
||||
'database.config_error' => 'Baza de date nu a putut fi configurată. Verifică detaliile conexiunii tale. Detalii:',
|
||||
'database.db_host' => 'Gazda bazei de date',
|
||||
'database.db_port' => 'Portul bazei de date',
|
||||
'database.db_name' => 'Denumirea bazei de date',
|
||||
'database.db_user' => 'Utilizatorul bazei de date',
|
||||
'database.db_password' => 'Parola bazei de date',
|
||||
'database.complete_hint' => 'Salvarea configurației bazei de date și pregătirea acesteia în vederea utilizării aplicației poate dura câteva secunde. Te rugăm să ai răbdare.',
|
||||
|
||||
'database.data_present' => 'Atenție! Am descoperit date în baza de date specificată! Asigură-te că ai o copie de rezervă pentru această bază de date și confirmă ștergerea tuturor datelor.',
|
||||
'database.overwrite_data' => 'Confirm că toate datele trebuie șterse și suprascrise cu o nouă bază de date LinkAce',
|
||||
|
||||
'account_setup' => 'Configurare cont',
|
||||
'account_setup.intro' => 'Înainte de a putea începe, trebuie să îți creezi contul de utilizator.',
|
||||
'account_setup.name' => 'Introdu-ți numele',
|
||||
'account_setup.email' => 'Introdu-ți adresa de poștă electronică',
|
||||
'account_setup.password' => 'Introdu o parolă puternică',
|
||||
'account_setup.password_requirements' => 'Lungime minimă: 10 caractere',
|
||||
'account_setup.password_confirmed' => 'Confirmă-ți parola',
|
||||
'account_setup.create' => 'Creare cont',
|
||||
|
||||
'complete' => 'Configurare finalizată!',
|
||||
'outro' => 'Ai finalizat configurarea și acum poți utiliza LinkAce! Te-ai autentificat și poți începe să aplici marcaje imediat.',
|
||||
];
|
33
lang/ro_RO/sharing.php
Normal file
33
lang/ro_RO/sharing.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
return [
|
||||
'sharetext' => 'Am găsit această legătură uluitoare. Aruncă o privire: #URL#',
|
||||
'subject' => 'Aruncă o privire peste această legătură grozavă',
|
||||
'share' => 'Distribuie legătura prin :service',
|
||||
'share_link' => 'Distribuie această legătură',
|
||||
'service' => [
|
||||
'email' => 'Poștă electronică',
|
||||
'print' => 'Imprimare',
|
||||
'facebook' => 'Facebook',
|
||||
'twitter' => 'Twitter',
|
||||
'reddit' => 'Reddit',
|
||||
'pinterest' => 'Pinterest',
|
||||
'whatsapp' => 'WhatsApp',
|
||||
'telegram' => 'Telegram',
|
||||
'fb-messenger' => 'Facebook Messenger',
|
||||
'wechat' => 'WeChat',
|
||||
'sms' => 'SMS',
|
||||
'slack' => 'Slack',
|
||||
'skype' => 'Skype',
|
||||
'hackernews' => 'Hacker News',
|
||||
'discord' => 'Discord',
|
||||
'mastodon' => 'Mastodon',
|
||||
'pocket' => 'Pocket',
|
||||
'flipboard' => 'Flipboard',
|
||||
'evernote' => 'Evernote',
|
||||
'trello' => 'Trello',
|
||||
'buffer' => 'Buffer',
|
||||
'tumblr' => 'Tumblr',
|
||||
'xing' => 'Xing',
|
||||
'linkedin' => 'LinkedIn',
|
||||
],
|
||||
];
|
12
lang/ro_RO/stats.php
Normal file
12
lang/ro_RO/stats.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'stats' => 'Statistici',
|
||||
'total_links' => 'Legături totale',
|
||||
'total_lists' => 'Liste totale',
|
||||
'total_tags' => 'Etichete totale',
|
||||
'total_notes' => 'Observații totale',
|
||||
'total_broken_links' => 'Legături nefuncționale',
|
||||
|
||||
];
|
28
lang/ro_RO/tag.php
Normal file
28
lang/ro_RO/tag.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
return [
|
||||
'tag' => 'Etichetă',
|
||||
'tags' => 'Etichete',
|
||||
'all_tags' => 'Toate etichetele',
|
||||
'recent_tags' => 'Etichete recente',
|
||||
|
||||
'add' => 'Adăugare etichetă',
|
||||
'show' => 'Afișare etichetă',
|
||||
'edit' => 'Editare etichetă',
|
||||
'update' => 'Actualizare etichetă',
|
||||
'delete' => 'Ștergere etichetă',
|
||||
|
||||
'filter_tags' => 'Filtrare etichete...',
|
||||
|
||||
'private' => 'Etichetă privată',
|
||||
|
||||
'name' => 'Denumirea etichetei',
|
||||
|
||||
'author' => 'de :user',
|
||||
|
||||
'no_tags' => 'Nu există etichete',
|
||||
|
||||
'added_successfully' => 'Eticheta a fost adăugată.',
|
||||
'updated_successfully' => 'Eticheta a fost actualizată.',
|
||||
'deleted_successfully' => 'Eticheta a fost ștearsă.',
|
||||
'deletion_error' => 'Eticheta nu a putut fi ștearsă.',
|
||||
];
|
31
lang/ro_RO/trash.php
Normal file
31
lang/ro_RO/trash.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'trash' => 'Coș de gunoi',
|
||||
|
||||
'deleted_links' => 'Legături șterse',
|
||||
'deleted_lists' => 'Liste șterse',
|
||||
'deleted_tags' => 'Etichete șterse',
|
||||
'deleted_notes' => 'Observații șterse',
|
||||
|
||||
'restore' => 'Restaurare înregistrare',
|
||||
|
||||
'clear_trash' => 'Golire coș de gunoi',
|
||||
'delete_warning' => 'Înregistrările șterse permanent nu pot fi restaurate!',
|
||||
'delete_no_entries' => 'Nu există înregistrări de șters.',
|
||||
|
||||
'delete_success.links' => 'Toate legăturile au fost șterse permanent.',
|
||||
'delete_success.lists' => 'Toate listele au fost șterse permanent.',
|
||||
'delete_success.tags' => 'Toate etichetele au fost șterse permanent.',
|
||||
'delete_success.notes' => 'Toate observațiile au fost șterse permanent.',
|
||||
|
||||
'restore.link' => 'Legătura a fost restaurată din coșul de gunoi.',
|
||||
'restore.list' => 'Lista a fost restaurată din coșul de gunoi.',
|
||||
'restore.tag' => 'Eticheta a fost restaurată din coșul de gunoi.',
|
||||
'restore.note' => 'Observația a fost restaurată din coșul de gunoi.',
|
||||
|
||||
'restore.not_found' => 'Elementul de restaurat nu a putut fi găsit.',
|
||||
'restore.not_allowed' => 'Nu ai permisiunea de a restaura acest element.',
|
||||
|
||||
];
|
10
lang/ro_RO/user.php
Normal file
10
lang/ro_RO/user.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
return [
|
||||
'user' => 'Utilizator',
|
||||
'users' => 'Utilizatori',
|
||||
|
||||
'username' => 'Nume de utilizator',
|
||||
'email' => 'Poștă electronică',
|
||||
|
||||
'hello' => 'Salut, :user!',
|
||||
];
|
146
lang/ro_RO/validation.php
Normal file
146
lang/ro_RO/validation.php
Normal file
@ -0,0 +1,146 @@
|
||||
<?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' => 'Câmpul :attribute trebuie să fie acceptat.',
|
||||
'active_url' => 'Câmpul :attribute nu este un URL valid.',
|
||||
'after' => 'Câmpul :attribute trebuie să fie o dată după :date.',
|
||||
'after_or_equal' => 'Câmpul :attribute trebuie să fie o dată ulterioară sau egală cu :date.',
|
||||
'alpha' => 'Câmpul :attribute poate conține doar litere.',
|
||||
'alpha_dash' => 'Câmpul :attribute poate conține doar litere, numere și cratime.',
|
||||
'alpha_num' => 'Câmpul :attribute poate conține doar litere și numere.',
|
||||
'array' => 'Câmpul :attribute trebuie să fie un array.',
|
||||
'before' => 'Câmpul :attribute trebuie să fie o dată înainte de :date.',
|
||||
'before_or_equal' => 'Câmpul :attribute trebuie să fie o dată înainte sau egală cu :date.',
|
||||
'between' => [
|
||||
'numeric' => ':attribute trebuie să fie între :min și :max.',
|
||||
'file' => ':attribute trebuie să aibă dimensiunea cuprinsă între :min și :max kilobaiți.',
|
||||
'string' => ':attribute trebuie să aibă între :min și :max caractere.',
|
||||
'array' => ':attribute trebuie să aibă între :min și :max elemente.',
|
||||
],
|
||||
'boolean' => 'Câmpul :attribute trebuie să fie adevărat sau fals.',
|
||||
'confirmed' => 'Confirmarea :attribute nu se potrivește.',
|
||||
'date' => 'Câmpul :attribute nu este o dată validă.',
|
||||
'date_format' => 'Câmpul :attribute trebuie să fie în formatul :format.',
|
||||
'different' => 'Câmpurile :attribute și :other trebuie să fie diferite.',
|
||||
'digits' => 'Câmpul :attribute trebuie să aibă :digits cifre.',
|
||||
'digits_between' => 'Câmpul :attribute trebuie să aibă între :min și :max cifre.',
|
||||
'dimensions' => 'Câmpul :attribute are dimensiuni de imagine nevalide.',
|
||||
'distinct' => 'Câmpul :attribute are o valoare duplicat.',
|
||||
'email' => 'Câmpul :attribute trebuie să fie o adresă de e-mail validă.',
|
||||
'exists' => 'Câmpul :attribute selectat nu este valid.',
|
||||
'file' => 'Câmpul :attribute trebuie să fie un fișier.',
|
||||
'filled' => 'Câmpul :attribute trebuie completat.',
|
||||
'gt' => [
|
||||
'numeric' => ':attribute trebuie să fie mai mare decât :value.',
|
||||
'file' => ':attribute trebuie să aibă dimensiunea mai mare decât :value kilobaiți.',
|
||||
'string' => ':attribute trebuie să aibă mai mult decât :value caractere.',
|
||||
'array' => ':attribute trebuie să aibă mai mult decât :value elemente.',
|
||||
],
|
||||
'gte' => [
|
||||
'numeric' => ':attribute trebuie să fie mai mare sau egal cu :value.',
|
||||
'file' => ':attribute trebuie să aibă dimensiunea egală cu sau mai mare decât :value kilobaiți.',
|
||||
'string' => ':attribute trebuie să fie mai mare sau egal cu :value caractere.',
|
||||
'array' => ':attribute trebuie să aibă :value elemente sau mai multe.',
|
||||
],
|
||||
'image' => 'Câmpul :attribute trebuie să fie o imagine.',
|
||||
'in' => 'Câmpul :attribute selectat nu este valid.',
|
||||
'in_array' => 'Câmpul :attribute nu există în :other.',
|
||||
'integer' => 'Câmpul :attribute trebuie să fie un număr întreg.',
|
||||
'ip' => 'Câmpul :attribute trebuie să fie o adresă IP validă.',
|
||||
'ipv4' => 'Câmpul :attribute trebuie să fie o adresă IPv4 validă.',
|
||||
'ipv6' => 'Câmpul :attribute trebuie să fie o adresă IPv6 validă.',
|
||||
'json' => 'Câmpul :attribute trebuie să fie un string JSON valid.',
|
||||
'lt' => [
|
||||
'numeric' => ':attribute trebuie să fie mai mic decât :value.',
|
||||
'file' => ':attribute trebuie să aibă dimensiunea mai mică decât :value kilobaiți.',
|
||||
'string' => ':attribute trebuie să aibă mai puțin decât :value caractere.',
|
||||
'array' => ':attribute trebuie să aibă mai puțin decât :value elemente.',
|
||||
],
|
||||
'lte' => [
|
||||
'numeric' => ':attribute trebuie să fie mai mic sau egal cu :value.',
|
||||
'file' => ':attribute trebuie să aibă dimensiunea egală cu sau mai mică decât :value kilobaiți.',
|
||||
'string' => ':attribute trebuie să fie mai mic sau egal cu :value caractere.',
|
||||
'array' => ':attribute nu trebuie să aibă mai mult decât :value elemente.',
|
||||
],
|
||||
'max' => [
|
||||
'numeric' => ':attribute nu poate fi mai mare decât :max.',
|
||||
'file' => ':attribute nu trebuie să aibă dimensiunea mai mare decât :max kilobaiți.',
|
||||
'string' => ':attribute nu trebuie să aibă mai mult decât :max caractere.',
|
||||
'array' => ':attribute nu trebuie să aibă mai mult decât :value elemente.',
|
||||
],
|
||||
'mimes' => 'Câmpul :attribute trebuie să fie un fișier de tipul: :values.',
|
||||
'mimetypes' => 'Câmpul :attribute trebuie să fie un fișier de tipul: :values.',
|
||||
'min' => [
|
||||
'numeric' => ':attribute trebuie sa aiba cel putin :min.',
|
||||
'file' => ':attribute trebuie să aibă dimensiunea de cel puțin :min kilobaiți.',
|
||||
'string' => ':attribute trebuie să aibă cel puțin :min caractere.',
|
||||
'array' => ':attribute trebuie să aibă cel puțin :min elemente.',
|
||||
],
|
||||
'not_in' => 'Câmpul :attribute selectat nu este valid.',
|
||||
'not_regex' => 'Câmpul :attribute nu are un format valid.',
|
||||
'numeric' => 'Câmpul :attribute trebuie să fie un număr.',
|
||||
'present' => 'Câmpul :attribute trebuie să fie prezent.',
|
||||
'regex' => 'Câmpul :attribute nu are un format valid.',
|
||||
'required' => 'Câmpul :attribute este obligatoriu.',
|
||||
'required_if' => 'Câmpul :attribute este necesar când :other este :value.',
|
||||
'required_unless' => 'Câmpul :attribute este necesar, cu excepția cazului :other este in :values.',
|
||||
'required_with' => 'Câmpul :attribute este necesar când există :values.',
|
||||
'required_with_all' => 'Câmpul :attribute este necesar când există :values.',
|
||||
'required_without' => 'Câmpul :attribute este necesar când nu există :values.',
|
||||
'required_without_all' => 'Câmpul :attribute este necesar când niciuna dintre valorile :values nu există.',
|
||||
'same' => 'Câmpurile :attribute și :other trebuie să fie identice.',
|
||||
'size' => [
|
||||
'numeric' => 'Câmpul :attribute trebuie să fie :size.',
|
||||
'file' => ':attribute trebuie să aibă dimensiunea de :size kilobaiți.',
|
||||
'string' => ':attribute trebuie sa aiba :size caractere.',
|
||||
'array' => 'Câmpul :attribute trebuie să aibă :size elemente.',
|
||||
],
|
||||
'string' => 'Câmpul :attribute trebuie să fie string.',
|
||||
'timezone' => 'Câmpul :attribute trebuie să fie un fus orar valid.',
|
||||
'unique' => 'Câmpul :attribute a fost deja folosit.',
|
||||
'uploaded' => 'Câmpul :attribute nu a reușit încărcarea.',
|
||||
'url' => 'Câmpul :attribute nu este un URL valid.',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| 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' => 'mesaj-personalizat',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| 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' => [],
|
||||
|
||||
];
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'password' => 'Mật khẩu phải gồm 6 ký tự và khớp với phần xác nhận.',
|
||||
'reset' => 'Mật khẩu của bạn đã được đặt lại!',
|
||||
'sent' => 'Hướng dẫn đặt lại mật khẩu đã được gửi vào email của bạn!',
|
||||
'sent' => 'Nếu một tài khoản với địa chỉ e-mail của bạn tồn tại, chúng tôi đã gửi e-mail liên kết đặt lại mật khẩu của bạn.',
|
||||
'token' => 'Token khởi tạo mật khẩu này không hợp lệ.',
|
||||
'user' => "Không tìm thấy người dùng với địa chỉ email này.",
|
||||
|
||||
|
@ -14,14 +14,15 @@ return [
|
||||
'empty_lists' => 'không có danh sách',
|
||||
|
||||
'order_by' => 'Sắp xếp bởi',
|
||||
'order_by.title:asc' => 'Tiêu đề tăng dần',
|
||||
'order_by.title:desc' => 'Tiêu đề giảm dần',
|
||||
'order_by.url:asc' => 'URL tăng dần',
|
||||
'order_by.url:desc' => 'URL giảm dần',
|
||||
'order_by.created_at:asc' => 'Ngày tạo giảm dần',
|
||||
'order_by.created_at:desc' => 'Ngày tạo tăng dần',
|
||||
'order_by.number_links:asc' => 'Số liên kết tăng dần',
|
||||
'order_by.number_links:desc' => 'Số liên kết giảm dần',
|
||||
'order_by.title:asc' => 'Tiêu đề A-Z',
|
||||
'order_by.title:desc' => 'Tiêu đề Z-A',
|
||||
'order_by.url:asc' => 'URL A-Z',
|
||||
'order_by.url:desc' => 'URL Z-A',
|
||||
'order_by.created_at:asc' => 'Cũ nhất',
|
||||
'order_by.created_at:desc' => 'Mới nhất',
|
||||
'order_by.number_links:asc' => 'Ít liên kết nhất',
|
||||
'order_by.number_links:desc' => 'Hầu hết các liên kết',
|
||||
'order_by.random' => 'Ngẫu Nhiên',
|
||||
|
||||
'no_results' => 'Không tìm thấy kết quả nào.',
|
||||
|
||||
|
@ -14,14 +14,15 @@ return [
|
||||
'empty_lists' => '没有列表',
|
||||
|
||||
'order_by' => '排序方式',
|
||||
'order_by.title:asc' => '按标题升序排序',
|
||||
'order_by.title:desc' => '按标题降序排序',
|
||||
'order_by.url:asc' => '按网址升序排序',
|
||||
'order_by.url:desc' => '按网址降序排序',
|
||||
'order_by.created_at:asc' => '按创建日期升序排序',
|
||||
'order_by.created_at:desc' => '按创建日期降序排序',
|
||||
'order_by.number_links:asc' => '链接数,升序',
|
||||
'order_by.number_links:desc' => '链接数,降序',
|
||||
'order_by.title:asc' => '标题A-Z',
|
||||
'order_by.title:desc' => '标题Z-A',
|
||||
'order_by.url:asc' => 'URL A-Z',
|
||||
'order_by.url:desc' => 'URL Z-A',
|
||||
'order_by.created_at:asc' => '最早创建',
|
||||
'order_by.created_at:desc' => '最新的',
|
||||
'order_by.number_links:asc' => '最少链接',
|
||||
'order_by.number_links:desc' => '最多链接',
|
||||
'order_by.random' => '随机',
|
||||
|
||||
'no_results' => '未找到任何结果。',
|
||||
|
||||
|
9255
package-lock.json
generated
9255
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "linkace",
|
||||
"version": "1.11.1",
|
||||
"version": "1.12.2",
|
||||
"description": "A small, selfhosted bookmark manager with advanced features, built with Laravel and Docker",
|
||||
"homepage": "https://github.com/Kovah/LinkAce",
|
||||
"repository": {
|
||||
@ -16,10 +16,10 @@
|
||||
"laravel-mix": "^6.0.31",
|
||||
"postcss": "^8.4.5",
|
||||
"sass": "^1.46.0",
|
||||
"sass-loader": "^12.4.0"
|
||||
"sass-loader": "^13.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"bootstrap": "^5.1.3",
|
||||
"bootstrap": "^5.2.3",
|
||||
"tom-select": "^2.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
12
resources/assets/sass/_variables-dark.scss
vendored
12
resources/assets/sass/_variables-dark.scss
vendored
@ -151,6 +151,11 @@ $card-cap-bg: $darkmode-bg;
|
||||
$card-bg: $darkmode-bg;
|
||||
|
||||
|
||||
// Inputs
|
||||
$input-group-addon-bg: $input-bg !default;
|
||||
$input-group-addon-border-color: $input-border-color !default;
|
||||
|
||||
|
||||
// List group
|
||||
$list-group-bg: $darkmode-bg;
|
||||
$list-group-color: $body-color;
|
||||
@ -167,10 +172,11 @@ $list-group-action-color: $white;
|
||||
$list-group-action-active-color: $white;
|
||||
$list-group-action-active-bg: $darkmode-bg-dark;
|
||||
|
||||
|
||||
// Alerts
|
||||
$alert-bg-level: +8;
|
||||
$alert-border-level: +7;
|
||||
$alert-color-level: -8;
|
||||
$alert-bg-scale: 70%;
|
||||
$alert-border-scale: 50%;
|
||||
$alert-color-scale: -60%;
|
||||
|
||||
// Code
|
||||
$code-background-color: $darkmode-bg;
|
||||
|
16
resources/assets/sass/_variables.scss
vendored
16
resources/assets/sass/_variables.scss
vendored
@ -87,14 +87,14 @@ $color-contrast-light: $white;
|
||||
|
||||
|
||||
// Options
|
||||
$enable-dark-mode: false;
|
||||
$enable-caret: false;
|
||||
|
||||
|
||||
// Body
|
||||
$body-bg: $white;
|
||||
$body-color: $black;
|
||||
$body-color-pale: $gray-600;
|
||||
$body-color-muted: $gray;
|
||||
$body-bg: $white;
|
||||
$body-secondary-color: $gray-600;
|
||||
|
||||
|
||||
// Links
|
||||
@ -106,6 +106,7 @@ $link-hover-decoration: none;
|
||||
|
||||
|
||||
// Components
|
||||
$border-width: 1px;
|
||||
$border-radius-xs: .2rem;
|
||||
|
||||
$line-height-sm: 1.5;
|
||||
@ -115,13 +116,11 @@ $link-thumbnail-placeholder-color: $gray-200;
|
||||
|
||||
// Typography
|
||||
$font-family-sans-serif: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
|
||||
$font-weight-normal: 400;
|
||||
$font-size-base: 1rem;
|
||||
$font-size-xs: $font-size-base * .75;
|
||||
|
||||
$font-weight-normal: 400;
|
||||
|
||||
$text-muted: $body-color-muted;
|
||||
$text-muted: $body-secondary-color;
|
||||
|
||||
|
||||
// Tables
|
||||
@ -130,6 +129,7 @@ $table-dark-color: $white;
|
||||
|
||||
|
||||
// Buttons + Forms
|
||||
$input-color: $body-color;
|
||||
$input-border-color: $gray-300;
|
||||
$input-btn-focus-width: .15rem;
|
||||
$input-btn-padding-y-xs: .15rem;
|
||||
@ -139,6 +139,8 @@ $input-btn-line-height-xs: $line-height-sm;
|
||||
|
||||
$input-placeholder-color: $text-muted;
|
||||
|
||||
$input-btn-border-width: $border-width;
|
||||
|
||||
|
||||
// Buttons
|
||||
$btn-padding-y-xs: $input-btn-padding-y-xs;
|
||||
|
6
resources/assets/sass/custom/_app.scss
vendored
6
resources/assets/sass/custom/_app.scss
vendored
@ -108,7 +108,7 @@ a.badge {
|
||||
}
|
||||
|
||||
.text-pale {
|
||||
color: $body-color-pale;
|
||||
color: $body-secondary-color;
|
||||
}
|
||||
|
||||
.btn-xs {
|
||||
@ -178,6 +178,10 @@ code {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.btn-cloud .btn {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.link-thumbnail {
|
||||
box-shadow: inset 0 0 1px $secondary;
|
||||
display: flex;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Bootstrap v5.2.0 (https://getbootstrap.com/)
|
||||
* Bootstrap v5.3.0 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2022 The Bootstrap Authors
|
||||
* Copyright 2011-2022 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
@ -9,6 +9,7 @@
|
||||
// Configuration
|
||||
//@import "~bootstrap/scss/functions";
|
||||
@import "~bootstrap/scss/variables";
|
||||
@import "~bootstrap/scss/variables-dark";
|
||||
@import "~bootstrap/scss/maps";
|
||||
@import "~bootstrap/scss/mixins";
|
||||
@import "~bootstrap/scss/utilities";
|
||||
|
@ -19,10 +19,11 @@ $select-color-optgroup: $white;
|
||||
$select-color-optgroup-text: $dropdown-header-color;
|
||||
$select-color-optgroup-border: $dropdown-divider-bg;
|
||||
$select-color-dropdown: $white;
|
||||
$select-color-dropdown-border-top: mix($input-border-color, $input-bg, 0.8);
|
||||
$select-color-dropdown-border-top: color-mix($input-border-color, $input-bg, 80%);
|
||||
$select-color-dropdown-item-active: $dropdown-link-hover-bg;
|
||||
$select-color-dropdown-item-active-text: $dropdown-link-hover-color;
|
||||
$select-color-dropdown-item-create-active-text: $dropdown-link-hover-color;
|
||||
$select-color-dropdown-item-create-text: rgba(red($select-color-text), green($select-color-text), blue($select-color-text), 0.5);
|
||||
$select-opacity-disabled: 0.5;
|
||||
$select-shadow-input: none;
|
||||
$select-shadow-input-focus: inset 0 1px 2px rgba($black, 0.15);
|
||||
|
@ -1,7 +1,7 @@
|
||||
# DOCKERFILE DEVELOPMENT
|
||||
# Installs MySQL Client for database exports, xDebug with PCov and Composer
|
||||
|
||||
FROM php:8.0-fpm
|
||||
FROM php:8.0.29-fpm
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
|
@ -1,7 +1,8 @@
|
||||
FROM php:8.2-fpm-alpine
|
||||
|
||||
# Install package and PHP dependencies
|
||||
RUN apk add --no-cache mariadb-client postgresql postgresql-dev zip libzip-dev; \
|
||||
RUN apk add --no-cache mariadb-client postgresql postgresql-dev sqlite zip libzip-dev; \
|
||||
docker-php-ext-configure zip; \
|
||||
docker-php-ext-install bcmath pdo_mysql pdo_pgsql zip; \
|
||||
mkdir /ssl-certs
|
||||
mkdir /ssl-certs; \
|
||||
docker-php-source delete
|
||||
|
@ -21,6 +21,15 @@ COPY ./.env.example /app/.env
|
||||
# Install dependencies using Composer
|
||||
RUN composer install -n --prefer-dist --no-dev
|
||||
|
||||
RUN mv vendor/spatie/laravel-backup/resources/lang/de vendor/spatie/laravel-backup/resources/lang/de_DE; \
|
||||
mv vendor/spatie/laravel-backup/resources/lang/en vendor/spatie/laravel-backup/resources/lang/en_US; \
|
||||
mv vendor/spatie/laravel-backup/resources/lang/es vendor/spatie/laravel-backup/resources/lang/es_ES; \
|
||||
mv vendor/spatie/laravel-backup/resources/lang/fr vendor/spatie/laravel-backup/resources/lang/fr_FR; \
|
||||
mv vendor/spatie/laravel-backup/resources/lang/it vendor/spatie/laravel-backup/resources/lang/it_IT; \
|
||||
mv vendor/spatie/laravel-backup/resources/lang/no vendor/spatie/laravel-backup/resources/lang/no_NO; \
|
||||
mv vendor/spatie/laravel-backup/resources/lang/pl vendor/spatie/laravel-backup/resources/lang/pl_PL; \
|
||||
mv vendor/spatie/laravel-backup/resources/lang/zh-CN vendor/spatie/laravel-backup/resources/lang/zh_CN
|
||||
|
||||
# ================================
|
||||
# Compile all assets
|
||||
FROM node:18 AS npm_builder
|
||||
@ -61,14 +70,6 @@ COPY --from=builder /app/bootstrap/cache /app/bootstrap/cache
|
||||
|
||||
# Publish package resources
|
||||
RUN php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider"
|
||||
RUN mv vendor/spatie/laravel-backup/resources/lang/de vendor/spatie/laravel-backup/resources/lang/de_DE; \
|
||||
mv vendor/spatie/laravel-backup/resources/lang/en vendor/spatie/laravel-backup/resources/lang/en_US; \
|
||||
mv vendor/spatie/laravel-backup/resources/lang/es vendor/spatie/laravel-backup/resources/lang/es_ES; \
|
||||
mv vendor/spatie/laravel-backup/resources/lang/fr vendor/spatie/laravel-backup/resources/lang/fr_FR; \
|
||||
mv vendor/spatie/laravel-backup/resources/lang/it vendor/spatie/laravel-backup/resources/lang/it_IT; \
|
||||
mv vendor/spatie/laravel-backup/resources/lang/no vendor/spatie/laravel-backup/resources/lang/no_NO; \
|
||||
mv vendor/spatie/laravel-backup/resources/lang/pl vendor/spatie/laravel-backup/resources/lang/pl_PL; \
|
||||
mv vendor/spatie/laravel-backup/resources/lang/zh-CN vendor/spatie/laravel-backup/resources/lang/zh_CN
|
||||
|
||||
# Copy files from the theme build
|
||||
COPY --from=npm_builder /srv/public/assets/dist/js /app/public/assets/dist/js
|
||||
|
@ -46,6 +46,7 @@ server {
|
||||
|
||||
try_files $uri /index.php;
|
||||
include fastcgi.conf;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_keep_conn on;
|
||||
fastcgi_intercept_errors on;
|
||||
fastcgi_index index.php;
|
||||
|
@ -138,6 +138,10 @@ use App\Enums\ModelAttribute;
|
||||
@lang('search.order_by.' . $order_by)
|
||||
</option>
|
||||
@endforeach
|
||||
<option value="random"
|
||||
@if($query_settings['order_by'] == 'random') selected @endif>
|
||||
@lang('search.order_by.random')
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@ -149,9 +153,11 @@ use App\Enums\ModelAttribute;
|
||||
<div class="card-table mt-4">
|
||||
|
||||
@if($results->isEmpty())
|
||||
<div class="alert alert-info m-3">
|
||||
@lang('search.no_results')
|
||||
</div>
|
||||
@if($query_settings['performed_search'])
|
||||
<div class="alert alert-info m-3">
|
||||
@lang('search.no_results')
|
||||
</div>
|
||||
@endif
|
||||
@else
|
||||
@include('app.search.partials.table', ['results' => $results])
|
||||
@endif
|
||||
|
@ -124,7 +124,7 @@
|
||||
@lang('list.recent_lists')
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="card-body btn-cloud">
|
||||
@forelse($recent_lists as $list)
|
||||
<a href="{{ route('lists.show', ['list' => $list]) }}" class="btn btn-light btn-sm m-1">
|
||||
<x-models.name-with-user :model="$list"/>
|
||||
@ -145,7 +145,7 @@
|
||||
@lang('tag.recent_tags')
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="card-body btn-cloud">
|
||||
@forelse($recent_tags as $tag)
|
||||
<a href="{{ route('tags.show', ['tag' => $tag]) }}" class="btn btn-light btn-sm m-1">
|
||||
<x-models.name-with-user :model="$tag"/>
|
||||
|
@ -28,4 +28,8 @@
|
||||
href="{{ route($baseRoute, ['orderBy' => 'title', 'orderDir' => 'desc']) }}">
|
||||
@lang('search.order_by.title:desc')
|
||||
</a>
|
||||
<a class="dropdown-item small"
|
||||
href="{{ route($baseRoute, ['orderBy' => 'random']) }}">
|
||||
@lang('search.order_by.random')
|
||||
</a>
|
||||
</div>
|
||||
|
1
storage/app/.gitignore
vendored
1
storage/app/.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
*
|
||||
!public/
|
||||
!backup-temp/
|
||||
!backups/
|
||||
!.gitignore
|
||||
|
2
storage/app/backups/.gitignore
vendored
Normal file
2
storage/app/backups/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
@ -27,7 +27,7 @@
|
||||
<DD>Free tool for web application load testing that allows for the simulation of concurrent connections to your web
|
||||
application&#39;s APIs
|
||||
<DT>
|
||||
<A HREF="https://astralapp.com/" ADD_DATE="1549404064" PRIVATE="0" TAGS="favourites,Github,organization">Astral —
|
||||
<A HREF="https://astralapp.com/" ADD_DATE="1549404064" TAGS="favourites,Github,organization">Astral —
|
||||
Organize Your GitHub Stars With Ease</A>
|
||||
<DD>Astral is the best way to manage your starred repositories on GitHub using tags, notes and a powerful search
|
||||
feature.
|
||||
|
@ -49,6 +49,22 @@ class LinkControllerTest extends TestCase
|
||||
->assertSee('https://public-link.com')
|
||||
->assertSee('https://internal-link.com')
|
||||
->assertDontSee('https://private-link.com');
|
||||
|
||||
$this->flushSession();
|
||||
$this->get('links?orderBy=created_at&orderDir=asc')
|
||||
->assertOk()
|
||||
->assertSeeInOrder([
|
||||
'https://linkace.example.com/test',
|
||||
'https://the-new-linkace.com',
|
||||
]);
|
||||
|
||||
$this->flushSession();
|
||||
$this->get('links?orderBy=created_at&orderDir=wrong-asc')
|
||||
->assertOk()
|
||||
->assertSeeInOrder([
|
||||
'https://the-new-linkace.com',
|
||||
'https://linkace.example.com/test',
|
||||
]);
|
||||
}
|
||||
|
||||
public function testCreateView(): void
|
||||
|
@ -33,6 +33,22 @@ class ListControllerTest extends TestCase
|
||||
->assertSee('Public List')
|
||||
->assertSee('Internal List')
|
||||
->assertDontSee('Private List');
|
||||
|
||||
$this->flushSession();
|
||||
$this->get('lists?orderBy=created_at&orderDir=desc')
|
||||
->assertOk()
|
||||
->assertSeeInOrder([
|
||||
'Super New List',
|
||||
'A Test List',
|
||||
]);
|
||||
|
||||
$this->flushSession();
|
||||
$this->get('lists?orderBy=created_at&orderDir=wrong-desc')
|
||||
->assertOk()
|
||||
->assertSeeInOrder([
|
||||
'A Test List',
|
||||
'Super New List',
|
||||
]);
|
||||
}
|
||||
|
||||
public function testIndexViewWithValidFilterResult(): void
|
||||
|
@ -29,6 +29,22 @@ class TagControllerTest extends TestCase
|
||||
$this->createTestTags();
|
||||
|
||||
$this->get('tags')->assertOk()->assertSee('Public Tag')->assertSee('Internal Tag')->assertDontSee('Private Tag');
|
||||
|
||||
$this->flushSession();
|
||||
$this->get('tags?orderBy=created_at&orderDir=desc')
|
||||
->assertOk()
|
||||
->assertSeeInOrder([
|
||||
'new-tag',
|
||||
'a-tag',
|
||||
]);
|
||||
|
||||
$this->flushSession();
|
||||
$this->get('tags?orderBy=created_at&orderDir=wrong-desc')
|
||||
->assertOk()
|
||||
->assertSeeInOrder([
|
||||
'a-tag',
|
||||
'new-tag',
|
||||
]);
|
||||
}
|
||||
|
||||
public function testIndexViewWithValidFilterResult(): void
|
||||
|
Loading…
x
Reference in New Issue
Block a user