mirror of
https://github.com/MarekWo/mc-webui.git
synced 2026-07-13 21:30:59 +02:00
feat(ui): add channel/contact sidebar for wide screens (desktop/tablet)
On screens >= 992px (lg breakpoint), show a persistent sidebar panel: - Group chat: channel list with unread badges, active highlight, muted state - DM: conversation/contact list with search, unread dots, type badges - Desktop contact header with info button replaces mobile selector - Mobile/narrow screens unchanged (dropdown/top selector still used) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+118
-94
@@ -189,110 +189,134 @@
|
||||
<!-- Main Content -->
|
||||
<main>
|
||||
<div class="container-fluid d-flex flex-column" style="height: 100vh;">
|
||||
<!-- Conversation Selector Bar -->
|
||||
<div class="row border-bottom bg-light">
|
||||
<div class="col-12 p-2">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<!-- Searchable contact selector -->
|
||||
<div class="position-relative flex-grow-1" id="dmContactSearchWrapper">
|
||||
<input type="text"
|
||||
id="dmContactSearchInput"
|
||||
class="form-control"
|
||||
placeholder="Select chat..."
|
||||
autocomplete="off">
|
||||
<div id="dmContactDropdown" class="dm-contact-dropdown" style="display: none;"></div>
|
||||
</div>
|
||||
<!-- Clear search button -->
|
||||
<button type="button"
|
||||
class="btn btn-outline-secondary flex-shrink-0"
|
||||
id="dmClearSearchBtn"
|
||||
title="Clear selection"
|
||||
style="display: none;">
|
||||
<i class="bi bi-x-lg"></i>
|
||||
</button>
|
||||
<!-- Contact info button -->
|
||||
<button type="button"
|
||||
class="btn btn-outline-secondary flex-shrink-0"
|
||||
id="dmContactInfoBtn"
|
||||
title="Contact info"
|
||||
disabled>
|
||||
<i class="bi bi-info-circle"></i>
|
||||
</button>
|
||||
<!-- Main content: sidebar + chat -->
|
||||
<div class="d-flex flex-grow-1 overflow-hidden" style="min-height: 0;">
|
||||
<!-- DM Sidebar (visible on lg+ screens) -->
|
||||
<div id="dmSidebar" class="dm-sidebar">
|
||||
<div class="dm-sidebar-header">
|
||||
<input type="text"
|
||||
id="dmSidebarSearch"
|
||||
class="form-control form-control-sm"
|
||||
placeholder="Search contacts..."
|
||||
autocomplete="off">
|
||||
</div>
|
||||
<div class="dm-sidebar-list" id="dmSidebarList">
|
||||
<!-- Populated by JavaScript -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Messages Container -->
|
||||
<div class="row flex-grow-1 overflow-hidden" style="min-height: 0;">
|
||||
<div class="col-12 position-relative" style="height: 100%;">
|
||||
<!-- Filter bar overlay -->
|
||||
<div id="dmFilterBar" class="filter-bar">
|
||||
<div class="filter-bar-inner">
|
||||
<input type="text" id="dmFilterInput" class="filter-bar-input" placeholder="Filter messages..." autocomplete="off">
|
||||
<span id="dmFilterMatchCount" class="filter-match-count"></span>
|
||||
<button type="button" id="dmFilterClearBtn" class="filter-bar-btn filter-bar-btn-clear" title="Clear">
|
||||
<i class="bi bi-x"></i>
|
||||
</button>
|
||||
<button type="button" id="dmFilterCloseBtn" class="filter-bar-btn filter-bar-btn-close" title="Close">
|
||||
<i class="bi bi-x-lg"></i>
|
||||
<!-- Chat Area -->
|
||||
<div class="flex-grow-1 d-flex flex-column" style="min-width: 0;">
|
||||
<!-- Conversation Selector Bar (mobile only, hidden on lg+) -->
|
||||
<div class="dm-mobile-selector border-bottom bg-light">
|
||||
<div class="p-2">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<!-- Searchable contact selector -->
|
||||
<div class="position-relative flex-grow-1" id="dmContactSearchWrapper">
|
||||
<input type="text"
|
||||
id="dmContactSearchInput"
|
||||
class="form-control"
|
||||
placeholder="Select chat..."
|
||||
autocomplete="off">
|
||||
<div id="dmContactDropdown" class="dm-contact-dropdown" style="display: none;"></div>
|
||||
</div>
|
||||
<!-- Clear search button -->
|
||||
<button type="button"
|
||||
class="btn btn-outline-secondary flex-shrink-0"
|
||||
id="dmClearSearchBtn"
|
||||
title="Clear selection"
|
||||
style="display: none;">
|
||||
<i class="bi bi-x-lg"></i>
|
||||
</button>
|
||||
<!-- Contact info button -->
|
||||
<button type="button"
|
||||
class="btn btn-outline-secondary flex-shrink-0"
|
||||
id="dmContactInfoBtn"
|
||||
title="Contact info"
|
||||
disabled>
|
||||
<i class="bi bi-info-circle"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Desktop contact header (visible on lg+ when sidebar is shown) -->
|
||||
<div class="dm-desktop-header border-bottom bg-light d-none">
|
||||
<div class="p-2 d-flex align-items-center gap-2">
|
||||
<span id="dmDesktopContactName" class="fw-medium flex-grow-1 text-truncate"></span>
|
||||
<button type="button"
|
||||
class="btn btn-outline-secondary btn-sm flex-shrink-0"
|
||||
id="dmDesktopInfoBtn"
|
||||
title="Contact info"
|
||||
disabled>
|
||||
<i class="bi bi-info-circle"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dmMessagesContainer" class="messages-container h-100 overflow-auto p-3">
|
||||
<div id="dmMessagesList">
|
||||
<!-- Placeholder shown when no conversation selected -->
|
||||
<div class="dm-empty-state">
|
||||
<i class="bi bi-envelope"></i>
|
||||
<p class="mb-1">Select a conversation</p>
|
||||
<small class="text-muted">Choose from the dropdown above or start a new chat from channel messages</small>
|
||||
<!-- Messages Container -->
|
||||
<div class="flex-grow-1 position-relative overflow-hidden" style="min-height: 0;">
|
||||
<!-- Filter bar overlay -->
|
||||
<div id="dmFilterBar" class="filter-bar">
|
||||
<div class="filter-bar-inner">
|
||||
<input type="text" id="dmFilterInput" class="filter-bar-input" placeholder="Filter messages..." autocomplete="off">
|
||||
<span id="dmFilterMatchCount" class="filter-match-count"></span>
|
||||
<button type="button" id="dmFilterClearBtn" class="filter-bar-btn filter-bar-btn-clear" title="Clear">
|
||||
<i class="bi bi-x"></i>
|
||||
</button>
|
||||
<button type="button" id="dmFilterCloseBtn" class="filter-bar-btn filter-bar-btn-close" title="Close">
|
||||
<i class="bi bi-x-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dmMessagesContainer" class="messages-container h-100 overflow-auto p-3">
|
||||
<div id="dmMessagesList">
|
||||
<!-- Placeholder shown when no conversation selected -->
|
||||
<div class="dm-empty-state">
|
||||
<i class="bi bi-envelope"></i>
|
||||
<p class="mb-1">Select a conversation</p>
|
||||
<small class="text-muted">Choose from the list or start a new chat from channel messages</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Scroll to bottom button -->
|
||||
<button id="dmScrollToBottomBtn" class="scroll-to-bottom-btn" title="Scroll to bottom">
|
||||
<i class="bi bi-chevron-double-down"></i>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Scroll to bottom button -->
|
||||
<button id="dmScrollToBottomBtn" class="scroll-to-bottom-btn" title="Scroll to bottom">
|
||||
<i class="bi bi-chevron-double-down"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Send Message Form -->
|
||||
<div class="row border-top bg-light">
|
||||
<div class="col-12">
|
||||
<form id="dmSendForm" class="p-3">
|
||||
<div class="emoji-picker-container">
|
||||
<div class="input-group">
|
||||
<textarea
|
||||
id="dmMessageInput"
|
||||
class="form-control"
|
||||
placeholder="Type a message..."
|
||||
rows="2"
|
||||
maxlength="500"
|
||||
disabled
|
||||
></textarea>
|
||||
<button type="button" class="btn btn-outline-secondary" id="dmEmojiBtn" title="Insert emoji">
|
||||
<i class="bi bi-emoji-smile"></i>
|
||||
</button>
|
||||
<button type="submit" class="btn btn-success px-4" id="dmSendBtn" disabled>
|
||||
<i class="bi bi-send"></i>
|
||||
</button>
|
||||
<!-- Send Message Form -->
|
||||
<div class="border-top bg-light">
|
||||
<form id="dmSendForm" class="p-3">
|
||||
<div class="emoji-picker-container">
|
||||
<div class="input-group">
|
||||
<textarea
|
||||
id="dmMessageInput"
|
||||
class="form-control"
|
||||
placeholder="Type a message..."
|
||||
rows="2"
|
||||
maxlength="500"
|
||||
disabled
|
||||
></textarea>
|
||||
<button type="button" class="btn btn-outline-secondary" id="dmEmojiBtn" title="Insert emoji">
|
||||
<i class="bi bi-emoji-smile"></i>
|
||||
</button>
|
||||
<button type="submit" class="btn btn-success px-4" id="dmSendBtn" disabled>
|
||||
<i class="bi bi-send"></i>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Emoji picker popup (hidden by default) -->
|
||||
<div id="dmEmojiPickerPopup" class="emoji-picker-popup hidden"></div>
|
||||
</div>
|
||||
<!-- Emoji picker popup (hidden by default) -->
|
||||
<div id="dmEmojiPickerPopup" class="emoji-picker-popup hidden"></div>
|
||||
<div class="d-flex justify-content-end">
|
||||
<small class="text-muted"><span id="dmCharCounter">0</span> / 150</small>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!-- Status Bar -->
|
||||
<div class="border-top">
|
||||
<div class="p-2 small text-muted d-flex justify-content-between align-items-center">
|
||||
<span id="dmStatusText">
|
||||
<i class="bi bi-circle-fill text-secondary"></i> Connecting...
|
||||
</span>
|
||||
<span id="dmLastRefresh">Updated: Never</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-end">
|
||||
<small class="text-muted"><span id="dmCharCounter">0</span> / 150</small>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Status Bar -->
|
||||
<div class="row border-top">
|
||||
<div class="col-12">
|
||||
<div class="p-2 small text-muted d-flex justify-content-between align-items-center">
|
||||
<span id="dmStatusText">
|
||||
<i class="bi bi-circle-fill text-secondary"></i> Connecting...
|
||||
</span>
|
||||
<span id="dmLastRefresh">Updated: Never</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user