Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Related links #1054

Open
wants to merge 28 commits into
base: dev/new_features
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
31c2f5d
related links
Aug 21, 2024
7debca3
related links
Aug 22, 2024
5e61bb1
related links
Aug 22, 2024
09a1a0d
php fixer
Aug 22, 2024
eb2daa7
Merge branch 'main' into related-links
Aug 22, 2024
8a3275b
cleaning
Aug 22, 2024
6c2ca55
Required changes.
Sep 2, 2024
8174113
docs(contributor): contrib-readme-action has updated readme
github-actions[bot] Sep 2, 2024
b750fa1
Merge remote-tracking branch 'origin/main' into related-links
Sep 2, 2024
3055403
Merge branch 'main' into related-links
JaviviJR Sep 3, 2024
3f043fd
Related links
JaviviJR Sep 4, 2024
68d6d11
Changes requested
JaviviJR Sep 16, 2024
a5b7f85
Changes requested
JaviviJR Sep 16, 2024
1d0f707
Changes requested
JaviviJR Sep 16, 2024
09a90b4
Introducing bookmarks (#1095)
BentiGorlich Oct 6, 2024
85bd770
Make related panels respect blocks (#1183)
BentiGorlich Oct 13, 2024
55cc85a
Improve search (#1167)
BentiGorlich Oct 16, 2024
f282a29
Merge branch 'dev/new_features' into related-links
melroy89 Nov 8, 2024
77b9631
Merge branch 'main' into dev/new_features
melroy89 Nov 8, 2024
552e4bf
Merge branch 'dev/new_features' into related-links
melroy89 Nov 8, 2024
498b961
Fix php cs fixer
melroy89 Nov 8, 2024
cf72318
Merge branch 'main' into dev/new_features
melroy89 Nov 8, 2024
f34d504
Merge branch 'dev/new_features' into related-links
melroy89 Nov 8, 2024
a8ea966
Introducing bookmarks (#1095)
BentiGorlich Oct 6, 2024
6992f10
Make related panels respect blocks (#1183)
BentiGorlich Oct 13, 2024
5fec24b
Improve search (#1167)
BentiGorlich Oct 16, 2024
9b44612
Fix checkmarks not being rendered correctly anymore (#1233)
BentiGorlich Nov 20, 2024
679d683
Merge branch 'dev/new_features' into related-links
BentiGorlich Nov 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions assets/controllers/form-related-links_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Controller } from '@hotwired/stimulus';

export default class extends Controller {
static targets = ['relatedContainer'];

static values = {
index: Number,
link: String,
};

connect() {
const container = this.element;
container
.querySelectorAll('.related-link-item')
.forEach((item) => {
this.#addButtonDeleteLink(item);
});
}

addRelatedElement() {
console.log('addRelatedElement method');

const item = document.createElement('span');
item.className = 'flex related-link-item';

const nodeLink = this.#htmlToNode(this.linkValue.replace(
/__name__/g,
this.indexValue,
));
item.append(nodeLink);

this.#addButtonDeleteLink(item);

this.relatedContainerTarget.appendChild(item);
this.indexValue++;
}

#addButtonDeleteLink(item) {
melroy89 marked this conversation as resolved.
Show resolved Hide resolved
const removeFormButton = document.createElement('button');
removeFormButton.innerText = '⌫';
melroy89 marked this conversation as resolved.
Show resolved Hide resolved
removeFormButton.className = 'btn';

item.append(removeFormButton);

removeFormButton.addEventListener('click', (e) => {
e.preventDefault();
item.remove();
});
}

#htmlToNode(html) {
const template = document.createElement('div');
template.innerHTML = html;
return template.firstChild;
}
}
19 changes: 19 additions & 0 deletions assets/styles/layout/_forms.scss
Original file line number Diff line number Diff line change
Expand Up @@ -525,3 +525,22 @@ div.input-box {
border-radius: var(--kbin-rounded-edges-radius) !important;
}
}

.related-link-fieldset {
border: 0;
margin: 0;
padding: 0;
}

.related-link-item {
align-items: center;
}

.related-link-item button {
padding: 0;
background: none;
font-size: 1.5rem;
border: 0;
color: var(--kbin-input-text-color);

}
4 changes: 4 additions & 0 deletions assets/styles/layout/_layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,10 @@ figure {
flex-wrap: wrap;
}

.flex-grow-1 {
flex-grow: 1;
}

pre, code {
white-space: pre-wrap;
word-wrap: break-word;
Expand Down
26 changes: 26 additions & 0 deletions migrations/Version20240822112013.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20240822112013 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add related links to user';
}

public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE "user" ADD related_links JSONB DEFAULT \'[]\' NOT NULL');
}

public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE "user" DROP related_links');
}
}
3 changes: 3 additions & 0 deletions src/DTO/UserDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class UserDto implements UserDtoInterface
public ?string $totpSecret = null;
public ?string $serverSoftware = null;
public ?string $serverSoftwareVersion = null;
public array $relatedLinks = [];

#[Assert\Callback]
public function validate(
Expand Down Expand Up @@ -91,6 +92,7 @@ public static function create(
?bool $isBot = null,
?bool $isAdmin = null,
?bool $isGlobalModerator = null,
array $relatedLinks = []
): self {
$dto = new UserDto();
$dto->id = $id;
Expand All @@ -107,6 +109,7 @@ public static function create(
$dto->isBot = $isBot;
$dto->isAdmin = $isAdmin;
$dto->isGlobalModerator = $isGlobalModerator;
$dto->relatedLinks = $relatedLinks;

return $dto;
}
Expand Down
13 changes: 13 additions & 0 deletions src/Entity/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface, Visibil
#[Column(type: 'string', nullable: false, options: ['default' => self::USER_TYPE_PERSON])]
public string $type;

#[Column(type: 'json', nullable: false, options: ['jsonb' => true, 'default' => '[]'])]
public array $relatedLinks = [];

public function __construct(
string $email,
string $username,
Expand Down Expand Up @@ -894,4 +897,14 @@ public function canUpdateUser(User $actor): bool
return $this->apDomain === $actor->apDomain;
}
}

public function getRelatedLinks(): array
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add phpDoc so we know which kind of array is returned? I really liked if the returned value would be of RelatedLink[] so an array of objects, so we can add some validation logic so we can mark links as "checked" or something so we know that the rel=me is actually correct

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed Discussed on element chat.
I don't know a elegant way to denormalize the json field from table and return it on get method. This'll required some dependencies inside entity that I think is not a good practice.
Instead, I created a RelatedLinkDTO class and this will be returned in UserDTO.

{
return $this->relatedLinks;
}

public function setRelatedLinks(array $relatedLinks): void
melroy89 marked this conversation as resolved.
Show resolved Hide resolved
{
$this->relatedLinks = $relatedLinks;
}
}
1 change: 1 addition & 0 deletions src/Factory/UserFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public function createDto(User $user): UserDto
'Service' === $user->type, // setting isBot
$user->isAdmin(),
$user->isModerator(),
$user->relatedLinks,
);

/** @var User $currentUser */
Expand Down
12 changes: 11 additions & 1 deletion src/Form/UserBasicType.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
use App\Form\EventListener\DisableFieldsOnUserEdit;
use App\Form\EventListener\ImageListener;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\UrlType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

Expand All @@ -31,7 +33,15 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
$builder
->add('username', TextType::class, ['required' => false])
->add('about', TextareaType::class, ['required' => false])
->add('submit', SubmitType::class);
->add('relatedLinks', CollectionType::class, [
'entry_type' => UrlType::class,
'entry_options' => ['label' => false],
'label' => false,
'allow_add' => true,
'allow_delete' => true,
])
->add('submit', SubmitType::class)
;

$builder->addEventSubscriber($this->disableUsernameFieldOnUserEdit);
$builder->addEventSubscriber($this->addAvatarFieldOnUserEdit);
Expand Down
2 changes: 2 additions & 0 deletions src/Service/UserManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ public function edit(User $user, UserDto $dto): User
$user->setTotpSecret($dto->totpSecret);
}

$user->relatedLinks = $dto->relatedLinks;

$user->lastActive = new \DateTime();

$this->entityManager->flush();
Expand Down
35 changes: 35 additions & 0 deletions templates/user/settings/profile.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,41 @@
}}) }}
{{ form_row(form.avatar, {label: 'avatar'}) }}
{{ form_row(form.cover, {label: 'cover'}) }}

melroy89 marked this conversation as resolved.
Show resolved Hide resolved
<fieldset class='related-link-fieldset'
{{ stimulus_controller('form-related-links') }}
data-form-related-links-index-value="{{ form.relatedLinks|length }}"
data-form-related-links-link-value="{{
form_widget(form.relatedLinks.vars.prototype, {
label: false,
row_attr: { class: 'flex-grow-1' }
})|e('html_attr')
}}"

>
<legend>{{ 'related_links'|trans }}</legend>

<div
class='related-links-group'
data-form-related-links-target="relatedContainer"
>
{% for item_form in form.relatedLinks %}
<span class='flex related-link-item'>
{{ form_widget(item_form, {
label: false,
row_attr: { class: 'flex-grow-1' }
}) }}
</span>
{% endfor %}
</div>

<button
type="button"
class="btn btn__primary"
{{ stimulus_action('form-related-links', 'addRelatedElement') }}
>Add link</button>
</fieldset>

<div class="row actions">
{{ form_row(form.submit, {label: 'save', attr: {class: 'btn btn__primary'}}) }}
</div>
Expand Down
1 change: 1 addition & 0 deletions translations/messages.en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -890,3 +890,4 @@ admin_users_suspended: Suspended
admin_users_banned: Banned
user_verify: Activate account
max_image_size: Maximum file size
related_links: Related links
melroy89 marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions translations/messages.es.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -532,3 +532,4 @@ marked_for_deletion_at: Marcado para eliminar el %date%
sort_by: Ordenar por
filter_by_subscription: Filtrar por suscripción
filter_by_federation: Filtrar por estado de la federación
related_links: Enlaces relacionados