Update comments UI : Refonte complète des commentaires — threading N-niveaux, éditeur riche, sécurité, validation#37
Merged
Merged
Conversation
…ve N‑level tree using a CommentNode structure, parent pointing to the direct parent and nested recursive rendering in the frontend, removing the old flat CommentThreadView
…ip <script> and non‑allowed tags, use a SunEditor‑compatible whitelist, move ALLOWED_TAGS to a frozenset on CommentService, update docstrings, and adjust integration tests to match nh3’s stripping. Add the nh3 dependency and update service + tests
…) for N‑level threading (depth capped at 4, deeper levels flattened), remove <hr> separators and update integration test to expect Level 3 rendering. Update article_detail.html with the recursive macro, .comment-depth-N classes, avatar initial + circle, formatted timestamp, and Reply button with hidden form
… .comment-avatar and .comment-content flex layout, depth‑based indentation via .comment-depth‑1..4, header row for author and timestamp, reply toggle and form styles, recursive .comment-replies wrapper, SunEditor dark‑theme variables, and a mobile media query. Remove five obsolete comment‑related classes
…e textarea with SunEditor‑ready IDs, syncing HTML to a hidden input on submit, adding per‑reply editors, loading SunEditor CSS/JS only when comments are present and adding the v2.43.10 bundles plus an initialization script for main and reply editors
…, replacing their content with “Comment removed” and setting the author to Anonymous, including legacy “[deleted]”. They are displayed in italics via .comment-deleted. Reply handling now allows only one reply form at a time. SunEditor initialization binds the form and hidden input before the editor is created. Docstrings are updated, CommentThreadView is removed, the emoji button is dropped, the repository adds get_by_reply_to and tests are adjusted for soft‑delete and the updated threading model
…he plugin triggers a CustomEvent, prompting the popup script to show an EmojiMart picker at the button location and inject the selected emoji into the appropriate editor. CSP is extended for CDN access, required bundles load only on comment pages and minimal CSS styles the floating popup
…avior. The popup now repositions when it overflows the viewport, scroll events outside the picker close it and mobile layouts center the picker with adjusted sizing
…moji picker by setting EmojiMart’s skinTonePosition to 'none' in the Picker options
…r UI by setting EmojiMart’s --font-family variable to var(--font-primary), so labels, categories and search text match the site typography
…ng the emoji button now closes the picker when it is already open instead of reopening it, matching expected UI behavior
…ditor UI by overriding its default font on the root container, so the toolbar, menus, tooltips and editor chrome match the site typography
…atic cache policy. Dark mode uses proper class overrides, Inter is applied to the editor and chrome, spacing around comment forms is adjusted and static assets now use a split cache policy (dist → immutable, others → no‑cache)
…ons and list dropdowns. Toolbar SVGs now use var(--on-surface) instead of black and dark theme overrides are added for the list layer background, border and hover states
…ides unused link‑dialog fields, unifies link color to var(--primary) and preserves target="_blank" with rel="noopener noreferrer" in sanitization. Tests updated accordingly
…e comment template for correct reply overflow. Caps visual depth at 3, moves replies outside the padded header section and updates CSS accordingly
…mpact comment editing. Adds lineHeight: '1.4' to the editor config and CSS overrides for paragraphs and editable text
…eply forms. A hidden input catches bots and submissions with the field filled are silently rejected. Tests cover both comment and reply honeypot redirects
… limit to comments. Honeypot submissions are silently dropped and rate‑limited users get a flash with the remaining wait time. Tests updated for both behaviors
…ve cascade, strips the <!--cmt‑removed--> marker in DTOs and introduces orphan‑children helpers in repository adapters. Template updated for new delete flow, dead CSS removed and tests added for cascade and first‑click behavior
…ies are collapsed by default and expanded recursively on click, with CSS display rules and template/JS updates to place the toggle in .comment-actions
…earer visual separation from the article content
… now computes total comment nodes (including nested and soft‑deleted), passes the count to the template and tests cover zero, nested, and soft‑deleted cases plus an integration check
…ditor comment editor. Capture‑phase filters stop paste and drag‑and‑drop images, upload inputs are disabled, insertImage is neutralized and unused callbacks removed. JS is modernized and image‑related tags are dropped from ALLOWED_TAGS
…r article load and synced comment reveal. useArticle skips fetching when inline data exists, legacy text is wrapped for BlockNote, comments are revealed after the editor renders and vendor chunk preload speeds up the React mount
…browser, application, and database. Validation now runs before the rate‑limit check, preventing false cooldowns and error messages are cleaned for users. Frontend editors use maxlength, Pydantic enforces the limit and the database column is capped accordingly
… comment editors by enabling charCounter and setting maxTextLength to 5000 in the initCommentEditor config for both comment and reply editors
…to comment editors. CSS adds the hint style and removes default h4 spacing, the template restores the title and places the hint directly above SunEditor and the editor keeps the 5000‑character limit without placeholder or counter
… comment threads. Adds a .comment button rule in article.css to disable the default highlight on Reply, View replies, Cancel, Delete and Post Comment buttons
…idation. The editor strips HTML and shows a toast when the result is empty, hint text now requires 1–5000 chars, backend and validator both reject empty sanitized input, tests cover HTML‑only cases and the migration enforces VARCHAR(5000) with a minimum‑length check
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Résumé
Refonte complète du système de commentaires. 30 commits, 37 fichiers modifiés, ~1500 lignes ajoutées.
Commentaires hiérarchiques (N-niveaux)
CommentNodeavecbuild_comment_nested_tree()render_comment(node, depth=0), profondeur limitée à 3 avant aplatissement.comment-depth-1à.comment-depth-4) avec layout flex (avatar, en-tête, contenu)Éditeur de commentaires — SunEditor
<textarea>brut par SunEditor WYSIWYG, synchronisation du HTML vers un champ caché à la soumissioninitReplyEditor(commentId))insertImageneutralisé)1.4pour une saisie compacteSélecteur d'emoji
CustomEvent('open-emoji-picker')Sécurité
nh3.clean()avec une liste blanche compatible SunEditor bloque<script>et les tags non autoriséshp_commentattrape les bots ; les soumissions remplies sont silencieusement rejetéesCommentService; message : "You're posting too fast..."Limite de caractères et validation
maxCharCount: 5000dans SunEditor,maxlengthsur le textarea de secours, validateur Pydantic,VARCHAR(5000)en basenh3.clean()dans le service,CHECKconstraint en baseStyle et UX
.comment-join-titleavecmargin: 0).comment button { box-shadow: none }supprime le highlight des boutonsdist/immutable, le reste no-cache)