Files
web/views/template.twig

192 lines
9.9 KiB
Twig
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{###########################################################################
# Copyright (c) 2025, Антон Аксенов
# This file is part of m3u.su project
# MIT License: {{config('app.repo_url}}/web/src/branch/master/LICENSE
###########################################################################}
<!DOCTYPE html>
<html lang="ru" class="h-100">
<head>
<title>{% block title %}{{ config('app.title') }}{% endblock %}</title>
<meta charset="utf-8">
<meta name="description" content="{% block metadescription %}{% endblock %}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="keywords" content="{% block metakeywords %}{% endblock %}" />
<meta http-equiv="x-ua-compatible" content="ie=edge">
<style>.cursor-pointer{cursor:pointer}.cursor-help{cursor:help}</style>
<script async type="module" src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"></script>
<script async nomodule src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"></script>
<link href="/css/bootstrap.min.css" rel="stylesheet">
<link rel="shortcut icon" href="/favicon/favicon.ico" />
<link rel="icon" type="image/png" sizes="96x96" href="/favicon/favicon-96x96.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png" />
<link rel="icon" type="image/svg+xml" href="/favicon/favicon.svg" />
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" />
<meta name="apple-mobile-web-app-title" content="IPTV Плейлисты" />
<link rel="manifest" href="/favicon/site.webmanifest" />
<meta name="msapplication-TileColor" content="#00aba9">
<meta name="msapplication-TileImage" content="/favicon/mstile-150x150.png">
<meta name="theme-color" content="#212529">
{% block head %}{% endblock %}
</head>
<body class="d-flex flex-column h-100 bg-dark text-light">
<header class="sticky-top bg-dark border-bottom border-secondary">
<nav class="navbar navbar-expand-lg navbar-dark container px-2">
<a class="navbar-brand d-flex align-items-center gap-2" href="/" title="На главную">
<img src="/favicon/favicon-32x32.png" alt="Логотип проекта" class="d-inline-block">
<span>{{ config('app.title') }}</span>
</a>
<button class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNav"
aria-controls="navbarNav"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link" target="_blank" href="https://status.m3u.su">
<ion-icon name="pulse-outline" class="me-1"></ion-icon>&nbsp;Аптайм
</a>
</li>
<li class="nav-item">
<a class="nav-link" target="_blank" href="/docs">
<ion-icon name="document-text-outline" class="me-1"></ion-icon>&nbsp;Документация
</a>
</li>
<li class="nav-item">
<a class="nav-link" target="_blank" href="/docs/support.html">
<ion-icon name="heart-outline" class="me-1"></ion-icon>&nbsp;Помочь проекту
</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle d-flex align-items-center"
href="#"
role="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
<ion-icon name="paper-plane-outline" class="me-1"></ion-icon>&nbsp;Telegram
</a>
<ul class="dropdown-menu dropdown-menu-dark">
<li>
<a class="dropdown-item d-flex align-items-center gap-2" target="_blank" href="https://t.me/iptv_aggregator">
<ion-icon name="megaphone-outline"></ion-icon>&nbsp;Канал @iptv_aggregator
</a>
</li>
<li>
<a class="dropdown-item d-flex align-items-center gap-2" target="_blank" href="https://t.me/iptv_aggregator_chat">
<ion-icon name="chatbubbles-outline"></ion-icon>&nbsp;Чат @iptv_aggregator_chat
</a>
</li>
<li>
<a class="dropdown-item d-flex align-items-center gap-2" target="_blank" href="https://t.me/iptv_aggregator_bot">
<ion-icon name="chatbox-ellipses-outline"></ion-icon>&nbsp;Бот @iptv_aggregator_bot
</a>
</li>
</ul>
</li>
</ul>
</div>
</nav>
</header>
<main class="flex-grow-1 container py-4">
{% block header %}{% endblock %}
<div class="content-wrapper">
{% block content %}{% endblock %}
</div>
</main>
<footer class="bg-dark border-top border-secondary py-4">
<div class="container text-center">
<div class="d-flex flex-wrap justify-content-center gap-3 mb-3">
<a target="_blank" href="/docs" class="text-light text-decoration-none d-flex align-items-center gap-1">
<ion-icon name="document-text-outline"></ion-icon>Документация
</a>
<a target="_blank" href="{{ config('app.repo_url') }}" class="text-light text-decoration-none d-flex align-items-center gap-1">
<ion-icon name="code-slash-outline"></ion-icon>Исходники
</a>
<a target="_blank" href="https://axenov.dev" class="text-light text-decoration-none d-flex align-items-center gap-1">
<ion-icon name="person-outline"></ion-icon>axenov.dev
</a>
<a target="_blank" href="https://t.me/iptv_aggregator" class="text-light text-decoration-none d-flex align-items-center gap-1">
<ion-icon name="megaphone-outline"></ion-icon>Канал
</a>
<a target="_blank" href="https://t.me/iptv_aggregator_chat" class="text-light text-decoration-none d-flex align-items-center gap-1">
<ion-icon name="chatbubbles-outline"></ion-icon>Чат
</a>
<a target="_blank" href="https://t.me/iptv_aggregator_bot" class="text-light text-decoration-none d-flex align-items-center gap-1">
<ion-icon name="chatbox-ellipses-outline"></ion-icon>Бот
</a>
</div>
<div>
<a class="small text-secondary d-inline-flex align-items-center gap-1"
href="{{ config('app.repo_url') }}/web/releases/tag/v{{ version() }}"
target="_blank"
>
<ion-icon name="pricetag-outline"></ion-icon>v{{ version() }}
</a>
</div>
</div>
</footer>
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<div class="toast align-items-center text-bg-success border-0" role="alert" id="clipboardToast">
<div class="d-flex">
<div class="toast-body" id="clipboardToastBody"></div>
</div>
</div>
</div>
<script src="/js/bootstrap.bundle.min.js"></script>
{% block footer %}{% endblock %}
<script>
function showToast(message) {
const toastEl = document.getElementById('clipboardToast');
const toastBodyEl = document.getElementById('clipboardToastBody');
toastBodyEl.innerHTML = message;
const toast = new bootstrap.Toast(toastEl, {delay: 5000});
toast.show();
}
function copyPlaylistUrl(code) {
const url = '{{ base_url() }}/' + code;
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard
.writeText(url)
.then(() => showToast(`Ссылка на плейлист '${code}' скопирована в буфер обмена`))
.catch(err => console.error('Failed to copy:', err));
} else {
try {
const textArea = document.createElement("textarea");
textArea.value = url;
textArea.style.position = "fixed"; // Avoid scrolling to bottom
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
const successful = document.execCommand('copy');
document.body.removeChild(textArea);
if (successful) {
showToast(`Ссылка на плейлист '${code}' скопирована в буфер обмена`);
} else {
showToast('Ошибка при копировании ссылки', true);
}
} catch (err) {
console.error('Fallback copy failed:', err);
showToast('Ошибка при копировании ссылки', true);
}
}
}
</script>
{% include("custom.twig") ignore missing %}
</body>
</html>