Skip to content

Commit

Permalink
Notify users if a link already exists in create and edit forms (#318)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kovah committed Oct 6, 2021
1 parent 7974f1d commit 792de8b
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 16 deletions.
2 changes: 2 additions & 0 deletions app/Http/Controllers/App/BookmarkletController.php
Expand Up @@ -3,6 +3,7 @@
namespace App\Http\Controllers\App;

use App\Http\Controllers\Controller;
use App\Models\Link;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
Expand Down Expand Up @@ -43,6 +44,7 @@ public function getLinkAddForm(Request $request)
session(['bookmarklet.create' => true]);

return view('app.bookmarklet.create', [
'existing_link' => Link::withTrashed()->whereUrl($newUrl)->first() ?: false,
'bookmark_url' => $newUrl,
'bookmark_title' => $newTitle,
'bookmark_description' => $newDescription,
Expand Down
10 changes: 7 additions & 3 deletions app/Http/Controllers/FetchController.php
Expand Up @@ -92,11 +92,15 @@ public function searchExistingUrls(Request $request): JsonResponse
return response()->json([]);
}

$linkCount = Link::byUser(auth()->user()->id)
$link = Link::byUser(auth()->user()->id)
->where('url', trim($query))
->count();
->where('id', '!=', $request->input('ignore_id', 0))
->first();

return response()->json(['linkFound' => $linkCount > 0]);
return response()->json([
'linkFound' => $link !== null,
'editLink' => $link ? route('links.edit', ['link' => $link]) : null,
]);
}

/**
Expand Down
5 changes: 4 additions & 1 deletion app/Http/Controllers/Models/LinkController.php
Expand Up @@ -49,7 +49,9 @@ public function create(): View
// Reset the bookmarklet session identifier to prevent issues on regular pages
session()->forget('bookmarklet.create');

return view('models.links.create');
return view('models.links.create', [
'existing_link' => null,
]);
}

/**
Expand Down Expand Up @@ -115,6 +117,7 @@ public function edit(Link $link): View
{
return view('models.links.edit', [
'link' => $link,
'existing_link' => null,
]);
}

Expand Down
11 changes: 9 additions & 2 deletions resources/assets/js/components/UrlField.js
Expand Up @@ -8,6 +8,8 @@ export default class UrlField {
this.$field = $el;

this.$field.addEventListener('keyup', this.onKeyup.bind(this));
this.$linkExistsWarning = document.querySelector('.link-exists');
this.$linkExistsLink = this.$linkExistsWarning.querySelector('a');

const $tags = document.querySelector('#tags');
this.tagSuggestions = $tags ? getInstance($tags, TagsSelect) : null;
Expand All @@ -20,14 +22,14 @@ export default class UrlField {

// Check for existing links if the value is longer than http://
if (value.length > 6) {
this.checkforExistingUrl(value);
this.checkForExistingUrl(value);
} else {
this.resetField();
}
});
}

checkforExistingUrl (url) {
checkForExistingUrl (url) {
const checkUrl = window.appData.routes.fetch.existingLinks;

fetch(checkUrl, {
Expand All @@ -36,6 +38,7 @@ export default class UrlField {
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
_token: window.appData.user.token,
ignore_id: this.$field.dataset.ignoreId ?? null,
query: url
})
}).then((response) => {
Expand All @@ -45,8 +48,12 @@ export default class UrlField {
// If the link already exist, mark the field as invalid
if (result.linkFound === true) {
this.$field.classList.add('is-invalid');
this.$linkExistsLink.href = result.editLink;
this.$linkExistsWarning.classList.remove('d-none');
} else {
this.$field.classList.remove('is-invalid');
this.$linkExistsWarning.classList.add('d-none');
this.$linkExistsLink.href = '';
this.querySiteForMetaTags(url);
}

Expand Down
1 change: 1 addition & 0 deletions resources/lang/en_US/link.php
Expand Up @@ -59,6 +59,7 @@
'deletion_error' => 'Link could not be deleted.',

'duplicates_found' => 'LinkAce found possible duplicates of the submitted URL:',
'existing_found' => 'A Link with that URL already exists.',

'notifications.linkcheck.errors' => 'LinkAce found errors while checking your Links.',
'notifications.linkcheck.errors.moved' => '⚠ ️The following Links moved to a new location:',
Expand Down
6 changes: 5 additions & 1 deletion resources/views/models/links/edit.blade.php
Expand Up @@ -16,10 +16,14 @@

<div class="form-group">
<label class="label" for="url">@lang('link.url')</label>
<input name="url" id="url" type="url"
<input name="url" id="url" type="url" data-ignore-id="{{ $link->id }}"
class="form-control form-control-lg{{ $errors->has('url') ? ' is-invalid' : '' }}"
placeholder="@lang('placeholder.link_url')" value="{{ old('url') ?: $link->url }}"
required autofocus>
<p class="invalid-feedback link-exists {{ $existing_link ? '' : 'd-none' }}">
@lang('link.existing_found')
<a href="{{ route('links.edit', [$existing_link->id ?? 0]) }}">@lang('link.edit')</a>
</p>
@if ($errors->has('url'))
<p class="invalid-feedback" role="alert">
{{ $errors->first('url') }}
Expand Down
19 changes: 10 additions & 9 deletions resources/views/models/links/partials/create-form.blade.php
Expand Up @@ -10,19 +10,20 @@
<div class="form-group">
<label class="label" for="url">@lang('link.url')</label>
<input name="url" id="url" type="url"
class="form-control form-control-lg{{ $errors->has('url') ? ' is-invalid' : '' }}"
class="form-control form-control-lg{{ $errors->has('url') || $existing_link ? ' is-invalid' : '' }}"
placeholder="@lang('placeholder.link_url')" value="{{ old('url') ?: $bookmark_url ?? '' }}"
required autofocus>

<p class="invalid-feedback {{ $errors->has('url') ? 'd-none' : '' }}">
@lang('validation.unique', ['attribute' => trans('link.url')])
<p class="invalid-feedback link-exists {{ $existing_link ? '' : 'd-none' }}">
@lang('link.existing_found')
<a href="{{ route('links.edit', [$existing_link->id ?? 0]) }}">@lang('link.edit')</a>
</p>

@if ($errors->has('url'))
<p class="invalid-feedback" role="alert">
{{ $errors->first('url') }}
</p>
@endif
@error('url')
<p class="invalid-feedback" role="alert">
{{ $errors->first('url') }}
</p>
@enderror
</div>

<div class="row">
Expand All @@ -44,7 +45,7 @@ class="form-control{{ $errors->has('title') ? ' is-invalid' : '' }}"
<div class="form-group">
<label for="description">@lang('link.description')</label>
<textarea name="description" id="description" rows="4" class="form-control"
>{{ old('description') ?: $bookmark_description ?? '' }}</textarea>
>{{ old('description') ?: $bookmark_description ?? '' }}</textarea>

@if ($errors->has('description'))
<p class="invalid-feedback" role="alert">
Expand Down
15 changes: 15 additions & 0 deletions tests/Controller/App/BookmarkletControllerTest.php
Expand Up @@ -2,6 +2,7 @@

namespace Tests\Controller\App;

use App\Models\Link;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
Expand All @@ -22,6 +23,20 @@ public function testValidBookmarkletResponse(): void
->assertSee('Example Title');
}

public function testBookmarkletWithExistingLink(): void
{
Link::factory()->create([
'url' => 'https://example.com/test',
]);

$user = User::factory()->create();
$this->actingAs($user);

$response = $this->get('bookmarklet/add?u=https://example.com/test&t=Example%20Title');

$response->assertOk()->assertSee('A Link with that URL already exists.');
}

public function testLoginRedirectForBookmarklet(): void
{
$response = $this->get('bookmarklet/add?u=https://example.com&t=Example%20Title');
Expand Down

0 comments on commit 792de8b

Please sign in to comment.