You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2020/02/08 17:47:24 UTC

[openmeetings] branch csp updated: [OPENMEETINGS-2165] more work on confirmations and chat, initial work on room

This is an automated email from the ASF dual-hosted git repository.

solomax pushed a commit to branch csp
in repository https://gitbox.apache.org/repos/asf/openmeetings.git


The following commit(s) were added to refs/heads/csp by this push:
     new 5527f1b  [OPENMEETINGS-2165] more work on confirmations and chat, initial work on room
5527f1b is described below

commit 5527f1b1a27d447139b2f977061eb2b47d3e5215
Author: Maxim Solodovnik <so...@gmail.com>
AuthorDate: Sun Feb 9 00:47:11 2020 +0700

    [OPENMEETINGS-2165] more work on confirmations and chat, initial work on room
---
 .../openmeetings/web/admin/AdminActionsPanel.html  |  2 +-
 .../openmeetings/web/admin/AdminActionsPanel.java  | 20 ++++----
 .../apache/openmeetings/web/common/MainPanel.html  | 13 +++--
 .../org/apache/openmeetings/web/common/main.js     | 16 +++---
 .../apache/openmeetings/web/pages/BasePage.html    |  1 +
 .../apache/openmeetings/web/room/RoomPanel.html    |  4 +-
 .../apache/openmeetings/web/room/raw-settings.js   | 12 +----
 .../apache/openmeetings/web/user/chat/Chat.html    | 20 +++-----
 .../openmeetings/web/user/chat/ChatPanel.html      |  2 +-
 .../openmeetings/web/user/chat/ChatToolbar.html    | 40 ++++++++-------
 .../apache/openmeetings/web/user/chat/raw-chat.js  | 59 +++++++++++++---------
 .../dashboard/admin/AdminCleanupInfoDialog.java    |  9 +---
 .../web/user/profile/MessagesContactsPanel.html    |  2 +-
 .../web/user/profile/SettingsPanel.java            | 36 ++-----------
 .../web/util/CallbackFunctionHelper.java           |  7 +++
 openmeetings-web/src/main/webapp/css/raw-chat.css  | 48 +++++++-----------
 .../src/main/webapp/css/raw-general-rtl.css        |  3 ++
 .../src/main/webapp/css/raw-general.css            |  9 +++-
 18 files changed, 143 insertions(+), 160 deletions(-)

diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminActionsPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminActionsPanel.html
index 8ade455..4124e6c 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminActionsPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminActionsPanel.html
@@ -24,7 +24,7 @@
 	<div class="btn btn-outline-primary btn-sm" wicket:id="btn-new" wicket:message="title:155">
 		<i class="fas fa-plus"></i>
 	</div>
-	<div class="btn btn-outline-warning btn-sm" wicket:id="btn-delete" wicket:message="title:157">
+	<div class="btn btn-outline-warning btn-sm" wicket:id="btn-delete" wicket:message="title:157,data-original-title:157">
 		<i class="fas fa-times"></i>
 	</div>
 	<div class="btn btn-outline-success btn-sm" wicket:id="btn-restore" wicket:message="title:admin.restore">
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminActionsPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminActionsPanel.java
index 8c0bed9..400f6f3 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminActionsPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminActionsPanel.java
@@ -18,7 +18,8 @@
  */
 package org.apache.openmeetings.web.admin;
 
-import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
+import static org.apache.openmeetings.web.util.CallbackFunctionHelper.newOkCancelDangerConfirm;
+
 import org.apache.openmeetings.web.common.FormActionsPanel;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
@@ -30,7 +31,7 @@ public abstract class AdminActionsPanel<T> extends FormActionsPanel<T> {
 	private static final long serialVersionUID = 1L;
 	private final Label newRecord = new Label("newRecord", Model.of(""));
 	private final Form<T> form;
-	private ConfirmableAjaxBorder delBtn;
+	private AjaxButton delBtn;
 	private AjaxButton restoreBtn;
 
 	public AdminActionsPanel(String id, final Form<T> form) {
@@ -66,25 +67,26 @@ public abstract class AdminActionsPanel<T> extends FormActionsPanel<T> {
 		final Form<?> cForm = new Form<>("form");
 		cForm.setMultiPart(form.isMultiPart());
 		add(cForm);
-		delBtn = new ConfirmableAjaxBorder("btn-delete", getString("80"), getString("833"), cForm) {
+		delBtn = new AjaxButton("btn-delete", cForm) {
 			private static final long serialVersionUID = 1L;
 
 			@Override
-			protected void onError(AjaxRequestTarget target) {
-				// repaint the feedback panel so errors are shown
+			protected void onSubmit(AjaxRequestTarget target) {
+				// repaint the feedback panel so that it is hidden
 				target.add(feedback);
 				setNewVisible(false);
-				AdminActionsPanel.this.onError(target, form);
+				onDeleteSubmit(target, form);
 			}
 
 			@Override
-			protected void onSubmit(AjaxRequestTarget target) {
-				// repaint the feedback panel so that it is hidden
+			protected void onError(AjaxRequestTarget target) {
+				// repaint the feedback panel so errors are shown
 				target.add(feedback);
 				setNewVisible(false);
-				onDeleteSubmit(target, form);
+				AdminActionsPanel.this.onError(target, form);
 			}
 		};
+		delBtn.add(newOkCancelDangerConfirm(this, getString("833")));
 		restoreBtn = new AjaxButton("btn-restore", form) {
 			private static final long serialVersionUID = 1L;
 
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.html
index 5526e9c..83c995f 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.html
@@ -21,13 +21,12 @@
 <html xmlns:wicket="http://wicket.apache.org">
 <wicket:panel>
 	<div wicket:id="topControls">
-		<div wicket:id="topLinks"><span
-			id="contactsAndMessages"><a wicket:id="messages"><wicket:message key="1188"/></a></span><span
-			id="profile"><a wicket:id="profile"><wicket:message key="5"/></a></span><span
-			id="logout"><a wicket:id="logout" href="#"><wicket:message key="310"/></a></span><span
-			id="reportBug"><a target="_blank" href="https://issues.apache.org/jira/browse/OPENMEETINGS"
-			rel="noopener noreferrer"><wicket:message key="284"/></a></span><span><a
-			wicket:id="about"><wicket:message key="1549"/></a></span>
+		<div wicket:id="topLinks">
+			<span id="contactsAndMessages"><a wicket:id="messages"><wicket:message key="1188"/></a></span>
+			<span id="profile"><a wicket:id="profile"><wicket:message key="5"/></a></span>
+			<span id="logout"><a wicket:id="logout" href="#" wicket:message="title:310"><wicket:message key="310"/></a></span>
+			<span id="reportBug"><a target="_blank" href="https://issues.apache.org/jira/browse/OPENMEETINGS" rel="noopener noreferrer"><wicket:message key="284"/></a></span>
+			<span><a wicket:id="about"><wicket:message key="1549"/></a></span>
 		</div>
 		<div id="busy-indicator"></div>
 		<div wicket:id="menu"></div>
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js
index 3f008cd..08d8428 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js
@@ -51,13 +51,19 @@ var OmUtil = (function() {
 	function _tmpl(tmplId, newId) {
 		return $(tmplId).clone().attr('id', newId || '');
 	}
+	function __alert(level, msg, autohideAfter) {
+		const holder = $('#alert-holder');
+		holder.append($(`<div class="alert alert-${level} alert-dismissible fade show m-0" role="alert">${msg}
+				<button type="button" class="close" data-dismiss="alert" aria-label="${holder.data('lbl-close')}">
+					<span aria-hidden="true">&times;</span>
+				</button>
+			</div>`))
+	}
 	function _error(msg) {
 		if (typeof(msg) === 'object') {
 			msg = msg.name + ': ' + msg.message;
 		}
-		if (!!errs && errs.length > 0) {
-			errs.getKendoNotification().error(msg);
-		}
+		__alert('danger', msg, 20000);
 		return console.error(msg);
 	}
 	function _debugEnabled() {
@@ -89,9 +95,7 @@ var OmUtil = (function() {
 			, msg = JSON.stringify($.extend({}, base, m));
 		Wicket.WebSocket.send(msg);
 	};
-	self.initErrs = function(_e) {
-		errs = _e;
-	};
+	self.alert = __alert;
 	self.error = _error;
 	self.info = _info;
 	self.log = _log;
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BasePage.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BasePage.html
index e6b8f42..6af7f7d 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BasePage.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BasePage.html
@@ -36,5 +36,6 @@
 	</div>
 	<div wicket:id="header" id="header"></div>
 	<wicket:child />
+	<div id="alert-holder" wicket:message="data-lbl-close:85" class="mr-3 ml-3"/>
 </body>
 </html>
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
index f4c6a72..56d5c2f 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.html
@@ -21,7 +21,7 @@
 <html xmlns:wicket="http://wicket.apache.org">
 <wicket:panel>
 	<div class="room-block">
-		<div class="container" wicket:id="roomContainer">
+		<div class="container p-0 m-0" wicket:id="roomContainer">
 			<div class="menu" wicket:id="menu"></div>
 			<div class="sidebar" wicket:id="sidebar"></div>
 			<div wicket:id="wb-area" class="wb-block">
@@ -94,7 +94,7 @@
 		</div>
 		<div id="sharer" wicket:message="title:730">
 			<h2 class="alert" hidden="hidden">Screen-sharing is not supported in your browser</h2>
-			<div class="container">
+			<div class="container p-0 m-0">
 				<div>
 					<span class="label"><wicket:message key="734"/></span>
 					<select name="type" class="type">
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-settings.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-settings.js
index 22d71b5..b5ea7c5 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-settings.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-settings.js
@@ -179,18 +179,8 @@ var VideoSettings = (function() {
 	function _init(options) {
 		o = JSON.parse(JSON.stringify(options));
 		if (!!o.infoMsg) {
-			$('#jsInfo').kendoNotification({
-				autoHideAfter: 0
-				, button: true
-				, hideOnClick: false
-			}).getKendoNotification().info(o.infoMsg);
+			OmUtil.alert('info', o.infoMsg, 0);
 		}
-		OmUtil.initErrs($('#jsNotifications').kendoNotification({
-			autoHideAfter: 20000
-			, button: true
-			, hideOnClick: false
-			, stacking: 'up'
-		}));
 		vs = $('#video-settings');
 		lm = vs.find('.level-meter');
 		cam = vs.find('select.cam').iconselectmenu({
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.html
index 05d7dd6..c1d6d48 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.html
@@ -21,8 +21,9 @@
 <html xmlns:wicket="http://wicket.apache.org">
 <wicket:panel>
 	<div id="chatTabs">
-		<ul>
+		<ul class="nav nav-tabs" role="tablist">
 		</ul>
+		<div class="tab-content"></div>
 	</div>
 	<form wicket:id="sendForm">
 		<div wicket:id="toolbarContainer" class="tool-container"></div>
@@ -48,20 +49,15 @@
 		<span id="chat-close-block" class='ui-icon ui-icon-close' wicket:message="title:85"
 			role='presentation'></span>
 
-		<div id="chat-msg-area-template" class="messageArea bg-white">
+		<div id="chat-msg-area-template" class="messageArea bg-white tab-pane h-100" role="tabpanel">
 			<div class="clear icons actions short">
-				<div class='user om-icon clickable' wicket:message="title:1167"
-						onclick='const e=$(this).parent();showUserInfo(e.data("userId"));'></div>
+				<div class='user clickable' wicket:message="title:1167"><i class="fas fa-address-card"></i></div>
 			</div>
 			<div class="clear icons actions full">
-				<div class='user om-icon clickable' wicket:message="title:1167"
-						onclick='const e=$(this).parent();showUserInfo(e.data("userId"));'></div>
-				<div class='add om-icon clickable' wicket:message="title:1186"
-						onclick='const e=$(this);addContact(e.data("userId"));'></div>
-				<div class='new-email om-icon clickable' wicket:message="title:1253"
-						onclick='const e=$(this);privateMessage(e.data("userId"));'></div>
-				<div class='invite om-icon clickable' wicket:message="title:1131"
-						onclick='const e=$(this);inviteUser(e.data("userId"));'></div>
+				<div class='user clickable' wicket:message="title:1167"><i class="fas fa-address-card"></i></div>
+				<div class='add clickable' wicket:message="title:1186"><i class="fas fa-plus-square"></i></div>
+				<div class='new-email clickable' wicket:message="title:1253"><i class="fas fa-envelope"></i></div>
+				<div class='invite clickable' wicket:message="title:1131"><i class="fas fa-link"></i></div>
 			</div>
 		</div>
 	</div>
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.html
index 39dd871..1a577c4 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatPanel.html
@@ -22,7 +22,7 @@
 <wicket:panel>
 	<div id="chatPopup" class="bg-light">
 		<div class="control block clickable bg-secondary" wicket:message="data-ttl-dock:label.dock.panel,data-ttl-undock:label.undock.panel">
-			<i class="fas"></i>
+			<i class="fas ml-1"></i>
 			<div class="label"><wicket:message key="244"/></div>
 		</div>
 		<div wicket:id="chat"></div>
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatToolbar.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatToolbar.html
index 0fcfdf3..1d6f5f7 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatToolbar.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatToolbar.html
@@ -23,7 +23,7 @@
 <wicket:panel>
 	<div wicket:id="toolbar" class="btn-toolbar chat-toolbar" data-role="editor-toolbar">
 		<div class="dropup">
-			<a id="emoticons" class="chat btn btn-default emt dropdown-toggle" data-toggle="dropdown" title="Emoticons"></a>
+			<a id="emoticons" class="chat btn btn-outline-secondary emt dropdown-toggle" data-toggle="dropdown" title="Emoticons"></a>
 			<ul class="chat dropdown-menu" >
 				<li>
 					<table id="emotMenuList">
@@ -32,44 +32,48 @@
 			</ul>
 		</div>
 		<div class="dropup">
-			<a id="fontSize" class="chat btn btn-default dropdown-toggle" data-toggle="dropdown" role="button" title="Font Size"> A </a>
+			<a id="fontSize" class="chat btn btn-outline-secondary dropdown-toggle" data-toggle="dropdown" role="button" title="Font Size"> A </a>
 			<ul class="dropdown-menu">
-				<li><a data-edit="fontSize 5"><span class="font-huge">Huge</span></a></li>
-				<li><a data-edit="fontSize 3"><span class="font-small">Normal</span></a></li>
-				<li><a data-edit="fontSize 1"><span class="font-tiny">Small</span></a></li>
+				<li><a data-edit="fontSize 5"><span class="font-huge text-center clickable">Huge</span></a></li>
+				<li><a data-edit="fontSize 3"><span class="font-small text-center clickable">Normal</span></a></li>
+				<li><a data-edit="fontSize 1"><span class="font-tiny text-center clickable">Small</span></a></li>
 			</ul>
 		</div>
 		<div class="dropup">
-			<a id="fontStyle" class="chat btn btn-default dropdown-toggle" data-toggle="dropdown" title="Font Style">
+			<a id="fontStyle" class="chat btn btn-outline-secondary dropdown-toggle" data-toggle="dropdown" title="Font Style">
 				<i class="fas fa-cog"></i>
 			</a>
 			<ul class="dropdown-menu btns-only">
-				<li><a class="chat-btn chat-tool-icon btn btn-default bold" id="bold" data-edit="bold" title="Bold (Ctrl/Cmd+B)"> B </a></li>
-				<li><a class="chat-btn chat-tool-icon btn btn-default italic" id="italic" data-edit="italic" title="Italic (Ctrl/Cmd+I)"> I </a></li>
-				<li><a class="chat-btn chat-tool-icon btn btn-default strike" id="strikethrough" data-edit="strikethrough" title="Strikethrough"> S </a></li>
-				<li><a class="chat-btn chat-tool-icon btn btn-default under" id="underline" data-edit="underline" title="Underline (Ctrl/Cmd+U)"> U </a></li>
+				<li><a class="chat-btn chat-tool-icon btn btn-outline-secondary bold" id="bold" data-edit="bold" title="Bold (Ctrl/Cmd+B)"> B </a></li>
+				<li><a class="chat-btn chat-tool-icon btn btn-outline-secondary italic" id="italic" data-edit="italic" title="Italic (Ctrl/Cmd+I)"> I </a></li>
+				<li><a class="chat-btn chat-tool-icon btn btn-outline-secondary strike" id="strikethrough" data-edit="strikethrough" title="Strikethrough"> S </a></li>
+				<li><a class="chat-btn chat-tool-icon btn btn-outline-secondary under" id="underline" data-edit="underline" title="Underline (Ctrl/Cmd+U)"> U </a></li>
 			</ul>
 		</div>
 		<div class="dropup">
-			<a id="hyperlink" class="chat btn btn-default dropdown-toggle" data-toggle="dropdown" title="Hyperlink">
+			<a id="hyperlink" class="chat btn btn-outline-secondary dropdown-toggle" data-toggle="dropdown" title="Hyperlink">
 				<i class="fas fa-link"></i>
 			</a>
 			<div wicket:id="hyperlink" class="dropdown-menu input-append">
 				<input class="span2" placeholder="URL" type="text" onkeypress="if (event.keyCode === 13) {$(this).parent().find('button').trigger('click');}; return event.keyCode !== 13;"/>
-				<button class="btn btn-default" type="button"><wicket:message key="1261"/></button>
+				<button class="btn btn-outline-secondary" type="button"><wicket:message key="1261"/></button>
 			</div>
 		</div>
 		<div class="dropup">
-			<a id="actions" class="chat btn btn-default dropdown-toggle" data-toggle="dropdown" wicket:message="title:635">
+			<a id="actions" class="chat btn btn-outline-secondary dropdown-toggle" data-toggle="dropdown" wicket:message="title:635">
 				<i class="fas fa-bars"></i>
 			</a>
 			<ul class="dropdown-menu btns-only">
-				<li><a class="chat-btn chat-tool-icon btn btn-default save" wicket:message="title:197" wicket:id="save"></a></li>
-				<li><a class="chat-btn chat-tool-icon btn btn-default ui-state-error" wicket:message="title:442" wicket:id="delete">
-					<span class="ui-button-icon ui-icon ui-icon-closethick"></span>
+				<li><a class="chat-btn chat-tool-icon btn btn-outline-secondary save" wicket:message="title:197" wicket:id="save">
+					<i class="fas fa-save"></i>
 				</a></li>
-				<li><a class="chat-btn chat-tool-icon btn btn-default audio" wicket:message="data-sound-enabled:sound.mute,data-sound-muted:sound.enable">&nbsp;</a></li>
-				<li><a class="chat-btn chat-tool-icon btn btn-default send-btn" wicket:message="data-send-enter:send.on.enter,data-send-ctrl:send.on.ctrl.enter"><strong>&crarr;</strong></a></li>
+				<li><a class="chat-btn chat-tool-icon btn btn-outline-danger" wicket:message="title:442" wicket:id="delete">
+					<i class="fas fa-trash-alt"></i>
+				</a></li>
+				<li><a class="chat-btn chat-tool-icon btn btn-outline-secondary audio" wicket:message="data-sound-enabled:sound.mute,data-sound-muted:sound.enable">
+					<i class="fas"></i>
+				</a></li>
+				<li><a class="chat-btn chat-tool-icon btn btn-outline-secondary send-btn" wicket:message="data-send-enter:send.on.enter,data-send-ctrl:send.on.ctrl.enter"><strong>&crarr;</strong></a></li>
 			</ul>
 		</div>
 	</div>
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/raw-chat.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/raw-chat.js
index 88cd28e..3b208e7 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/raw-chat.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/raw-chat.js
@@ -16,7 +16,7 @@ var Chat = function() {
 	let p, pp, ctrl, icon, tabs, openedHeight = "345px", openedWidth = "300px", allPrefix = "All"
 		, roomPrefix = "Room ", typingTimer, audio, roomMode = false, globalWidth = 600
 		, editor = $('#chatMessage .wysiwyg-editor'), muted = false, sendOn, DEF_SEND
-		, userId
+		, userId, inited = false
 		;
 
 	try {
@@ -126,10 +126,7 @@ var Chat = function() {
 		return p.hasClass('closed');
 	}
 	function activateTab(id) {
-		tabs.tabs("option", "active", tabs.find('a[href="#' + id + '"]').parent().index());
-	}
-	function isInited() {
-		return !!$("#chatTabs").data("ui-tabs");
+		$('#' + id).tab('show');
 	}
 	function _reinit(opts) {
 		userId = opts.userId;
@@ -146,20 +143,19 @@ var Chat = function() {
 		icon.removeClass(function(index, className) {
 			return (className.match (/(^|\s)ui-icon-caret-\S+/g) || []).join(' ');
 		});
-		__hideActions().addClass(align);
 		initToolbar();
-		tabs = $("#chatTabs").tabs({
+		tabs = $("#chatTabs");
+		/*FIXME TODO.tabs({
 			activate: function(event, ui) {
 				const ct = ui.newPanel[0].id;
 				_scrollDown($('#' + ct));
 				$('#activeChatTab').val(ct).trigger('change');
 			}
-		});
+		});*/
 		// close icon: removing the tab on click
 		tabs.delegate("span.ui-icon-close", "click", function() {
 			const panelId = $(this).closest("li").remove().attr("aria-controls");
 			$("#" + panelId).remove();
-			tabs.tabs("refresh");
 		});
 		if (roomMode) {
 			icon.addClass(isClosed() ? iconOpenRoom : iconCloseRoom);
@@ -196,16 +192,14 @@ var Chat = function() {
 				typingTimer = setTimeout(doneTyping, doneTypingInterval);
 			}
 		});
+		inited = true;
 	}
 	function _removeTab(id) {
-		$('#chat li[aria-controls="' + id + '"]').remove();
+		$('#chatTabs li a[aria-controls="chatTab-all"]').parent().remove();
 		$('#' + id).remove();
-		if (isInited()) {
-			tabs.tabs("refresh");
-		}
 	}
 	function _addTab(id, label) {
-		if (!isInited()) {
+		if (!inited) {
 			_reinit({});
 		}
 		if ($('#chat').length < 1 || $('#' + id).length) {
@@ -214,17 +208,37 @@ var Chat = function() {
 		if (!label) {
 			label = id === "chatTab-all" ? allPrefix : roomPrefix + id.substr(9);
 		}
-		const li = $('<li>').append($('<a>').attr('href', '#' + id).text(label));
+		const li = $('<li class="nav-item">')
+			.append($('<a class="nav-link" data-toggle="tab" role="tab">')
+				.attr('aria-controls', id)
+				.attr('href', '#' + id).text(label));
 		if (id.indexOf("chatTab-r") !== 0) {
 			li.append(OmUtil.tmpl('#chat-close-block'));
 		}
-		tabs.find(".ui-tabs-nav").append(li);
-		tabs.append(OmUtil.tmpl('#chat-msg-area-template', id));
-		tabs.tabs("refresh");
+		tabs.find('.nav.nav-tabs').append(li);
+		tabs.find('.tab-content').append(OmUtil.tmpl('#chat-msg-area-template', id));
+		const actions = __hideActions();
+		actions.addClass(align);
+		actions.find('.user').off('click').click(function() {
+			const e = $(this).parent();
+			showUserInfo(e.data("userId"));
+		});
+		actions.find('.add').off('click').click(function() {
+			const e = $(this).parent();
+			addContact(e.data("userId"));
+		});
+		actions.find('.new-email').off('click').click(function() {
+			const e = $(this).parent();
+			privateMessage(e.data("userId"));
+		});
+		actions.find('.invite').off('click').click(function() {
+			const e = $(this).parent();
+			inviteUser(e.data("userId"));
+		});
 		activateTab(id);
 	}
 	function __hideActions() {
-		return $('#chat .messageArea .icons').hide();
+		return $('#chat .tab-content .messageArea .icons').hide();
 	}
 	function __getActions(row) {
 		return row.closest('.messageArea').find('.actions.' + ('full' === row.data('actions') ? 'full' : 'short'));
@@ -275,7 +289,7 @@ var Chat = function() {
 				}
 			}
 			if (notify) {
-				ctrl.addClass('ui-state-highlight');
+				ctrl.addClass('bg-warning');
 				if (p.is(':visible') && !muted) {
 					audio.play()
 						.then(function() {
@@ -308,7 +322,7 @@ var Chat = function() {
 	function _open(handler) {
 		if (isClosed()) {
 			icon.removeClass(roomMode ? iconOpenRoom : iconOpen).addClass(roomMode ? iconCloseRoom : iconClose);
-			ctrl.removeClass('ui-state-highlight');
+			ctrl.removeClass('bg-warning');
 			let opts;
 			if (roomMode) {
 				opts = {width: openedWidth};
@@ -372,11 +386,10 @@ var Chat = function() {
 	}
 	function _setRoomMode(_mode) {
 		roomMode = _mode;
-		if (isInited() && !roomMode) {
+		if (inited && !roomMode) {
 			// remove all private chats on room exit
 			$('li[aria-controls^="chatTab-u"]').remove();
 			$('div[id^="chatTab-u"]').remove();
-			tabs.tabs("refresh");
 		}
 		_reinit({userId: userId, all: allPrefix, room: roomPrefix, sendOnEnter: sendOn === SEND_ENTER});
 	}
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/dashboard/admin/AdminCleanupInfoDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/dashboard/admin/AdminCleanupInfoDialog.java
index 02aa25b..08f8f9e 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/dashboard/admin/AdminCleanupInfoDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/dashboard/admin/AdminCleanupInfoDialog.java
@@ -26,7 +26,7 @@ import static org.apache.openmeetings.cli.CleanupHelper.getRecUnit;
 import static org.apache.openmeetings.util.OmFileHelper.getHumanSize;
 import static org.apache.openmeetings.util.OmFileHelper.getStreamsDir;
 import static org.apache.openmeetings.util.OmFileHelper.getUploadDir;
-import static org.apache.openmeetings.web.util.CallbackFunctionHelper.newOkCancelConfirmCfg;
+import static org.apache.openmeetings.web.util.CallbackFunctionHelper.newOkCancelDangerConfirm;
 
 import org.apache.openmeetings.cli.CleanupEntityUnit;
 import org.apache.openmeetings.cli.CleanupUnit;
@@ -44,7 +44,6 @@ import org.apache.wicket.spring.injection.annot.SpringBean;
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
-import de.agilecoders.wicket.extensions.markup.html.bootstrap.confirmation.ConfirmationBehavior;
 import de.agilecoders.wicket.extensions.markup.html.bootstrap.spinner.SpinnerAjaxButton;
 
 public class AdminCleanupInfoDialog extends Modal<String> {
@@ -97,11 +96,7 @@ public class AdminCleanupInfoDialog extends Modal<String> {
 					private static final long serialVersionUID = 1L;
 
 					{
-						add(new ConfirmationBehavior(
-								newOkCancelConfirmCfg(this, getString("dashboard.widget.admin.cleanup.warn"))
-								.withBtnOkClass("btn btn-sm btn-danger")
-								.withBtnOkIconClass("fas fa-exclamation-triangle")
-								));
+						add(newOkCancelDangerConfirm(this, getString("dashboard.widget.admin.cleanup.warn")));
 					}
 
 					@Override
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.html
index 32ae988..971a4ad 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.html
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.html
@@ -122,8 +122,8 @@
 				</td>
 			</tr>
 		</table>
-		<div class="bottom-bumper"></div>
 	</div>
+	<div class="bottom-bumper"></div>
 	<div wicket:id="addFolder"></div>
 </wicket:panel>
 </html>
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/SettingsPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/SettingsPanel.java
index 8e16a36..78e7345 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/SettingsPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/SettingsPanel.java
@@ -25,15 +25,14 @@ import java.util.List;
 
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.web.common.UserBasePanel;
-import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
 import org.apache.wicket.extensions.markup.html.tabs.ITab;
 import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.model.Model;
 import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 
-import com.googlecode.wicket.jquery.core.Options;
-import com.googlecode.wicket.jquery.ui.widget.tabs.TabbedPanel;
+import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
 
 public class SettingsPanel extends UserBasePanel {
 	private static final long serialVersionUID = 1L;
@@ -44,8 +43,6 @@ public class SettingsPanel extends UserBasePanel {
 	public static final int INVITATIONS_TAB_ID = 4;
 	public static final int DASHBOARD_TAB_ID = 5;
 	public final int active;
-	private UserProfilePanel profilePanel;
-	private MessagesContactsPanel messagesPanel;
 	@SpringBean
 	private UserDao userDao;
 
@@ -62,10 +59,7 @@ public class SettingsPanel extends UserBasePanel {
 
 			@Override
 			public WebMarkupContainer getPanel(String panelId) {
-				if (profilePanel == null) {
-					profilePanel = new UserProfilePanel(panelId, getUserId());
-				}
-				return profilePanel;
+				return new UserProfilePanel(panelId, getUserId());
 			}
 		});
 		tabs.add(new AbstractTab(new ResourceModel("1188")) {
@@ -73,10 +67,7 @@ public class SettingsPanel extends UserBasePanel {
 
 			@Override
 			public WebMarkupContainer getPanel(String panelId) {
-				if (messagesPanel == null) {
-					messagesPanel = new MessagesContactsPanel(panelId);
-				}
-				return messagesPanel;
+				return new MessagesContactsPanel(panelId);
 			}
 		});
 		tabs.add(new AbstractTab(new ResourceModel("1171")) {
@@ -111,24 +102,7 @@ public class SettingsPanel extends UserBasePanel {
 				return new WidgetsPanel(panelId);
 			}
 		});
-		add(new TabbedPanel("tabs", tabs, new Options("active", active)) {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			public boolean isActivatingEventEnabled() {
-				return true;
-			}
-
-			@Override
-			public void onActivating(AjaxRequestTarget target, int index, ITab tab) {
-				if (index == 0) {
-					profilePanel.update(target);
-				} else if (index == 1) {
-					messagesPanel.updateTable(target);
-				}
-			}
-		}.setActiveTab(active));
-
+		add(new AjaxBootstrapTabbedPanel<>("tabs", tabs, Model.of(active)));
 		super.onInitialize();
 	}
 }
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/CallbackFunctionHelper.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/CallbackFunctionHelper.java
index 01e3791..078fbfd 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/CallbackFunctionHelper.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/CallbackFunctionHelper.java
@@ -76,4 +76,11 @@ public class CallbackFunctionHelper {
 	public static ConfirmationBehavior newOkCancelConfirm(Component c, String title) {
 		return new ConfirmationBehavior(newOkCancelConfirmCfg(c, title));
 	}
+
+	public static ConfirmationBehavior newOkCancelDangerConfirm(Component c, String title) {
+		return new ConfirmationBehavior(newOkCancelConfirmCfg(c, title)
+				.withBtnOkClass("btn btn-sm btn-danger")
+				.withBtnOkIconClass("fas fa-exclamation-triangle")
+				);
+	}
 }
diff --git a/openmeetings-web/src/main/webapp/css/raw-chat.css b/openmeetings-web/src/main/webapp/css/raw-chat.css
index 1c8613b..124d246 100644
--- a/openmeetings-web/src/main/webapp/css/raw-chat.css
+++ b/openmeetings-web/src/main/webapp/css/raw-chat.css
@@ -13,34 +13,24 @@
 #chat {
 	height: calc(100% - 20px);
 }
-#chat .btn-toolbar {
-	margin-top: 2px;
-	margin-bottom: 0;
-	margin-left: 5px;
+#chat .chat-toolbar.btn-toolbar .dropdown-menu.btns-only li {
+	display: inline-block;
 }
-#chat #chatTabs.ui-tabs {
+#chat #chatTabs {
 	padding: 0;
 	height: calc(100% - var(--chat-tools-height) - var(--chat-msg-height) - var(--buffer-size));
 }
-#chat #chatTabs.ui-tabs .ui-tabs-nav {
-	padding: 0;
+#chat #chatTabs .nav.nav-tabs .nav-item {
 	max-height: var(--chat-tabs-height);
 	height: var(--chat-tabs-height);
 	overflow: hidden;
 }
-#chat #chatTabs.ui-tabs .ui-tabs-nav li {
-	margin: 0;
+#chat #chatTabs .nav.nav-tabs .nav-item .nav-link {
+	padding: 1px 0.9rem;
 }
 #chat #chatTabs.ui-tabs .ui-tabs-nav li .ui-icon.ui-icon-close {
 	float: left;
 }
-#chat #chatTabs.ui-tabs .ui-tabs-nav .ui-tabs-anchor {
-	padding: 2px .5em;
-	float: left;
-}
-#chatPopup .control.block .ui-icon {
-	text-align: center;
-}
 #chatPopup .control.block .label {
 	display: inline-block;
 	width: 70px;
@@ -63,6 +53,10 @@
 	z-index: 1;
 	left: 50px;
 }
+#chat .messageArea .icons div {
+	display: inline-block;
+	vertical-align: super;
+}
 html[dir="rtl"] #chat .messageArea .icons {
 	left: initial;
 	right: 50px;
@@ -77,8 +71,10 @@ html[dir="rtl"] #chat .messageArea .icons {
 	font-style: italic;
 	padding: 5px 0;
 }
-.ui-tabs .ui-tabs-panel.messageArea {
+#chat #chatTabs .tab-content {
 	height: calc(100% - var(--chat-tabs-height));
+}
+#chat #chatTabs .tab-content .tab-pane.messageArea {
 	overflow-y: auto;
 	padding: 0 5px;
 	position: relative;
@@ -96,21 +92,19 @@ html[dir="rtl"] #chat .messageArea .icons {
 	background-repeat: no-repeat;
 	background-position: center;
 	background-size: 16px;
-	width: 20px;
-	height: 20px;
 	display: inline-block;
 }
 .list.chat-tool-icon {
 	background-image: url(images/list.png);
 }
-.sound.chat-tool-icon {
-	background-image: url(images/sound.png);
+#chat .chat-tool-icon, #chat .chat.btn {
+	font-size: 1.1em;
 }
-.sound-mute.chat-tool-icon {
-	background-image: url(images/sound_mute.png);
+#chat .sound.chat-tool-icon i::before {
+	content: '\f028';
 }
-.save.chat-tool-icon {
-	background-image: url(images/file_save_as.png);
+#chat .sound-mute.chat-tool-icon i::before {
+	content: '\f6a9';
 }
 .send-ctrl.chat-tool-icon {
 	background-image: url(images/key_ctrl.png);
@@ -119,10 +113,6 @@ html[dir="rtl"] #chat .messageArea .icons {
 }
 #chat .chat-btn {
 	display: inline-block;
-	float: right;
-}
-#chat .chat-btn:first-of-type {
-	margin-right: 10px;
 }
 #chat .send {
 	width: 16px;
diff --git a/openmeetings-web/src/main/webapp/css/raw-general-rtl.css b/openmeetings-web/src/main/webapp/css/raw-general-rtl.css
index edd32bf..20ff361 100644
--- a/openmeetings-web/src/main/webapp/css/raw-general-rtl.css
+++ b/openmeetings-web/src/main/webapp/css/raw-general-rtl.css
@@ -144,3 +144,6 @@ html[dir="rtl"] .adminForm label
 {
 	float: right !important;
 }
+html[dir="rtl"] #alert-holder {
+	left: 0;
+}
diff --git a/openmeetings-web/src/main/webapp/css/raw-general.css b/openmeetings-web/src/main/webapp/css/raw-general.css
index 17b2902..e52807c 100644
--- a/openmeetings-web/src/main/webapp/css/raw-general.css
+++ b/openmeetings-web/src/main/webapp/css/raw-general.css
@@ -83,10 +83,10 @@ html, body {
 .help.support h3 {
 	margin-bottom: 5px;
 }
-.user-settings.ui-tabs {
+.user-settings {
 	height: calc(100% - 10px);
 }
-.user-settings.ui-tabs .ui-tabs-panel {
+.user-settings .tab-content {
 	height: calc(100% - 60px);
 }
 .user-settings .edit-profile {
@@ -775,3 +775,8 @@ select.messages.selector {
 .profile-edit-form {
 	height: calc(100% - 50px);
 }
+#alert-holder {
+	position: fixed;
+	right: 0;
+	bottom: 0;
+}