diff --git a/backend/data/blooms.py b/backend/data/blooms.py index 7e280cf..3914020 100644 --- a/backend/data/blooms.py +++ b/backend/data/blooms.py @@ -6,6 +6,7 @@ from data.connection import db_cursor from data.users import User +MAX_BLOOM_LENGTH = 280 @dataclass class Bloom: @@ -16,6 +17,9 @@ class Bloom: def add_bloom(*, sender: User, content: str) -> Bloom: + 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("#")] now = datetime.datetime.now(tz=datetime.UTC) diff --git a/front-end/components/bloom.mjs b/front-end/components/bloom.mjs index 0b4166c..f962a2a 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 ${MAX_BLOOM_LENGTH} 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 ${MAX_BLOOM_LENGTH} 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