barre de séparation

This commit is contained in:
Flatlogic Bot 2026-02-15 22:48:16 +00:00
parent a757fa13ed
commit f604713529
3 changed files with 64 additions and 2 deletions

View File

@ -60,6 +60,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$chan = $stmt->fetch();
if ($chan && Permissions::hasPermission($user_id, $chan['server_id'], Permissions::MANAGE_CHANNELS)) {
if ($type === 'separator' && !$name) $name = 'separator';
$name = strtolower(preg_replace('/[^a-zA-Z0-9\-]/', '-', $name));
$stmt = db()->prepare("UPDATE channels SET name = ?, type = ?, status = ?, allow_file_sharing = ?, message_limit = ?, icon = ?, category_id = ? WHERE id = ?");
$stmt->execute([$name, $type, $status, $allow_file_sharing, $message_limit, $icon, $category_id, $channel_id]);
@ -87,8 +88,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$user_id = $_SESSION['user_id'];
// Check if user has permission to manage channels
if (Permissions::hasPermission($user_id, $server_id, Permissions::MANAGE_CHANNELS) && $name) {
if (Permissions::hasPermission($user_id, $server_id, Permissions::MANAGE_CHANNELS) && ($name || $type === 'separator')) {
try {
if ($type === 'separator' && !$name) $name = 'separator';
// Basic sanitization for channel name
$name = strtolower(preg_replace('/[^a-zA-Z0-9\-]/', '-', $name));
$allow_file_sharing = isset($_POST['allow_file_sharing']) ? 1 : 0;

View File

@ -229,6 +229,19 @@ body {
min-height: 5px;
}
.channel-item-container.separator-item {
cursor: default;
}
.channel-item-container.separator-item:hover {
background-color: transparent !important;
}
.channel-item-container.separator-item .channel-settings-btn {
opacity: 0;
}
.channel-item-container.separator-item:hover .channel-settings-btn {
opacity: 0.7 !important;
}
.sortable-ghost {
opacity: 0.4;
background-color: var(--blurple) !important;

View File

@ -338,6 +338,28 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
// Helper to render a channel item
function renderChannelItem($c, $active_channel_id, $active_server_id, $can_manage_channels) {
if ($c['type'] === 'separator') {
?>
<div class="channel-item-container separator-item d-flex align-items-center justify-content-between px-2 py-1" data-id="<?php echo $c['id']; ?>" data-type="separator" style="min-height: 24px;">
<div class="flex-grow-1" style="height: 1px; background: rgba(255,255,255,0.1); margin: 10px 0;"></div>
<?php if ($can_manage_channels): ?>
<span class="channel-settings-btn ms-2" style="cursor: pointer; color: var(--text-muted); opacity: 0; transition: opacity 0.2s;"
data-bs-toggle="modal" data-bs-target="#editChannelModal"
data-id="<?php echo $c['id']; ?>"
data-name="separator"
data-type="separator"
data-files="0"
data-limit="0"
data-status=""
data-icon=""
data-category="<?php echo $c['category_id'] ?? ''; ?>">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33 1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82 1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
</span>
<?php endif; ?>
</div>
<?php
return;
}
?>
<div class="channel-item-container d-flex align-items-center" data-id="<?php echo $c['id']; ?>">
<a href="?server_id=<?php echo $active_server_id; ?>&channel_id=<?php echo $c['id']; ?>"
@ -1069,7 +1091,8 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
<option value="rules">Rules</option>
<option value="forum">Forum</option>
<option value="voice">Voice Channel</option>
<option value="category">Category (Separator)</option>
<option value="separator">Separator</option>
<option value="category">Category</option>
</select>
</div>
<div class="mb-3">
@ -1166,6 +1189,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
<option value="forum">Forum</option>
<option value="voice">Voice Channel</option>
<option value="category">Category</option>
<option value="separator">Separator</option>
</select>
</div>
</div>
@ -1512,11 +1536,34 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
if (type === 'announcement') return '<i class="fa-solid fa-bullhorn"></i>';
if (type === 'rules') return '<i class="fa-solid fa-gavel"></i>';
if (type === 'forum') return '<i class="fa-solid fa-comments"></i>';
if (type === 'separator') return '—';
return '#';
}
function updatePrefix(typeSelect, iconSelect, prefixSpan) {
if (!prefixSpan || !typeSelect) return;
// Handle name input visibility for separator
const modal = typeSelect.closest('.modal');
const nameInputContainer = modal.querySelector('input[name="name"]')?.closest('.mb-3');
const iconSelectContainer = modal.querySelector('select[name="icon"]')?.closest('.mb-3');
const fileSharingContainer = modal.querySelector('input[name="allow_file_sharing"]')?.closest('.mb-3') || modal.querySelector('input[name="allow_file_sharing"]')?.closest('.form-check');
const limitContainer = modal.querySelector('input[name="message_limit"]')?.closest('.mb-3');
if (typeSelect.value === 'separator') {
if (nameInputContainer) nameInputContainer.style.display = 'none';
if (iconSelectContainer) iconSelectContainer.style.display = 'none';
if (fileSharingContainer) fileSharingContainer.style.display = 'none';
if (limitContainer) limitContainer.style.display = 'none';
if (modal.querySelector('input[name="name"]')) modal.querySelector('input[name="name"]').required = false;
} else {
if (nameInputContainer) nameInputContainer.style.display = 'block';
if (iconSelectContainer) iconSelectContainer.style.display = 'block';
if (fileSharingContainer) fileSharingContainer.style.display = 'block';
if (limitContainer) limitContainer.style.display = 'block';
if (modal.querySelector('input[name="name"]')) modal.querySelector('input[name="name"]').required = true;
}
let prefix = getPrefixForType(typeSelect.value);
if (iconSelect && iconSelect.value) {
prefix += ` <i class="fa-solid ${iconSelect.value}"></i>`;