/**
* @namespace Tchap
* @property {module:Tchap} Module
* @memberof Plugins
*/
/**
* @module Tchap
*/
import { FramesManager } from '../mel_metapage/js/lib/classes/frame_manager.js';
import { MainNav } from '../mel_metapage/js/lib/classes/main_nav.js';
import {
EMPTY_STRING,
TCHAT_UNREAD,
} from '../mel_metapage/js/lib/constants/constants.js';
import { MelObject } from '../mel_metapage/js/lib/mel_object.js';
export { tchap_manager };
const SETTING_BUTTON = 'mx_UserMenu_contextMenuButton';
const PARAMS_BUTTON = 'mx_UserMenu_iconSettings';
const DISCONNECT_BUTTON = 'mx_UserMenu_iconSignOut';
const LEFT_PANEL = 'mx_SpacePanel';
const CONTEXTUAL_MENU = 'mx_ContextualMenu';
const THEME_BUTTON = 'mx_UserMenu_contextMenu_themeButton';
const CURRENT_THEME_BODY_CLASS = 'cpd-theme-light';
const CONTEXTUAL_MENU_BACKGROUND = 'mx_ContextualMenu_background';
const SLEEP_ON_TASK = 2500;
const SLEEP_OUTSIDE = 30000;
/**
* @class
* @classdesc Classe de gestion de tchap en JS
* @extends {MelObject}
*/
class tchap_manager extends MelObject {
constructor() {
super();
}
// #region ReadOnlyVar
/**
* Document de la frame de tchap
* @type {Document}
* @readonly
*/
get tchapContext() {
return this.tchap_frame()[0].contentWindow.document;
}
/**
* Badge qui contient si il y a des messages non-lu
* @type {HTMLElement}
* @readonly
*/
get badge() {
return this.tchapContext.querySelector(
'.mx_SpaceButton_home .mx_SpacePanel_badgeContainer .mx_NotificationBadge_count',
);
}
/**
* Bouton qui ouvre le menu des paramètres
* @type {HTMLElement}
* @readonly
*/
get settingMenuButton() {
return this.tchapContext.querySelector(`.${SETTING_BUTTON}`);
}
/**
* Ouvre le menu des paramètres puis récupère le bouton qui ouvre les paramètres.
* @type {HTMLElement}
* @readonly
*/
get settingButton() {
this.settingMenuButton.click();
//On récupère l'icône puis l'élément parent, car l'icône est pour le moment, le seul moyen de retrouver le bouton dans la liste
return this.tchapContext.querySelector(
`.${CONTEXTUAL_MENU} .${PARAMS_BUTTON}`,
).parentElement;
}
/**
* Ouvre le menu des paramètres puis récupère le bouton de déconnexion.
* @type {HTMLElement}
* @readonly
*/
get disconnectButton() {
this.settingMenuButton.click();
//On récupère l'icône puis l'élément parent, car l'icône est pour le moment, le seul moyen de retrouver le bouton dans la liste
return this.tchapContext.querySelector(
`.${CONTEXTUAL_MENU} .${DISCONNECT_BUTTON}`,
).parentElement;
}
/**
* Panneau de gauche
* @type {HTMLElement}
* @readonly
*/
get leftPanel() {
return this.tchapContext.querySelector(`.${LEFT_PANEL}`);
}
/**
* Div en arrière plan lorsque le menu des paramètres est ouvert.
* @type {HTMLElement}
* @readonly
*/
get contextualMenuBackground() {
return this.tchapContext.querySelector(`.${CONTEXTUAL_MENU_BACKGROUND}`);
}
/**
* Ouvre le menu des paramètres puis récupère le bouton de thème.
* @type {HTMLElement}
* @readonly
*/
get themeButton() {
this.settingMenuButton.click();
return this.tchapContext.querySelector(`.${THEME_BUTTON}`);
}
/**
* Messages non-lu
* @type {string | number}
* @readonly
*/
get unread() {
if (!this.badge) return null;
const val = +(this.badge.textContent || 'user_defined_unread');
return isNaN(val) ? TCHAT_UNREAD : val;
}
// #endregion
// #region Main
/**
* @async
* @package
*/
async main() {
super.main();
if ($('#wait_box').length) $('#wait_box').hide();
/**
* Interrupteur local qui défini si tchap à été lancer en mode mobile puis redimensionner.
*
* La page de "redirection" ne doit pas être afficher en cas de redimensionnement.
* @private
* @type {boolean}
*/
this._tchap_mobile_mode_removed = false;
const url = this.get_env('tchap_startup_url') || this.get_env('tchap_url');
let $tchap = $('#tchap_frame').attr('src', url);
if (navigator.appName === 'Microsoft Internet Explorer')
$tchap[0].contentWindow.location.reload(true);
//Ne pas afficher tchap en mode mobile
if ((top ?? parent).$('html').hasClass('layout-phone')) {
$('#tchap_frame').hide();
$('#tchap_mobile').show();
} else {
this._tchap_mobile_mode_removed = true;
}
{
const CONNECTED_SELECTOR = `.${SETTING_BUTTON}`;
await this.wait_something(
() => this.tchapContext.querySelector(CONNECTED_SELECTOR) !== null,
60,
);
if (this.tchapContext.querySelector(CONNECTED_SELECTOR) !== null) {
try {
this.change_theme();
} catch (error) {
console.warn(
'/!\\[tchamanager]Erreur lors du premier changement de thème',
error,
);
}
}
}
if (this._tchap_mobile_mode_removed) {
window.addEventListener('resize', () => {
if (
!this._tchap_mobile_mode_removed &&
$('html').hasClass('layout-phone')
) {
$('#tchap_frame').hide();
$('#tchap_mobile').show();
} else {
$('#tchap_frame').show();
$('#tchap_mobile').hide();
}
});
}
this.rcmail().addEventListener(
'switched_color_theme',
this.change_theme.bind(this),
);
this.rcmail().addEventListener(
'tchap.options',
this.tchap_options.bind(this),
);
this.rcmail().addEventListener(
'tchap.sidebar',
this.tchap_sidebar.bind(this),
);
this.rcmail().addEventListener(
'tchap.disconnect',
this.tchap_disconnect.bind(this),
);
this._notificationhandler();
if (this.get_env('display_tchap_sidebar') === 'false')
this.leftPanel.style.display = 'none';
//Mettre à jours les messages quand on vient sur le frame.
const is_top = true;
this.rcmail(is_top).addEventListener('frame_loaded', (eClass) => {
if (eClass === 'tchap') this.update_badge();
});
}
//#endregion
// #region private
/**
* Gestion des notifications sur la barre de gauche
* @private
* @return {Promise<void>}
*/
async _notificationhandler() {
while (true) {
this.update_badge(); //this._update_badge();
await this.sleep(
FramesManager.Instance.currentTask === 'tchap'
? SLEEP_ON_TASK
: SLEEP_OUTSIDE,
);
}
}
/**
* Met à jour le badge de notification du bouton lié à ce plugin de la barre de navigation principale.
* @private
*/
_update_badge() {
const val = this.unread;
if (val) {
MainNav.update_badge(val, 'tchap_badge');
} else {
MainNav.update_badge(0, 'tchap_badge');
}
}
// #endregion
// #region publics
/**
* Met à jour le badge de notification du bouton lié à ce plugin de la barre de navigation principale.
*
* Initialise le badge si besoin.
*/
update_badge() {
MainNav.try_add_round('.button-tchap', 'tchap_badge');
this._update_badge();
}
/**
* Retourne la frame de tchap
* @public
* @returns {external:Jquery}
*/
tchap_frame() {
return $('#tchap_frame');
}
/**
* Change le thème de tchap
* @public
* @method
*/
change_theme() {
const color = this.get_skin().color_mode();
const tchap_color = this.tchapContext
.querySelector('body')
.classList.contains(CURRENT_THEME_BODY_CLASS)
? 'light'
: 'dark';
if (color !== tchap_color) {
this.themeButton.click();
if (this.contextualMenuBackground) this.contextualMenuBackground.click();
}
}
/**
* Ouvre les paramètres de tchap
* @public
* @method
*/
tchap_options() {
this.settingButton.click();
top.m_mp_ToggleGroupOptionsUser();
}
/**
* Options gérant l'affichage de la barre latérale de tchap
* @public
* @method
*/
tchap_sidebar() {
let checked = top.$('#tchap_sidebar').prop('checked');
this.http_internal_post({
task: 'tchap',
action: 'sidebar',
params: { _showsidebar: checked },
});
this.leftPanel.style.display = checked ? EMPTY_STRING : 'none';
}
/**
* Deconnecte de tchap
* @public
* @method
*/
tchap_disconnect() {
this.disconnectButton.click();
top.m_mp_ToggleGroupOptionsUser();
}
// #endregion
}