Autosave: 20260218-203108
This commit is contained in:
parent
e923af9f34
commit
f1694cdee6
@ -138,8 +138,13 @@ if ($action === "poll") {
|
|||||||
$p_file = room_participants_file($room);
|
$p_file = room_participants_file($room);
|
||||||
$ps = read_json_file($p_file);
|
$ps = read_json_file($p_file);
|
||||||
|
|
||||||
|
$is_muted = isset($_REQUEST["is_muted"]) ? (int)$_REQUEST["is_muted"] : 0;
|
||||||
|
$is_deafened = isset($_REQUEST["is_deafened"]) ? (int)$_REQUEST["is_deafened"] : 0;
|
||||||
|
|
||||||
if (isset($ps[$my_id])) {
|
if (isset($ps[$my_id])) {
|
||||||
$ps[$my_id]["last_seen"] = now_ms();
|
$ps[$my_id]["last_seen"] = now_ms();
|
||||||
|
$ps[$my_id]["is_muted"] = $is_muted;
|
||||||
|
$ps[$my_id]["is_deafened"] = $is_deafened;
|
||||||
}
|
}
|
||||||
|
|
||||||
$stale_time = now_ms() - 10000;
|
$stale_time = now_ms() - 10000;
|
||||||
@ -151,8 +156,8 @@ if ($action === "poll") {
|
|||||||
// Update DB last_seen
|
// Update DB last_seen
|
||||||
if ($current_user_id > 0) {
|
if ($current_user_id > 0) {
|
||||||
try {
|
try {
|
||||||
$stmt = db()->prepare("UPDATE voice_sessions SET last_seen = ? WHERE user_id = ?");
|
$stmt = db()->prepare("UPDATE voice_sessions SET last_seen = ?, is_muted = ?, is_deafened = ? WHERE user_id = ?");
|
||||||
$stmt->execute([now_ms(), $current_user_id]);
|
$stmt->execute([now_ms(), $is_muted, $is_deafened, $current_user_id]);
|
||||||
} catch (Exception $e) {}
|
} catch (Exception $e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +223,7 @@ if ($action === "list_all") {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = db()->prepare("
|
$stmt = db()->prepare("
|
||||||
SELECT vs.channel_id, vs.user_id, u.username, u.display_name, u.avatar_url
|
SELECT vs.channel_id, vs.user_id, vs.is_muted, vs.is_deafened, u.username, u.display_name, u.avatar_url
|
||||||
FROM voice_sessions vs
|
FROM voice_sessions vs
|
||||||
JOIN users u ON vs.user_id = u.id
|
JOIN users u ON vs.user_id = u.id
|
||||||
WHERE vs.last_seen > ?
|
WHERE vs.last_seen > ?
|
||||||
|
|||||||
@ -926,8 +926,19 @@ body {
|
|||||||
|
|
||||||
/* Voice active state */
|
/* Voice active state */
|
||||||
.voice-item.active, .voice-item.connected {
|
.voice-item.active, .voice-item.connected {
|
||||||
background-color: rgba(35, 165, 89, 0.1);
|
background-color: var(--active);
|
||||||
color: #23a559 !important;
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
.user-actions .btn:hover {
|
||||||
|
background-color: var(--hover);
|
||||||
|
color: var(--text-primary) !important;
|
||||||
|
}
|
||||||
|
.user-actions .btn.active {
|
||||||
|
color: #f23f43 !important;
|
||||||
|
}
|
||||||
|
.user-actions a:hover {
|
||||||
|
background-color: var(--hover);
|
||||||
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.voice-user {
|
.voice-user {
|
||||||
|
|||||||
@ -13,6 +13,8 @@ class VoiceChannel {
|
|||||||
this.myPeerId = null;
|
this.myPeerId = null;
|
||||||
this.pollInterval = null;
|
this.pollInterval = null;
|
||||||
this.remoteAudios = {}; // userId -> Audio element
|
this.remoteAudios = {}; // userId -> Audio element
|
||||||
|
this.isMuted = false;
|
||||||
|
this.isDeafened = false;
|
||||||
|
|
||||||
this.audioContext = null;
|
this.audioContext = null;
|
||||||
this.analyser = null;
|
this.analyser = null;
|
||||||
@ -140,7 +142,7 @@ class VoiceChannel {
|
|||||||
if (!this.myPeerId || !this.currentChannelId) return;
|
if (!this.myPeerId || !this.currentChannelId) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resp = await fetch(`api_v1_voice.php?action=poll&room=${this.currentChannelId}&peer_id=${this.myPeerId}`);
|
const resp = await fetch(`api_v1_voice.php?action=poll&room=${this.currentChannelId}&peer_id=${this.myPeerId}&is_muted=${this.isMuted ? 1 : 0}&is_deafened=${this.isDeafened ? 1 : 0}`);
|
||||||
const data = await resp.json();
|
const data = await resp.json();
|
||||||
|
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
@ -230,6 +232,7 @@ class VoiceChannel {
|
|||||||
remoteAudio.autoplay = true;
|
remoteAudio.autoplay = true;
|
||||||
remoteAudio.style.display = 'none';
|
remoteAudio.style.display = 'none';
|
||||||
remoteAudio.srcObject = stream;
|
remoteAudio.srcObject = stream;
|
||||||
|
remoteAudio.muted = this.isDeafened;
|
||||||
document.body.appendChild(remoteAudio);
|
document.body.appendChild(remoteAudio);
|
||||||
this.remoteAudios[userId] = remoteAudio;
|
this.remoteAudios[userId] = remoteAudio;
|
||||||
|
|
||||||
@ -404,10 +407,53 @@ class VoiceChannel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setMute(mute) {
|
setMute(mute) {
|
||||||
|
this.isMuted = mute;
|
||||||
if (this.localStream) {
|
if (this.localStream) {
|
||||||
console.log('Setting mute to:', mute);
|
console.log('Setting mute to:', mute);
|
||||||
this.localStream.getAudioTracks().forEach(track => { track.enabled = !mute; });
|
this.localStream.getAudioTracks().forEach(track => { track.enabled = !mute; });
|
||||||
}
|
}
|
||||||
|
this.updateUserPanelButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleMute() {
|
||||||
|
this.setMute(!this.isMuted);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleDeafen() {
|
||||||
|
this.isDeafened = !this.isDeafened;
|
||||||
|
console.log('Setting deafen to:', this.isDeafened);
|
||||||
|
Object.values(this.remoteAudios).forEach(audio => {
|
||||||
|
audio.muted = this.isDeafened;
|
||||||
|
});
|
||||||
|
// If we deafen, we usually also mute in Discord
|
||||||
|
if (this.isDeafened && !this.isMuted) {
|
||||||
|
this.setMute(true);
|
||||||
|
} else if (!this.isDeafened && this.isMuted) {
|
||||||
|
// Not necessarily unmute when undeafen, but often expected
|
||||||
|
// Let's just update UI
|
||||||
|
}
|
||||||
|
this.updateUserPanelButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateUserPanelButtons() {
|
||||||
|
const btnMute = document.getElementById('btn-panel-mute');
|
||||||
|
const btnDeafen = document.getElementById('btn-panel-deafen');
|
||||||
|
|
||||||
|
if (btnMute) {
|
||||||
|
btnMute.classList.toggle('active', this.isMuted);
|
||||||
|
btnMute.style.color = this.isMuted ? '#f23f43' : 'var(--text-muted)';
|
||||||
|
btnMute.innerHTML = this.isMuted ?
|
||||||
|
'<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="1" y1="1" x2="23" y2="23"></line><path d="M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6"></path><path d="M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23"></path><line x1="12" y1="19" x2="12" y2="23"></line><line x1="8" y1="23" x2="16" y2="23"></line></svg>' :
|
||||||
|
'<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"></path><path d="M19 10v2a7 7 0 0 1-14 0v-2"></path><line x1="12" y1="19" x2="12" y2="23"></line><line x1="8" y1="23" x2="16" y2="23"></line></svg>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (btnDeafen) {
|
||||||
|
btnDeafen.classList.toggle('active', this.isDeafened);
|
||||||
|
btnDeafen.style.color = this.isDeafened ? '#f23f43' : 'var(--text-muted)';
|
||||||
|
btnDeafen.innerHTML = this.isDeafened ?
|
||||||
|
'<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="1" y1="1" x2="23" y2="23"></line><path d="M8.85 4.11A9 9 0 1 1 20 12"></path><path d="M11.64 6.64A5 5 0 1 1 15 10"></path></svg>' :
|
||||||
|
'<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 18v-6a9 9 0 0 1 18 0v6"></path><path d="M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z"></path></svg>';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
leave() {
|
leave() {
|
||||||
@ -506,6 +552,7 @@ class VoiceChannel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateSpeakingUI(userId, isSpeaking) {
|
updateSpeakingUI(userId, isSpeaking) {
|
||||||
|
userId = String(userId);
|
||||||
if (isSpeaking) {
|
if (isSpeaking) {
|
||||||
this.speakingUsers.add(userId);
|
this.speakingUsers.add(userId);
|
||||||
} else {
|
} else {
|
||||||
@ -548,8 +595,9 @@ class VoiceChannel {
|
|||||||
const listEl = container.querySelector('.voice-users-list');
|
const listEl = container.querySelector('.voice-users-list');
|
||||||
if (listEl) {
|
if (listEl) {
|
||||||
data.channels[channelId].forEach(p => {
|
data.channels[channelId].forEach(p => {
|
||||||
const isSpeaking = window.voiceHandler && window.voiceHandler.speakingUsers.has(p.user_id);
|
const pid = String(p.user_id);
|
||||||
VoiceChannel.renderUserToUI(listEl, p.user_id, p.display_name || p.username, p.avatar_url, isSpeaking);
|
const isSpeaking = window.voiceHandler && window.voiceHandler.speakingUsers.has(pid);
|
||||||
|
VoiceChannel.renderUserToUI(listEl, p.user_id, p.display_name || p.username, p.avatar_url, isSpeaking, p.is_muted, p.is_deafened);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -561,16 +609,25 @@ class VoiceChannel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static renderUserToUI(container, userId, username, avatarUrl, isSpeaking = false) {
|
static renderUserToUI(container, userId, username, avatarUrl, isSpeaking = false, isMuted = false, isDeafened = false) {
|
||||||
const userEl = document.createElement('div');
|
const userEl = document.createElement('div');
|
||||||
userEl.className = 'voice-user small text-muted d-flex align-items-center mb-1';
|
userEl.className = 'voice-user small text-muted d-flex align-items-center mb-1';
|
||||||
userEl.dataset.userId = userId;
|
userEl.dataset.userId = userId;
|
||||||
userEl.style.paddingLeft = '8px';
|
userEl.style.paddingLeft = '8px';
|
||||||
const avatarStyle = avatarUrl ? `background-image: url('${avatarUrl}'); background-size: cover;` : "background-color: #555;";
|
const avatarStyle = avatarUrl ? `background-image: url('${avatarUrl}'); background-size: cover;` : "background-color: #555;";
|
||||||
const boxShadow = isSpeaking ? 'box-shadow: 0 0 0 2px #23a559;' : '';
|
const boxShadow = isSpeaking ? 'box-shadow: 0 0 0 2px #23a559;' : '';
|
||||||
|
|
||||||
|
let icons = '';
|
||||||
|
if (isDeafened) {
|
||||||
|
icons += '<i class="fa-solid fa-volume-xmark ms-auto text-danger" style="font-size: 10px;"></i>';
|
||||||
|
} else if (isMuted) {
|
||||||
|
icons += '<i class="fa-solid fa-microphone-slash ms-auto text-danger" style="font-size: 10px;"></i>';
|
||||||
|
}
|
||||||
|
|
||||||
userEl.innerHTML = `
|
userEl.innerHTML = `
|
||||||
<div class="message-avatar me-2" style="width: 16px; height: 16px; border-radius: 50%; transition: box-shadow 0.2s; ${avatarStyle} ${boxShadow}"></div>
|
<div class="message-avatar me-2" style="width: 16px; height: 16px; border-radius: 50%; transition: box-shadow 0.2s; ${avatarStyle} ${boxShadow}"></div>
|
||||||
<span style="font-size: 13px;">${username}</span>
|
<span class="text-truncate" style="font-size: 13px; max-width: 100px;">${username}</span>
|
||||||
|
${icons}
|
||||||
`;
|
`;
|
||||||
container.appendChild(userEl);
|
container.appendChild(userEl);
|
||||||
}
|
}
|
||||||
|
|||||||
115
contact.php
Normal file
115
contact.php
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'auth/session.php';
|
||||||
|
require_once 'mail/MailService.php';
|
||||||
|
|
||||||
|
$success = '';
|
||||||
|
$error = '';
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$name = trim($_POST['name'] ?? '');
|
||||||
|
$email = trim($_POST['email'] ?? '');
|
||||||
|
$message = trim($_POST['message'] ?? '');
|
||||||
|
|
||||||
|
if (empty($name) || empty($email) || empty($message)) {
|
||||||
|
$error = 'All fields are required.';
|
||||||
|
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||||
|
$error = 'Invalid email address.';
|
||||||
|
} else {
|
||||||
|
$res = MailService::sendContactMessage($name, $email, $message);
|
||||||
|
if (!empty($res['success'])) {
|
||||||
|
$success = 'Your message has been sent successfully!';
|
||||||
|
} else {
|
||||||
|
$error = 'Failed to send message: ' . ($res['error'] ?? 'Unknown error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" data-theme="dark">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Contact Us - Flatlogic Discord</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
<link rel="stylesheet" href="assets/css/discord.css?v=<?php echo time(); ?>">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: var(--bg-chat);
|
||||||
|
color: var(--text-primary);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
.contact-card {
|
||||||
|
background-color: var(--bg-channels);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 32px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 480px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
.form-control {
|
||||||
|
background-color: #1e1f22;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.form-control:focus {
|
||||||
|
background-color: #1e1f22;
|
||||||
|
color: white;
|
||||||
|
box-shadow: none;
|
||||||
|
border: 1px solid var(--blurple);
|
||||||
|
}
|
||||||
|
.btn-primary {
|
||||||
|
background-color: var(--blurple);
|
||||||
|
border: none;
|
||||||
|
padding: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: #4752c4;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="contact-card">
|
||||||
|
<h3 class="text-center mb-4">Contact Us</h3>
|
||||||
|
|
||||||
|
<?php if ($success): ?>
|
||||||
|
<div class="alert alert-success"><?php echo htmlspecialchars($success); ?></div>
|
||||||
|
<div class="text-center mt-3">
|
||||||
|
<a href="index.php" class="btn btn-link text-white">Back to App</a>
|
||||||
|
</div>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php if ($error): ?>
|
||||||
|
<div class="alert alert-danger"><?php echo htmlspecialchars($error); ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<form method="POST">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label text-uppercase small fw-bold">Name</label>
|
||||||
|
<input type="text" name="name" class="form-control" required value="<?php echo htmlspecialchars($_POST['name'] ?? ''); ?>">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label text-uppercase small fw-bold">Email</label>
|
||||||
|
<input type="email" name="email" class="form-control" required value="<?php echo htmlspecialchars($_POST['email'] ?? ''); ?>">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label text-uppercase small fw-bold">Message</label>
|
||||||
|
<textarea name="message" class="form-control" rows="5" required><?php echo htmlspecialchars($_POST['message'] ?? ''); ?></textarea>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary w-100 mb-3">Send Message</button>
|
||||||
|
<div class="text-center">
|
||||||
|
<a href="index.php" class="btn btn-link text-muted small text-decoration-none">Cancel</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="mt-4 p-3 rounded" style="background-color: rgba(255,255,255,0.05); font-size: 0.8em;">
|
||||||
|
<p class="mb-0 text-muted">This is for testing purposes only — Flatlogic does not guarantee usage of the mail server. Please set up your own SMTP in .env with our AI Agent.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -1 +1 @@
|
|||||||
[]
|
{"cd751c28f7e35458":{"id":"cd751c28f7e35458","user_id":3,"name":"swefheim","avatar_url":"","last_seen":1771446668805,"is_muted":1,"is_deafened":0}}
|
||||||
@ -1 +1 @@
|
|||||||
{"ec29a24a820e7529":{"id":"ec29a24a820e7529","user_id":3,"name":"swefheim","avatar_url":"","last_seen":1771443332052},"9312694ff19bebf2":{"id":"9312694ff19bebf2","user_id":2,"name":"swefpifh ᵇʰᶠʳ","avatar_url":"","last_seen":1771443331634}}
|
{"6c0fa2db85f281cf":{"id":"6c0fa2db85f281cf","user_id":2,"name":"swefpifh ᵇʰᶠʳ","avatar_url":"","last_seen":1771446668059,"is_muted":1,"is_deafened":0}}
|
||||||
3
db/migrations/20260218_voice_status.sql
Normal file
3
db/migrations/20260218_voice_status.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
-- Add mute and deafen status to voice sessions
|
||||||
|
ALTER TABLE voice_sessions ADD COLUMN is_muted BOOLEAN DEFAULT FALSE;
|
||||||
|
ALTER TABLE voice_sessions ADD COLUMN is_deafened BOOLEAN DEFAULT FALSE;
|
||||||
22
healthz.php
Normal file
22
healthz.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'db/config.php';
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
$response = [
|
||||||
|
'status' => 'ok',
|
||||||
|
'timestamp' => time(),
|
||||||
|
'php_version' => PHP_VERSION,
|
||||||
|
'database' => 'unknown'
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = db();
|
||||||
|
$db->query('SELECT 1');
|
||||||
|
$response['database'] = 'connected';
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$response['status'] = 'error';
|
||||||
|
$response['database'] = 'error: ' . $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode($response);
|
||||||
19
index.php
19
index.php
@ -632,16 +632,23 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
|||||||
<div style="color: var(--text-muted); font-size: 0.75em;">@<?php echo htmlspecialchars($user['username']); ?> #<?php echo str_pad($user['id'], 4, '0', STR_PAD_LEFT); ?></div>
|
<div style="color: var(--text-muted); font-size: 0.75em;">@<?php echo htmlspecialchars($user['username']); ?> #<?php echo str_pad($user['id'], 4, '0', STR_PAD_LEFT); ?></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="user-actions">
|
<div class="user-actions d-flex align-items-center">
|
||||||
<a href="#" title="Settings" style="color: var(--text-muted); margin-right: 8px;" data-bs-toggle="modal" data-bs-target="#userSettingsModal">
|
<button class="btn btn-link p-1 text-muted border-0" id="btn-panel-mute" title="Mute/Unmute" onclick="if(window.voiceHandler) window.voiceHandler.toggleMute()">
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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-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>
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"></path><path d="M19 10v2a7 7 0 0 1-14 0v-2"></path><line x1="12" y1="19" x2="12" y2="23"></line><line x1="8" y1="23" x2="16" y2="23"></line></svg>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-link p-1 text-muted border-0" id="btn-panel-deafen" title="Deafen/Undeafen" onclick="if(window.voiceHandler) window.voiceHandler.toggleDeafen()">
|
||||||
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 18v-6a9 9 0 0 1 18 0v6"></path><path d="M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z"></path></svg>
|
||||||
|
</button>
|
||||||
|
<a href="#" title="Settings" class="p-1 text-muted d-inline-flex" data-bs-toggle="modal" data-bs-target="#userSettingsModal">
|
||||||
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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>
|
||||||
|
</a>
|
||||||
|
<a href="auth/logout.php" class="p-1 text-muted d-inline-flex" onclick="if(window.voiceHandler) window.voiceHandler.leave(); sessionStorage.clear();" title="Logout">
|
||||||
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line></svg>
|
||||||
</a>
|
</a>
|
||||||
<a href="auth/logout.php" onclick="if(window.voiceHandler) window.voiceHandler.leave(); sessionStorage.clear();" title="Logout" style="color: var(--text-muted);">
|
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line></svg></a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="padding: 10px; font-size: 10px; color: #4e5058; border-top: 1px solid #1e1f22;">
|
<div style="padding: 10px; font-size: 10px; color: #4e5058; border-top: 1px solid #1e1f22;">
|
||||||
PHP <?php echo PHP_VERSION; ?> | <?php echo date('H:i'); ?>
|
PHP <?php echo PHP_VERSION; ?> | <?php echo date('H:i'); ?> | <a href="healthz.php" style="color: inherit; text-decoration: none;">Health</a> | <a href="contact.php" style="color: inherit; text-decoration: none;">Contact</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
12
requests.log
12
requests.log
@ -688,3 +688,15 @@
|
|||||||
2026-02-18 19:21:05 - GET /?fl_project=38443 - POST: []
|
2026-02-18 19:21:05 - GET /?fl_project=38443 - POST: []
|
||||||
2026-02-18 19:34:14 - GET /index.php - POST: []
|
2026-02-18 19:34:14 - GET /index.php - POST: []
|
||||||
2026-02-18 19:34:43 - GET /index.php - POST: []
|
2026-02-18 19:34:43 - GET /index.php - POST: []
|
||||||
|
2026-02-18 19:35:59 - GET /index.php?server_id=3 - POST: []
|
||||||
|
2026-02-18 19:36:04 - GET /index.php?server_id=1 - POST: []
|
||||||
|
2026-02-18 19:36:06 - GET /index.php?server_id=1&channel_id=6 - POST: []
|
||||||
|
2026-02-18 19:36:50 - GET /index.php?server_id=1&channel_id=15 - POST: []
|
||||||
|
2026-02-18 19:37:29 - GET /index.php?server_id=1&channel_id=6 - POST: []
|
||||||
|
2026-02-18 19:37:38 - GET /index.php?server_id=1&channel_id=15 - POST: []
|
||||||
|
2026-02-18 19:40:34 - GET /?fl_project=38443 - POST: []
|
||||||
|
2026-02-18 19:52:03 - GET / - POST: []
|
||||||
|
2026-02-18 19:52:24 - GET /?fl_project=38443 - POST: []
|
||||||
|
2026-02-18 20:29:14 - GET /index.php?server_id=1&channel_id=15 - POST: []
|
||||||
|
2026-02-18 20:30:52 - GET /index.php - POST: []
|
||||||
|
2026-02-18 20:30:56 - GET /index.php - POST: []
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user