Файл: upload/core/footer.php
Строк: 235
<?php
$eml = FetchAssoc(dbquery("SELECT `email_support` FROM `general_parameters` WHERE `id` = '1'"));
echo '<audio id="msgSound" src="' . homeLink() . '/sounds/message.mp3" preload="auto"></audio>';
include ($_SERVER['DOCUMENT_ROOT'] . '/core/set-sidebar.php');
echo '</div>';
echo '</div>';
echo '<div class="home_us footer">
<div class="bottom_footer-info">
<a class="footer-info-link" href="' . homeLink() . '/offer">Публичная оферта</a>
<a class="footer-info-link" href="' . homeLink() . '/project-info">О проекте</a>
<a class="footer-info-link" href="' . homeLink() . '/orders">Услуги</a>
<a class="footer-info-link" href="' . homeLink() . '/privacy">Политика конфиденциальности</a>
<a class="footer-info-link" href="mailto:' . $eml['email_support'] . '">Обратная связь</a>
<a class="footer-info-link" href="' . homeLink() . '/solutions">База знаний</a>
</div>
</div>';
echo '</div>
</body>
</html>';
?>
<script>
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("/core/js/sw.js")
.then(() => console.log("PWA: Service Worker registered"))
.catch(err => console.error("SW error:", err));
}
</script>
<script>
// ===============================
// Web Audio API (звук в фоне)
// ===============================
let audioCtx = null;
let audioBuffer = null;
let soundReady = false;
// Загружаем звук в память
async function loadSound() {
try {
const response = await fetch("<?= homeLink() ?>/sounds/message.mp3");
const arrayBuffer = await response.arrayBuffer();
audioBuffer = await audioCtx.decodeAudioData(arrayBuffer);
soundReady = true;
console.log("Sound loaded");
} catch (e) {
console.error("Sound load error:", e);
}
}
// Активируем звук при ЛЮБОМ действии пользователя
function initSound() {
if (audioCtx) return;
console.log("initSound() → AudioContext created");
audioCtx = new (window.AudioContext || window.webkitAudioContext)();
if (audioCtx.state === "suspended") {
audioCtx.resume();
}
loadSound();
}
// Проигрываем звук
function playSound() {
if (!soundReady || !audioBuffer) {
console.warn("Sound not ready");
return;
}
const source = audioCtx.createBufferSource();
source.buffer = audioBuffer;
source.connect(audioCtx.destination);
source.start(0);
console.log("Sound played");
}
// === Вешаем активацию на ЛЮБОЕ действие ===
[
"click",
"touchstart",
"keydown",
"focus",
"mousemove",
"wheel", // колесо мыши
"touchmove" // прокрутка пальцем
].forEach(ev => {
window.addEventListener(ev, initSound, { once: true });
});
// ===============================
// ЛОГИКА МЕССЕНДЖЕРА
// ===============================
const notifyUserId = <?= $user['id'] ?>;
const notifyActivePeer = <?= isset($id) ? (int)$id : 0 ?>;
let lastStateMessages = null; // null = первый запуск
function moveDialogToTop(peerId) {
const dialog = document.querySelector(`.chat-box_mes[data-peer="${peerId}"]`);
const list = document.querySelector('.list_messages');
if (dialog && list) list.prepend(dialog);
}
function updateUnread() {
fetch(`/core/ajax/messages/state.php?user=${notifyUserId}`)
.then(r => r.json())
.then(data => {
const dialogs = data.dialogs;
const count = data.count;
const lastMessages = data.last;
// === 1. Бейджи ===
document.querySelectorAll('.chat-unread-badge').forEach(el => {
const peer = el.dataset.peer;
if (dialogs[peer] && parseInt(peer) !== notifyActivePeer) {
el.textContent = dialogs[peer];
el.style.display = 'flex';
} else {
el.style.display = 'none';
}
});
// === 2. Глобальный счётчик ===
const el = document.getElementById('unreadCounter');
if (el) {
el.textContent = count;
el.style.display = count > 0 ? 'flex' : 'none';
}
// === 3. Последние сообщения + звук ===
for (const peerId in lastMessages) {
const newText = lastMessages[peerId];
// --- Обновляем превью ---
const preview = document.querySelector(
`.chat-box_mes[data-peer="${peerId}"] .preview_user-mes`
);
if (preview && newText !== preview.textContent.trim()) {
preview.textContent = newText;
moveDialogToTop(peerId);
}
// --- Первый запуск — не играем звук ---
if (lastStateMessages === null) continue;
const oldText = lastStateMessages[peerId] || "";
// --- Новый текст? → звук ---
if (newText !== oldText && parseInt(peerId) !== notifyActivePeer) {
playSound();
}
}
// сохраняем состояние
lastStateMessages = lastMessages;
})
.finally(() => setTimeout(updateUnread, 2000));
}
updateUnread();
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
function toggleClasses(elements) {
elements.forEach(([id, className]) => {
const element = document.getElementById(id);
if (element) {
element.classList.toggle(className);
}
});
}
const overlay = document.getElementById('overlay');
const hamburger = document.getElementById('hamburger');
const backMess = document.getElementById('back_mess');
if (overlay && hamburger) {
overlay.onclick = hamburger.onclick = function() {
toggleClasses([
['nav-icon', 'open_burger'],
['sidebar', 'opened'],
['overlay', 'opened']
]);
};
}
if (backMess) {
backMess.onclick = function() {
toggleClasses([['chat-list', 'opened']]);
};
}
});
</script>
<script>
document.addEventListener('click', async function(e) {
const btn = e.target.closest('.set-cart');
if (!btn) return;
const workId = btn.dataset.work; // ← исправлено
const userId = <?= $user['id'] ?>;
const icon = btn.querySelector('i');
async function post(url, body) {
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams(body).toString()
});
return res.json();
}
const check = await post('/core/ajax/cart/check_in_cart.php', {
work_id: workId,
user_id: userId
});
if (check.success === false) {
const add = await post('/core/ajax/cart/add_to_cart.php', {
work_id: workId,
user_id: userId
});
if (add.success) {
btn.classList.add('active-cart');
icon.classList.remove('far');
icon.classList.add('fas');
}
} else {
const remove = await post('/core/ajax/cart/remove_from_cart.php', {
work_id: workId,
user_id: userId
});
if (remove.success) {
btn.classList.remove('active-cart');
icon.classList.remove('fas');
icon.classList.add('far');
}
}
});
</script>