Commit Graph
73 Commits
Author SHA1 Message Date
BordedDev 3ea97f1e97 fix: remove unused isVisible method and fix sibling tracking in message rendering
- Remove the unused `isVisible()` method from `MessageElement` class to clean up dead code
- Fix `siblingGenerated` tracking logic: change from boolean to storing the actual next sibling reference, ensuring proper re-evaluation when DOM changes occur
- Move `endOfMessages` element creation before the observer loop to ensure it's observed for intersection events
2025-07-24 14:14:51 +00:00
BordedDev 6bddaeb6a4 fix: strip embed links and media from reply text and trigger change event on reply insertion 2025-07-20 01:38:18 +00:00
BordedDev e0a253521a refactor: replace click-based reply delegation with custom ReplyEvent in message-list
Replace the global click delegation on `messagesContainer` that checked for anchor tags with `href="#reply"` by introducing a dedicated `ReplyEvent` class. The event is now dispatched from within `MessageElement` when the reply link is clicked, carrying the message text target directly. This moves the reply logic from a fragile DOM traversal to a composed, bubbling custom event, improving encapsulation and maintainability.
2025-07-19 23:11:05 +00:00
BordedDev b4e67834d1 fix: guard against null parentElement and missing _originalChildren in message upsert 2025-07-19 21:31:23 +00:00
BordedDev 1f187c616c fix: invert scrolled-to-bottom guard in scrollToBottom to always scroll when not at bottom 2025-07-18 22:13:06 +00:00
BordedDev c09c8acc93 fix: correct double-g scroll target to last message element
The double-g press handler was incorrectly scrolling to the first child of the messages container instead of the last element, causing the viewport to jump to the top of the conversation rather than the most recent message. Changed the selector from `.message:first-child` to `lastElementChild` to properly scroll to the latest message before triggering `loadExtra()`.
2025-07-18 22:00:29 +00:00
BordedDev 58f53ee252 fix: prevent cross-channel message updates and fix reply click handler with instant scroll
- Guard update_message_text handler to only upsert messages already in the local map, avoiding cross-channel text updates
- Add delegated click listener on messagesContainer for #reply links, extracting message text for reply input
- Change scrollToBottom default behavior from 'smooth' to 'instant' for immediate positioning
- Fix loadExtra to use lastElementChild and reverse fetched messages for correct prepend order
- Correct isScrolledPastHalf logic to use absolute scrollTop value for reliable detection
2025-07-18 21:57:41 +00:00
BordedDev 04ea146221 fix: prevent terminal scroll jump on blur by deferring input reset and aligning scroll anchor
The blur handler in chat-input.js now calls updateFromInput with the current value and isFinal=true before resetting, ensuring the live-typing send uses the correct isFinal flag to avoid premature message dispatch. In message-list.js, scrollToBottom anchors to block 'start' instead of 'end' to keep the terminal view stable when new messages arrive. The app.html keydown listener also receives the event parameter to properly handle Escape key detection.
2025-07-17 21:21:15 +00:00
BordedDev ccd443055b refactor: replace inline message template with custom chat-message web component and reverse message order
The diff replaces the static message HTML template with a custom `<chat-message>` web component, reverses message rendering order in the template, updates CSS to use `column-reverse` for chat layout, and adjusts scroll logic to append new messages at the end instead of prepending at the beginning.
2025-07-17 00:22:47 +00:00
BordedDev 36cf5d8109 feat: prioritize secure_url over url for og:image and og:video in embed_url
Reorder the fallback chain for Open Graph image and video extraction in
`src/snek/system/template.py` to check `secure_url` before `url` and `image`/`video`,
ensuring HTTPS resources are preferred when available for embedded player support.
2025-07-05 16:00:58 +00:00
BordedDev 64f86fa778 fix: fallback to application/octet-stream for untyped attachment downloads 2025-07-01 23:03:09 +00:00
BordedDev 0eeec72acb feat: add /shorts path support to youtube embed url detection
Extend the allowed path prefixes in embed_youtube to include "/shorts",
enabling embedding of YouTube Shorts videos alongside regular watch and
embed URLs.
2025-06-27 10:10:16 +00:00
BordedDev 328c2d840c fix: replace global eventBus with component subscription and fix file attachment URL building 2025-06-22 22:41:09 +00:00
BordedDev 90971bcb20 chore: remove title from SAFE_ATTRIBUTES set in template.py
The title attribute was removed from the SAFE_ATTRIBUTES dictionary
in src/snek/system/template.py, likely to tighten security by
preventing arbitrary title attributes in sanitized HTML output.
2025-06-19 07:33:05 +00:00
BordedDev 96f0c09cda fix: add target, rel, referrerpolicy, controls, frameborder, allow, allowfullscreen, and title to SAFE_ATTRIBUTES whitelist in template.py
Also fix string interpolation syntax in embed_url function where double quotes were incorrectly nested inside f-string, changing outer quotes from double to single to resolve syntax error.
2025-06-19 07:30:33 +00:00
BordedDev deb7a84082 feat: add get_element_options helper and improve embed dedup with height/width support
Extract repeated meta-tag lookup logic into reusable get_element_options function that accepts fallback priority chain (twitter, og, meta, elem). Enhance embed_url to skip already-processed URLs via attachment key check, and extend embed payload with optional height/width attributes from og:image:width/height or twitter:image:width/height. Refine site name selection to prefer og:site_name over twitter:site, falling back to title tag.
2025-06-19 07:10:31 +00:00
BordedDev 79528abcb5 feat: add music.youtube.com to allowed hosts and skip links with data-noembed attribute
Extend the embed_youtube function's hostname whitelist to include "music.youtube.com" for YouTube Music URL support. Also update embed_url to skip anchor elements that have a "data-noembed" attribute, preventing unwanted embedding of explicitly excluded links.
2025-06-19 06:11:27 +00:00
BordedDev 302ac459c4 feat: register HEIF opener for image handling and gracefully handle missing pty module on terminal import 2025-06-09 20:03:36 +00:00
BordedDev 3b0af36295 fix: remove redundant encoding field check from push notification body validation 2025-06-06 10:06:43 +00:00
BordedDev c424385c1a feat: add CSP middleware, HTML sanitization, spoiler CSS, and chat input rate-limit protection 2025-06-06 09:21:46 +00:00
BordedDev d8d49cdf2b feat: add spoiler message styling with hover reveal and delayed pointer events
Add CSS rules for `.message-content .spoiler` to hide child content via opacity, pointer-events, and visibility, and reveal it on hover/focus/active with a 0.3s opacity transition. Include a `delay-pointer-events` keyframe animation to prevent premature interaction during the reveal. Set spoiler container to a fixed 2.5rem height with overflow hidden, expanding on interaction.
2025-06-05 23:22:40 +00:00
BordedDev 7bf5460491 fix: prevent duplicate message sends by queuing pending finalize calls and debouncing key repeat events 2025-06-05 17:41:43 +00:00
BordedDev a86c79077a refactor: remove unused previousValue, lastChange, and changed fields from ChatInputComponent 2025-06-01 18:57:28 +00:00
BordedDev 62add04d1c refactor: simplify resolveAutoComplete logic by removing counter and early return on duplicate match 2025-06-01 18:56:24 +00:00
BordedDev 6d44c26692 refactor: replace manual for-loop with flatMap in getAuthors method of ChatInputComponent 2025-06-01 18:53:02 +00:00
BordedDev ed3b8b69a8 chore: reformat whitespace and fix trailing spaces in chat-input.js 2025-06-01 18:48:17 +00:00
BordedDev 6c3e26aca3 feat: skip push notification for message sender in channel member loop
Add a guard condition in the notification creation flow to compare
channel_member["user_uid"] against user["uid"] before calling
notify_user, preventing the sender from receiving a push notification
for their own message.
2025-06-01 11:03:47 +00:00
BordedDev d3fe68a78e feat: add IP2Location geolocation middleware and user model fields for country, city, and coordinates 2025-06-01 10:43:37 +00:00
BordedDev 4eabb7a817 chore: remove 29-line comment block with license and author header from push.py 2025-05-31 22:56:39 +00:00
BordedDev c177dbacc4 fix: strip only width and height params from image zoom URL instead of clearing all search params 2025-05-31 22:52:02 +00:00
BordedDev e16062f7e9 refactor: replace synchronous requests with async aiohttp in push notification handler
Remove unused `memberships` and `user` variables, eliminate debug print statements for headers, and migrate the HTTP POST call from the blocking `requests` library to an `aiohttp.ClientSession` with async context managers. Adjust response attribute access from `.status_code` to `.status` to match aiohttp's API.
2025-05-31 21:29:45 +00:00
BordedDev de8a99e13f feat: add self-signed TLS certificate and key for local development server
Add a PEM-encoded X.509 certificate (cert.pem) and its corresponding RSA private key (key.pem) to enable HTTPS for debug and testing environments. The certificate is self-signed with a 1-year validity period, issued to "Internet Widgets Pty Ltd" in the Netherlands, and includes basic constraints for CA usage.
2025-05-31 21:09:56 +00:00
BordedDev f0b668d6ea feat: add push notification service with WebPush registration and SSL support
- Introduce PushMapper and PushRegistrationModel for storing user push subscription data (endpoint, key_auth, key_p256dh)
- Implement PushService replacing old Notifications class, with async notify_user method sending WebPush payloads via aiohttp
- Register PushService in service registry and PushMapper in mapper registry
- Update NotificationService to trigger push notifications on new channel messages
- Enable SSL context in main app runner loading cert.pem and key.pem
- Remove deprecated get_notifications calls and old notification module
- Refactor PushView to use new PushService for key retrieval and subscription registration
- Add await navigator.serviceWorker.ready in push.js to ensure service worker readiness before fetching public key
2025-05-31 17:08:55 +00:00
BordedDev 3ed67d3dfe chore: remove unused asyncio and aiohttp imports from template.py
Clean up the import block in src/snek/system/template.py by removing
the unused `asyncio` and `aiohttp` modules, and reordering remaining
imports to follow standard grouping conventions (stdlib, third-party,
local).
2025-05-30 00:14:45 +00:00
BordedDev 8e3956af9f feat: add URL embedding with metadata extraction and responsive CSS styling 2025-05-30 00:13:36 +00:00
BordedDev 5d22454230 feat: restructure layout to CSS grid with named areas and add interactive-widget viewport meta
Replace flexbox body layout with a CSS grid using named template areas (header, sidebar, chat-area) to improve mobile responsiveness and sidebar positioning. Update viewport meta tag to include `interactive-widget=resizes-content` for better mobile keyboard handling. Add `html { height: 100% }` and `.chat-messages { display: flex; flex-direction: column }` to support proper vertical sizing. Move `<main>` element after sidebar block in app.html template to match new grid structure. Change umami analytics script from `defer` to `async defer` in base.html.
2025-05-26 22:23:41 +00:00
BordedDev 0df2d595e5 fix: inline replaceMentionsWithAuthors call in updateMessageText handler 2025-05-25 00:46:49 +00:00
BordedDev fd859ac552 fix: prevent duplicate message send on live typing submit by clearing input before send
The fix reorders operations in the submit handler to clear the input field value before calling `sendMessage`, and moves the `messageUid` assignment into the live-typing path only, eliminating the double-send that occurred when both the submit handler and the live-typing timer triggered message transmission.
2025-05-25 00:23:52 +00:00
BordedDev f96a179861 fix: replace last-child selector with :not(:has(+ .message)) for accurate last message time display 2025-05-24 16:41:12 +00:00
BordedDev bbaa458a62 fix: correct string slicing to strip trailing 's' from each start time element instead of the entire list 2025-05-22 06:10:39 +00:00
BordedDev 530f9ab27c feat: show reply time indicator when message gap exceeds 20 minutes
Add logic to detect time gaps between consecutive messages from the same user. When the difference between two messages' timestamps exceeds 20 minutes, the later message receives a `long-time` CSS class, causing its timestamp to be displayed persistently alongside the existing `switch-user` rule. The CSS selector `.message:has(+ .message.long-time)` ensures the preceding message's time remains visible when followed by a long-delayed reply.
2025-05-21 22:19:39 +00:00
BordedDev bf32ab8d47 fix: set opacity to 1 for last message's time display in chat CSS 2025-05-21 22:00:51 +00:00
BordedDev 3279f3f861 feat: hide avatar via max-height and fade time on non-hover messages
Add max-height:0 with overflow:hidden to .avatar in collapsed state, and set
max-height:unset on hover to prevent layout shift. Replace .time display:none
with conditional opacity:0 when message is not hovered, focused, or active,
keeping .author display:none unchanged.
2025-05-21 20:30:15 +00:00
BordedDev c9b9a1d7ea fix: preserve gif quality and animation frames in channel attachment resizing 2025-05-18 12:51:38 +00:00
BordedDev c0c9b942a0 fix: restore webp fallback in picture template and add file existence check in attachment view 2025-05-17 11:55:46 +00:00
BordedDev e450716508 fix: re-add webp format parameter to image src for fallback support
- Append `&format=webp` to the image source URL in `enrich_image_rendering` function
- Restore webp format query parameter that was previously removed, enabling browser fallback to webp when supported
2025-05-17 11:29:25 +00:00
BordedDev db776b4a6a fix: rewrite YouTube embed parsing with urlparse and handle missing channel attachments
- Replace fragile string splitting with urlparse/parse_qs for robust YouTube URL parsing
- Support youtu.be, youtube-nocookie.com, and /embed paths alongside /watch
- Properly extract start time (t=) parameter and append to embed src
- Add early 404 return in ChannelAttachmentView when channel_attachment is None
- Set Content-Type header from original format in attachment download response
2025-05-17 11:23:32 +00:00
BordedDev 414cce6c71 feat: add image conversion and resizing via query params in channel attachment view 2025-05-11 23:47:54 +00:00
BordedDev 4164fbd877 feat: add paste and file drop support to web input handler
Implement clipboard paste event listener in initInputField that reads image files from clipboard and triggers upload via the upload-button component. Add drag-and-drop file drop support to the textarea input field for improved user experience.
2025-05-06 21:14:52 +00:00
BordedDev c53e2062fa refactor: replace chained boolean condition with all() for readability in PushView
Refactor the subscription body validation in `src/snek/view/push.py` to use `all()` with a list comprehension instead of a multi-line `and` chain, improving code clarity. Also normalize string quotes from single to double for `body["endpoint"]` and reformat the `requests.post` call to span multiple lines for consistency with project style.
2025-04-19 19:33:31 +00:00
BordedDev a15c44b1b1 refactor: rename create_encrypted_payload to create_notification_info_with_payload in notification and push modules 2025-04-13 21:20:30 +00:00
BordedDev 69dabea653 feat: refactor push notification encryption to return headers and data dict
Refactor `create_encrypted_payload` to accept endpoint parameter and return a dictionary containing pre-built HTTP headers and encrypted payload data, eliminating manual header construction in the PushView caller. Remove unused `public_key_base64` certificate retrieval and inline header generation logic.
2025-04-13 21:14:01 +00:00
BordedDev 697935c9de feat: refactor push notification service worker and key management with async registration
Replace commented-out push handler with a full async `registerServiceWorker` function that fetches the VAPID public key, subscribes the push manager, and POSTs the subscription object to `/push.json`. Remove unused helper functions (`arrayBufferToBase64`, `requestNotificationPermission`, `subscribeUser`) and top-level fetch calls. Convert notification key file paths from string constants to `pathlib.Path` objects, replacing `os.path.isfile` checks with `.exists()` and `open`/`write` calls with `.read_bytes()`/`.write_bytes()`. Update the notification test payload to use relative icon and URL paths. Fix the app.html onclick handler to call the renamed `registerNotificationsServiceWorker()` function.
2025-04-13 01:19:28 +00:00
BordedDev 3595e40851 feat: add notification body and icon support to push subscription handling
- Extend service-worker push event to parse and display notification body, icon, and title from push data payload
- Add AESGCM and HKDF imports to notification module for future encryption support
- Refactor notification key file path constants to use double quotes for consistency
- Update push view to include notification body in subscription response and validate request fields
2025-04-12 12:25:57 +00:00
BordedDev 46b4630c9a feat: add notification button and fix push subscription encoding for chrome
- Export registerServiceWorker function in push.js and add debug logging for key data
- Add notificationclose event listener and fetch cache-first strategy in service-worker.js
- Add notification button to app.html template calling registerServiceWorker
- Fix public key encoding from base64 to urlsafe_b64encode in push.py for chrome compatibility
2025-04-06 22:36:49 +00:00
BordedDev 5293d483c4 fix: replace manifest icon paths with correctly sized 192 and 512 png assets
The manifest.json previously referenced a single icon file (snek1.png) for both 192x192 and 512x512 sizes, causing browser instability warnings due to mismatched dimensions. This commit adds properly sized snek192.png and snek512.png images and updates the manifest to point each icon entry to its corresponding size-specific asset, resolving the Firefox Android manifest validation issue.
2025-04-06 21:47:18 +00:00
BordedDev 3188b180df fix: revert multi-line formatting of umami script tag in base.html 2025-03-17 21:06:52 +00:00
BordedDev bf8ca3c69b feat: add Promise.withResolvers polyfill and include it in app and base templates
The polyfill provides a static method on Promise that returns an object with resolve and reject functions exposed, enabling external resolution of a promise. It is loaded as a module script in both app.html and base.html to ensure compatibility before app.js runs.
2025-03-17 21:05:46 +00:00
BordedDev 95643d717e feat: add push notification infrastructure with VAPID key generation and service worker registration
Introduce initial push notification support by adding a new `notification.py` module for VAPID key pair generation (EC P-256), a `PushView` endpoint serving the public key, and a `push.js` client that fetches the key and subscribes the service worker with `userVisibleOnly` flag. The service worker push listener is refactored to check notification permission and handle click events. The `app.html` template now includes the push script as a module, and the application startup calls `get_notifications()` to ensure keys exist. Note: FCM-based push on Chrome/Opera remains non-functional due to unresolved compatibility issues.
2025-03-17 02:16:39 +00:00
BordedDev 24ce2ceb83 style: normalize import spacing and object literal formatting in app.js 2025-03-16 04:03:05 +00:00
BordedDev 4e9c8c55bb refactor: extract EventHandler and Socket classes into separate modules from app.js 2025-03-16 03:55:01 +00:00
BordedDev e12d3b7c5d feat: convert JavaScript classes to ES modules with export/import across app and templates
Convert all JavaScript classes in app.js and schedule.js from implicit globals to ES module exports, add import statements in template scripts for the app instance, and mark all script tags with type="module" to enable module scoping. Also fix a potential null reference in web.html by using optional chaining on lastMessage.scrollIntoView and hoist the lastMessage variable to outer scope for proper closure behavior.
2025-03-15 18:10:52 +00:00
BordedDev 22d13d4385 feat: extract shared input focus styles into shared.css and import on all pages
Create a new shared.css file containing consistent focus ring and placeholder opacity transition rules for input and textarea elements. Import shared.css into both base.css and style.css to apply the updated input styling across all pages, replacing previously scattered or missing focus indicators.
2025-03-15 14:53:24 +00:00
BordedDev 7f9273d9dc fix: add missing semicolon to loadForm call in GenericForm URL handler 2025-03-08 20:18:20 +00:00
BordedDev ef8ee90276 feat: preload form structure into login and register templates and autofocus first input
Add `preloaded-structure` attribute to `<generic-form>` elements in both login and register templates, passing the serialized form JSON from the server. This enables instant form rendering without an additional fetch. Also implement autofocus logic in `generic-form.js` to focus the first input field on page load, improving UX for authentication flows.
2025-03-08 20:04:32 +00:00
BordedDev a504af4c6f style: revert indentation from 4-space to 2-space in base.css across all selectors 2025-03-08 18:35:22 +00:00
BordedDev f36b94e46b feat: wrap back button and form in grid container with new back-form.css stylesheet
Add a new CSS file `back-form.css` defining a two-column grid layout for the back button and generic form, with the button positioned at (1,1) with 30px margins and z-index 1. Update both `login.html` and `register.html` to include the stylesheet in the head block and wrap the existing `fancy-button` and `generic-form` elements in a `div.back-form` container, replacing the previous standalone button placement.
2025-03-08 18:07:09 +00:00
BordedDev 852d949d7f feat: add head block placeholder to base template for child template injection
Insert an empty Jinja2 block named 'head' inside the <head> element of base.html, enabling child templates to inject custom meta tags, styles, or scripts before the closing head tag.
2025-03-08 17:59:00 +00:00
BordedDev ba39d16635 style: add focus outline and placeholder opacity transition to form input fields 2025-03-08 17:56:55 +00:00
BordedDev 8855e40d6d feat: add theme-color, application-name, and author meta tags to base.html head
Add six new meta elements to the HTML head in base.html: theme-color set to black,
application-name and description both set to "Snek chat by Molodetz", author set to
"Molodetz", keywords including "snek, chat, molodetz", and color-scheme set to dark.
Also insert a blank line after the title block for improved readability.
2025-03-08 17:25:15 +00:00
BordedDev 64fe00b161 fix: dispatch change event on blur to sync autocomplete with form state 2025-03-08 17:09:14 +00:00
BordedDev 9c844d9f30 feat: add default page title and specific titles for login and register templates
Set a default "Snek chat by Molodetz" title in base.html and override it with
"Login - Snek chat by Molodetz" and "Register - Snek chat by Molodetz" in their
respective templates, improving user-facing page identification.
2025-03-08 17:04:53 +00:00
BordedDev 4b59f8b780 fix: correct border-radius on follow-up messages to prevent sharp corners 2025-03-08 16:25:56 +00:00