From f5a4014e41839648dc96d6b5abf0cb39c7138135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20FAMIBELLE-PRONZOLA?= Date: Tue, 7 Jul 2026 16:11:46 +0400 Subject: [PATCH] =?UTF-8?q?feat:=20ajouter=20un=20s=C3=A9lecteur=20d'insta?= =?UTF-8?q?nce=20Mastodon=20et=20expliciter=20BOKANTE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../teks/__tests__/repons-mastodon.test.jsx | 37 ++++++-- components/teks/repons-mastodon.jsx | 87 ++++++++++++++----- 2 files changed, 92 insertions(+), 32 deletions(-) diff --git a/components/teks/__tests__/repons-mastodon.test.jsx b/components/teks/__tests__/repons-mastodon.test.jsx index afe6b19..f1880ec 100644 --- a/components/teks/__tests__/repons-mastodon.test.jsx +++ b/components/teks/__tests__/repons-mastodon.test.jsx @@ -15,19 +15,36 @@ describe('ReponsMastodon', () => { expect(container).toBeEmptyDOMElement() }) - it('affiche un lien direct vers le fil bokante', () => { + it('affiche un lien direct vers le fil BOKANTE', () => { render() - const lien = screen.getByRole('link', {name: 'Mastodon'}) + const lien = screen.getByRole('link', {name: 'BOKANTE (Mastodon)'}) expect(lien).toHaveAttribute('href', 'https://bokante.o-k-i.net/@pawol_nu/112233') }) - it('redirige vers authorize_interaction avec le domaine extrait d\'un identifiant complet', async () => { + it('redirige vers BOKANTE par défaut quand on continue', async () => { window.open = vi.fn() const user = userEvent.setup() render() - await user.click(screen.getByRole('button', {name: /répondre via mastodon/i})) - await user.type(screen.getByLabelText(/@vous@votre-instance/i), '@quelqun@mastodon.social') + await user.click(screen.getByRole('button', {name: /répondre sur mastodon/i})) + await user.click(screen.getByRole('button', {name: /continuer/i})) + + expect(window.open).toHaveBeenCalledWith( + 'https://bokante.o-k-i.net/authorize_interaction?uri=' + encodeURIComponent('https://bokante.o-k-i.net/@pawol_nu/112233'), + '_blank', + 'noopener,noreferrer' + ) + }) + + it('permet de choisir une autre instance dans le select', async () => { + window.open = vi.fn() + const user = userEvent.setup() + render() + + await user.click(screen.getByRole('button', {name: /répondre sur mastodon/i})) + await user.click(screen.getByLabelText(/instance mastodon/i)) + await user.click(screen.getByRole('option', {name: /autre instance/i})) + await user.type(screen.getByLabelText(/@vous@votre-instance/i), 'mastodon.social') await user.click(screen.getByRole('button', {name: /continuer/i})) expect(window.open).toHaveBeenCalledWith( @@ -37,17 +54,19 @@ describe('ReponsMastodon', () => { ) }) - it('accepte aussi juste un nom d\'instance sans @', async () => { + it('accepte un identifiant complet pour une autre instance', async () => { window.open = vi.fn() const user = userEvent.setup() render() - await user.click(screen.getByRole('button', {name: /répondre via mastodon/i})) - await user.type(screen.getByLabelText(/@vous@votre-instance/i), 'mastodon.social') + await user.click(screen.getByRole('button', {name: /répondre sur mastodon/i})) + await user.click(screen.getByLabelText(/instance mastodon/i)) + await user.click(screen.getByRole('option', {name: /autre instance/i})) + await user.type(screen.getByLabelText(/@vous@votre-instance/i), '@quelqun@mastodon.social') await user.click(screen.getByRole('button', {name: /continuer/i})) expect(window.open).toHaveBeenCalledWith( - expect.stringContaining('https://mastodon.social/authorize_interaction'), + 'https://mastodon.social/authorize_interaction?uri=' + encodeURIComponent('https://bokante.o-k-i.net/@pawol_nu/112233'), '_blank', 'noopener,noreferrer' ) diff --git a/components/teks/repons-mastodon.jsx b/components/teks/repons-mastodon.jsx index fd63b63..afb13da 100644 --- a/components/teks/repons-mastodon.jsx +++ b/components/teks/repons-mastodon.jsx @@ -10,11 +10,24 @@ import DialogContent from '@mui/material/DialogContent' import DialogActions from '@mui/material/DialogActions' import TextField from '@mui/material/TextField' import Typography from '@mui/material/Typography' +import FormControl from '@mui/material/FormControl' +import InputLabel from '@mui/material/InputLabel' +import Select from '@mui/material/Select' +import MenuItem from '@mui/material/MenuItem' import Link from 'next/link' +import {Mastodon} from '@icons-pack/react-simple-icons' const BOKANTE_URL = process.env.NEXT_PUBLIC_BOKANTE_URL || 'https://bokante.o-k-i.net' const BOKANTE_ACCOUNT = process.env.NEXT_PUBLIC_BOKANTE_ACCOUNT || 'pawol_nu' +const INSTANCES_SUGGEREES = [ + {domain: 'bokante.o-k-i.net', label: 'BOKANTE - notre instance'}, + {domain: 'mastodon.social', label: 'mastodon.social'}, + {domain: 'piaille.fr', label: 'piaille.fr'}, +] + +const AUTRE_INSTANCE = 'autre' + function extraireInstance(saisie) { const valeur = saisie.trim().replace(/^@/, '').replace(/^https?:\/\//, '').replace(/\/$/, '') return valeur.includes('@') ? valeur.split('@').pop() : valeur @@ -22,7 +35,8 @@ function extraireInstance(saisie) { export default function ReponsMastodon({bokanteStatusId}) { const [ouvert, setOuvert] = useState(false) - const [saisie, setSaisie] = useState('') + const [instance, setInstance] = useState(INSTANCES_SUGGEREES[0].domain) + const [autreInstance, setAutreInstance] = useState('') if (!bokanteStatusId) { return null @@ -31,43 +45,70 @@ export default function ReponsMastodon({bokanteStatusId}) { const tootUrl = `${BOKANTE_URL}/@${BOKANTE_ACCOUNT}/${bokanteStatusId}` const repondre = () => { - const instance = extraireInstance(saisie) - if (!instance) { + const domaine = instance === AUTRE_INSTANCE ? extraireInstance(autreInstance) : instance + if (!domaine) { return } - window.open(`https://${instance}/authorize_interaction?uri=${encodeURIComponent(tootUrl)}`, '_blank', 'noopener,noreferrer') + window.open(`https://${domaine}/authorize_interaction?uri=${encodeURIComponent(tootUrl)}`, '_blank', 'noopener,noreferrer') setOuvert(false) + setAutreInstance('') } return ( - Rejoignez la discussion sur{' '} - Mastodon + Rejoignez la discussion sur le Fediverse via{' '} + BOKANTE (Mastodon) - setOuvert(false)}> - Répondre depuis votre compte Mastodon + Répondre depuis Mastodon - Indiquez votre identifiant (@vous@votre-instance) ou juste le nom de votre - instance, vous serez redirigé·e vers votre compte pour répondre. + Choisissez l’instance Mastodon sur laquelle vous avez un compte. + BOKANTE est l’instance de OKI : vous pouvez aussi utiliser + n’importe quelle autre instance du Fediverse. - setSaisie(event.target.value)} - onKeyDown={event => { - if (event.key === 'Enter') { - repondre() - } - }} - /> + + Instance Mastodon + + + {instance === AUTRE_INSTANCE && ( + setAutreInstance(event.target.value)} + onKeyDown={event => { + if (event.key === 'Enter') { + repondre() + } + }} + /> + )}