Introduction
Bonjour à tous !
J'en conviens que le LS que je propose aujourd'hui n'est pas très conventionnel, mais j'espère tout de même qu'il vous sera tout aussi utile qu'à vos membres. Il y a un peu plus d'une semaine déjà, j'écrivais un sujet ici pour teaser le plugin sur lequel je travaillais. Il est maintenant terminé et je ne suis pas peu fier d'enfin pouvoir le partager !
Si vous êtes intéressés, je vous invite à lire la suite pour savoir comment Switcheroo fonctionne et comment l'installer sur vos forums !
Prérequis
Switcheroo nécessite quelques modifications de votre part avant d'être installer et je vais expliquer comment tout bien préparer :
- Tout d'abord, il vous faudra autoriser les formulaires non-officiel à poster leurs données sur votre forum. Pour ce faire, rien de compliqué : accédez au panneau d'administration et suivez ce chemin Général > Forum > Sécurité. Il faudra décocher l'option "Interdire les formulaires non officiels à poster des messages et messages privés sur le forum" et sauvegarder les changements (image). Cette modification permettra au formulaire de Switcheroo de fonctionner avec Fetch, une API de Javascript.
- Ensuite, vous devrez vous assurez que la Toolbar de ForumActif est activée. Si ce n'est pas le cas, faites-le en suivant ce chemin : Module > Toolbar > Configuration (image). Si elle était désactivée parce que vous ne l'utilisiez pas, je proposerai plus bas une façon de la rendre invisible, ne vous en faites pas. Cette modification nous permettra de récupérer facilement l'ID d'un membre ainsi que son avatar et de savoir s'il est connecté ou non.
- En dernier, la barre de navigation principale de votre forum (celle qui permet de faire une recherche, de se connecter, de s'inscrire et de se déconnecter) devra être présente quelque part sur toutes les pages. Si vous l'avez retiré de vos templates, assurez-vous de l'ajouter quelque part, dans un <div> quelconque et de la cacher avec un style="display: none;". C'est avec cette barre que nous récupérons l'ID temporaire de votre session, qui permettra de changer de compte instantanément.
Installation
Le plugin en lui-même est très simple à installer. Il comprend deux fichiers Javascript hébergés sur dropbox – ce qui me permettra de pouvoir patcher directement les scripts en cas de besoin. Le premier, monomer_core.js, est un outil où je centralise toutes les fonctions utilitaires dont je me sers. Notamment, c'est grâce à ce script que le formulaire de connexion du plugin est appelé en popup. Le deuxième fichier, c'est le plugin : switcheroo.js.
Voici le code qui permet de tout mettre en place d'un seul coup :
- Code:
<nav id="switcheroo" class="switcheroo" theme="discord" direction="vertical" position="top"></nav>
<script src="https://cdn.jsdelivr.net/gh/caezd/switcheroo@master/monomer.js"></script>
<script src="https://cdn.jsdelivr.net/gh/caezd/switcheroo@master/switcheroo.js"></script>
<script>
(function() {
new Switcheroo('#switcheroo');
})();
</script>
Options
Switcheroo vient avec quelques options qu'il vous est possible de modifier facilement. Elles doivent être ajouter à l'initialisation du plugin pour fonctionner. Celles ci-dessous sont lest options par défaut.
- Code:
(function() {
new Switcheroo('#switcheroo', {
logo: '', /* accepte html, permet d'afficher un logo qui retourne à l'accueil du forum */
enableReorder: true, /* activer le drag&drop pour l'ordre des comptes (true/false) */
updateAvatar: true, /* activer le clique droit pour charger un nouvel avatar (true/false) */
customButtons: [], /* boutons personnalisés, explication plus bas */
confirm: true, /* demande une confirmation avant le changement de compte */
confirmMsg: 'Confirmer le Switcheroo de personnage ?', /* le message affiché lors de la confirmation */
deleteIcon: '×', /* accepte html, icone pour supprimer un compte lié */
addIcon: '+', /* accepte html, icone qui ouvre le formulaire de connexion et d'association */
errorMsg: 'Une erreur est surviendue lors du Switcheroo.',
});
})();
- Code:
<script>
(function() {
new Switcheroo('#switcheroo', {
logo: '<img src="https://i.imgur.com/C01GNxF.png" />'
});
})();
</script>
Boutons Customisés
- Explication des custom-buttons:
- L'option des boutons customisé est un peu plus complexe que les autres et demande un peu de connaissances en Javascript. Il s'agit d'un tableau d'objets, c'est-à-dire qu'à l'intérieur des crochets "[" et "]" il faudra créer chaque bouton entre "{" et "}" comme ceci :
- Code:
customButtons: [
{
tooltip: 'Bouton 1',
classes: ['bouton1', 'bouton1rouge'],
html: '<img src="http://imagebouton1.etc" />',
before: false,
action: '/t1-titre-du-topic'
},
{
html: '<i class="material-icons">icon_au_choix<i/>',
action: function(e, el) { }
}
]
- L'option "tooltip" parle un peu d'elle même : elle affiche le nom du bouton au survol de la souris, comme le reste des autres boutons/comptes.
- L'option "classes" est un tableau qui permet d'ajouter des classes CSS différentes pour chaque bouton. En plus de celle par défaut ".switcheroo__button", elles seront formatées de cette façon : ".switcheroo__button--bouton1"
(pour respecter mon semblant de covention BEM, fufu). - L'option "html" vous permet de décider du contenu qui sera ajouter à l'intérieur du bouton. Ça peut être du simple texte, une image, etc.
- L'option "before" est un boolean (true/false, par défaut "false") qui permet de changer la position du bouton avec à la propriété "order: -1" de CSS, accessible grâce au flexbox de la barre. Lorsque "true", le bouton sera ajouté avant la liste des comptes mémorisés. Si plusieurs boutons sont placés avant grâce à "before", ils s'afficheront dans l'ordre qu'ils sont créés avant les comptes.
- L'option "action" peut être exploiter de deux façons différente. D'une part, elle accepte comme valeur un lien valide (soit une adresse complète ou relative, du genre "/f1-forum" ou "/t1-topic"). (Blabla JS plus spécifique incoming :) Sinon, il est également possible de passer une fonction qui sera appelée au clique de la souris. Le premier argument est l'équivalent "event" du listener, le deuxième renvoi l'élément du bouton cliqué et "this" est bind à Switcheroo (et donne donc accès à ses fonctions internes).
Voici un exemple de boutons en Javascript :Bouton de déconnexion
- Code:
{
tooltip: 'Se déconnecter',
before: true,
classes: ['logout'],
html: '<i class="material-icons">icon_au_choix<i/>',
action: function(e, el) {
alert("À la prochaine ! o/");
this.logout(e => monomer.reload());
}
}
Apparence
Pour ce qui est du CSS maintenant, vous devez l'installer sur votre forum dans sa totalité. Il est complet et vient avec quelques variables pour vous permettre de modifier les couleurs facilement. Celles par défaut vous donneront le même visuel que celui présenté tout en haut de ce sujet (ou sur le forum d'exemple) :
- CSS:
- Code:
:root {
--color-text: rgba(255, 255, 255, 0.87);
--color-bg: #17141b;
--color-delete: #e74c3c;
--color-tooltip: #010203;
--color-squircle: #201f2e;
--color-accent: #b14255;
--color-button: #aaa2f2;
--color-pill: #ffffff;
--gap-size: 16px;
--ease: cubic-bezier(0.4, 0.0, 0.2, 1);
--ease-bounce: cubic-bezier(0.43, 0.09, 0.38, 2.56);
}
.switcheroo {
color: var(--color-text);
background-color: var(--color-bg);
font-size: 16px;
}
.switcheroo[position="static"] {
position: relative;
}
.switcheroo[position="top"] {
position: fixed;
top: 0;
left: 0;
z-index: 100;
}
.switcheroo[position="bottom"] {
position: fixed;
bottom: 0;
left: 0;
z-index: 100;
}
.switcheroo[direction="horizontal"] {
width: 100%;
}
.switcheroo[direction="vertical"] {
height: 100%;
}
.switcheroo__squircles {
display: flex;
margin: 0;
padding: 0;
list-style: none;
padding: var(--gap-size);
gap: var(--gap-size);
}
.switcheroo[direction="horizontal"] .switcheroo__squircles {
flex-direction: row;
}
.switcheroo[direction="vertical"] .switcheroo__squircles {
flex-direction: column;
}
/* squircle */
.switcheroo[theme="discord"] .switcheroo__squircle {
position: relative;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-squircle);
}
.switcheroo[theme="discord"] .switcheroo__squircle {
width: 48px;
height: 48px;
border-radius: 50%;
cursor: pointer;
transition: border-radius 128ms var(--ease);
}
.switcheroo[theme="discord"] .switcheroo__squircle:hover {
border-radius: 36%;
}
.switcheroo[theme="discord"][direction="vertical"] .switcheroo__squircle:before {
content: "";
width: 100%;
height: 100%;
display: block;
background-color: var(--color-pill);
position: absolute;
border-radius: 4px;
top: 50%;
transform: translate(-100%, -50%) scale(0);
transition: transform 128ms, opacity 64ms;
pointer-events: none;
opacity: 0;
}
.switcheroo[theme="discord"][direction="horizontal"] .switcheroo__squircle:before {
content: "";
width: 100%;
height: 100%;
display: block;
background-color: var(--color-pill);
position: absolute;
border-radius: 4px;
left: 50%;
transform: translate(-50%, -100%) scale(0);
transition: transform 128ms, opacity 64ms;
pointer-events: none;
opacity: 0;
}
.switcheroo[theme="discord"] .switcheroo__squircle.active {
border-radius: 36%;
cursor: default;
}
.switcheroo[theme="discord"][direction="vertical"] .switcheroo__squircle:hover:before {
opacity: 1;
transform: translate(-100%, -50%) scale(0.5);
}
.switcheroo[theme="discord"][direction="horizontal"] .switcheroo__squircle:hover:before {
opacity: 1;
transform: translate(-50%, -100%) scale(0.5);
}
.switcheroo[theme="discord"][direction="vertical"] .switcheroo__squircle.active:before {
opacity: 1;
transform: translate(-85%, -50%) scale(0.2);
border-radius: 50%;
}
.switcheroo[theme="discord"][direction="horizontal"] .switcheroo__squircle.active:before {
opacity: 1;
transform: translate(-50%, -85%) scale(0.2);
border-radius: 50%;
}
/* tooltip */
.switcheroo__popper {
background-color: var(--color-tooltip);
padding: 0.68rem 1rem;
position: absolute;
width: -webkit-max-content;
width: max-content;
border-radius: 4px;
z-index: 0;
opacity: 0;
transition: opacity 64ms var(--ease), transform 128ms var(--ease-bounce);
pointer-events: none;
color: #fff;
}
.switcheroo[direction="vertical"] .switcheroo__popper {
left: 155%;
top: 50%;
transform-origin: left;
transform: translateY(-50%) scale(0.98);
}
.switcheroo[direction="horizontal"] .switcheroo__popper {
top: 155%;
left: 50%;
transform-origin: top;
transform: translateX(-50%) scale(0.98);
}
.switcheroo__popper:before {
content: "";
position: absolute;
width: 24px;
height: 24px;
background-color: var(--color-tooltip);
z-index: -1;
}
.switcheroo[direction="vertical"] .switcheroo__popper:before {
left: -2px;
top: 50%;
transform: translateY(-50%) rotate(-45deg);
}
.switcheroo[direction="horizontal"] .switcheroo__popper:before {
left: 50%;
top: -2px;
transform: translateX(-50%) rotate(-45deg);
}
.switcheroo[direction="vertical"] .switcheroo__squircle:hover .switcheroo__popper {
opacity: 1;
transform: translateY(-50%) scale(1);
}
.switcheroo[direction="horizontal"] .switcheroo__squircle:hover .switcheroo__popper {
opacity: 1;
transform: translateX(-50%) scale(1);
}
.switcheroo__squircle:hover:before {
opacity: 1;
transform: translate(-100%, -50%) scale(0.5);
}
/* avatar */
.switcheroo[theme="discord"] .switcheroo__avatar {
position: relative;
width: 100%;
height: 100%;
border-radius: inherit;
overflow: hidden;
}
.switcheroo[theme="discord"] .switcheroo__avatar img {
width: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* divider */
.switcheroo[theme="discord"][direction="vertical"] .switcheroo__divider {
width: 100%;
height: 2px;
background-color: var(--color-pill);
border-radius: 1px;
opacity: 0.06;
transform: scale(0.8);
}
.switcheroo[theme="discord"][direction="horizontal"] .switcheroo__divider {
width: 2px;
background-color: var(--color-pill);
border-radius: 1px;
opacity: 0.06;
transform: scale(0.8);
}
/* delete button */
.switcheroo[theme="discord"] .switcheroo__delete {
display: flex;
justify-content: center;
position: absolute;
width: 16px;
line-height: 14px;
height: 16px;
top: -2px;
right: -2px;
border-radius: 50%;
background-color: var(--color-delete);
transform: scale(0);
opacity: 1;
transition: transform 128ms var(--ease), opacity 64ms var(--ease);
cursor: pointer;
font-size: 13px;
}
.switcheroo[theme="discord"] .switcheroo__squircle:hover .switcheroo__delete {
opacity: 1;
transform: scale(1);
}
/* logo */
.switcheroo[theme="discord"] .switcheroo__logo {
}
.switcheroo[theme="discord"] .switcheroo__logo img {
width: 32px;
}
.switcheroo[theme="discord"] .switcheroo__logo:hover {
background-color: var(--color-accent);
}
/* buttons */
.switcheroo[theme="discord"] .switcheroo__squircle--button {
transition: border-radius 128ms var(--ease);
color: var(--color-button);
}
.switcheroo[theme="discord"] .switcheroo__squircle--button:hover {
color: #fff;
background-color: var(--color-button);
}
/* modal */
.switcheroo__form {
padding: 48px;
}
.switcheroo__form-row {
display: flex;
flex-flow: column;
align-items: flex-start;
margin-bottom: 16px;
}
.switcheroo__form-label {
margin-bottom: 8px;
font-size: 14px;
text-transform: uppercase;
color: var(--color-text) !important;
}
.switcheroo__form-input {
padding: 6px !important;
font-size: 16px !important;
border-radius: 4px !important;
width: 100% !important;
border-bottom: 2px solid var(--color-accent) !important;
background-color: var(--color-bg) !important;
color: var(--color-text) !important;
cursor: text !important;
}
.switcheroo__form-button {
border-radius: 8px;
padding: 8px;
border: none;
outline: none;
box-shadow: none;
text-transform: uppercase;
font-size: 14px;
align-self: flex-end;
color: #fff;
background-color: var(--color-accent);
}
.monomer-overlay {
position: fixed;
z-index: 999;
top: 0;
left: 0;
opacity: 0;
width: 100%;
height: 100%;
transition: 0.2s opacity ease;
background: rgba(0, 0, 0, 0.6);
}
.monomer-modal {
position: fixed;
z-index: 999;
top: 50%;
left: 50%;
opacity: 0;
width: 94%;
padding: 24px 20px;
transition: 0.2s opacity ease;
transform: translate(-50%, -50%);
border-radius: 2px;
background: var(--color-squircle);
color: var(--color-text);
}
.monomer-modal.monomer-open.monomer-anchored {
top: 20px;
transform: translate(-50%, 0);
}
.monomer-modal.monomer-open {
opacity: 1;
}
.monomer-overlay.monomer-open {
opacity: 1;
}
.monomer-close {
font-family: Helvetica, Arial, sans-serif;
font-size: 20px;
font-weight: 700;
line-height: 24px;
text-align: center;
width: 24px;
height: 24px;
position: absolute;
top: -5px;
right: -5px;
padding: 5px;
cursor: pointer;
color: #fff;
border: 0;
outline: none;
background: var(--color-delete);
border-radius: 50%;
padding: 0;
}
.monomer-close:hover {
opacity: 0.8;
}
Variantes visuelles
Le CSS vient également avec certaines variantes qui vous permettent, par exemple, de changer l'orientation de la barre (verticale ou horizontale), sa position et son comportement.
Si nous reprenons le HTML installé dans le template "Fin du bas de page" : Template > Général > overall_footer_end, vous remarquerez sans doute certaines valeurs :
- Code:
<nav id="switcheroo" class="switcheroo" theme="discord" direction="vertical" position="top"></nav>
- id="switcheroo" Il s'agit de l'identifiant de la balise, qui permet entre autres au JS de fonctionner.
- class="switcheroo" La classe sert surtout pour le style général de la barre. Je vous déconseille de la changer sans également modifier le CSS.
- theme="discord" Une option qui permettra, éventuellement, de changer le thème de switcheroo (lorsque j'en aurai ajouté d'autres). Pour l'instant, "discord" est le seul présent et celui à utiliser par défaut.
- direction="vertical" Permet de changer la direction de la barre, soit "vertical" (par défaut, voir l'exemple plus haut) ou "horizontal".
position="top"Après révision (et en écrivant ces lignes), je réalise que cette fonction n'était pas très bien réfléchie. Pour l'instant, n'y touchez pas.
Masquer la toolbar moche
Comme promis, ce petit bout de CSS vous débarrassera de la toolbar sans la désactiver, permettant ainsi au plugin de fonctionner incognito. Si jamais elle a ajouté un espace indésirable en haut de votre forum, assurez-vous qu'elle ne soit pas fixée à l'écran : comme ceci.
- Code:
#fa_toolbar, #fa_toolbar_hidden {
display: none!important;
}
Conclusion
Voilà. Je pense que c'est tout bon. Si jamais vous avez des questions ou des suggestions pour améliorer ce petit plugin, n'hésitez pas à m'en faire part ! Je suis ouvert à publier des mises à jour et ajouter de nouvelles fonctionnalités si j'en vois l'utilité. Je travaille déjà sur une deuxième version qui devrait ajouter quelques fonctionnalités sympathiques et j'ai d'autres idées potentielles sur lesquelles j'hésite encore. Et qui sait, si vous les proposez vous-même, peut-être que j'y réfléchirai plus sérieusement.
Si vous rencontrez un problème lors de l'installation, quoique ce soit, n'hésitez pas à venir me le dire et je m'empresserai de vous aider !
Et, sur ce... enjoyez bien.
FAQ
Sécurité
Pour reprendre ce que j'ai expliqué à 'Christa, je ne suis clairement pas un expert sur le sujet, mais voici comment est abordée la sécurité de Switcheroo :
- Les identifiants sont enregistrés en LocalStorage (un peu comme les sessions sont enregistrés par FA quand vous cochez "se souvenir de moi" en vous connectant sur un forum).
- Ces données sont encryptées, au-moins pour les protéger s'il y a plusieurs membres d'une même famille qui sont sur un forum (auquel cas, ils peuvent quand même se servir du plugin s'ils sont d'accord, mais n'auront pas accès aux mots de passe directement, même en allant fouiller l'inspecteur).
- L'utilisation de scripts par les membres d'un forum étant limitée, ils ne peuvent accéder qu'à leurs identifiants même en utilisant la console.
- Un administrateur mal intentionné, Switcheroo ou non, pourrait très bien récupérer les identifiants de ses membres avec n'importe quel script JS actif sur n'importe quel formulaire de connexion (ou même changer leurs mot de passe dans son panneau d'administration), donc ce côté là ne change pas.
- Switcheroo ne stocke aucunes informations sur une base de données externe.
Changelog
Version 1.1.0
- Une nouvelle option customButtons permet d'ajouter d'autres boutons à la barre.
- L'option updateAvatar (activée par défaut) permet de rafraîchir l'avatar du compte connecté au clique droit de la souris.
- L'option enableReorder (activée par défaut) permet de changer l'ordre des comptes enregistrés (drag & drop support).
Version 1.0.1
- Amélioration du visuel et ajout d'un mode horizontal. Mise place des thèmes.
Dernière édition par Monomer le Dim 18 Avr 2021 - 6:46, édité 11 fois