[TWIG] Restructure user settings template, making it much easier to use and extend
This commit is contained in:
parent
6627006e61
commit
d52a043705
@ -50,15 +50,16 @@ class Avatar extends Component
|
|||||||
/**
|
/**
|
||||||
* @throws \App\Util\Exception\ClientException
|
* @throws \App\Util\Exception\ClientException
|
||||||
*/
|
*/
|
||||||
public function onPopulateProfileSettingsTabs(Request $request, &$tabs): bool
|
public function onPopulateSettingsTabs(Request $request, string $section, &$tabs): bool
|
||||||
{
|
{
|
||||||
// TODO avatar template shouldn't be on settings folder
|
if ($section === 'profile') {
|
||||||
$tabs[] = [
|
$tabs[] = [
|
||||||
'title' => 'Avatar',
|
'title' => 'Avatar',
|
||||||
'desc' => 'Change your avatar.',
|
'desc' => 'Change your avatar.',
|
||||||
'controller' => C\Avatar::settings_avatar($request),
|
'id' => 'settings-avatar',
|
||||||
];
|
'controller' => C\Avatar::settings_avatar($request),
|
||||||
|
];
|
||||||
|
}
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +127,6 @@ class Avatar extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ['_template' => 'settings/avatar.html.twig', 'avatar' => $form->createView()];
|
return ['_template' => 'avatar/settings.html.twig', 'avatar' => $form->createView()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,14 +54,16 @@ class Cover extends Plugin
|
|||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onPopulateProfileSettingsTabs(Request $request, &$tabs)
|
public function onPopulateSettingsTabs(Request $request, string $section, &$tabs)
|
||||||
{
|
{
|
||||||
$tabs[] = [
|
if ($section === 'profile') {
|
||||||
'title' => 'Cover',
|
$tabs[] = [
|
||||||
'desc' => 'Change your cover.',
|
'title' => 'Cover',
|
||||||
'controller' => C\Cover::coverSettings($request),
|
'desc' => 'Change your cover.',
|
||||||
];
|
'id' => 'settings-cover',
|
||||||
|
'controller' => C\Cover::coverSettings($request),
|
||||||
|
];
|
||||||
|
}
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,9 +41,9 @@ class EmailNotifications extends Plugin
|
|||||||
{
|
{
|
||||||
public function onAddNotificationTransport(&$form_defs): bool
|
public function onAddNotificationTransport(&$form_defs): bool
|
||||||
{
|
{
|
||||||
$form_defs['email'] = $form_defs['placeholder'];
|
$form_defs['Email'] = $form_defs['placeholder'];
|
||||||
$form_defs['email'][] = $form_defs['placeholder']['save']('Email', 'save_email');
|
$form_defs['Email'][] = $form_defs['placeholder']['save']('Email', 'save_email');
|
||||||
unset($form_defs['email']['post_on_status_change']);
|
unset($form_defs['Email']['post_on_status_change']);
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,17 +28,13 @@ use App\Core\Event;
|
|||||||
use App\Core\Modules\Plugin;
|
use App\Core\Modules\Plugin;
|
||||||
use App\Core\Router\RouteLoader;
|
use App\Core\Router\RouteLoader;
|
||||||
use App\Core\Router\Router;
|
use App\Core\Router\Router;
|
||||||
use App\Entity\Actor;
|
|
||||||
use App\Entity\LocalUser;
|
use App\Entity\LocalUser;
|
||||||
use App\Util\Common;
|
use App\Util\Common;
|
||||||
use App\Util\Exception\ClientException;
|
|
||||||
use App\Util\Exception\NotFoundException;
|
use App\Util\Exception\NotFoundException;
|
||||||
use App\Util\Exception\RedirectException;
|
use App\Util\Exception\RedirectException;
|
||||||
use App\Util\Exception\ServerException;
|
use App\Util\Exception\ServerException;
|
||||||
use App\Util\Formatting;
|
|
||||||
use Plugin\Oomox\Controller as C;
|
use Plugin\Oomox\Controller as C;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use function App\Core\I18n\_m;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Profile Colour plugin main class
|
* Profile Colour plugin main class
|
||||||
@ -52,12 +48,8 @@ use function App\Core\I18n\_m;
|
|||||||
*/
|
*/
|
||||||
class Oomox extends Plugin
|
class Oomox extends Plugin
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map URLs to actions
|
* Map URLs to actions
|
||||||
*
|
|
||||||
* @param RouteLoader $r
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function onAddRoute(RouteLoader $r): bool
|
public function onAddRoute(RouteLoader $r): bool
|
||||||
{
|
{
|
||||||
@ -66,55 +58,49 @@ class Oomox extends Plugin
|
|||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populates an additional profile user panel section
|
* Populates an additional profile user panel section
|
||||||
* Used in templates/settings/base.html.twig
|
* Used in templates/settings/base.html.twig
|
||||||
*
|
*
|
||||||
* @param Request $request
|
* @throws \App\Util\Exception\NoLoggedInUser
|
||||||
* @param array $tabs
|
|
||||||
* @return bool
|
|
||||||
* @throws RedirectException
|
* @throws RedirectException
|
||||||
* @throws ServerException
|
* @throws ServerException
|
||||||
* @throws \App\Util\Exception\NoLoggedInUser
|
|
||||||
*/
|
*/
|
||||||
public function onPopulateProfileSettingsTabs(Request $request, array &$tabs): bool
|
public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): bool
|
||||||
{
|
{
|
||||||
$tabs[] = [
|
if ($section === 'colours') {
|
||||||
'title' => 'Light theme colours',
|
$tabs[] = [
|
||||||
'desc' => 'Change the theme colours.',
|
'title' => 'Light theme colours',
|
||||||
'controller' => C\Oomox::oomoxSettingsLight($request),
|
'desc' => 'Change the theme colours.',
|
||||||
];
|
'id' => 'settings-light-theme-colours-details',
|
||||||
|
'controller' => C\Oomox::oomoxSettingsLight($request),
|
||||||
$tabs[] = [
|
];
|
||||||
'title' => 'Dark theme colours',
|
|
||||||
'desc' => 'Change the theme colours.',
|
|
||||||
'controller' => C\Oomox::oomoxSettingsDark($request),
|
|
||||||
];
|
|
||||||
|
|
||||||
|
$tabs[] = [
|
||||||
|
'title' => 'Dark theme colours',
|
||||||
|
'desc' => 'Change the theme colours.',
|
||||||
|
'id' => 'settings-dark-theme-colours-details',
|
||||||
|
'controller' => C\Oomox::oomoxSettingsDark($request),
|
||||||
|
];
|
||||||
|
}
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns Oomox cache key for the given user.
|
* Returns Oomox cache key for the given user.
|
||||||
*
|
|
||||||
* @param LocalUser $user
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function cacheKey(LocalUser $user) :string {
|
public static function cacheKey(LocalUser $user): string
|
||||||
|
{
|
||||||
return "oomox-css-{$user->getId()}";
|
return "oomox-css-{$user->getId()}";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns Entity\Oomox if it already exists
|
* Returns Entity\Oomox if it already exists
|
||||||
*
|
|
||||||
* @param LocalUser $user
|
|
||||||
* @return Entity\Oomox|null
|
|
||||||
*/
|
*/
|
||||||
public static function getEntity(LocalUser $user): ?Entity\Oomox
|
public static function getEntity(LocalUser $user): ?Entity\Oomox
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return Cache::get(self::cacheKey($user), fn() => DB::findOneBy('oomox', ['actor_id' => $user->getId()]));
|
return Cache::get(self::cacheKey($user), fn () => DB::findOneBy('oomox', ['actor_id' => $user->getId()]));
|
||||||
} catch (NotFoundException $e) {
|
} catch (NotFoundException $e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -123,14 +109,12 @@ class Oomox extends Plugin
|
|||||||
/**
|
/**
|
||||||
* Adds to array $styles the generated CSS according to user settings, if any are present.
|
* Adds to array $styles the generated CSS according to user settings, if any are present.
|
||||||
*
|
*
|
||||||
* @param array $styles
|
|
||||||
* @param string $route
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function onEndShowStyles(array &$styles, string $route)
|
public function onEndShowStyles(array &$styles, string $route)
|
||||||
{
|
{
|
||||||
$user = Common::user();
|
$user = Common::user();
|
||||||
if (!is_null($user) && !is_null(Cache::get(self::cacheKey($user), fn () => self::getEntity($user)))) {
|
if (!\is_null($user) && !\is_null(Cache::get(self::cacheKey($user), fn () => self::getEntity($user)))) {
|
||||||
$styles[] = Router::url('oomox_css');
|
$styles[] = Router::url('oomox_css');
|
||||||
}
|
}
|
||||||
return Event::next;
|
return Event::next;
|
||||||
|
@ -61,15 +61,16 @@ class ProfileColor extends Plugin
|
|||||||
* @throws RedirectException
|
* @throws RedirectException
|
||||||
* @throws ServerException
|
* @throws ServerException
|
||||||
*/
|
*/
|
||||||
public function onPopulateProfileSettingsTabs(Request $request, array &$tabs): bool
|
public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): bool
|
||||||
{
|
{
|
||||||
// TODO avatar template shouldn't be on settings folder
|
if ($section === 'colours') {
|
||||||
$tabs[] = [
|
$tabs[] = [
|
||||||
'title' => 'Color',
|
'title' => 'Profile Colour',
|
||||||
'desc' => 'Change your profile color.',
|
'desc' => 'Change your profile colour.',
|
||||||
'controller' => C\ProfileColor::profileColorSettings($request),
|
'id' => 'settings-profile-colour-details',
|
||||||
];
|
'controller' => C\ProfileColor::profileColorSettings($request),
|
||||||
|
];
|
||||||
|
}
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +41,8 @@ class XMPPNotifications extends Plugin
|
|||||||
{
|
{
|
||||||
public function onAddNotificationTransport(&$form_defs): bool
|
public function onAddNotificationTransport(&$form_defs): bool
|
||||||
{
|
{
|
||||||
$form_defs['xmpp'] = $form_defs['placeholder'];
|
$form_defs['XMPP'] = $form_defs['placeholder'];
|
||||||
$form_defs['xmpp'][] = $form_defs['placeholder']['save']('XMMP', 'save_xmpp');
|
$form_defs['XMPP'][] = $form_defs['placeholder']['save']('XMMP', 'save_xmpp');
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,10 +95,10 @@ class UserPanel extends Controller
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'_template' => 'settings/base.html.twig',
|
'_template' => 'settings/base.html.twig',
|
||||||
'profile' => $personal_form->createView(),
|
'personal_info_form' => $personal_form->createView(),
|
||||||
'email' => $email_form->createView(),
|
'email_form' => $email_form->createView(),
|
||||||
'password' => $password_form->createView(),
|
'password_form' => $password_form->createView(),
|
||||||
'language' => $language_form->createView(),
|
'language_form' => $language_form->createView(),
|
||||||
'tabbed_forms_notify' => $notifications_form_array,
|
'tabbed_forms_notify' => $notifications_form_array,
|
||||||
'open_details_query' => $this->string('open'),
|
'open_details_query' => $this->string('open'),
|
||||||
];
|
];
|
||||||
@ -327,8 +327,11 @@ class UserPanel extends Controller
|
|||||||
$tabbed_forms = [];
|
$tabbed_forms = [];
|
||||||
foreach ($form_defs as $transport_name => $f) {
|
foreach ($form_defs as $transport_name => $f) {
|
||||||
unset($f['save']);
|
unset($f['save']);
|
||||||
$form = Form::create($f);
|
$form = Form::create($f);
|
||||||
$tabbed_forms[$transport_name] = $form;
|
$tabbed_forms[$transport_name]['title'] = $transport_name;
|
||||||
|
$tabbed_forms[$transport_name]['desc'] = _m('{transport} notification settings', ['transport' => $transport_name]);
|
||||||
|
$tabbed_forms[$transport_name]['id'] = "settings-notifications-{$transport_name}";
|
||||||
|
$tabbed_forms[$transport_name]['form'] = $form->createView();
|
||||||
|
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
@ -353,7 +356,6 @@ class UserPanel extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$tabbed_forms = F\map($tabbed_forms, fn ($f) => $f->createView());
|
|
||||||
return $tabbed_forms;
|
return $tabbed_forms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,8 +8,11 @@
|
|||||||
<link rel="stylesheet" href="{{ asset('assets/default_theme/css/pages/settings.css') }}">
|
<link rel="stylesheet" href="{{ asset('assets/default_theme/css/pages/settings.css') }}">
|
||||||
{% endblock stylesheets %}
|
{% endblock stylesheets %}
|
||||||
|
|
||||||
{% macro settings_details_element(title, summary, form_name, context) %}
|
{% macro settings_details_element(title, summary, id, details_content, context, details_ids) %}
|
||||||
<details class="section-title-settings" {{ open_details(context.open_details_query, [ form_name ]) }} id={{ form_name ~ '-details' }}>
|
{% if details_ids is null %}
|
||||||
|
{% set details_ids = [id] %}
|
||||||
|
{% endif %}
|
||||||
|
<details class="section-title-settings" {{ open_details(context.open_details_query, details_ids) }} id={{ id }}>
|
||||||
<summary>
|
<summary>
|
||||||
<h3>
|
<h3>
|
||||||
{{ title | trans }}
|
{{ title | trans }}
|
||||||
@ -20,87 +23,37 @@
|
|||||||
</em>
|
</em>
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
|
{% if details_content is instanceof('Twig\\Markup') %}
|
||||||
{{ form(attribute(context, form_name) | default) }}
|
{{ details_content }}
|
||||||
|
{% else %}
|
||||||
|
{{ form(details_content) }}
|
||||||
|
{% endif %}
|
||||||
</details>
|
</details>
|
||||||
{% endmacro settings_details_element %}
|
{% endmacro settings_details_element %}
|
||||||
|
|
||||||
{% macro settings_details_container(title, summary, tabs, context) %}
|
{% macro settings_details_container(title, summary, container_id, tabs, context) %}
|
||||||
<details class="section-title-settings" {{ open_details(context.open_details_query, tabs) }} id={{ tabs[0] ~ '-details' }}>
|
{% set children_ids = [container_id] %}
|
||||||
<summary>
|
{% set details_content %}
|
||||||
<h3>
|
<nav class='section-settings-nav'>
|
||||||
{{ title | trans }}
|
<ul>
|
||||||
{{ icon('arrow-down', 'icon icon-details-open') | raw }}
|
{% for tab in tabs %}
|
||||||
</h3>
|
<hr>
|
||||||
<em>
|
<li>
|
||||||
{{ summary | trans }}
|
{% set content %}
|
||||||
</em>
|
{% if tab['controller'] is defined %}
|
||||||
</summary>
|
{% include tab['controller']['_template'] with tab['controller'] only %}
|
||||||
|
{% else %}
|
||||||
|
{{ form(tab['form']) }}
|
||||||
{% if title == 'Profile' %}
|
{% endif %}
|
||||||
<li>
|
{% endset %}
|
||||||
<nav class='section-settings-nav'>
|
{{ _self.settings_details_element(tab['title'], tab['desc'], tab['id'] ~ '-details', content, context) }}
|
||||||
<ul>
|
{% set children_ids = children_ids|merge([tab['id'] ~ '-details']) %}
|
||||||
<li>
|
</li>
|
||||||
{{ _self.settings_details_element('Personal Info', 'Nickname, Homepage, Bio, Self Tags and more.', 'profile', context) }}
|
{% endfor %}
|
||||||
</li>
|
</ul>
|
||||||
|
</nav>
|
||||||
<hr>
|
{% endset %}
|
||||||
|
{{ _self.settings_details_element(title, summary, container_id, details_content, context, children_ids) }}
|
||||||
{% for tab in context.profile_tabs %}
|
|
||||||
<li>
|
|
||||||
<details class="section-title-settings"> {# TODO: add ID and open_details and to parent #}
|
|
||||||
<summary>
|
|
||||||
<h3>{{ tab['title'] }}{{ icon('arrow-down', 'icon icon-details-open') | raw }}</h3>
|
|
||||||
<em>{{ tab['desc'] }}</em>
|
|
||||||
</summary>
|
|
||||||
|
|
||||||
{% include tab['controller']['_template'] with tab['controller'] only %}
|
|
||||||
</details>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</li>
|
|
||||||
{% elseif title == 'Email' %}
|
|
||||||
<li>
|
|
||||||
{{ form(context.email) }}
|
|
||||||
</li>
|
|
||||||
{% elseif title == 'Password' %}
|
|
||||||
<li>
|
|
||||||
{{ form(context.password) }}
|
|
||||||
</li>
|
|
||||||
{% elseif title == 'Language' %}
|
|
||||||
<li>
|
|
||||||
{{ form(context.language) }}
|
|
||||||
</li>
|
|
||||||
{% elseif title == 'Notifications' %}
|
|
||||||
<li>
|
|
||||||
<nav class='section-settings-nav'>
|
|
||||||
<ul>
|
|
||||||
{% for transport, form_transport in context.tabbed_forms_notify %}
|
|
||||||
<li>
|
|
||||||
<details class="section-title-settings">
|
|
||||||
<summary>
|
|
||||||
<h3>{{ transport }}{{ icon('arrow-down', 'icon icon-details-open') | raw }}</h3>
|
|
||||||
<em>{{ transport }}'s notification options.</em>
|
|
||||||
</summary>
|
|
||||||
|
|
||||||
<div id="form_{{ transport }}" class='form'>
|
|
||||||
{{ form(form_transport) }}
|
|
||||||
</div>
|
|
||||||
</details>
|
|
||||||
</li>
|
|
||||||
<hr>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
</details>
|
|
||||||
{% endmacro settings_details_container %}
|
{% endmacro settings_details_container %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
@ -108,22 +61,28 @@
|
|||||||
<h2>Settings</h2>
|
<h2>Settings</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
{% set profile_tabs = handle_event('PopulateProfileSettingsTabs', app.request) %}
|
{% set profile_tabs = [{'title': 'Personal Info', 'desc': 'Nickname, Homepage, Bio, Self Tags and more.', 'id': 'settings-personal-info', 'form': personal_info_form}] %}
|
||||||
{{ _self.settings_details_container('Profile', 'Personal Information, Avatar and Profile', ['profile', 'personal-info'], _context) }}
|
{% set profile_tabs = profile_tabs|merge(handle_event('PopulateSettingsTabs', app.request, 'profile')) %}
|
||||||
|
{{ _self.settings_details_container('Profile', 'Personal Information, Avatar and Profile', 'settings-profile-details', profile_tabs, _context) }}
|
||||||
</li>
|
</li>
|
||||||
<hr>
|
<hr>
|
||||||
<li>
|
<li>
|
||||||
{{ _self.settings_details_container('Email', 'Set incoming and outgoing email settings', ['email'], _context) }}
|
{{ _self.settings_details_element('Email', 'Set incoming and outgoing email settings', 'settings-email-details', email_form, _context) }}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
{{ _self.settings_details_container('Password', 'Change current password', ['password'], _context) }}
|
{{ _self.settings_details_element('Password', 'Change current password', 'settings-password-details', password_form, _context) }}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
{{ _self.settings_details_container('Language', 'Select and set language preferences', ['language'], _context) }}
|
{{ _self.settings_details_element('Language', 'Select and set language preferences', 'settings-language-details', language_form, _context) }}
|
||||||
</li>
|
</li>
|
||||||
<hr>
|
<hr>
|
||||||
<li>
|
<li>
|
||||||
{{ _self.settings_details_container('Notifications', 'Enable/disable notifications (Email, XMPP, Replies...)', ['notifications'], _context) }}
|
{% set colour_tabs = handle_event('PopulateSettingsTabs', app.request, 'colours') %}
|
||||||
|
{{ _self.settings_details_container('Colours', 'Customize your interface colours', 'settings-colour-details', colour_tabs, _context) }}
|
||||||
|
</li>
|
||||||
|
<hr>
|
||||||
|
<li>
|
||||||
|
{{ _self.settings_details_container('Notifications', 'Enable/disable notifications (Email, XMPP, Replies...)', 'notifications', tabbed_forms_notify, _context) }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
Loading…
Reference in New Issue
Block a user