From 9cc04b640b45f7eadb7979629a22b35feb1ccd8c Mon Sep 17 00:00:00 2001 From: Luke Manyamazi Date: Fri, 17 Apr 2026 11:19:24 +0200 Subject: [PATCH 1/3] added code to limit bloom in the backend and control in the frontend --- backend/data/blooms.py | 3 +++ front-end/components/bloom.mjs | 26 ++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/backend/data/blooms.py b/backend/data/blooms.py index 7e280cf..925f398 100644 --- a/backend/data/blooms.py +++ b/backend/data/blooms.py @@ -16,6 +16,9 @@ class Bloom: def add_bloom(*, sender: User, content: str) -> Bloom: + if len(content) > 280: + raise ValueError("Bloom must not exceed 280 characters") + hashtags = [word[1:] for word in content.split(" ") if word.startswith("#")] now = datetime.datetime.now(tz=datetime.UTC) diff --git a/front-end/components/bloom.mjs b/front-end/components/bloom.mjs index 0b4166c..495a48d 100644 --- a/front-end/components/bloom.mjs +++ b/front-end/components/bloom.mjs @@ -8,10 +8,12 @@ * "sender": username, * "content": "string from textarea", * "sent_timestamp": "datetime as ISO 8601 formatted string"} - */ const createBloom = (template, bloom) => { if (!bloom) return; + + const MAX_BLOOM_LENGTH = 280; + const bloomFrag = document.getElementById(template).content.cloneNode(true); const bloomParser = new DOMParser(); @@ -21,14 +23,30 @@ const createBloom = (template, bloom) => { const bloomTimeLink = bloomFrag.querySelector("a:has(> [data-time])"); const bloomContent = bloomFrag.querySelector("[data-content]"); + const isTooLong = bloom.content && bloom.content.length > MAX_BLOOM_LENGTH; + + // Highlight invalid blooms (UI only) + if (isTooLong) { + bloomArticle.style.border = "2px solid red"; + bloomArticle.style.backgroundColor = "#fff5f5"; + bloomArticle.title = "This bloom exceeds 280 characters (invalid)"; + } + bloomArticle.setAttribute("data-bloom-id", bloom.id); bloomUsername.setAttribute("href", `/profile/${bloom.sender}`); bloomUsername.textContent = bloom.sender; bloomTime.textContent = _formatTimestamp(bloom.sent_timestamp); bloomTimeLink.setAttribute("href", `/bloom/${bloom.id}`); + + const displayContent = isTooLong + ? `[INVALID BLOOM - exceeds 280 characters]\n\n${bloom.content}` + : bloom.content; + bloomContent.replaceChildren( - ...bloomParser.parseFromString(_formatHashtags(bloom.content), "text/html") - .body.childNodes + ...bloomParser.parseFromString( + _formatHashtags(displayContent), + "text/html" + ).body.childNodes ); return bloomFrag; @@ -84,4 +102,4 @@ function _formatTimestamp(timestamp) { } } -export {createBloom}; +export { createBloom }; \ No newline at end of file From 6c20c8045c596291376129282ce62d10cd2ef01c Mon Sep 17 00:00:00 2001 From: Luke Manyamazi Date: Thu, 23 Apr 2026 08:05:29 +0200 Subject: [PATCH 2/3] refactor: replaced hardcoded bloom character limit with constant --- backend/data/blooms.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/data/blooms.py b/backend/data/blooms.py index 925f398..d1edefc 100644 --- a/backend/data/blooms.py +++ b/backend/data/blooms.py @@ -6,7 +6,7 @@ from data.connection import db_cursor from data.users import User - +MAX_BLOOM_LENGTH = 280 @dataclass class Bloom: id: int @@ -16,8 +16,8 @@ class Bloom: def add_bloom(*, sender: User, content: str) -> Bloom: - if len(content) > 280: - raise ValueError("Bloom must not exceed 280 characters") + if len(content) > MAX_BLOOM_LENGTH: + raise ValueError(f"Bloom must not exceed {MAX_BLOOM_LENGTH} characters") hashtags = [word[1:] for word in content.split(" ") if word.startswith("#")] From 14f32a49bb84d2b5f0b1ae953cc952d8b69de31f Mon Sep 17 00:00:00 2001 From: Luke Manyamazi Date: Fri, 24 Apr 2026 15:57:19 +0200 Subject: [PATCH 3/3] fixed the character limit constant reference Co-authored-by: Copilot --- backend/data/blooms.py | 1 + front-end/components/bloom.mjs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/data/blooms.py b/backend/data/blooms.py index d1edefc..3914020 100644 --- a/backend/data/blooms.py +++ b/backend/data/blooms.py @@ -7,6 +7,7 @@ from data.users import User MAX_BLOOM_LENGTH = 280 + @dataclass class Bloom: id: int diff --git a/front-end/components/bloom.mjs b/front-end/components/bloom.mjs index 495a48d..f962a2a 100644 --- a/front-end/components/bloom.mjs +++ b/front-end/components/bloom.mjs @@ -29,7 +29,7 @@ const createBloom = (template, bloom) => { if (isTooLong) { bloomArticle.style.border = "2px solid red"; bloomArticle.style.backgroundColor = "#fff5f5"; - bloomArticle.title = "This bloom exceeds 280 characters (invalid)"; + bloomArticle.title = `This bloom exceeds ${MAX_BLOOM_LENGTH} characters (invalid)`; } bloomArticle.setAttribute("data-bloom-id", bloom.id); @@ -39,7 +39,7 @@ const createBloom = (template, bloom) => { bloomTimeLink.setAttribute("href", `/bloom/${bloom.id}`); const displayContent = isTooLong - ? `[INVALID BLOOM - exceeds 280 characters]\n\n${bloom.content}` + ? `[INVALID BLOOM - exceeds ${MAX_BLOOM_LENGTH} characters]\n\n${bloom.content}` : bloom.content; bloomContent.replaceChildren(