feat(cinema): multi-layer adblock & popup shield, iframe anti-popunder sandbox, adguard click interceptor & hud toggle in 0.0.7

This commit is contained in:
Nikita 2026-10-27 13:18:00 +05:00
parent 2fafe24afa
commit 429b81e6ad
7 changed files with 128 additions and 5 deletions

View file

@ -7,6 +7,46 @@
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<title>has</title> <title>has</title>
<!-- HAS Cinema AdGuard & Anti-Popup Shield -->
<script>
(function() {
try {
const fakeWindow = {
closed: true,
close: function() {},
focus: function() {},
blur: function() {},
postMessage: function() {},
location: { href: "about:blank" }
};
window.open = function(url) {
console.warn("[HAS AdGuard] Blocked unauthorized window.open:", url);
return fakeWindow;
};
} catch (_) {}
const AD_PATTERNS = [
/1xbet/i, /vavada/i, /mostbet/i, /pin-up/i, /bet365/i, /casino/i,
/adsterra/i, /propellerads/i, /popcash/i, /monetag/i, /clickadu/i,
/exoclick/i, /juicyads/i, /adcash/i, /trafficjunky/i, /syndication/i,
/delivembd/i, /betandyou/i, /melbet/i, /linebet/i, /fonbet/i, /parimatch/i
];
document.addEventListener("click", function(e) {
const a = e.target && e.target.closest ? e.target.closest("a") : null;
if (a && a.href) {
for (let i = 0; i < AD_PATTERNS.length; i++) {
if (AD_PATTERNS[i].test(a.href)) {
e.preventDefault();
e.stopPropagation();
console.warn("[HAS AdGuard] Intercepted ad redirect:", a.href);
return;
}
}
}
}, true);
})();
</script>
</head> </head>
<body> <body>

View file

@ -1,7 +1,7 @@
{ {
"name": "has", "name": "has",
"private": true, "private": true,
"version": "0.0.6", "version": "0.0.7",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

2
src-tauri/Cargo.lock generated
View file

@ -1581,7 +1581,7 @@ dependencies = [
[[package]] [[package]]
name = "has" name = "has"
version = "0.0.5" version = "0.0.6"
dependencies = [ dependencies = [
"base64 0.22.1", "base64 0.22.1",
"bcrypt", "bcrypt",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "has" name = "has"
version = "0.0.6" version = "0.0.7"
description = "has" description = "has"
authors = ["autli"] authors = ["autli"]
edition = "2024" edition = "2024"

View file

@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "has", "productName": "has",
"version": "0.0.6", "version": "0.0.7",
"identifier": "com.has.tauri-app", "identifier": "com.has.tauri-app",
"build": { "build": {
"beforeDevCommand": "npm run dev", "beforeDevCommand": "npm run dev",

View file

@ -769,6 +769,37 @@
color: #ffffff; color: #ffffff;
} }
/* AdBlock Guard pill */
.has-cinema-player-hud-btn.adblock-pill {
font-size: 12px;
padding: 7px 13px;
border-radius: 9999px;
background: rgba(16, 185, 129, 0.12);
border: 1px solid rgba(16, 185, 129, 0.35);
color: #a7f3d0;
transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}
.has-cinema-player-hud-btn.adblock-pill:hover {
background: rgba(16, 185, 129, 0.25);
border-color: #34d399;
color: #ffffff;
}
.has-cinema-player-hud-btn.adblock-pill.active {
background: linear-gradient(135deg, rgba(16, 185, 129, 0.35), rgba(5, 150, 105, 0.5));
border-color: #10b981;
color: #ffffff;
box-shadow: 0 0 16px rgba(16, 185, 129, 0.55);
}
.has-cinema-player-hud-btn.adblock-pill:focus-visible,
.has-cinema-player-hud-btn.adblock-pill[data-tv-focused="true"] {
outline: 3px solid #10b981 !important;
box-shadow: 0 0 25px rgba(16, 185, 129, 0.85) !important;
transform: scale(1.05);
}
/* Server selector pills in top HUD */ /* Server selector pills in top HUD */
.has-cinema-player-hud-servers { .has-cinema-player-hud-servers {
display: flex; display: flex;

View file

@ -618,6 +618,7 @@ export default function Cinema({
const [currentKpId, setCurrentKpId] = useState<number | null>(null); const [currentKpId, setCurrentKpId] = useState<number | null>(null);
const [currentImdbId, setCurrentImdbId] = useState<string | null>(null); const [currentImdbId, setCurrentImdbId] = useState<string | null>(null);
const [currentAllohaUrl, setCurrentAllohaUrl] = useState<string | null>(null); const [currentAllohaUrl, setCurrentAllohaUrl] = useState<string | null>(null);
const [isAdBlockEnabled, setIsAdBlockEnabled] = useState<boolean>(true);
const [isFullscreen, setIsFullscreen] = useState(false); const [isFullscreen, setIsFullscreen] = useState(false);
const [kodikResults, setKodikResults] = useState<KodikItem[]>([]); const [kodikResults, setKodikResults] = useState<KodikItem[]>([]);
const [selectedKodikLink, setSelectedKodikLink] = useState<string | null>(null); const [selectedKodikLink, setSelectedKodikLink] = useState<string | null>(null);
@ -3728,6 +3729,27 @@ export default function Cinema({
🔄 Сменить источник 🔄 Сменить источник
</button> </button>
{/* AdBlock Guard toggle */}
<button
type="button"
className={`has-cinema-player-hud-btn adblock-pill ${isAdBlockEnabled ? "active" : ""}`}
onClick={() => {
setIsAdBlockEnabled((prev) => !prev);
showTvToast(
!isAdBlockEnabled
? "🛡️ Блокировка рекламы и казино ВКЛ"
: "⚠️ Блокировка рекламы ВЫКЛ",
"🛡️",
1800
);
resetHudTimer();
}}
title={isAdBlockEnabled ? "Блокировщик рекламы активен (всплывающие окна и казино заблокированы)" : "Включить блокировку рекламы"}
data-tv-focusable="true"
>
🛡️ {isAdBlockEnabled ? "Без рекламы" : "Реклама: Вкл"}
</button>
{/* Single Settings button (Contains voiceover studios & mirrors) */} {/* Single Settings button (Contains voiceover studios & mirrors) */}
<button <button
type="button" type="button"
@ -3842,10 +3864,15 @@ export default function Cinema({
) )
) : playerMode === "balancer" ? ( ) : playerMode === "balancer" ? (
<iframe <iframe
key={`${selectedMirror}-${balancerEmbedUrl}`} key={`${selectedMirror}-${balancerEmbedUrl}-${isAdBlockEnabled}`}
src={balancerEmbedUrl} src={balancerEmbedUrl}
title={(playingMedia || selectedMedia).title} title={(playingMedia || selectedMedia).title}
className="has-cinema-iframe-elem" className="has-cinema-iframe-elem"
sandbox={
isAdBlockEnabled
? "allow-scripts allow-same-origin allow-forms allow-presentation"
: undefined
}
allow="autoplay *; fullscreen *; encrypted-media *; picture-in-picture *; clipboard-write *" allow="autoplay *; fullscreen *; encrypted-media *; picture-in-picture *; clipboard-write *"
referrerPolicy="no-referrer-when-downgrade" referrerPolicy="no-referrer-when-downgrade"
allowFullScreen allowFullScreen
@ -4050,6 +4077,31 @@ export default function Cinema({
</div> </div>
</div> </div>
{/* AdBlock Guard Section */}
<div className="has-cinema-drawer-section">
<h4 className="has-cinema-drawer-section-title">
🛡️ Блокировка рекламы и всплывающих окон
</h4>
<button
type="button"
className={`has-cinema-drawer-option-btn ${isAdBlockEnabled ? "active" : ""}`}
onClick={() => {
setIsAdBlockEnabled((prev) => !prev);
showTvToast(!isAdBlockEnabled ? "🛡️ Защита от рекламы ВКЛ" : "⚠️ Защита от рекламы ВЫКЛ", "🛡️", 2000);
}}
data-tv-focusable="true"
>
<span className="option-name">
{isAdBlockEnabled ? "🛡️ Блокировщик рекламы: ВКЛЮЧЕН" : "⚠️ Блокировщик рекламы: ВЫКЛЮЧЕН"}
</span>
<span className="option-desc">
{isAdBlockEnabled
? "Защита активна: блокируются всплывающие окна, казино 1xBet, редиректы и баннеры"
: "Защита отключена: разрешены все всплывающие окна балансера"}
</span>
</button>
</div>
{/* External Tools */} {/* External Tools */}
<div className="has-cinema-drawer-section actions"> <div className="has-cinema-drawer-section actions">
<button <button