Restore the theme toggle into the chat utility belt (desktop + mobile),
placed directly above the Auto-Play TTS button. Re-wires updateThemeButtonText
to label both buttons (shows the mode a click switches to). toggleTheme()
already persisted to localStorage and swapped the highlight.js theme.
Flip the Thinking toggle to default ON: localStorage init now reads
!== 'false' (matching the standard default-on idiom), and both desktop
and mobile buttons render green "Thinking: ON" by default. Users opt out
to save tokens; the OFF path still drives server-side enable_thinking=false.
Add a Thinking on/off button next to Auto-Play TTS. When OFF (default),
the client sends enable_thinking=false with each chat_message and the
server passes chat_template_kwargs.enable_thinking=false to self-hosted
OpenAI-compatible endpoints (Qwen3-style), suppressing chain-of-thought
to save tokens rather than merely hiding it. Skips the param for
api.openai.com (which would 400) and o1/o3 (always think); templates that
ignore the kwarg simply drop it. Client-side reasoning suppression remains
as a fallback. State persists to localStorage across desktop and mobile.
- Add helper functions to extract first image and generate description from chat messages
- Update base.html and index.html with og:image, og:description, twitter:card meta tags
- Chat rooms now use first image from messages for unfurling instead of site logo
- Description shows first 500 chars of room content for link previews
- Add default OG image (black with OC) as fallback when no image found
Add inline script at top of base.html <head> to set theme immediately
before any rendering occurs. Prevents white flash when loading chat
and other pages that extend base.html in dark mode.
* Redesign UI: unified design system across all pages
- Replace scattered inline CSS with comprehensive single style.css
- Implement modern design system:
- System font stack (-apple-system, Segoe UI, etc.)
- Consistent spacing scale (4px base)
- Unified color tokens for light/dark themes
- Reusable component classes (buttons, cards, badges, forms)
- Update all templates to use new CSS classes:
- browse.html: Less chunky, better space usage with room-grid
- index.html: Cleaner centered card layout
- auth.html: Streamlined 4-step flow with gradient background
- profile.html: Modern settings interface
- search.html: Browse-style card layout
- Chat page improvements:
- Tighter layouts (240px/280px sidebars instead of 15%/25%)
- Better message spacing
- Improved code blocks with proper padding
- Cleaner utility belt
- Better responsive design and dark mode support
* modified: app.py
modified: templates/base.html
modified: templates/profile.html
* Revert standalone pages to original design
- Browse, index, auth, profile restored to original inline CSS
- Chat page improvements preserved in style.css
- Search page still uses improved card layout
* Add dark mode support to index and browse pages
- index.html now supports dark mode with CSS variables
- browse.html now supports dark mode with CSS variables
- Theme persists from localStorage across pages
* Remove theme toggle from chat page
- Theme toggle button removed from desktop chat sidebar
- Theme toggle button removed from mobile chat modal
- Theme management now done via profile page only
* Make usernames clickable links to profile pages in chat
* Update search page to match browse page layout and CSS
* Fix chat layout positioning
* Fix room list auto-update when title changes
* Fix new room creation appearing in sidebar
- Add socketio.emit in create_room_api() to broadcast new rooms
- Update socket handler to add new rooms to sidebar dynamically
- Rooms now appear without hard refresh
* Fix /title and /cancel commands being sent to LLM
- Add missing return statements after command handlers
- Commands now properly terminate message processing
- Prevents commands from being interpreted as chat messages
* Make usernames in user lists clickable links to profiles
- Update updateUserLists() to create links for all usernames
- Add hover effect CSS for user list links
- Works for both active and inactive users
- Works for both desktop and mobile views
* Revert user list profile links and update profile page layout
- Remove profile links from user lists (no backend route for other users)
- Update profile page to full-screen layout like browse page
- Add header with navigation buttons
- Remove centered container, use full-width layout
- Add box shadows to sections for visual separation
* Convert all flexbox layouts to CSS grid
- Replace all display: flex with CSS grid equivalents
- Update templates: profile, browse, search, index, auth
- Update static CSS for consistent grid usage
- Use grid-template-columns, grid-auto-flow, and place-items
- Improve layout consistency across all pages
* Fix chatroom horizontal scrolling
- Add overflow-x: hidden to #chat-container and #chat to prevent horizontal scroll
- Add word-break and overflow-wrap to message content for text wrapping
- Change pre tags from overflow: hidden to overflow-x: auto for individual scrolling
- Add min-width: 0 to grid containers to prevent overflow
- Code blocks can now scroll individually while chatroom wraps content
* Remove duplicate CSS variables and fix XSS vulnerability
- search.html: Remove inline styles, link to style.css
- index.html: Remove duplicate CSS variable blocks, link to style.css
- browse.html: Remove duplicate CSS variable blocks, link to style.css
- chat.html: Fix XSS vulnerability in room list updates
- Use textContent/createTextNode instead of innerHTML for user data
- Use DOM methods instead of string concatenation
- Encode URL components with encodeURIComponent
- Extract user count from textContent instead of innerHTML regex
* Merge duplicate CSS rules and replace inline styles with design system
style.css:
- Merge duplicate html, body rules (lines 137-143 and 159-167)
- Consolidate typography and layout properties in single rule
- Remove duplicate BASE LAYOUT section
profile.html:
- Replace style.display mutations with classList API
- Add .availability-indicator.show CSS rule for visibility
- Use classList.add('show') and classList.remove('show')
- Consistent with existing .message.show pattern
browse.html:
- Replace hard-coded gradient colors with CSS variables
- Use var(--gradient-start) and var(--gradient-end) for buttons
- Replace #667eea with var(--button-primary) for tabs and room names
- Remove inline .room-badge styles, use .badge .badge-public/.badge-private
- Apply existing badge classes from style.css for dark mode support
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Russell Ballestrini <russell@unturf.com>
* Add email OTP authentication system and private room management
## Authentication System
- Implement email OTP-based authentication with User and OTPToken models
- Add auth.py module with OTP generation, email sending, and session management
- Create authentication endpoints: /auth/send-otp, /auth/verify-otp, /auth/claim-name, /auth/status, /auth/logout
- Add authentication modal UI with email verification and display name claiming
- Support SMTP configuration via environment variables (optional)
## Room Privacy & Ownership
- Add is_private, is_archived, owner_id, and forked_from_id fields to Room model
- Implement private rooms (single-user, owner-only access)
- Add room forking: users can fork public rooms to public or private
- Add room archive/delete endpoints (owner-only operations)
- Implement access control for private room viewing
## UI Improvements
- Add public/private room tabs in sidebar
- Show authentication prompt in private rooms tab for non-authenticated users
- Add room action buttons (fork, archive, delete) with proper permissions
- Update homepage with statistics (public/private rooms, active users, active rooms)
- Remove model/voice from URL query strings, use localStorage exclusively
## Database Migration
- Create migration 2025011100 for User, OTPToken tables and Room model updates
- Add indexes for email, display_name, is_private, is_archived, owner_id
## Breaking Changes
- URL parameters now only include username (model/voice moved to localStorage)
- Private rooms require authentication to access
- Room creation can now require authentication (for private rooms)
* Update README with authentication and private room documentation
* Simplify README to be less verbose
* Add missing session import to fix linter errors
* Fix migration dependency to resolve multiple heads conflict
* asdf
* Fix SQLAlchemy auto-correlation error in homepage statistics query
* Change tagline from AI-Powered to Machine Learning Powered
* Add dedicated authentication page instead of modal
- Create new /auth route with full-page authentication flow
- Remove modal code from index.html
- Update Sign in link to point to /auth page
- Auth page has 4-step flow: email, OTP, display name, success
- Better UX with gradient background and cleaner design
* Fix migration: remove batch_alter_table to avoid circular dependency
- Use op.add_column() directly instead of batch_alter_table()
- Remove foreign key constraints (defined in models, not needed in migration)
- User and OTPToken tables created by db.create_all() in make init-db
- Fixes CircularDependencyError during migration
* Fix migration: check if columns exist before adding
- Use inspector to check existing columns and indexes
- Only add columns/indexes if they don't already exist
- Handles case where db.create_all() was run before migration
- Fixes 'duplicate column name' error
* Add profile page, room browsing, and updated_at timestamp
Features:
- Profile page with username change and dark/light mode settings
- Browse page for discovering public and private rooms
- Room updated_at timestamp (integer Unix epoch) that updates on new messages
- Dynamic room tabs based on current room type (public/private)
- Fork and delete room actions moved to right sidebar utility belt
- Remove archive feature and success alerts from room actions
Technical changes:
- Add updated_at column to Room model (integer timestamp)
- Add /profile route with authentication requirement
- Add /browse route for room discovery
- Add API endpoints for username availability check and update
- Update room.updated_at on message creation in app.py:1189
- Wider right sidebar (25% instead of 15%) for better button layout
- Profile link on homepage and browse page for authenticated users
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: russell@unturf. <russell@unturf.com>
Move all CSS from base.html to static/css/style.css for better:
- Separation of concerns
- Browser caching
- Maintainability
- Code organization
Changes:
- Created static/css/style.css with all application styles
- Updated base.html to link to external stylesheet
- Reduced base.html from ~980 to ~407 lines
Add custom scrollbar styles that properly match dark and light themes:
- Webkit browsers: styled scrollbars with theme-appropriate colors
- Firefox: thin scrollbars with matching color scheme
- Dark mode: darker gray scrollbars that blend with the UI
- Light mode: light gray scrollbars for better visibility
Added CSS variables for link colors with better contrast:
- Light mode: #0066cc (normal), #004499 (hover)
- Dark mode: #58a6ff (normal), #79b8ff (hover)
Applied general link styling rules that adapt to both themes,
ensuring links are clearly visible and distinguishable in dark mode.
Added CSS variables for code execution result colors that adapt to theme:
- --text-info: Blue for informational text (language labels)
- --text-success: Green for successful output
- --text-error: Red for errors and warnings
Updated JavaScript to use CSS variables instead of hard-coded colors,
ensuring proper contrast and readability in both light and dark modes.
- Switch from default highlight.js theme to GitHub themes
- Use github-dark theme for dark mode with better color contrast
- Use github theme for light mode
- Dynamically switch themes when user toggles dark/light mode
- Apply correct theme on page load based on saved preferences
- Moved all theme-related inline styles to CSS rules
- Created proper selectors for labels, inputs, and buttons
- Added utility-belt class to mobile menu for consistent styling
- Removed redundant inline style attributes
- Added CSS variables for light and dark themes
- Implemented theme toggle buttons in both desktop sidebar and mobile menu
- Added JavaScript logic to switch themes and persist choice in localStorage
- Applied dark theme styling to all UI elements including code blocks
- Theme is applied immediately on page load to prevent flash
- Add copy button after edit button for all messages
- Fix model/voice settings persistence when creating new rooms
- Save model/voice selections to localStorage for better state management
- Ensure settings are loaded from localStorage if not in URL parameters
Voice Persistence:
- Add voice/model saving to localStorage for persistent settings
- Load voice from URL → localStorage → default priority order
- Voice selection now persists across browser sessions and page refreshes
Dynamic Room Links:
- Add updateRoomLinksWithCurrentParams() function to update sidebar room links
- Room links now dynamically update with current username, model, and voice settings
- Both desktop and mobile room links stay synchronized with current parameters
- Fixes issue where clicking room links would lose user's current settings
Technical improvements:
- Enhanced syncInputsAndQueryString() to save to localStorage and update room links
- Initial sync call on page load ensures proper state from the start
- Maintains backwards compatibility with existing functionality
- Add username field to right sidebar and mobile modal with 'guest' default
- Implement real-time username sync with URL query string updates
- Add opencompletion.com button and new room creation in left sidebar
- Implement room name slugification (e.g. "a whole new world" → "a-whole-new-world")
- Create shared utils.js for common functions like slugify
- Add single search result auto-redirect functionality
- Remove redundant UI elements ("Create New Room" header, docs link)
- Preserve user settings (username, model, voice) across redirects and room creation
Technical improvements:
- Consolidated duplicate code into shared utility functions
- Enhanced search logic with parameter preservation
- Improved mobile/desktop sync for all input fields
- Better URL handling and query string management
- Separate username/model header from message content using distinct DOM elements
- Fix button positioning to appear on left side of messages
- Ensure TTS only reads clean message content, not username/model header
- Add support for stopping current TTS when auto-play is toggled off
- Improve DOM structure with message-body wrapper for proper layout
- Fix streaming messages to maintain header display throughout entire stream
- Fix battleship feedback perspective confusion with better Hermes prompting
- Add auto-play TTS button with localStorage persistence and queueing system
- Move activity controls below model/voice selectors in sidebar
- Add activity controls to mobile hamburger menu
- Fix model/activity dropdowns to stay within container bounds
- Filter activities API to only show .yaml/.yml files
- Clean up system message labels by moving to usernames (System (Feedback), System (Question))
- Apply black formatting to app.py