Commit Graph
17 Commits
Author SHA1 Message Date
Jannis Braun 907728ab24 fix: replace broken border-hard/50 opacity with subtle white borders
Tailwind can't decompose CSS variables for opacity modifiers, so
border-border-hard/50 fell back to white currentColor. Replaced with
border-white/[0.06] on image attachments, code blocks, and action
toolbar. Also applied frosted glass material to message action toolbar.
2026-03-02 17:07:33 +01:00
Jannis Braun 7608afccc4 fix: panel separator borders and reaction spacing to match prototype
Replace @apply border-none with @apply border-0 on global * selector.
border-none sets border-style: none, which silently kills all Tailwind
border utilities (they only set width/color, relying on preflight's
border-style: solid). border-0 sets border-width: 0 instead, preserving
the solid style so border-r/border-l/border-b utilities render correctly.

- Add border-r border-border-hard to ChannelSidebar (both DM and server views)
- Add border-l border-border-hard to MemberSidebar and ActivityPanel
- Replace shadow-header with border-b border-border-hard on sidebar headers
- Remove duplicate mt-1 on reaction container (parent gap-1 already provides 4px)
2026-03-02 16:51:17 +01:00
Jannis Braun b8ce05ad6c fix: precise chat layout alignment to match Aether Drift prototype
Message rows: 20px horizontal padding, 3px vertical, 56px avatar column,
subtle 2.5% hover. Channel headers: border instead of shadow, text # hash,
10px gap, 6px button radius. Date dividers: 8px margin, 11px text, border-hard
lines. Input bubble: 34px buttons with 18px SVGs, 10px textarea padding.
Inline code: lavender on #111115 with border-soft border.
2026-03-02 16:17:42 +01:00
Jannis Braun 9491edb3c9 fix: reaction pill frosted glass + compact sizing to match prototype
Replace inline JS hover handlers with .glass-pill CSS classes for proper
Aether Drift frosted glass depth (blur, inset highlight, box-shadow).
Constrain emoji size and use exact prototype padding (2px 8px) for compact pills.
2026-03-02 15:55:42 +01:00
Jannis Braun cdee450cf5 fix: channel sidebar and reaction bubbles to match Aether Drift prototype
Channel sidebar: subtle bg-surface-elevated highlight with rounded-[6px],
active channel left pill, rose unread dot on right, smaller #/voice icons
(18px), 10px horizontal padding, 24px voice user avatars at 36px indent.

Reaction bubbles: inline styles for background/border colors to bypass
Tailwind opacity modifier failures on hex CSS variables. Both mine (mint
tint) and non-mine states now render visible pill containers reliably.
2026-03-02 14:45:47 +01:00
Jannis Braun ddeb72101e feat: dynamic PiP collision avoidance, reaction pill redesign, channel dedup fix
PiP positioning:
- Replace hardcoded layout constants with dynamic DOM measurement system
- Obstacle elements declare themselves via data-pip-obstacle="left|bottom"
- getPipBounds() queries actual element rects at runtime via getBoundingClientRect
- MutationObserver + ResizeObserver re-clamp PiP when obstacles appear/resize
- PiP reappears after close when navigating away from voice channel

Reactions:
- Align reaction pills with Aether Drift prototype
- Own-reaction accent: purple → mint (bg, border, count color)
- Default pills: subtle white overlay bg + border-soft border
- Count text: 12px/semibold/txt-secondary per prototype spec

Bug fix:
- Deduplicate channel insertion in createChannel store action
- Prevents double-add race between REST response and WS broadcast
2026-03-02 02:09:52 +01:00
Jannis Braun f79575ffa7 fix: consistent avatar gradient colors across all 17 call sites
Avatar fallback gradients were hashed by display name alone when no
user prop was passed, causing the same person to appear in different
colors across messages, replies, member lists, voice panels, etc.

Added userId prop to Avatar and wired it through all 17 call sites
so the gradient always hashes by user ID.
2026-03-02 01:16:58 +01:00
Jannis Braun 95fc6f0693 feat: Phase 7 Aether Drift — typography, spacing & detail alignment
Align all component typography to the design prototype's exact measurements:
- Message author: 16px bold → 15px semibold
- Message text: 16px → 15px, line-height 1.5
- Timestamps: 12px → 11px
- Category headers: 12px bold → 11px medium, #484854 color
- Member/activity names: 15px → 13.5px with tighter line-height
- Member activity text: 12px → 11px
- Section headers: 12px → 10.5px
- Channel header names: 15px with -0.02em tracking
- Channel topic: 12px → 13px
- Header padding: 16px → 20px
- User area avatar: 32px → 34px
2026-03-02 01:05:42 +01:00
Jannis Braun 662eb8abc5 feat: Phase 2 Aether Drift — chat component token migration + scroll fix
Migrate all 8 chat rendering components from Discord tokens to Aether Drift
design system: Message, MarkdownRenderer, MentionBadge, MentionPopover,
FriendsPage, TypingIndicator, Embed, ImagePreview. Eliminates ~83 discord-*
class references and ~24 hardcoded hex values from components/chat/.

Fix critical scroll regression from Phase 1 grid migration by adding explicit
grid-rows-[minmax(0,1fr)] and min-h-0 to AppLayout's grid container, restoring
the height constraint chain to MessageList's overflow-y-auto.
2026-03-01 23:23:46 +01:00
Jannis Braun e219229b63 feat: add Backspace design prototype and rebrand from Opencord
- Add Backspace-design-prototype.html: finalized "Aether Drift" design
  language with warm matte surfaces and subtle frosted glass accents
- Update CLAUDE.md with DESIGN SYSTEM section and remove Discord clone references
- Rename all Opencord references to Backspace across the full codebase
- Archive outdated design experiments and Discord-specific assets
- Add science-backed accessibility fallback (prefers-reduced-transparency)
2026-03-01 21:26:57 +01:00
Jannis Braun c9f9787b99 feat: rich markdown renderer with @mention badges and autocomplete
- Add MarkdownRenderer with syntax-highlighted code blocks (prism-react-renderer),
  GFM tables, and Discord-style theming
- Add MentionBadge that resolves user IDs to display names with role colors
- Add MentionPopover autocomplete triggered by @ in MessageInput
- Fix mention:// URL sanitization — allowlist the scheme in urlTransform so
  react-markdown v9 passes it through to the component override
- Highlight messages that mention the current user (amber border)
- Bump rate limit from 60 to 200 req/min
2026-02-25 23:49:41 +01:00
Jannis Braun 0a157de162 refactor: purge legacy server_members.role column, single source of truth via member_roles
Remove the legacy TEXT role column ('owner'/'admin'/'member') from
server_members and make the bitwise RBAC member_roles junction table
the sole authority for role assignments. Owner detection now uses
servers.ownerId exclusively.

- Remove MemberRole type and role field from shared types
- Remove role from Drizzle schema, raw SQL CREATE TABLE, and seed data
- Rewrite PATCH /members/:uid to accept { roleIds: string[] }
- Fix GET /members to populate roles array (was TODO)
- Replace member.role === 'owner' guard with isServerOwner()
- Remove getMemberRole() helper and legacy bridge code
- MemberSidebar groups by highest-positioned role instead of legacy string
- ServerSettings replaces admin/member dropdown with role checkboxes
- Message.tsx derives color from roles[] with owner fallback via ownerId
- Existing DBs keep vestigial column (Drizzle ignores it); new DBs omit it
2026-02-25 22:46:50 +01:00
Jannis Braun 8030c89c6c feat: bitwise RBAC engine with channel-level permission overrides
Replace string-based role checks (role === 'admin') with a bitwise BigInt
permission system. Adds computePermissions() resolution engine following
Discord's model: @everyone base → role union → admin shortcut → channel
overrides (role deny/allow → member deny/allow). Ready payload now filters
channels by VIEW_CHANNEL and attaches per-user myPermissions to each
server and channel. Includes channel_overrides table, @everyone role
auto-creation, migration for existing servers, and override CRUD API.
2026-02-24 05:08:59 +01:00
Jannis Braun 435d12e5b8 feat: unread indicators + DM bug fixes + data-driven isDmChannel
- Fix stale message cache: add force param to loadMessages, clearAllMessages action
- Fix reload race condition: URL-based isDmChannel fallback before WS ready
- Add read_states DB table for persistent unread tracking
- Add channel_ack WS event (client→server→echo) with BigInt comparison
- Wire up unread state in chatStore (readStates, unreadChannels, ackChannel)
- Auto-ack channels on MessageList view (200ms debounced)
- Unread pill indicators on server icons in ServerSidebar
- Bold text + white dot on unread channels/DMs in ChannelSidebar
- Replace all showDms reads with data-driven isDmChannel() across 8 files
- Design system, UI polish, and component fixes from previous sessions
2026-02-18 20:48:48 +01:00
Jannis Braun 7168149d98 feat: DM infrastructure overhaul + volume sliders + LiveKit dynamic URL
- Add DM edit/delete endpoints (REST + WebSocket)
- Add DM typing indicators with real-time broadcast
- Fix volume sliders to control LiveKit mic/speaker
- Fix Send Message button on user profile popout
- Add New DM modal with user search
- Fix message pagination (SQL cursor instead of in-memory)
- Guard optional attachments on DM messages
- Dynamic LiveKit URL from request Host header
- DM sidebar auto-sorts by most recent message
2026-02-18 17:29:39 +01:00
Jannis Braun 5ef502f2e3 fix: repair invite links, social features, messaging + Discord UI overhaul
Phase 1 - Feature Repair:
- Fix member kick/leave: add missing db.delete() call in servers.ts
- Stabilize invite codes: return existing code instead of regenerating
- Fix user search: use LIKE instead of exact match in social.ts
- Wire DM button on FriendsPage to create/navigate to DM channels
- Add cancel outgoing friend request (DELETE endpoint + frontend)
- Add accept/decline friend request actions with WS real-time events
- Fix replyToId persistence in message creation
- Hydrate reactions and replyTo in message queries
- Add joinByCode to API client and serverStore
- Add friend_request_received/accepted WebSocket events

Phase 2 - Discord UI Overhaul:
- Remove stray borders between layout columns
- Replace shadow-sm with shadow-header on content headers
- Replace all bg-gray-*/text-gray-* with Discord color tokens
- Ensure flat color contrast (#1E1F22, #2B2D31, #313338)

Testing:
- Set up vitest + @testing-library/react + jsdom
- Add 17 tests across InviteModal, JoinServer, FriendsPage (all passing)
- Fix vite resolve.extensions to prefer .tsx over stale .js files
2026-02-18 05:34:45 +01:00
Jannis Braun 4fd17084a5 chore: Initial commit of Opencord base state 2026-02-18 02:49:21 +01:00