Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@

declare(strict_types=1);

use ILIAS\Filesystem\Stream\Streams;
use ILIAS\HTTP\Response\ResponseHeader;
use ILIAS\HTTP\Services;
use ILIAS\UI\Factory as UIFactory;
use ILIAS\UI\Renderer as UIRenderer;

/**
* Class ilBuddySystemGUI
Expand All @@ -39,6 +43,8 @@ class ilBuddySystemGUI
protected ilLanguage $lng;
protected Services $http;
private readonly ilGlobalTemplateInterface $main_tpl;
private UIFactory $ui_factory;
private UIRenderer $ui_renderer;

public function __construct()
{
Expand All @@ -49,6 +55,8 @@ public function __construct()
$this->ctrl = $DIC['ilCtrl'];
$this->user = $DIC['ilUser'];
$this->lng = $DIC['lng'];
$this->ui_factory = $DIC->ui()->factory();
$this->ui_renderer = $DIC->ui()->renderer();

$this->buddyList = ilBuddyList::getInstanceByGlobalUser();
$this->stateFactory = ilBuddySystemRelationStateFactory::getInstance();
Expand All @@ -68,8 +76,14 @@ public static function initializeFrontend(ilGlobalTemplateInterface $page): void
$DIC->language()->loadLanguageModule('buddysystem');

$page->addJavaScript('./assets/js/buddy_system.js');
$page->addJavaScript('./assets/js/modal.min.js');

$config = new stdClass();
$config->async_get_unlink_modal_confirmation_html = $DIC->ctrl()->getLinkTargetByClass([
ilUIPluginRouterGUI::class,
self::class
], 'asyncGetUnlinkModalConfirmationHtml', '', true, false);

$config->http_post_url = $DIC->ctrl()->getFormActionByClass([
ilUIPluginRouterGUI::class,
self::class
Expand All @@ -87,6 +101,32 @@ public static function initializeFrontend(ilGlobalTemplateInterface $page): void
}
}

public function asyncGetUnlinkModalConfirmationHtmlCommand(): never
{
$confirmation_modal = $this->ui_factory->modal()->interruptive(
$this->lng->txt('confirmation'),
$this->lng->txt('buddy_confirm_unlink'),
''
)
->withActionButtonLabel($this->lng->txt('confirm'));

$this->http->saveResponse(
$this->http->response()->withBody(
Streams::ofString(
json_encode([
"html" => $this->ui_renderer->renderAsync($confirmation_modal),
"signals" => [
"show" => $confirmation_modal->getShowSignal()->getId(),
"close" => $confirmation_modal->getCloseSignal()->getId()
]
], JSON_THROW_ON_ERROR)
)
)->withHeader(ResponseHeader::CONTENT_TYPE, 'application/json')
);
$this->http->sendResponse();
$this->http->close();
}

/**
* @throws RuntimeException
*/
Expand Down
113 changes: 88 additions & 25 deletions components/ILIAS/Contact/resources/buddy_system.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@

const BuddySystemButton = {
config: {},
unlinkConfirmationModal: {
signals: {
show: '',
close: '',
}
},
unlinkModalAbortController: null,
unlinkModal: null,
unlinkModalReady: false,

setConfig(config) {
this.config = config;
Expand All @@ -40,32 +49,86 @@

const triggerButton = e.target.closest(triggerSelector);
const container = triggerButton.closest(`.${this.config.bnt_class}`);
if (triggerButton.dataset.submitted === 'true') return Promise.resolve();

const values = new FormData();
values.append('usr_id', container.dataset.buddyId);
values.append('action', triggerButton.dataset.action);
values.append(`cmd[${BuddySystem.config.transition_state_cmd}]`, 1);

return disableButtons(container)
.then(() => fetch(BuddySystem.config.http_post_url, {
method: 'POST',
headers: { Accept: 'application/json' },
body: values,
}))
.then((response) => {
if (!response.ok) throw new Error('Request failed');
return response.json();
})
.then((data) => processResponse(container, data))
.then(() => {
container.querySelector(toggleSelector)?.focus();
})
.catch((error) => {
console.error(error);
enableButtons(container);
container.querySelector(toggleSelector)?.focus();

const widgetClickAction = () => {
if (triggerButton.dataset.submitted === 'true') return Promise.resolve();

const values = new FormData();
values.append('usr_id', container.dataset.buddyId);
values.append('action', triggerButton.dataset.action);
values.append(`cmd[${BuddySystem.config.transition_state_cmd}]`, 1);

return disableButtons(container)
.then(() => fetch(BuddySystem.config.http_post_url, {
method: 'POST',
headers: { Accept: 'application/json' },
body: values,
}))
.then((response) => {
if (!response.ok) throw new Error('Request failed');
return response.json();
})
.then((data) => processResponse(container, data))
.then(() => {
container.querySelector(toggleSelector)?.focus();
})
.catch((error) => {
console.error(error);
enableButtons(container);
container.querySelector(toggleSelector)?.focus();
});
};

if (triggerButton.dataset.action === 'unlink') {
return showUnlinkConfirmationModal().then(() => {
return widgetClickAction();
});
}

return widgetClickAction();
};

const showUnlinkConfirmationModal = () => {
const ensureModal = () => {
if (this.unlinkModalReady) {
return Promise.resolve();
}

return fetch(BuddySystem.config.async_get_unlink_modal_confirmation_html)
.then((response) => {
if (!response.ok) throw new Error('Request failed');
return response.json();
})
.then((data) => {
const wrapper = document.createElement('div');
const modalFragment = document.createRange().createContextualFragment(data.html);
wrapper.appendChild(modalFragment);
document.body.append(wrapper);

this.unlinkModal = wrapper.querySelector('dialog');
this.unlinkConfirmationModal.signals.show = data.signals.show;
this.unlinkConfirmationModal.signals.close = data.signals.close;
this.unlinkModalReady = true;
});
};

return ensureModal().then(() => new Promise((resolve) => {
if (this.unlinkModalAbortController) {
this.unlinkModalAbortController.abort();
}

this.unlinkModalAbortController = new AbortController();

const submitButton = this.unlinkModal.querySelector('input[type="submit"]');

submitButton.addEventListener('click', (event) => {
event.preventDefault();
global.jQuery(document).trigger(this.unlinkConfirmationModal.signals.close, {});
resolve();
}, { signal: this.unlinkModalAbortController.signal });

global.jQuery(document).trigger(this.unlinkConfirmationModal.signals.show, {});
}));
};

const disableButtons = (container) => new Promise((resolve) => {
Expand Down
1 change: 1 addition & 0 deletions lang/ilias_de.lang
Original file line number Diff line number Diff line change
Expand Up @@ -2769,6 +2769,7 @@ buddysystem#:#buddy_bs_state_requested_p#:#Angefragt
buddysystem#:#buddy_bs_state_unlinked#:#Nicht vernetzt
buddysystem#:#buddy_bs_state_unlinked_a#:#Nicht vernetzt
buddysystem#:#buddy_bs_state_unlinked_p#:#Nicht vernetzt
buddysystem#:#buddy_confirm_unlink#:#Möchten Sie die Verbindung zu diesem Kontakt wirklich aufheben?
buddysystem#:#buddy_enable#:#Aktiviere „Benutzerkontakte“
buddysystem#:#buddy_enable_info#:#Falls aktiviert, können Benutzer im System über Kontaktanfragen miteinander in Verbindung treten. Eine zusätzliche persönliche Einstellung ermöglicht jedem Benutzer, Kontaktaufnahmen zuzulassen oder zu verhindern.
buddysystem#:#buddy_handle_contact_request#:#Kontaktanfrage
Expand Down
1 change: 1 addition & 0 deletions lang/ilias_en.lang
Original file line number Diff line number Diff line change
Expand Up @@ -2770,6 +2770,7 @@ buddysystem#:#buddy_bs_state_requested_p#:#Requested
buddysystem#:#buddy_bs_state_unlinked#:#Unlinked
buddysystem#:#buddy_bs_state_unlinked_a#:#Unlinked
buddysystem#:#buddy_bs_state_unlinked_p#:#Unlinked
buddysystem#:#buddy_confirm_unlink#:#Do you really want to disconnect from this contact?
buddysystem#:#buddy_enable#:#Activate ‘Contacts’
buddysystem#:#buddy_enable_info#:#If enabled, users are allowed to contact each other by initiating contact requests. Additionally, there is a personal user setting to allow or prevent being contacted.
buddysystem#:#buddy_handle_contact_request#:#Contact Request
Expand Down