diff --git a/assets/css/discord.css b/assets/css/discord.css index 64c06c2..65e45c8 100644 --- a/assets/css/discord.css +++ b/assets/css/discord.css @@ -8,6 +8,8 @@ --blurple: #5865f2; --hover: #35373c; --active: #3f4147; + --separator: rgba(255,255,255,0.1); + --separator-soft: rgba(255,255,255,0.05); } [data-theme="light"] { @@ -19,10 +21,137 @@ --text-muted: #5c5e66; --hover: #e8e9eb; --active: #dbdee1; + --separator: rgba(0,0,0,0.2); + --separator-soft: rgba(0,0,0,0.1); } -[data-theme="light"] .chat-input-wrapper { +[data-theme="light"] .modal-content label:not(.btn) { + color: var(--text-primary); +} + +[data-theme="light"] .modal-content .fw-bold { + color: var(--text-primary); +} + +[data-theme="light"] .modal-content .text-muted { + color: var(--text-muted) !important; +} + +[data-theme="light"] .bg-dark { + background-color: #ebedef !important; +} + +[data-theme="light"] .text-white { + color: #313338 !important; +} + +[data-theme="light"] .btn-outline-light { + color: #313338; + border-color: #dbdee1; +} + +[data-theme="light"] .btn-outline-light:hover { background-color: #ebedef; + color: #313338; +} + +[data-theme="light"] .list-group-item.bg-dark { + background-color: #ffffff !important; + color: #313338 !important; +} + +[data-theme="light"] .nav-link.text-white { + color: #313338 !important; +} + +[data-theme="light"] .nav-link.text-white.active { + color: var(--blurple) !important; +} + +[data-theme="light"] .btn-outline-secondary { + color: #5c5e66; + border-color: #dbdee1; +} + +[data-theme="light"] .btn-outline-secondary:hover { + background-color: #f2f3f5; + color: #313338; + border-color: #c7ccd1; +} + +[data-theme="light"] .btn-check:checked + .btn-outline-secondary { + background-color: var(--blurple) !important; + border-color: var(--blurple) !important; + color: #ffffff !important; +} + +[data-theme="dark"] .btn-check:checked + .btn-outline-secondary { + background-color: var(--blurple) !important; + border-color: var(--blurple) !important; + color: #ffffff !important; +} + +[data-theme="light"] .voice-controls { + background-color: #ebedef !important; + border-top: 1px solid rgba(0,0,0,0.05); +} + +[data-theme="light"] .reaction-badge { + background-color: #f2f3f5; + border-color: #dbdee1; +} + +[data-theme="light"] .reaction-badge:hover { + background-color: #e3e5e8; +} + +[data-theme="light"] .emoji-picker { + background-color: #ffffff; + border-color: #dbdee1; +} + +[data-theme="light"] .emoji-picker span:hover { + background-color: #f2f3f5; +} + +[data-theme="light"] .message-img-preview { + background-color: #f2f3f5; +} + +[data-theme="light"] .user-info:hover { + background-color: #e3e5e8; +} + +[data-theme="light"] .channels-header, [data-theme="light"] .chat-header { + box-shadow: 0 1px 0 rgba(0,0,0,0.1); +} + +[data-theme="light"] .custom-scrollbar::-webkit-scrollbar-thumb { + background: #dbdee1; +} + +[data-theme="light"] .custom-scrollbar::-webkit-scrollbar-thumb:hover { + background: #c7ccd1; +} + +[data-theme="light"] .perm-tri-state { + background-color: #e3e5e8; +} + +[data-theme="light"] .perm-tri-state .btn { + color: #5c5e66; +} + +[data-theme="light"] .perm-tri-state .btn:hover { + background-color: #dbdee1; +} + +[data-theme="light"] .list-group-item { + color: #313338 !important; +} + +[data-theme="light"] .text-muted { + color: #5c5e66 !important; } [data-theme="light"] .message-item:hover { @@ -75,10 +204,26 @@ background-color: #f2f3f5; } +[data-theme="light"] .chat-input-wrapper { + background-color: #ebedef; +} + +[data-theme="light"] .chat-input::placeholder { + color: #5c5e66; +} + [data-theme="light"] .rich-embed { background: rgba(0,0,0,0.05) !important; } +[data-theme="light"] .voice-controls { + background-color: #ebedef !important; +} + +[data-theme="light"] .attachment-link:hover { + background-color: #dbdee1 !important; +} + body { margin: 0; padding: 0; @@ -204,7 +349,7 @@ body { text-transform: uppercase; font-weight: bold; margin-bottom: 4px; - padding: 16px 8px 4px 8px; + padding: 6px 8px 4px 8px; display: flex; justify-content: space-between; align-items: center; @@ -439,7 +584,7 @@ body { .message-text { font-size: 0.95em; line-height: 1.4; - color: #dbdee1; + color: var(--text-primary); } .message-time { @@ -772,7 +917,7 @@ body { .voice-user .message-avatar { background-color: var(--bg-servers); - border: 1px solid rgba(255,255,255,0.1); + border: 1px solid var(--separator); } .video-grid { @@ -793,18 +938,18 @@ body { } .voice-controls { - border-top: 1px solid rgba(255,255,255,0.05); + border-top: 1px solid var(--separator-soft); background-color: #232428 !important; } /* Roles Management */ #roles-list .list-group-item:hover { - background-color: rgba(255, 255, 255, 0.05) !important; + background-color: var(--separator-soft) !important; } .nav-tabs .nav-link.active { border-bottom: 2px solid var(--blurple) !important; - color: white !important; + color: var(--text-primary) !important; } .nav-tabs .nav-link { @@ -858,7 +1003,7 @@ body { .upload-progress-container { padding: 8px 16px; background-color: rgba(0,0,0,0.1); - border-top: 1px solid rgba(255,255,255,0.05); + border-top: 1px solid var(--separator-soft); } .progress-bar { @@ -1077,19 +1222,19 @@ body { } /* Modal text visibility fixes */ -.modal-content .text-muted { +[data-theme="dark"] .modal-content .text-muted { color: #dbdee1 !important; /* Lighter than before */ } -.modal-content .small { +[data-theme="dark"] .modal-content .small { color: #dbdee1; } -.modal-content label { - color: #ffffff; /* Even brighter */ +[data-theme="dark"] .modal-content label:not(.btn) { + color: var(--text-primary); } -.modal-content .fw-bold { +[data-theme="dark"] .modal-content .fw-bold { color: #ffffff; } diff --git a/assets/js/main.js b/assets/js/main.js index eaf9793..37ad53b 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -104,7 +104,7 @@ document.addEventListener('DOMContentLoaded', () => { const div = document.createElement('div'); div.className = 'role-emoji-item rounded d-flex flex-column align-items-center justify-content-center p-2 text-center position-relative'; div.style.cursor = 'pointer'; - div.style.backgroundColor = 'rgba(255,255,255,0.05)'; + div.style.backgroundColor = 'var(--separator-soft)'; div.style.minHeight = '70px'; div.innerHTML = ` @@ -159,7 +159,7 @@ document.addEventListener('DOMContentLoaded', () => { div.className = 'role-emoji-item rounded d-flex align-items-center justify-content-center p-2'; div.style.cursor = 'pointer'; div.style.fontSize = '24px'; - div.style.backgroundColor = 'rgba(255,255,255,0.05)'; + div.style.backgroundColor = 'var(--separator-soft)'; div.textContent = emoji; div.onclick = () => { navigator.clipboard.writeText(emoji); @@ -176,209 +176,13 @@ document.addEventListener('DOMContentLoaded', () => { categories.forEach((cat, idx) => { const btn = document.createElement('button'); btn.className = `btn w-100 text-start text-white border-0 py-2 px-3 mb-1 d-flex align-items-center gap-2 ${idx === 0 ? 'active' : ''}`; - btn.style.backgroundColor = idx === 0 ? 'rgba(255,255,255,0.1)' : 'transparent'; - btn.style.fontSize = '0.9em'; - btn.innerHTML = `${categoryIcons[cat] || '❓'} ${cat}`; + btn.style.backgroundColor = idx === 0 ? 'var(--separator)' : 'transparent'; + btn.innerHTML = ` ${cat}`; + btn.onclick = () => { - sidebar.querySelectorAll('button').forEach(b => { - b.classList.remove('active'); - b.style.backgroundColor = 'transparent'; - }); - btn.classList.add('active'); - btn.style.backgroundColor = 'rgba(255,255,255,0.1)'; - if (searchInput) searchInput.value = ''; - renderGrid(cat); - }; - sidebar.appendChild(btn); - }); - - if (uploadInput) { - uploadInput.onchange = async () => { - const file = uploadInput.files[0]; - if (!file) return; - const name = prompt("Nom de l'emote:", file.name.split('.')[0]); - if (!name) return; - const fd = new FormData(); - fd.append('emote', file); - fd.append('name', name); - const res = await (await fetch('api/emotes.php?action=upload', { method: 'POST', body: fd })).json(); - if (res.success) { - renderGrid('Custom'); - window.loadCustomEmotes(); - } else alert(res.error); - uploadInput.value = ''; - }; - } - - if (searchInput) { - searchInput.oninput = () => { - const term = searchInput.value.trim(); - if (term) { - sidebar.querySelectorAll('button').forEach(b => { - b.classList.remove('active'); - b.style.backgroundColor = 'transparent'; - }); - renderGrid(null, term); - } else { - const activeBtn = sidebar.querySelector('button.active'); - renderGrid(activeBtn ? activeBtn.querySelector('span:last-child').textContent : 'Custom'); - } - }; - } - - renderGrid('Custom'); - } - - // Call when tab is shown - const emotesTabBtn = document.getElementById('emotes-tab-btn'); - if (emotesTabBtn) { - emotesTabBtn.addEventListener('shown.bs.tab', setupSettingsEmotes); - } - - /** - * Centralized Emoji Picker Component - */ - const UniversalEmojiPicker = { - currentPicker: null, - - async show(anchor, callback, options = {}) { - this.hide(); - - const picker = document.createElement('div'); - picker.className = 'universal-emoji-picker p-0 overflow-hidden d-flex flex-column'; - picker.style.width = options.width || '900px'; - picker.style.height = options.height || '500px'; - picker.style.backgroundColor = '#313338'; - picker.style.border = '1px solid #1e1f22'; - picker.style.borderRadius = '8px'; - picker.style.boxShadow = '0 8px 24px rgba(0,0,0,0.5)'; - picker.style.zIndex = '11000'; // Higher than most modals - picker.style.position = 'fixed'; - picker.style.padding = '0'; // Explicitly override any CSS - - // Tab Navigation - const tabs = document.createElement('div'); - tabs.className = 'd-flex overflow-x-auto border-bottom border-secondary p-1 no-scrollbar'; - tabs.style.gap = '2px'; - tabs.style.backgroundColor = '#2b2d31'; - tabs.style.flexShrink = '0'; - tabs.style.minHeight = '42px'; - - // Search Container - const searchContainer = document.createElement('div'); - searchContainer.className = 'p-2 border-bottom border-secondary'; - searchContainer.style.backgroundColor = '#313338'; - searchContainer.style.flexShrink = '0'; - - const searchInput = document.createElement('input'); - searchInput.type = 'text'; - searchInput.placeholder = 'Chercher un emoji...'; - searchInput.className = 'form-control form-control-sm bg-dark border-secondary text-white'; - searchContainer.appendChild(searchInput); - - // Grid Container - const grid = document.createElement('div'); - grid.className = 'flex-grow-1 overflow-auto p-1 custom-scrollbar'; // Reduced padding - grid.style.display = 'grid'; - grid.style.gridTemplateColumns = 'repeat(15, 1fr)'; - grid.style.gap = '2px'; - grid.style.backgroundColor = '#313338'; - grid.style.alignContent = 'start'; - - const renderGrid = async (cat = null, term = '') => { - grid.innerHTML = ''; - - if (term) { - const customEmotes = window.CUSTOM_EMOTES_CACHE || []; - const filteredCustom = customEmotes.filter(e => e.name.toLowerCase().includes(term.toLowerCase()) || e.code.toLowerCase().includes(term.toLowerCase())); - const filteredStandard = ALL_EMOJIS.filter(e => e.includes(term)); - - filteredCustom.forEach(emote => { - const div = document.createElement('div'); - div.className = 'role-emoji-item rounded d-flex align-items-center justify-content-center p-1'; - div.style.cursor = 'pointer'; - div.style.aspectRatio = '1/1'; - div.innerHTML = ``; - div.title = emote.code; - div.onclick = (e) => { - e.stopPropagation(); - callback(emote.code); - if (!options.keepOpen) this.hide(); - }; - grid.appendChild(div); - }); - - filteredStandard.forEach(emoji => { - const div = document.createElement('div'); - div.className = 'role-emoji-item rounded d-flex align-items-center justify-content-center p-1'; - div.style.cursor = 'pointer'; - div.style.fontSize = '24px'; - div.style.aspectRatio = '1/1'; - div.textContent = emoji; - div.onclick = (e) => { - e.stopPropagation(); - callback(emoji); - if (!options.keepOpen) this.hide(); - }; - grid.appendChild(div); - }); - return; - } - - if (cat === 'Custom') { - const customEmotes = (window.CUSTOM_EMOTES_CACHE && window.CUSTOM_EMOTES_CACHE.length > 0) ? window.CUSTOM_EMOTES_CACHE : await window.loadCustomEmotes(); - if (customEmotes.length === 0) { - grid.innerHTML = '
Aucune emote personnalisée.
'; - return; - } - customEmotes.forEach(emote => { - const div = document.createElement('div'); - div.className = 'role-emoji-item rounded d-flex align-items-center justify-content-center p-1'; - div.style.cursor = 'pointer'; - div.style.aspectRatio = '1/1'; - div.innerHTML = ``; - div.title = emote.code; - div.onclick = (e) => { - e.stopPropagation(); - callback(emote.code); - if (!options.keepOpen) this.hide(); - }; - grid.appendChild(div); - }); - return; - } - - let list = EMOJI_CATEGORIES[cat]; - (list || []).forEach(emoji => { - const div = document.createElement('div'); - div.className = 'role-emoji-item rounded d-flex align-items-center justify-content-center p-1'; - div.style.cursor = 'pointer'; - div.style.fontSize = '24px'; - div.style.aspectRatio = '1/1'; - div.textContent = emoji; - div.onclick = (e) => { - e.stopPropagation(); - callback(emoji); - if (!options.keepOpen) this.hide(); - }; - grid.appendChild(div); - }); - }; - - const cats = ['Custom', ...Object.keys(EMOJI_CATEGORIES)]; - cats.forEach((cat, idx) => { - const btn = document.createElement('button'); - btn.className = `btn btn-sm text-white border-0 p-2 ${idx === 0 ? 'active' : ''}`; - btn.style.backgroundColor = idx === 0 ? 'rgba(255,255,255,0.1)' : 'transparent'; - btn.innerHTML = categoryIcons[cat] || '❓'; - btn.title = cat; - btn.onclick = async () => { - tabs.querySelectorAll('button').forEach(b => { - b.classList.remove('active'); - b.style.backgroundColor = 'transparent'; - }); - btn.classList.add('active'); - btn.style.backgroundColor = 'rgba(255,255,255,0.1)'; + const sidebar_btns = picker.querySelectorAll('.emoji-sidebar button'); + sidebar_btns.forEach(b => b.style.backgroundColor = 'transparent'); + btn.style.backgroundColor = 'var(--separator)'; await renderGrid(cat); }; tabs.appendChild(btn); @@ -1133,8 +937,8 @@ document.addEventListener('DOMContentLoaded', () => { availableRoles.forEach(role => { const li = document.createElement('li'); li.innerHTML = ` -
- ${role.name} +
+ ${role.name}
`; li.onclick = async (e) => { e.preventDefault(); @@ -1166,7 +970,7 @@ document.addEventListener('DOMContentLoaded', () => { function renderRoleOverridesList(channelId) { channelPermissionsRolesList.innerHTML = ''; if (channelPermissionsData.length === 0) { - channelPermissionsRolesList.innerHTML = '
No overrides configured for this channel.
'; + channelPermissionsRolesList.innerHTML = '
No overrides configured for this channel.
'; return; } @@ -2003,7 +1807,7 @@ document.addEventListener('DOMContentLoaded', () => { const percent = Math.min(100, (day.count / 100) * 100); // Normalize to 100 for visual bar.innerHTML = `
${day.date}
-
+
${day.count}
@@ -2403,6 +2207,13 @@ document.addEventListener('DOMContentLoaded', () => { } catch (e) { console.error(e); } }); + // Theme preview + document.querySelectorAll('input[name="theme"]').forEach(radio => { + radio.addEventListener('change', (e) => { + document.body.setAttribute('data-theme', e.target.value); + }); + }); + // Toggle members sidebar const toggleMembersBtn = document.getElementById('toggle-members-btn'); const membersSidebar = document.querySelector('.members-sidebar'); @@ -2593,8 +2404,8 @@ document.addEventListener('DOMContentLoaded', () => { } else { btn.classList.add('btn-outline-secondary'); btn.classList.remove('btn-primary'); - btn.style.backgroundColor = '#2b2d31'; - btn.style.border = '1px solid #4e5058'; + btn.style.backgroundColor = 'var(--bg-channels)'; + btn.style.border = '1px solid var(--separator)'; } // Refresh sidebar channels and members diff --git a/index.php b/index.php index 2be5341..0087a6f 100644 --- a/index.php +++ b/index.php @@ -300,7 +300,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? ''; } .role-emoji-item:hover { - background-color: rgba(255,255,255,0.1); + background-color: var(--separator); transform: scale(1.2); transition: transform 0.1s; } @@ -314,7 +314,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? ''; -
+
-
+
-
+
@@ -938,7 +938,7 @@ $emote_html = ' -
+
@@ -1620,7 +1620,7 @@ $emote_html = '' . htmlspe
                                         <button class=Clear Overrides
-
+
View Channel
diff --git a/requests.log b/requests.log index 5308278..c18c77a 100644 --- a/requests.log +++ b/requests.log @@ -280,3 +280,24 @@ 2026-02-16 18:50:31 - GET /?fl_project=38443 - POST: [] 2026-02-16 18:50:41 - GET /index.php?server_id=1&channel_id=12 - POST: [] 2026-02-16 18:51:08 - GET /index.php?server_id=1&channel_id=12 - POST: [] +2026-02-16 18:54:57 - GET /?fl_project=38443 - POST: [] +2026-02-16 18:54:58 - GET /index.php?server_id=1&channel_id=12 - POST: [] +2026-02-16 18:55:39 - GET /index.php?server_id=1&channel_id=6 - POST: [] +2026-02-16 18:56:06 - GET /?fl_project=38443 - POST: [] +2026-02-16 18:56:52 - GET /index.php?server_id=1&channel_id=6 - POST: [] +2026-02-16 19:05:49 - GET /index.php?server_id=1&channel_id=6 - POST: [] +2026-02-16 19:06:59 - GET /index.php?server_id=1&channel_id=6 - POST: [] +2026-02-16 19:09:05 - GET / - POST: [] +2026-02-16 19:09:11 - GET /?fl_project=38443 - POST: [] +2026-02-16 19:09:19 - GET /index.php?server_id=1&channel_id=6 - POST: [] +2026-02-16 19:09:23 - GET /index.php?server_id=1&channel_id=6 - POST: [] +2026-02-16 19:11:40 - GET /?fl_project=38443 - POST: [] +2026-02-16 19:15:47 - GET /index.php?server_id=1&channel_id=6 - POST: [] +2026-02-16 19:15:54 - GET /index.php?server_id=1&channel_id=6 - POST: [] +2026-02-16 19:16:02 - GET /index.php?server_id=1&channel_id=6 - POST: [] +2026-02-16 19:19:15 - GET /?fl_project=38443 - POST: [] +2026-02-16 20:15:59 - GET /index.php?server_id=1&channel_id=6 - POST: [] +2026-02-16 20:16:11 - GET /index.php?server_id=1&channel_id=6 - POST: [] +2026-02-16 20:18:56 - GET /?fl_project=38443 - POST: [] +2026-02-16 20:29:33 - GET /index.php?server_id=1&channel_id=6 - POST: [] +2026-02-16 20:29:40 - GET /index.php?server_id=1&channel_id=6 - POST: []