Skip to content

Commit

Permalink
Chatroom: Apply FR: Further revamping of Repository Chat
Browse files Browse the repository at this point in the history
  • Loading branch information
lscharmer authored and mjansenDatabay committed Oct 10, 2024
1 parent 5cbd49c commit 79ad52d
Show file tree
Hide file tree
Showing 53 changed files with 2,750 additions and 3,043 deletions.
25 changes: 15 additions & 10 deletions components/ILIAS/Chatroom/Chatroom.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,20 @@ public function init(
array | \ArrayAccess &$pull,
array | \ArrayAccess &$internal,
): void {
$contribute[\ILIAS\Setup\Agent::class] = static fn() =>
new \ilChatroomSetupAgent(
$pull[\ILIAS\Refinery\Factory::class]
);
$contribute[Component\Resource\PublicAsset::class] = fn() =>
new Component\Resource\ComponentJS($this, "chatroom.js");
$contribute[Component\Resource\PublicAsset::class] = fn() =>
new Component\Resource\ComponentJS($this, "iliaschat.jquery.js");
$contribute[Component\Resource\PublicAsset::class] = fn() =>
new Component\Resource\ComponentCSS($this, "chatroom.css");
$contribute[\ILIAS\Setup\Agent::class] = static fn() => new \ilChatroomSetupAgent($pull[\ILIAS\Refinery\Factory::class]);

$files = [
'../chat/node_modules/socket.io-client/dist/socket.io.min.js',
'js/dist/Chatroom.min.js',
];

$type = ['js' => Component\Resource\ComponentJS::class, 'css' => Component\Resource\ComponentCSS::class];

foreach ($files as $file) {
$class = $type[substr($file, strrpos($file, '.') + 1)];
if (file_exists(__DIR__ . '/resources/' . $file)) {
$contribute[Component\Resource\PublicAsset::class] = fn() => new $class($this, $file);
}
}
}
}
3 changes: 2 additions & 1 deletion components/ILIAS/Chatroom/chat/Model/Room.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ var Room = function Room(id)
if(this.subscriberHasJoined(key)) {
jsonSubscribers[key] = {
id: _subscribers[key].getId(),
username: _subscribers[key].getName()
username: _subscribers[key].getName(),
profile_picture_visible: _subscribers[key].isProfilePictureVisible(),
};
}
}
Expand Down
13 changes: 13 additions & 0 deletions components/ILIAS/Chatroom/chat/Model/Subscriber.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ function Subscriber(id) {
*/
var _socketIds = [];

/**
* @type {boolean}
*/
var _profile_picture_visible = false;

/**
* @returns {number}
*/
Expand Down Expand Up @@ -65,6 +70,14 @@ function Subscriber(id) {
}
};

this.setProfilePictureVisible = function(visible) {
_profile_picture_visible = visible;
};

this.isProfilePictureVisible = function() {
return _profile_picture_visible;
};

/**
* @returns {string}
*/
Expand Down
2 changes: 0 additions & 2 deletions components/ILIAS/Chatroom/chat/SocketTasks/Disconnect.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ module.exports = function()
var userListAction = UserlistAction.create(splitIds[0], room.getJoinedSubscribers());
var notice = Notice.create('disconnected', splitIds[0], {username: subscriber.getName()});

namespace.getDatabase().addHistory(notice);

Container.getLogger().info('Disconnected %s from %s of namespace %s', subscriberId, room.getId(), namespace.getName());
Container.getLogger().info('Updated user list for room %s of namespace %s', room.getId(), namespace.getName());

Expand Down
2 changes: 0 additions & 2 deletions components/ILIAS/Chatroom/chat/SocketTasks/EnterRoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ module.exports = function(roomId)
var messageSubscriber = 'welcome_to_chat';
var noticeSubscriber = Notice.create(messageSubscriber, roomId, subscriber);

namespace.getDatabase().addHistory(noticeRoom);

this.emit('notice', noticeSubscriber);
this.broadcast.in(serverRoomId).emit('notice', noticeRoom);
}
Expand Down
3 changes: 2 additions & 1 deletion components/ILIAS/Chatroom/chat/SocketTasks/Login.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
var Container = require('../AppContainer');
var ConnectAction = require('../Model/Messages/ConnectAction');

module.exports = function(subscriberName, subscriberId)
module.exports = function(subscriberName, subscriberId, profilePictureVisible)
{
var namespace = Container.getNamespace(this.nsp.name);

Expand All @@ -17,6 +17,7 @@ module.exports = function(subscriberName, subscriberId)
}
} else {
var subscriber = namespace.getSubscriber(subscriberId);
subscriber.setProfilePictureVisible(profilePictureVisible);
subscriber.setName(subscriberName);
subscriber.addSocketId(this.id);

Expand Down
3 changes: 1 addition & 2 deletions components/ILIAS/Chatroom/chat/SocketTasks/SendMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ module.exports = function (data, roomId) {
return;
}

var subscriber = {id: this.subscriber.getId(), username: this.subscriber.getName()};

var subscriber = {id: this.subscriber.getId(), username: this.subscriber.getName(), profile_picture_visible: this.subscriber.isProfilePictureVisible()};
data.content = HTMLEscape.escape(data.content);

var message = {};
Expand Down
2 changes: 1 addition & 1 deletion components/ILIAS/Chatroom/chat/SystemTasks/Ban.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ module.exports = function exports(req, res) {
room.subscriberLeft(subscriberId);

var userlistAction = UserlistAction.create(splitted[0], room.getJoinedSubscribers());
var notice = Notice.create('user_kicked', splitted[0], {user: subscriber.getName()});
var notice = Notice.create('user_banned', splitted[0], {user: subscriber.getName()});

subscriber.getSocketIds().forEach(
userBannedMessageCallbackFactory(namespace, room.getId())
Expand Down
157 changes: 157 additions & 0 deletions components/ILIAS/Chatroom/classes/BuildChat.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
<?php

/**
* This file is part of ILIAS, a powerful learning management system
* published by ILIAS open source e-Learning e.V.
*
* ILIAS is licensed with the GPL-3.0,
* see https://www.gnu.org/licenses/gpl-3.0.en.html
* You should have received a copy of said license along with the
* source code, too.
*
* If this is not the case or you just want to try ILIAS, you'll find
* us at:
* https://www.ilias.de
* https://github.com/ILIAS-eLearning
*
*********************************************************************/

declare(strict_types=1);

namespace ILIAS\Chatroom;

use ilCtrlInterface;
use ilLanguage;
use ilChatroomObjectGUI;
use ilChatroom;
use ilChatroomServerSettings;
use ilUtil;
use ilTemplate;
use ilObjUser;
use ilCalendarSettings;

class BuildChat
{
public function __construct(
private readonly ilCtrlInterface $ilCtrl,
private readonly ilLanguage $ilLng,
private readonly ilChatroomObjectGUI $gui,
private readonly ilChatroom $room,
private readonly ilChatroomServerSettings $settings,
private readonly ilObjUser $user
) {
}

public function template(bool $read_only, array $initial, string $input, string $output): ilTemplate
{
$room_tpl = new ilTemplate('tpl.chatroom.html', true, true, 'components/ILIAS/Chatroom');
$set_json_var = fn($var, $value) => $room_tpl->setVariable($var, json_encode($value));
$set_json_var('BASEURL', $this->settings->generateClientUrl());
$set_json_var('INSTANCE', $this->settings->getInstance());
$set_json_var('SCOPE', $this->room->getRoomId());
$set_json_var('POSTURL', ILIAS_HTTP_PATH . '/' . $this->ilCtrl->getLinkTarget($this->gui, 'postMessage', '', true));
$room_tpl->setVariable('JS_CALL', 'il.Chatroom.' . ($read_only ? 'runReadOnly' : 'run'));

$set_json_var('INITIAL_DATA', $initial);
$set_json_var('INITIAL_USERS', $this->room->getConnectedUsers());
$set_json_var('DATE_FORMAT', (string) $this->user->getDateFormat());
$set_json_var('TIME_FORMAT', $this->timeFormat());

$room_tpl->setVariable('CHAT_OUTPUT', $output);
$room_tpl->setVariable('CHAT_INPUT', $input);

$this->renderLanguageVariables($room_tpl);

return $room_tpl;
}

public function initialData(array $users, bool $show_auto_messages, ?string $redirect_url, array $userinfo, array $messages): array
{
$initial = [];
$initial['users'] = $users;
$initial['redirect_url'] = $redirect_url;
$initial['profile_image_url'] = $this->ilCtrl->getLinkTarget($this->gui, 'view-getUserProfileImages', '', true);
$initial['no_profile_image_url'] = ilUtil::getImagePath('placeholder/no_photo_xxsmall.jpg');
$initial['subdirectory'] = $this->settings->getSubDirectory();

$initial['userinfo'] = $userinfo;
$initial['messages'] = $messages;

$initial['state'] = [
'scrolling' => true,
'show_auto_msg' => $show_auto_messages,
'system_message_update_url' => $this->ilCtrl->getFormAction($this->gui, 'view-toggleAutoMessageDisplayState', '', true, false),
];

return $initial;
}

private function renderLanguageVariables(ilTemplate $room_tpl): void
{
$set_vars = fn($a) => array_map($room_tpl->setVariable(...), array_keys($a), array_values($a));

$js_translations = [
'LBL_MAINROOM' => 'chat_mainroom',
'LBL_JOIN' => 'chat_join',
'LBL_INVITE_TO_PRIVATE_ROOM' => 'invite_to_private_room',
'LBL_KICK' => 'chat_kick',
'LBL_BAN' => 'chat_ban',
'LBL_KICK_QUESTION' => 'kick_question',
'LBL_BAN_QUESTION' => 'ban_question',
'LBL_ADDRESS' => 'chat_address',
'LBL_WHISPER' => 'chat_whisper',
'LBL_CONNECT' => 'chat_connection_established',
'LBL_DISCONNECT' => 'chat_connection_disconnected',
'LBL_TO_MAINROOM' => 'chat_to_mainroom',
'LBL_WELCOME_TO_CHAT' => 'welcome_to_chat',
'LBL_USER_INVITED' => 'user_invited',
'LBL_USER_KICKED' => 'user_kicked',
'LBL_USER_BANNED' => 'user_banned',
'LBL_USER_INVITED_SELF' => 'user_invited_self',
'LBL_PRIVATE_ROOM_CLOSED' => 'private_room_closed',
'LBL_PRIVATE_ROOM_ENTERED' => 'private_room_entered',
'LBL_PRIVATE_ROOM_LEFT' => 'private_room_left',
'LBL_PRIVATE_ROOM_ENTERED_USER' => 'private_room_entered_user',
'LBL_KICKED_FROM_PRIVATE_ROOM' => 'kicked_from_private_room',
'LBL_OK' => 'ok',
'LBL_DELETE' => 'delete',
'LBL_INVITE' => 'chat_invite',
'LBL_CANCEL' => 'cancel',
'LBL_HISTORY_CLEARED' => 'history_cleared',
'LBL_CLEAR_ROOM_HISTORY' => 'clear_room_history',
'LBL_CLEAR_ROOM_HISTORY_QUESTION' => 'clear_room_history_question',
'LBL_END_WHISPER' => 'end_whisper',
'LBL_TIMEFORMAT' => 'lang_timeformat_no_sec',
'LBL_DATEFORMAT' => 'lang_dateformat',
'LBL_START_PRIVATE_CHAT' => 'start_private_chat',
];

$set_vars(array_map(
fn($v) => json_encode($this->ilLng->txt($v), JSON_THROW_ON_ERROR),
$js_translations
));

$this->ilLng->toJSMap([
'chat_user_x_is_typing' => $this->ilLng->txt('chat_user_x_is_typing'),
'chat_users_are_typing' => $this->ilLng->txt('chat_users_are_typing'),
]);

$vars = [
'LBL_LAYOUT' => 'layout',
'LBL_SHOW_SETTINGS' => 'show_settings',
'LBL_USER_IN_ROOM' => 'user_in_room',
'LOADING_IMAGE' => 'media/loader.svg',
];

$set_vars(array_map($this->ilLng->txt(...), $vars));
$room_tpl->setVariable('LOADING_IMAGE', ilUtil::getImagePath('media/loader.svg'));
}

private function timeFormat(): string
{
return match ($this->user->getTimeFormat()) {
(string) ilCalendarSettings::TIME_FORMAT_12 => 'h:ia',
default => 'H:i',
};
}
}
21 changes: 12 additions & 9 deletions components/ILIAS/Chatroom/classes/class.ilChatroom.php
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,8 @@ public function connectUser(ilChatroomUser $user): bool

$userdata = [
'login' => $user->getUsername(),
'id' => $user->getUserId()
'id' => $user->getUserId(),
'profile_picture_visible' => $user->isProfilePictureVisible(),
];

$query = 'SELECT user_id FROM ' . self::$userTable . ' WHERE room_id = %s AND user_id = %s';
Expand Down Expand Up @@ -331,7 +332,7 @@ public function getConnectedUsers(bool $only_data = true): array
$users = [];

while ($row = $DIC->database()->fetchAssoc($rset)) {
$users[] = $only_data ? json_decode($row['userdata'], false, 512, JSON_THROW_ON_ERROR) : $row;
$users[] = $only_data ? json_decode($row['userdata'], true, 512, JSON_THROW_ON_ERROR) : $row;
}

return $users;
Expand Down Expand Up @@ -757,16 +758,18 @@ public function getLastMessages(int $number, ilChatroomUser $chatuser): array
// by sql. So we fetch twice as much as we need and hope that there
// are not more than $number private messages.
$DIC->database()->setLimit($number);
$rset = $DIC->database()->query(
$rset = $DIC->database()->queryF(
'SELECT *
FROM ' . self::$historyTable . '
WHERE room_id = ' . $DIC->database()->quote($this->roomId, ilDBConstants::T_INTEGER) . '
WHERE room_id = %s
AND (
(' . $DIC->database()->like('message', ilDBConstants::T_TEXT, '%"type":"message"%') . ' AND NOT ' . $DIC->database()->like('message', ilDBConstants::T_TEXT, '%"public":0%') . ')
OR ' . $DIC->database()->like('message', ilDBConstants::T_TEXT, '%"target":{%"id":"' . $chatuser->getUserId() . '"%') . '
OR ' . $DIC->database()->like('message', ilDBConstants::T_TEXT, '%"from":{"id":' . $chatuser->getUserId() . '%') . '
(JSON_VALUE(message, "$.type") = "message" AND (NOT JSON_CONTAINS_PATH(message, "one", "$.target.public") OR JSON_VALUE(message, "$.target.public") <> 0))
OR JSON_VALUE(message, "$.target.id") = %s
OR JSON_VALUE(message, "$.from.id") = %s
)
ORDER BY timestamp DESC'
ORDER BY timestamp DESC',
[ilDBConstants::T_INTEGER, ilDBConstants::T_INTEGER, ilDBConstants::T_INTEGER],
[$this->roomId, $chatuser->getUserId(), $chatuser->getUserId()]
);

$result_count = 0;
Expand All @@ -789,7 +792,7 @@ public function getLastMessages(int $number, ilChatroomUser $chatuser): array
'SELECT *
FROM ' . self::$historyTable . '
WHERE room_id = %s
AND ' . $DIC->database()->like('message', ilDBConstants::T_TEXT, '%%"type":"notice"%%') . '
AND JSON_VALUE(message, "$.type") = "notice"
AND timestamp <= %s AND timestamp >= %s
ORDER BY timestamp DESC',
[ilDBConstants::T_INTEGER, ilDBConstants::T_INTEGER, ilDBConstants::T_INTEGER],
Expand Down
21 changes: 14 additions & 7 deletions components/ILIAS/Chatroom/classes/class.ilChatroomGUIHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public function execute(string $method): void
{
$this->ilLng->loadLanguageModule('chatroom');

if (method_exists($this, $method)) {
if (is_callable([$this, $method])) {
$this->$method();
return;
}
Expand Down Expand Up @@ -157,23 +157,30 @@ protected function getRoomByObjectId(int $objectId): ?ilChatroom
protected function exitIfNoRoomExists(?ilChatroom $room): void
{
if (null === $room) {
$this->sendResponse([
$this->sendJSONResponse([
'success' => false,
'reason' => 'unknown room',
]);
}
}

/**
* Sends a json encoded response and exits the php process
* @param mixed $response
* Sends a json encoded response and exits the php process.
*/
public function sendResponse($response, bool $isJson = false): void
protected function sendJSONResponse($response): void
{
$this->sendResponse(json_encode($response), 'application/json');
}

/**
* Sends a response and exits the php process.
*/
protected function sendResponse(string $content, string $type): void
{
$this->http->saveResponse(
$this->http->response()
->withHeader(ResponseHeader::CONTENT_TYPE, 'application/json')
->withBody(Streams::ofString($isJson ? $response : json_encode($response, JSON_THROW_ON_ERROR)))
->withHeader(ResponseHeader::CONTENT_TYPE, $type)
->withBody(Streams::ofString($content))
);
$this->http->sendResponse();
$this->http->close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ public function getTabsForCommand(string $command): void

$config = [
'view' => [
'lng' => 'view',
'lng' => 'obj_chtr',
'link' => $DIC->ctrl()->getLinkTarget($this->gui, 'view'),
'permission' => 'read'
],
Expand Down
Loading

0 comments on commit 79ad52d

Please sign in to comment.