Team Chat
Team Chat enables real-time collaboration between Niuton users with rooms, file sharing, and AI integration.
Features
- Rooms — Create topic-based chat rooms
- Messages — Rich text with Markdown rendering
- @Mentions — Tag users or @Aurora for AI assistance
- Reactions — React to messages with emoji
- Shared Files — Per-room shared filesystem
- Presence — See who's online
- AI Integration — Aurora participates in conversations with full tool access
Room Management
- Any user can create a room
- Room creators and admins can delete rooms
- Deleting a room removes all messages, shared files, and membership data
Messaging
Messages support full Markdown rendering via marked.js:
- Bold, italic,
code - Code blocks with syntax highlighting
- Lists, links, blockquotes
- Sanitized output (no XSS)
@Mentions
Type @ followed by a username to mention someone. Special mention:
@Aurora— Triggers AI response in the room context
Reactions
Click the reaction button on any message to add an emoji reaction.
Shared Files
Each room has a shared filesystem accessible via:
- Team Chat "Dateien" button — Opens the Files app at the room's shared folder
- Files App — Navigate to
/Teamchat/{Room Name}/ - Aurora — Use shared file tools to read/write
Storage quota is configurable per-room (default: 200 MB).
Aurora in Team Chat
When @Aurora is mentioned, the AI receives:
- Room context (name, type, participants, date/time)
- Last 50 messages for context
- Access to 9 tools: shared file tools + user's private files (read-only) + web search
- A "denkt nach..." indicator while processing
- Up to 8 tool iterations for complex multi-step tasks
Aurora uses the unified Qwen 3.5 model with adaptive parameters and visible thinking. The thinking process is saved in message metadata and can be viewed by expanding the thinking block. Responses include tool call summaries showing which tools were used.
Architecture
team-chat/index.php → Chat UI (3-column layout)
api/team-chat.php → 15 API endpoints
lib/tools.php → Team chat Aurora tools
lib/shared-filesystem.php → Shared file operations
Database tables:
niuton_chat_rooms → Room definitions
niuton_chat_members → Room membership
niuton_chat_messages → Messages
niuton_chat_reactions → Reactions
niuton_chat_mentions → @mentions
niuton_chat_presence → Online statusCommunication uses HTTP polling (3-second interval) for real-time updates.
v3.9 Updates v3.9
Real-Time with SSE
Team Chat now uses Server-Sent Events (SSE) instead of polling:
- Messages appear instantly (< 1 second) instead of 3-second delay
- Typing indicators update in real-time
- Unread counts refresh automatically
- Graceful fallback: If SSE fails 3 times, falls back to polling
- Live status indicator: Green dot next to room name shows SSE is active
Member Management
Room creators and admins can now manage members:
- Add members: Invite users via the room members panel
- Remove members: Remove users (cannot remove yourself)
- API endpoints:
room_members,add_member,remove_member
Room Creation with User Selector
Creating a new room now includes a Discord-style user selector:
- Searchable list of all registered users
- Pill tags showing selected users
- Bulk actions: "Alle" / "Keine" buttons
- Creator is automatically added as admin
TopBar Quick-Chat Panel
Click the chat icon in the TopBar for a floating chat panel:
- 420x520px glassmorphism popup
- Room list with unread badges and last message preview
- Chat view with message stream and input field
- Fullscreen button opens the full Team Chat app
- SSE integration for real-time updates within the panel
Toast Notifications
New messages trigger desktop toast notifications:
- Bottom-right stacked toasts with slide-in animation
- Auto-dismiss after 5 seconds
- Click to open Team Chat
- Browser Notifications when tab is not focused (requires permission)
SSE Architecture
Browser (EventSource)
│
GET /api/chat-sse.php?room_id=X
│
▼
chat-sse.php (PHP long-poll SSE)
│ session_write_close() first
│ DB poll every 2s
│ 30s max connection
▼
Events streamed:
├── new_message (every 2s check)
├── typing (every 2s, deduplicated)
├── unread_count (every 5s)
└── reconnect (at 30s timeout)The nginx proxy is configured with proxy_buffering off for the SSE endpoint.
v3.10 Updates v3.10
Direct Messaging (DMs)
Team Chat now supports 1-zu-1 Direktnachrichten — private conversations between two users, similar to Discord, Teams, or Telegram.
Starting a DM
There are three ways to start a DM:
- TopBar Chat Panel — Click the pencil icon (compose), select a user from the picker
- Team Chat App — Click the
+button next to "DIREKTNACHRICHTEN" in the sidebar - API —
POST /api/team-chat.php?action=start_dmwith{user_id: X}
If a DM already exists between two users, the existing conversation is returned (no duplicates).
DM Features
- Full messaging — Everything that works in rooms also works in DMs: Markdown, @mentions, reactions, @Aurora
- Real-time — SSE delivers messages instantly, typing indicators work, unread badges update
- Presence — Green/grey dots show if the other user is online or offline
- Search — Filter DMs and rooms by name in the chat panel search bar
- Notifications — Toast notifications for incoming DM messages
Chat Panel Redesign
The TopBar chat panel now shows a unified view:
| Section | Description |
|---|---|
| Direktnachrichten | DMs sorted by most recent message, with avatar, presence dot, and unread badge |
| Räume | Regular chat rooms with # icon, last message preview, and unread badge |
The compose button (pencil icon) opens a User Picker with:
- Users grouped by Online (green) and Offline (dimmed)
- Live search filtering
- Click to instantly start or open a DM
Team Chat Sidebar
The sidebar in the full Team Chat app now has two sections:
┌────────────────────┐
│ Räume │
│ # general │
│ # projekt-x │
├────────────────────┤
│ Direktnachrichten [+] │
│ ● Kevin │
│ ○ Testnutzer │
└────────────────────┘- DMs show a circular avatar with presence indicator
- Unread badges appear next to names
- Members panel is hidden when viewing a DM (it's always just 2 people)
Architecture
DMs are implemented as 2-person rooms with type='dm'. This reuses the entire existing infrastructure:
Canonical room name: dm_{minUserId}_{maxUserId}
Unique index: Prevents duplicate DMs between same users
Room filtering: handleRooms() excludes type='dm'New API endpoints:
| Endpoint | Method | Description |
|---|---|---|
start_dm | POST | Find or create DM room. Body: {user_id} |
dm_list | GET | All DMs with presence, unread count, last message |
all_users | GET | All users with online status for picker |
Database changes:
-- Type constraint extended
CHECK (type IN ('global', 'group', 'private', 'dm'))
-- Unique index for deduplication
CREATE UNIQUE INDEX idx_chat_rooms_dm_name
ON niuton_chat_rooms (name) WHERE type = 'dm' AND is_active = true;v3.11 Updates v3.11
ChatPanel Markdown Rendering
All messages in the ChatPanel (Aurora conversations, DMs, and rooms) now render Markdown via marked.js:
- Headers, bold, italic, code — Full CommonMark support
- Tables — Styled with dark-theme borders and header backgrounds
- Code blocks — Monospace with background highlight
- Blockquotes — Left-border accent
- XSS sanitization — Script/style/iframe tags stripped,
on*event handlers blocked,javascript:URIs removed
Aurora Thinking Collapsible
When thinking is enabled (options.thinking = -1), Aurora's analysis is shown in a collapsible <details> block:
- "Denkprozess anzeigen" summary (collapsed by default)
- Only the final answer is visible by default
- Client-side parser (
cpSplitThinking()) handles models that embed thinking in the response text (e.g.,## Analyse / ## Antwortpatterns)
Message Grouping
Consecutive messages from the same sender within a 5-minute window are grouped:
- Name label shown only on the first message in a group
- Subsequent messages have tighter padding
- Aurora messages in groups show a spacer instead of repeating the avatar
- Grouping works in both Team Chat rooms and Aurora conversations
Unread Notification Badges
- Red badge on the Team Chat top bar button with total unread count
- Per-conversation unread badges in the ChatPanel overview (DMs and rooms)
- Badge updates every 30 seconds via
dm_list+roomsAPI calls - Badge updates immediately when the panel is opened
v3.12 Updates v3.12
Shared Rendering Module
Team Chat and ChatPanel now share a unified rendering module (/assets/js/chat-shared.js):
- NiutonChat.renderMd() — Markdown rendering with XSS sanitizer
- NiutonChat.formatTime() — Relative German timestamps (heute, Gestern, Mo, 17.02.)
- NiutonChat.stripMd() — Strip markdown for previews
- NiutonChat.splitThinking() — Extract thinking blocks from AI responses
- NiutonChat.escHtml() — HTML escaping
- NiutonChat.parseMentions() — @mention highlighting
- NiutonChat.shouldGroup() — 5-minute grouping check
Both Team Chat and ChatPanel delegate to the same module, ensuring consistent rendering across both UIs.
Message Grouping in Team Chat
Team Chat now groups consecutive messages from the same sender within 5 minutes:
- Avatar replaced with spacer in grouped messages
- Header (name + timestamp) hidden for grouped messages
- Tighter spacing (2px margin instead of default)
Message Animations
New messages appear with a subtle fade-in + slide-up animation (0.15s ease-out).
Aurora Conversations in Team Chat
The Team Chat sidebar now includes an Aurora section above the rooms list:
- Private Aurora conversations stored in localStorage (shared with ChatPanel)
- Create new conversations with the
+button - Full chat interface — Send messages, receive AI responses with markdown rendering
- Thinking toggle — Enable/disable thinking mode per conversation
- Cross-sync — Aurora conversations created in ChatPanel appear in Team Chat and vice versa (via
localStoragestorageevent) - Delete — Hover to reveal delete button with confirmation
Light Mode
Team Chat now supports Light Mode:
- PostMessage bridge — Desktop broadcasts
niuton-theme-changeevents to all app iframes - Initial detection — Team Chat reads
window.parent.NIUTON.themeon load - 50+ CSS rules — All UI components styled for light backgrounds (#f4f4f8 base)
- Live switching — Theme changes apply instantly without reload
ChatPanel Typing Indicator
ChatPanel now sends typing events to the Team Chat server:
- Throttled to max 1 event per 3 seconds
- Team Chat users see typing indicators from ChatPanel users
"In Team Chat oeffnen" Button
When viewing a Team Chat room in the ChatPanel popup, a new button opens the full Team Chat app with the same room selected.
Unread Badge Sync
When messages are read in Team Chat, the ChatPanel badge updates instantly via niuton-unread-changed postMessage (instead of waiting for the 30s polling cycle).
Display Name Fix
Temporary (optimistic) messages now show the user's display name instead of the raw username. This applies to messages sent from both the Team Chat app and the ChatPanel.
Edited Message Marker
Edited messages now display a "(bearbeitet)" label next to the timestamp, so users can see when a message has been modified after sending.
SSE and Polling Deduplication
When SSE successfully connects, polling is now stopped immediately to prevent duplicate messages. Previously both transports could run simultaneously, causing messages to appear twice.
openSharedFiles Bugfix
The "Dateien" button in Team Chat now correctly opens the Files app at the room's shared folder path.
Aurora Date/Time Awareness
Aurora now always includes the current date and time in her system prompt:
- Format:
01.03.2026 20:49 (Sonntag) Uhr (Zeitzone: Europe/Berlin) - Applied to all 3 system prompt builders (chat, pipeline, legacy)
- PHP timezone set to
Europe/Berlin