Skip to content

Tags: ryukinix/lisp-chat

Tags

0.10.0

Toggle 0.10.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat(web): client-side /settings, light-theme and auto-load history (#…

…162)

* feat(web): client-side /settings command with modal panel

Adds a /settings command (web client only) that opens a modal panel
with user-configurable options stored as cookies:

- Image inline preview toggle (default: enabled)
- Change nickname (sends /nick command on save)
- Timezone selection (default: auto-detect from browser)
- Dark/light theme toggle (default: dark)
- Reconnection in background toggle (default: enabled)
- Max reconnection attempts (default: 0 = infinite)

All settings persisted in a single cookie (lispchat_settings) as
JSON, valid for 365 days. No server-side changes required.

New files:
- src/static/modules/settings.js (settings storage + modal logic)

Modified files:
- src/static/main.js (/settings intercept, settings init)
- src/static/modules/formatting.js (runtime image preview toggle)
- src/static/modules/network.js (reconnect settings, timezone from settings)
- src/static/style.css (modal + light theme CSS)

* fix(web): settings panel issues - autocomplete, live refresh, light theme, reorder

1. /settings now appears in slash-command autocomplete (added as
   client-only command in autocomplete.js)
2. Toggling image preview now re-renders all existing messages
   (refreshMessageContent in messages.js, called from settings listener)
3. Light theme fixed: msg-content, timestamp, msg-from, links, commands,
   and user mention colors now have proper contrast against light
   background. Added CSS filter for inline color spans to darken
   mention colors in light mode.
4. Settings modal fields reordered: image preview, dark/light theme,
   reconnect in background, max reconnect attempts, timezone, nickname

* fix(web): image preview live refresh, light theme input/contrast, /settings prefix

1. Image preview toggle now properly collapses existing images:
   - Fixed refreshMessageContent to handle multi-line rawContent (\n)
   - Split on literal backslash-n and re-join with <br>
   - Re-applies reply reference states after re-render
   - Skip empty rawContent entries

2. Light theme fixes:
   - Input overlay text color now dark (#222) in light theme
   - Username/mention color contrast improved: brightness(0.55)
     saturate(1.5) filter on all .message span[style*='color:']
     (covers both fromSpan and mention spans)

3. /settings command matching relaxed to startsWith so
   '/settings ' and '/settings extra' both open the modal

* fix(web): robust image preview toggle, settings modal close, light theme prefix

1. Image preview toggle now uses CSS body class
   (image-preview-disabled) instead of re-rendering all messages.
   Unchecking hides all existing previews immediately; checking shows
   them again. New messages generate the img tag and are shown/hidden
   by the body class. Removed fragile refreshMessageContent logic.

2. Settings modal auto-close fixed:
   - Added stopPropagation() and preventDefault() on Save/Cancel buttons
   - Removed focus/blur race conditions from button handlers
   - Prevent overlay click from bubbling through modal contents

3. Light theme now applies to #username-prefix (dark color + contrast
   filter) so the nickname label over the input area is readable.

4. Simplified main.js: removed formatting import, listener just calls
   settings.applyAll() which toggles both theme and image classes.

* chore: remove accidental temp files

* fix(web): light theme contrast for user list and nickname prefix

1. #sidebar h3 gets dark color and lighter border in light theme.

2. #user-list .user-item applies the same high-contrast filter used for
   username colors in messages, so bright generated user colors remain
   readable against the light sidebar.

3. #username-prefix now keeps its generated user color and applies the
   brightness/saturate filter in light mode instead of being forced to
   black. The CSS uses color: inherit so JS-styled color still applies.

4. Added window.isLightTheme flag set by settings.applyTheme().
   users.js applies filter on render and exposes refreshUserListColors()
   to update existing items when toggling theme.

5. main.js settings listener re-renders user list colors and the
   username prefix whenever settings change.

* fix(web): settings nickname change sends /nick and updates local state

Bug: after saving a new nickname in settings, nothing happened.

Root causes:
1. pendingSettings was set to null by closeModal() before the save handler
   checked pendingSettings.nickname, so the /nick command was never sent.
2. The local auth username and prefix were not updated, so the UI still
   showed the old nickname even if the server accepted the change.

Fix:
- Capture newNickname before closing the modal.
- Send /nick <newNickname> over the WebSocket when connected.
- Immediately call auth.setUsername() and auth.updateUsernamePrefix() so
  the prefix updates locally without waiting for server broadcast.
- notifyListeners() is invoked after the async nick update as well.

Non-nick saves keep the previous synchronous notifyListeners() path.

* fix(web): pre-fill settings nickname and resolve dynamic import default

1. Nickname input in the settings modal now pre-fills with the current
   username from auth.getUsername() so users see their nick before editing.

2. The dynamic import('./network.js') returns the module namespace object,
   whose default export is the network API. The previous code called
   network.getWs() on the namespace itself, throwing
   'network.getWs is not a function'. Fixed by extracting module.default
   before accessing getWs().

* refactor(web): remove timezone setting, keep auto-detection

The timezone dropdown in settings was not actually used by the server
for anything meaningful; the WebSocket connection already sent a tz
parameter that was previously read from settings. This change removes
the timezone UI and setting entirely.

- Removed timezone from DEFAULTS and from the settings modal HTML.
- Removed timezoneOptions array.
- Removed pendingSettings.timezone read from save handler.
- getTimezoneOffset() now always auto-detects from the browser.
- network.js computes tzOffset directly via Date.getTimezoneOffset().

* fix(web): light theme input cursor and colored prefix

1. Added caret-color: #222 to body.light-theme #message-input so the
   text cursor is dark on the light input background instead of white.

2. Removed the body.light-theme #username-prefix rule that forced
   color: inherit. The JS sets prefix.style.color to the generated
   user color, so keeping that rule makes the prefix use the colored
   text. The brightness/saturate filter already handles contrast in
   light mode.

* fix(web): reconnect on page focus when background reconnect is disabled

The 'Reconnect while in background' setting now only controls whether
reconnection happens while the tab is hidden. When disabled:

- If the page is visible and the socket disconnects, it reconnects
  immediately (same as before).
- If the page is hidden and the socket disconnects, it waits. When the
  page becomes visible again, a visibilitychange listener triggers
  reconnection automatically.

When enabled, the behavior is unchanged: reconnection happens
regardless of page visibility.

- savedOnMessageCallback stores the callback so connect() can be called
  without arguments from the visibilitychange listener.
- Renamed setting label from 'Reconnection in background' to 'Reconnect
  while in background' for clarity.
- Bumped static asset hashes.

* revert: keep index.html hash placeholder

* fix(web): light theme sidebar and user items on mobile

The mobile media query (max-width: 768px) re-declared #sidebar
background: #1a1a1a and .user-item background: #2a2a2a, overriding
the light-theme rules due to higher specificity. Added light-theme
overrides inside the media query:

- #sidebar: #e8e8e8 background, #ccc border
- .user-item: #ddd background (clear gray instead of dark #2a2a2a)

Bumped static asset hashes.

* fix(web): remove sidebar/userlist background in light theme

Both desktop and mobile light-theme rules for #sidebar and .user-item
now use background: transparent. Dark theme keeps #1a1a1a / #2a2a2a.

* fix(web): reply highlight visible in light theme, persists until scroll

1. Dark theme: highlight starts at rgba(255,255,255,0.2) and settles
   to rgba(80,80,80,0.4) gray — stays visible instead of fading to
   transparent.

2. Light theme: new highlightFadeLight animation starts at
   rgba(120,120,120,0.35) dark gray and settles to rgba(200,200,200,0.4)
   lighter gray — visible against the light background.

3. Animation shortened from 3s to 1.5s (settles faster).

4. .focused class now persists until the user scrolls, clicks, or
   types — same behavior as shared-focus (URL message_ref). Removed
   the 3s auto-timeout. Listeners added after 800ms delay so the
   initial scrollIntoView doesn't trigger immediate removal.

* revert: restore index.html and bump_static.sh to master state

Revert accidental hash bumps to index.html. These files should not be
modified in this PR — hash bumping happens at deploy time, not during
development.

* feat(web): auto-load history on scroll setting (disabled by default)

Adds an 'Auto-load history on scroll' checkbox to the settings modal.

When enabled:
- Scrolling to the top automatically loads older messages (same as
  clicking the ⬆ button).
- Scrolling near the bottom in historical context automatically loads
  newer messages (same as clicking the ⬇ button).

When disabled (default):
- Behavior is unchanged: ⬆/⬇ buttons appear on scroll, user clicks
  to load.

Refactored history.js:
- Extracted loadOlderHistory() and loadNewerHistory() as standalone
  async functions (previously inline in click handlers).
- isLoadingHistory/isLoadingNewer flags moved to module scope.
- Scroll listener checks settings.get('autoloadHistory') and either
  calls the load functions directly or shows/hides buttons.
- Button click handlers now delegate to the same functions.

* fix(web): apply same highlight to absolute link message references

Changed the class 'shared-focus' to 'focused' when expanding an absolute
message_ref in the URL. This re-uses the new highlight animations (with
proper light/dark theme contrast) and persists until the user scrolls,
clicks, or types.

* fix(web): prevent image previews from exceeding viewport width on mobile

Added `max-width: min(400px, 100%)` to `.image-preview` (with a 400px
fallback for legacy browsers) so that inline images naturally scale down
to fit the chat container on narrow mobile screens, preventing them from
generating horizontal scrollbars.

0.9.1

Toggle 0.9.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix: timezone localization from client-side (#149)

* web: fix timezone localization from client-side

* feat: support timezone defined by websockect session from server

* Revert "web: fix timezone localization from client-side"

This reverts commit 2c48874.

* web: fix timezone localization from client-side

    - Dynamically calculate browser's timezone offset and append it as `tz` query parameter to the WebSocket URL.
    - Remove hardcoded America/Sao_Paulo timezone from `getTodayDate` allowing the date to be calculated in the local timezone.

* emacs: fix timezone localization from client-side

- Dynamically calculate system timezone offset and append it as `tz` query parameter to the WebSocket URL during connections and reconnections.

* client: fix timezone localization from client-side

- Dynamically calculate system timezone offset using get-decoded-time.
- Append it as `tz` query parameter to the WebSocket URL during connection.

0.9.0

Toggle 0.9.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat(web): add button to load older messages in top chat area (#143)

* feat: add to /log the parameters :before, :after and :around

* feat: add button to load old messages

* fix: upper arrow of the load message button in html

* draft: working version with dirty code

* refactor: cleanup useless code during debug of custom headers

* fix: ensure session ID is filled up and unify login procedure

Problems:

- with multiple ways of login when user already has a cookie username
or the username prompt is show, only new users would have a properly
- when no sessionId is not filled, the Client-Session is not passed,
creating a problem of not authenticated command.
- raise a error if fetchCommand is called without have a session
id (can be improved later by setting a special default parameter
called authenticated as false, so when is true it verify this session)

* refactor: address code review feedback

- Move session ID state from network.js to auth.js
- Keep session ID extraction in messages.js as a system message
- Unify server message filtering in commands.lisp with filter-messages helper
- Improve log command readability with get-messages-around helper
- Enhance api.js with provideSession flag and channels method
- Update autocomplete.js to use new api methods
- Add explanatory comment to sw.js activate event

* fix(web): do not cache messages when prepending

This prevents 'Load older messages' from overflowing the messageCache length limit with older messages, which was pushing the newest messages out of the cache and causing the duplicate reconnection bug.

* fix(web): use rawContent in addRawMessage for consistent deduplication

0.8.0

Toggle 0.8.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat: improve web app UX (#133)

* feat(web): highlight /command with green color

Closes #111

* feat(web): group multiline message from server

Closes #114

* fix(web): keyboard is not autofocused anymore in desktop version

Closes #128

* feat(web): web: make login step of username prompt more clear

Closes #132

* refactor: desktop min width constant and unify autofocus

* refactor: LoginNotification to LoginPanel and new message

0.8.0-rc3

Toggle 0.8.0-rc3's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix: keep #general channel always visible in /channels output (#127)

Closes #113

0.8.0-rc2

Toggle 0.8.0-rc2's commit message
fix: remove trivial-rc-1123 dead library

0.8.0-rc1

Toggle 0.8.0-rc1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix: userlist consistency across clients (#107)

* fix: /users command not always showing response in web client

Inverse the logic of the background task counter to track user
requests instead of background requests to avoid swallowing manual
/users calls.

* fix: userlist not updating properly in Emacs client

Update userlist by calling /users periodically and on /join, while
hiding background users command responses.

* fix: TUI users list not updated periodically

Send /users command periodically instead of /ping to keep the users
list up-to-date, and hide the response unless explicitly requested.

0.7.0

Toggle 0.7.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat: set user-agent for native lisp-chat client (#102)

* fix(emacs): set user-agent as Emacs/<version> (<system>)

* feat: set user-agent for native lisp-chat client

Exposes as user-agent that set of information:

- lisp-chat version
- operating system
- machine type (x86, arm)
- kind of client: readline-interface / TUI
- lisp implementation / compiler version

0.7.0-rc1

Toggle 0.7.0-rc1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix(tui): prevent periodic ping from auto-scrolling to bottom (#97)

* fix(tui): prevent periodic ping from auto-scrolling to bottom

* fix(tui): preserve scroll position on layout recalculation

* fix(tui): ensure autoscroll works with incoming messages

0.7.0-alpha2

Toggle 0.7.0-alpha2's commit message
fix: install libreadline8 in Dockerfile.tui