@hopeplayer/core 1.0.15 → 1.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -14
- package/dist/HopePlayerElement.d.ts +37 -0
- package/dist/HopePlayerElement.d.ts.map +1 -1
- package/dist/chunks/adTriggers-4SueRFgK.js +415 -0
- package/dist/chunks/adTriggers-4SueRFgK.js.map +1 -0
- package/dist/chunks/{index-BCMVXNL0.js → ads-DPL7m9PV.js} +135 -158
- package/dist/chunks/ads-DPL7m9PV.js.map +1 -0
- package/dist/chunks/{index-BeJNpAyx.js → audio-LkYgd5Wq.js} +7 -7
- package/dist/chunks/audio-LkYgd5Wq.js.map +1 -0
- package/dist/chunks/{ScratchSound-0XKHUcJK.js → audioScratchSound-7XkwCCDm.js} +1 -1
- package/dist/chunks/audioScratchSound-7XkwCCDm.js.map +1 -0
- package/dist/chunks/cast-DCAT2agI.js +387 -0
- package/dist/chunks/cast-DCAT2agI.js.map +1 -0
- package/dist/chunks/{index-rENB3n9O.js → countdownScreen-CI-u6jjA.js} +1 -1
- package/dist/chunks/countdownScreen-CI-u6jjA.js.map +1 -0
- package/dist/chunks/{index-Q8FMOHj0.js → dai-B9Tth1Iv.js} +1 -1
- package/dist/chunks/dai-B9Tth1Iv.js.map +1 -0
- package/dist/chunks/{index-DCXX1ZJG.js → debugPanel-Bnc_7GOn.js} +1 -1
- package/dist/chunks/debugPanel-Bnc_7GOn.js.map +1 -0
- package/dist/chunks/{index-DXWK4EFa.js → dubbing-kNMPpyHl.js} +1 -1
- package/dist/chunks/dubbing-kNMPpyHl.js.map +1 -0
- package/dist/chunks/{index-BBmuCtKu.js → geoChecker-BRtvHwI-.js} +1 -1
- package/dist/chunks/geoChecker-BRtvHwI-.js.map +1 -0
- package/dist/chunks/{index-Ca8hocby.js → gesture-BzPCgi87.js} +1 -1
- package/dist/chunks/gesture-BzPCgi87.js.map +1 -0
- package/dist/chunks/gpt-CGXHTG_H.js +18 -0
- package/dist/chunks/gpt-CGXHTG_H.js.map +1 -0
- package/dist/chunks/{index-3QALpwsf.js → inViewAutoplay-CRJe7GA4.js} +1 -1
- package/dist/chunks/inViewAutoplay-CRJe7GA4.js.map +1 -0
- package/dist/chunks/{index-7IBf8Y-R.js → liveWallClock-ChUTtzLD.js} +1 -1
- package/dist/chunks/liveWallClock-ChUTtzLD.js.map +1 -0
- package/dist/chunks/{index-f0vSgRIK.js → loopSection-CvF4l5uf.js} +1 -1
- package/dist/chunks/loopSection-CvF4l5uf.js.map +1 -0
- package/dist/chunks/{index-DRlQC-ev.js → markers-DE4O8xbw.js} +2 -2
- package/dist/chunks/markers-DE4O8xbw.js.map +1 -0
- package/dist/chunks/{index-CaMVTgh0.js → pauseAd-BQQe21X4.js} +55 -68
- package/dist/chunks/pauseAd-BQQe21X4.js.map +1 -0
- package/dist/chunks/{index-w7pACyTw.js → player-C886oKP-.js} +726 -391
- package/dist/chunks/player-C886oKP-.js.map +1 -0
- package/dist/chunks/{index-DpUZXNJS.js → playlist-CI3mRZjo.js} +2 -2
- package/dist/chunks/playlist-CI3mRZjo.js.map +1 -0
- package/dist/chunks/{VideoPrebid-CpckFzSq.js → prebid-CRY3i2OT.js} +1 -1
- package/dist/chunks/prebid-CRY3i2OT.js.map +1 -0
- package/dist/chunks/{index-DT8-oMPm.js → qrResume-BNy8XCp_.js} +1 -1
- package/dist/chunks/qrResume-BNy8XCp_.js.map +1 -0
- package/dist/chunks/redirectScreen-CJ3q9OX4.js +208 -0
- package/dist/chunks/redirectScreen-CJ3q9OX4.js.map +1 -0
- package/dist/chunks/rewardedUnlock-EyGMB9PK.js +264 -0
- package/dist/chunks/rewardedUnlock-EyGMB9PK.js.map +1 -0
- package/dist/chunks/{index-BOoNcKeR.js → segments-C2HKU6XK.js} +2 -2
- package/dist/chunks/segments-C2HKU6XK.js.map +1 -0
- package/dist/chunks/{index-D5P-LWbg.js → sponsorship-DyFwGmEb.js} +20 -20
- package/dist/chunks/sponsorship-DyFwGmEb.js.map +1 -0
- package/dist/chunks/{index-BvoB2O1p.js → spriteThumbnails-D0NQ5CCp.js} +2 -2
- package/dist/chunks/spriteThumbnails-D0NQ5CCp.js.map +1 -0
- package/dist/chunks/{index-DGtpFgHV.js → statsPanel-DSClIwA3.js} +1 -1
- package/dist/chunks/statsPanel-DSClIwA3.js.map +1 -0
- package/dist/chunks/{index-CDDke5rz.js → sticky-D_eLCNFk.js} +1 -1
- package/dist/chunks/sticky-D_eLCNFk.js.map +1 -0
- package/dist/chunks/{index-ClQg_X1N.js → story-D5Got6-6.js} +2 -2
- package/dist/chunks/{index-ClQg_X1N.js.map → story-D5Got6-6.js.map} +1 -1
- package/dist/chunks/{index-C5oGMHF_.js → tapGestures-DrC42DiI.js} +1 -1
- package/dist/chunks/tapGestures-DrC42DiI.js.map +1 -0
- package/dist/hls/SourceManager.d.ts +8 -0
- package/dist/hls/SourceManager.d.ts.map +1 -1
- package/dist/hls/sourceGroups.d.ts +19 -0
- package/dist/hls/sourceGroups.d.ts.map +1 -0
- package/dist/hope-player.js +1 -1
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/types.d.ts +12 -0
- package/dist/i18n/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/plugins/ad-triggers/AdTriggers.d.ts +99 -0
- package/dist/plugins/ad-triggers/AdTriggers.d.ts.map +1 -0
- package/dist/plugins/ad-triggers/index.d.ts +7 -0
- package/dist/plugins/ad-triggers/index.d.ts.map +1 -0
- package/dist/plugins/ads/AdsController.d.ts +8 -0
- package/dist/plugins/ads/AdsController.d.ts.map +1 -1
- package/dist/plugins/ads/generateVastUrl.d.ts +10 -0
- package/dist/plugins/ads/generateVastUrl.d.ts.map +1 -1
- package/dist/plugins/cast/CastController.d.ts +107 -0
- package/dist/plugins/cast/CastController.d.ts.map +1 -0
- package/dist/plugins/cast/RemoteMediaProxy.d.ts +41 -0
- package/dist/plugins/cast/RemoteMediaProxy.d.ts.map +1 -0
- package/dist/plugins/cast/castSdk.d.ts +160 -0
- package/dist/plugins/cast/castSdk.d.ts.map +1 -0
- package/dist/plugins/cast/index.d.ts +7 -0
- package/dist/plugins/cast/index.d.ts.map +1 -0
- package/dist/plugins/pause-ad/loadGpt.d.ts +2 -0
- package/dist/plugins/pause-ad/loadGpt.d.ts.map +1 -1
- package/dist/plugins/redirect-screen/RedirectScreen.d.ts +26 -3
- package/dist/plugins/redirect-screen/RedirectScreen.d.ts.map +1 -1
- package/dist/plugins/rewarded/RewardedUnlock.d.ts +2 -5
- package/dist/plugins/rewarded/RewardedUnlock.d.ts.map +1 -1
- package/dist/plugins/rewarded/gpt.d.ts +6 -2
- package/dist/plugins/rewarded/gpt.d.ts.map +1 -1
- package/dist/plugins/sponsorship/SponsorshipLayer.d.ts.map +1 -1
- package/dist/types/index.d.ts +308 -3
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +3 -1
- package/dist/chunks/ScratchSound-0XKHUcJK.js.map +0 -1
- package/dist/chunks/VideoPrebid-CpckFzSq.js.map +0 -1
- package/dist/chunks/index-3QALpwsf.js.map +0 -1
- package/dist/chunks/index-7IBf8Y-R.js.map +0 -1
- package/dist/chunks/index-BBmuCtKu.js.map +0 -1
- package/dist/chunks/index-BCMVXNL0.js.map +0 -1
- package/dist/chunks/index-BOoNcKeR.js.map +0 -1
- package/dist/chunks/index-BeJNpAyx.js.map +0 -1
- package/dist/chunks/index-BvoB2O1p.js.map +0 -1
- package/dist/chunks/index-C5oGMHF_.js.map +0 -1
- package/dist/chunks/index-CDDke5rz.js.map +0 -1
- package/dist/chunks/index-Ca8hocby.js.map +0 -1
- package/dist/chunks/index-CaMVTgh0.js.map +0 -1
- package/dist/chunks/index-D5P-LWbg.js.map +0 -1
- package/dist/chunks/index-D6r-BGAV.js +0 -77
- package/dist/chunks/index-D6r-BGAV.js.map +0 -1
- package/dist/chunks/index-DCXX1ZJG.js.map +0 -1
- package/dist/chunks/index-DGtpFgHV.js.map +0 -1
- package/dist/chunks/index-DRlQC-ev.js.map +0 -1
- package/dist/chunks/index-DT8-oMPm.js.map +0 -1
- package/dist/chunks/index-DXWK4EFa.js.map +0 -1
- package/dist/chunks/index-DpUZXNJS.js.map +0 -1
- package/dist/chunks/index-Q8FMOHj0.js.map +0 -1
- package/dist/chunks/index-TkG8IO6q.js +0 -239
- package/dist/chunks/index-TkG8IO6q.js.map +0 -1
- package/dist/chunks/index-f0vSgRIK.js.map +0 -1
- package/dist/chunks/index-rENB3n9O.js.map +0 -1
- package/dist/chunks/index-w7pACyTw.js.map +0 -1
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
var y = Object.defineProperty;
|
|
2
|
-
var x = (n, t, e) => t in n ? y(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
|
|
3
|
-
var d = (n, t, e) => x(n, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
-
import { L as w } from "./index-w7pACyTw.js";
|
|
5
|
-
const v = "https://securepagead2.googlesyndication.com/tag/js/gpt.js";
|
|
6
|
-
let f = null;
|
|
7
|
-
function b() {
|
|
8
|
-
var t;
|
|
9
|
-
const n = window;
|
|
10
|
-
return n.googletag ?? (n.googletag = { cmd: [] }), (t = n.googletag).cmd ?? (t.cmd = []), n.googletag.apiReady || document.querySelector(`script[src="${v}"]`) ? Promise.resolve() : (f ?? (f = new Promise((e, o) => {
|
|
11
|
-
const s = document.createElement("script");
|
|
12
|
-
s.async = !0, s.src = v, s.crossOrigin = "anonymous", s.onload = () => e(), s.onerror = () => {
|
|
13
|
-
f = null, o(new Error("gpt.js could not be loaded (ad blocker / network)"));
|
|
14
|
-
}, document.head.appendChild(s);
|
|
15
|
-
})), f);
|
|
16
|
-
}
|
|
17
|
-
async function k(n, t) {
|
|
18
|
-
await b();
|
|
19
|
-
const e = window.googletag;
|
|
20
|
-
return new Promise((o) => {
|
|
21
|
-
e.cmd.push(() => {
|
|
22
|
-
const s = e.defineOutOfPageSlot(n, e.enums.OutOfPageFormat.REWARDED);
|
|
23
|
-
if (!s) {
|
|
24
|
-
o("nofill");
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
s.addService(e.pubads());
|
|
28
|
-
const a = e.pubads();
|
|
29
|
-
let m = !1, c = !1;
|
|
30
|
-
const h = [], u = (i, l) => {
|
|
31
|
-
h.push([i, l]), a.addEventListener(i, l);
|
|
32
|
-
}, g = (i) => {
|
|
33
|
-
var l;
|
|
34
|
-
if (!c) {
|
|
35
|
-
c = !0, clearTimeout(r);
|
|
36
|
-
for (const [p, E] of h) (l = a.removeEventListener) == null || l.call(a, p, E);
|
|
37
|
-
try {
|
|
38
|
-
e.destroySlots([s]);
|
|
39
|
-
} catch {
|
|
40
|
-
}
|
|
41
|
-
o(i);
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
u("rewardedSlotReady", (i) => {
|
|
45
|
-
var l;
|
|
46
|
-
i.slot === s && (clearTimeout(r), (l = i.makeRewardedVisible) == null || l.call(i));
|
|
47
|
-
}), u("rewardedSlotGranted", (i) => {
|
|
48
|
-
i.slot === s && (m = !0);
|
|
49
|
-
}), u("rewardedSlotClosed", (i) => {
|
|
50
|
-
i.slot === s && g(m ? "granted" : "closed");
|
|
51
|
-
}), u("slotRenderEnded", (i) => {
|
|
52
|
-
i.slot === s && i.isEmpty && g("nofill");
|
|
53
|
-
});
|
|
54
|
-
const r = setTimeout(() => g("nofill"), t);
|
|
55
|
-
e.enableServices(), e.display(s);
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
const C = 480, T = "hope-rewarded-unlock", L = 8e3, S = 2600;
|
|
60
|
-
class D {
|
|
61
|
-
constructor(t, e) {
|
|
62
|
-
d(this, "options");
|
|
63
|
-
d(this, "button");
|
|
64
|
-
d(this, "dialog", null);
|
|
65
|
-
d(this, "toast", null);
|
|
66
|
-
d(this, "toastTimer", null);
|
|
67
|
-
d(this, "phase", "idle");
|
|
68
|
-
/** 'video' modunda kilidin açık olduğu içerik (kaynak listesi — kalite dosyası değil). */
|
|
69
|
-
d(this, "videoUnlockedKey", null);
|
|
70
|
-
d(this, "lastKey", "");
|
|
71
|
-
/** Kaynak değişti: 'video' modunda kilit yeniden kapanır; süreli kilit dolduysa menüler güncellenir. */
|
|
72
|
-
d(this, "onSourceChange", () => {
|
|
73
|
-
const t = this.ctx.contentKey();
|
|
74
|
-
t !== this.lastKey && (this.lastKey = t, this.onQualitiesChanged());
|
|
75
|
-
});
|
|
76
|
-
d(this, "resumeAfterDialog", !1);
|
|
77
|
-
this.ctx = t, this.options = e;
|
|
78
|
-
const o = document.createElement("button");
|
|
79
|
-
o.type = "button", o.className = "hp-rw-button", o.setAttribute("part", "rewarded-button"), o.addEventListener("click", (s) => {
|
|
80
|
-
s.stopPropagation(), this.requestUnlock();
|
|
81
|
-
}), o.addEventListener("pointerdown", (s) => s.stopPropagation()), t.chromeEl.appendChild(o), this.button = o, t.videoEl.addEventListener("loadstart", this.onSourceChange), this.refreshLabels(), this.onQualitiesChanged();
|
|
82
|
-
}
|
|
83
|
-
update(t) {
|
|
84
|
-
const e = this.unlocked;
|
|
85
|
-
this.options = t, e !== this.unlocked && this.ctx.onLockChange(!1), this.onQualitiesChanged();
|
|
86
|
-
}
|
|
87
|
-
// ── Kilit durumu ────────────────────────────────────────────────────
|
|
88
|
-
get maxFreeHeight() {
|
|
89
|
-
const t = this.options.maxFreeHeight;
|
|
90
|
-
return typeof t == "number" && t > 0 ? t : C;
|
|
91
|
-
}
|
|
92
|
-
get storageKey() {
|
|
93
|
-
return this.options.storageKey || T;
|
|
94
|
-
}
|
|
95
|
-
get unlockFor() {
|
|
96
|
-
const t = this.options.unlockFor;
|
|
97
|
-
return typeof t == "number" && t > 0 ? t : t === "video" ? "video" : "session";
|
|
98
|
-
}
|
|
99
|
-
get unlocked() {
|
|
100
|
-
const t = this.unlockFor;
|
|
101
|
-
if (t === "video") return !!this.videoUnlockedKey && this.videoUnlockedKey === this.ctx.contentKey();
|
|
102
|
-
try {
|
|
103
|
-
if (t === "session") return sessionStorage.getItem(this.storageKey) === "1";
|
|
104
|
-
const e = Number(localStorage.getItem(this.storageKey));
|
|
105
|
-
return Number.isFinite(e) && e > Date.now();
|
|
106
|
-
} catch {
|
|
107
|
-
return !1;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
grant() {
|
|
111
|
-
const t = this.unlockFor;
|
|
112
|
-
t === "video" && (this.videoUnlockedKey = this.ctx.contentKey());
|
|
113
|
-
try {
|
|
114
|
-
t === "session" ? sessionStorage.setItem(this.storageKey, "1") : typeof t == "number" && localStorage.setItem(this.storageKey, String(Date.now() + t * 6e4));
|
|
115
|
-
} catch {
|
|
116
|
-
this.videoUnlockedKey = this.ctx.contentKey();
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
/** Player için: bu yükseklikteki kalite kilitli mi? */
|
|
120
|
-
isLocked(t) {
|
|
121
|
-
return this.unlocked ? !1 : t !== null && t > this.maxFreeHeight;
|
|
122
|
-
}
|
|
123
|
-
/** Player kalite listesi değişince çağırır: buton yalnızca kilitli kalite varken görünür. */
|
|
124
|
-
onQualitiesChanged() {
|
|
125
|
-
const t = this.ctx.lockedQualityLabel(), e = this.options.button !== !1 && !!t && !this.unlocked;
|
|
126
|
-
this.button.hidden = !e, e && (this.button.innerHTML = `${w}<span>${F(this.fill(this.ctx.i18n.rewardedButton, t))}</span>`);
|
|
127
|
-
}
|
|
128
|
-
// ── Akış ────────────────────────────────────────────────────────────
|
|
129
|
-
/** Kilitli kaliteye ya da butona dokunuldu: onay penceresi. */
|
|
130
|
-
requestUnlock() {
|
|
131
|
-
if (this.unlocked || this.phase !== "idle") return;
|
|
132
|
-
const t = this.ctx.lockedQualityLabel() ?? "HD";
|
|
133
|
-
this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:rewardedprompt", { detail: { quality: t } })), this.showDialog("prompt", t);
|
|
134
|
-
}
|
|
135
|
-
async watch(t) {
|
|
136
|
-
const e = this.ctx.videoEl, o = !e.paused;
|
|
137
|
-
e.pause(), this.ctx.exitFullscreen(), this.showDialog("loading", t);
|
|
138
|
-
let s;
|
|
139
|
-
try {
|
|
140
|
-
s = await this.runProvider();
|
|
141
|
-
} catch (a) {
|
|
142
|
-
this.ctx.log({ message: `Rewarded ad failed: ${String(a)}` }), s = "nofill";
|
|
143
|
-
}
|
|
144
|
-
if (s === "nofill" && this.options.grantOnNoFill && (this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:rewardednofill", { detail: { granted: !0 } })), s = "granted"), s === "granted") {
|
|
145
|
-
this.grant(), this.closeDialog(), this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:rewardedgranted", { detail: { quality: t } })), this.ctx.onLockChange(!0), this.onQualitiesChanged(), this.showToast(this.fill(this.ctx.i18n.rewardedUnlocked, t)), o && this.ctx.play();
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
if (s === "nofill") {
|
|
149
|
-
this.ctx.log({ message: "Rewarded ad: no ad available (no fill / unsupported page / timeout)" }), this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:rewardednofill", { detail: { granted: !1 } })), this.showDialog("nofill", t), this.resumeAfterDialog = o;
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
this.closeDialog(), this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:rewardedclosed", { detail: { granted: !1 } })), o && this.ctx.play();
|
|
153
|
-
}
|
|
154
|
-
async runProvider() {
|
|
155
|
-
const t = this.options.provider;
|
|
156
|
-
if ((t == null ? void 0 : t.type) === "gpt") return k(t.adUnitPath, t.timeoutMs ?? L);
|
|
157
|
-
if ((t == null ? void 0 : t.type) === "custom") {
|
|
158
|
-
const e = await t.show();
|
|
159
|
-
return e === !0 ? "granted" : e === !1 ? "closed" : e;
|
|
160
|
-
}
|
|
161
|
-
throw new Error("rewardedUnlock.provider is missing");
|
|
162
|
-
}
|
|
163
|
-
// ── Arayüz ─────────────────────────────────────────────────────────
|
|
164
|
-
fill(t, e) {
|
|
165
|
-
const o = this.unlockFor, s = this.ctx.i18n, a = o === "video" ? s.rewardedForVideo : o === "session" ? s.rewardedForSession : s.rewardedForMinutes.replace("{n}", String(o));
|
|
166
|
-
return t.replace("{quality}", e).replace("{duration}", a);
|
|
167
|
-
}
|
|
168
|
-
showDialog(t, e) {
|
|
169
|
-
this.phase = t;
|
|
170
|
-
const o = this.ctx.i18n;
|
|
171
|
-
if (!this.dialog) {
|
|
172
|
-
const r = document.createElement("div");
|
|
173
|
-
r.className = "hp-rw-dialog", r.setAttribute("part", "rewarded-dialog"), r.setAttribute("role", "dialog"), r.setAttribute("aria-modal", "true");
|
|
174
|
-
for (const i of ["click", "pointerdown", "dblclick"]) r.addEventListener(i, (l) => l.stopPropagation());
|
|
175
|
-
r.addEventListener("keydown", (i) => {
|
|
176
|
-
i.stopPropagation(), i.key === "Escape" && this.phase !== "loading" && this.dismiss();
|
|
177
|
-
}), this.ctx.overlayEl.appendChild(r), this.dialog = r;
|
|
178
|
-
}
|
|
179
|
-
const s = this.dialog;
|
|
180
|
-
s.setAttribute("data-phase", t), s.innerHTML = "";
|
|
181
|
-
const a = document.createElement("div");
|
|
182
|
-
a.className = "hp-rw-card";
|
|
183
|
-
const m = document.createElement("div");
|
|
184
|
-
m.className = "hp-rw-icon", m.innerHTML = w;
|
|
185
|
-
const c = document.createElement("div");
|
|
186
|
-
c.className = "hp-rw-title";
|
|
187
|
-
const h = document.createElement("div");
|
|
188
|
-
h.className = "hp-rw-text";
|
|
189
|
-
const u = document.createElement("div");
|
|
190
|
-
u.className = "hp-rw-actions", a.append(m, c, h, u), s.appendChild(a);
|
|
191
|
-
const g = (r, i, l) => {
|
|
192
|
-
const p = document.createElement("button");
|
|
193
|
-
return p.type = "button", p.className = i ? "hp-rw-btn hp-rw-btn-primary" : "hp-rw-btn", p.textContent = r, p.addEventListener("click", l), u.appendChild(p), p;
|
|
194
|
-
};
|
|
195
|
-
if (t === "prompt")
|
|
196
|
-
c.textContent = this.fill(o.rewardedTitle, e), h.textContent = this.fill(o.rewardedBody, e), g(o.rewardedDecline, !1, () => this.dismiss()), g(o.rewardedWatch, !0, () => void this.watch(e)).focus();
|
|
197
|
-
else if (t === "loading") {
|
|
198
|
-
c.textContent = o.rewardedLoading;
|
|
199
|
-
const r = document.createElement("div");
|
|
200
|
-
r.className = "hp-rw-spinner", h.appendChild(r);
|
|
201
|
-
} else
|
|
202
|
-
c.textContent = this.fill(o.rewardedTitle, e), h.textContent = o.rewardedNoFill, g(o.rewardedOk, !0, () => this.dismiss()).focus();
|
|
203
|
-
}
|
|
204
|
-
dismiss() {
|
|
205
|
-
const t = this.phase === "nofill";
|
|
206
|
-
this.closeDialog(), t || this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:rewardedclosed", { detail: { granted: !1, declined: !0 } })), this.resumeAfterDialog && this.ctx.play(), this.resumeAfterDialog = !1;
|
|
207
|
-
}
|
|
208
|
-
closeDialog() {
|
|
209
|
-
var t;
|
|
210
|
-
this.phase = "idle", (t = this.dialog) == null || t.remove(), this.dialog = null;
|
|
211
|
-
}
|
|
212
|
-
showToast(t) {
|
|
213
|
-
var o;
|
|
214
|
-
this.toastTimer && clearTimeout(this.toastTimer), (o = this.toast) == null || o.remove();
|
|
215
|
-
const e = document.createElement("div");
|
|
216
|
-
e.className = "hp-rw-toast", e.setAttribute("part", "rewarded-toast"), e.setAttribute("role", "status"), e.textContent = t, this.ctx.overlayEl.appendChild(e), this.toast = e, this.toastTimer = setTimeout(() => {
|
|
217
|
-
var s;
|
|
218
|
-
(s = this.toast) == null || s.remove(), this.toast = null;
|
|
219
|
-
}, S);
|
|
220
|
-
}
|
|
221
|
-
refreshLabels() {
|
|
222
|
-
this.button.setAttribute("aria-label", this.ctx.i18n.rewardedButton.replace("{quality}", "HD")), this.onQualitiesChanged();
|
|
223
|
-
}
|
|
224
|
-
destroy() {
|
|
225
|
-
var t;
|
|
226
|
-
this.ctx.videoEl.removeEventListener("loadstart", this.onSourceChange), this.toastTimer && clearTimeout(this.toastTimer), (t = this.toast) == null || t.remove(), this.closeDialog(), this.button.remove();
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
function F(n) {
|
|
230
|
-
return n.replace(/[&<>"']/g, (t) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[t]);
|
|
231
|
-
}
|
|
232
|
-
function U(n, t) {
|
|
233
|
-
return new D(n, t);
|
|
234
|
-
}
|
|
235
|
-
export {
|
|
236
|
-
D as RewardedUnlock,
|
|
237
|
-
U as installRewardedUnlock
|
|
238
|
-
};
|
|
239
|
-
//# sourceMappingURL=index-TkG8IO6q.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-TkG8IO6q.js","sources":["../../src/plugins/rewarded/gpt.ts","../../src/plugins/rewarded/RewardedUnlock.ts","../../src/plugins/rewarded/index.ts"],"sourcesContent":["import type { RewardedResult } from '../../types';\n\n/** Google Publisher Tag'in kullanılan yüzeyi (minimal tipler). */\ninterface GptSlot {\n addService(service: unknown): GptSlot;\n}\ninterface GptEvent {\n slot: GptSlot;\n isEmpty?: boolean;\n makeRewardedVisible?: () => boolean | void;\n}\ninterface GptPubAds {\n addEventListener(type: string, listener: (e: GptEvent) => void): void;\n removeEventListener?(type: string, listener: (e: GptEvent) => void): void;\n}\ninterface GoogleTag {\n cmd: Array<() => void> | { push(fn: () => void): void };\n apiReady?: boolean;\n enums: { OutOfPageFormat: { REWARDED: unknown } };\n pubads(): GptPubAds;\n defineOutOfPageSlot(path: string, format: unknown): GptSlot | null;\n enableServices(): void;\n display(slot: GptSlot): void;\n destroySlots(slots: GptSlot[]): void;\n}\n\nconst GPT_SRC = 'https://securepagead2.googlesyndication.com/tag/js/gpt.js';\nlet gptLoading: Promise<void> | null = null;\n\n/** GPT sayfada yoksa yükler (sayfa zaten GPT kullanıyorsa onu paylaşır). */\nfunction loadGpt(): Promise<void> {\n const w = window as unknown as { googletag?: Partial<GoogleTag> };\n w.googletag ??= { cmd: [] } as Partial<GoogleTag>;\n w.googletag.cmd ??= [];\n if (w.googletag.apiReady || document.querySelector(`script[src=\"${GPT_SRC}\"]`)) return Promise.resolve();\n gptLoading ??= new Promise<void>((resolve, reject) => {\n const s = document.createElement('script');\n s.async = true;\n s.src = GPT_SRC;\n s.crossOrigin = 'anonymous';\n s.onload = () => resolve();\n s.onerror = () => {\n gptLoading = null;\n reject(new Error('gpt.js could not be loaded (ad blocker / network)'));\n };\n document.head.appendChild(s);\n });\n return gptLoading;\n}\n\n/**\n * GPT web rewarded akışı (Google'ın örneğiyle aynı): slot tanımla → display → `rewardedSlotReady` gelince göster →\n * `rewardedSlotGranted` ödül → `rewardedSlotClosed` kapandı → slotu yok et. Kullanıcı onayı bu fonksiyon çağrılmadan\n * ÖNCE alınmış olmalı (player'ın onay penceresi). `rewardedSlotReady` gelmezse (reklam yok) zaman aşımında 'nofill'.\n */\nexport async function showGptRewarded(adUnitPath: string, timeoutMs: number): Promise<RewardedResult> {\n await loadGpt();\n const googletag = (window as unknown as { googletag: GoogleTag }).googletag;\n return new Promise<RewardedResult>((resolve) => {\n googletag.cmd.push(() => {\n const slot = googletag.defineOutOfPageSlot(adUnitPath, googletag.enums.OutOfPageFormat.REWARDED);\n // null: sayfa formatı desteklemiyor (ör. mobil uyumlu viewport yok) — reklam yok sayılır.\n if (!slot) {\n resolve('nofill');\n return;\n }\n slot.addService(googletag.pubads());\n const pubads = googletag.pubads();\n let granted = false;\n let done = false;\n const listeners: Array<[string, (e: GptEvent) => void]> = [];\n const on = (type: string, fn: (e: GptEvent) => void): void => {\n listeners.push([type, fn]);\n pubads.addEventListener(type, fn);\n };\n const finish = (result: RewardedResult): void => {\n if (done) return;\n done = true;\n clearTimeout(timer);\n for (const [type, fn] of listeners) pubads.removeEventListener?.(type, fn);\n try {\n googletag.destroySlots([slot]);\n } catch {\n /* zaten yok edildi */\n }\n resolve(result);\n };\n on('rewardedSlotReady', (e) => {\n if (e.slot !== slot) return;\n clearTimeout(timer);\n e.makeRewardedVisible?.();\n });\n on('rewardedSlotGranted', (e) => {\n if (e.slot === slot) granted = true;\n });\n on('rewardedSlotClosed', (e) => {\n if (e.slot === slot) finish(granted ? 'granted' : 'closed');\n });\n on('slotRenderEnded', (e) => {\n if (e.slot === slot && e.isEmpty) finish('nofill');\n });\n const timer = setTimeout(() => finish('nofill'), timeoutMs);\n googletag.enableServices();\n googletag.display(slot);\n });\n });\n}\n","import type { RewardedResult, RewardedUnlockOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { LOCK_SVG } from '../../controls/SettingsMenu';\nimport { showGptRewarded } from './gpt';\n\nexport interface RewardedUnlockContext {\n hostEl: HTMLElement;\n videoEl: HTMLVideoElement;\n /** Onay penceresinin ekleneceği alan (video alanı). */\n overlayEl: HTMLElement;\n /** Buton kontrollerle birlikte görünüp gizlensin diye kontrol katmanına eklenir. */\n chromeEl: HTMLElement;\n i18n: HopeLocaleStrings;\n log(entry: { message: string; details?: Record<string, string | number | boolean | undefined> }): void;\n play(): void;\n exitFullscreen(): void;\n /** Kilitli kalitelerin en yükseği (ör. \"1080p\") — yoksa null (buton gizlenir). */\n lockedQualityLabel(): string | null;\n /** İçeriğin kimliği (kaynak listesi) — kalite değişince değişmez, başka video yüklenince değişir. */\n contentKey(): string;\n /** Kilit açıldı / geri geldi: player menüleri yeniden kurar; `upgrade` → en iyi kaliteye geç. */\n onLockChange(upgrade: boolean): void;\n}\n\nconst DEFAULT_MAX_FREE_HEIGHT = 480;\nconst DEFAULT_STORAGE_KEY = 'hope-rewarded-unlock';\nconst DEFAULT_GPT_TIMEOUT_MS = 8000;\nconst TOAST_MS = 2600;\n\ntype Phase = 'idle' | 'prompt' | 'loading' | 'nofill';\n\n/**\n * Ödüllü reklamla kalite kilidi. Akış (Google'ın ödüllü reklam politikasına göre): kullanıcı kilitli bir kaliteye ya da\n * \"Yüksek kaliteyi aç\" butonuna dokunur → ödülü açıkça yazan onay penceresi → yalnızca \"Reklamı izle\" ile reklam istenir\n * → ödül verildiyse kilit açılır. Vazgeçmek videoyu izlemeyi engellemez (düşük kalitede devam eder).\n */\nexport class RewardedUnlock {\n private options: RewardedUnlockOptions;\n private readonly button: HTMLButtonElement;\n private dialog: HTMLDivElement | null = null;\n private toast: HTMLDivElement | null = null;\n private toastTimer: ReturnType<typeof setTimeout> | null = null;\n private phase: Phase = 'idle';\n /** 'video' modunda kilidin açık olduğu içerik (kaynak listesi — kalite dosyası değil). */\n private videoUnlockedKey: string | null = null;\n private lastKey = '';\n\n constructor(\n private readonly ctx: RewardedUnlockContext,\n options: RewardedUnlockOptions\n ) {\n this.options = options;\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'hp-rw-button';\n btn.setAttribute('part', 'rewarded-button');\n btn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.requestUnlock();\n });\n btn.addEventListener('pointerdown', (e) => e.stopPropagation());\n ctx.chromeEl.appendChild(btn);\n this.button = btn;\n ctx.videoEl.addEventListener('loadstart', this.onSourceChange);\n this.refreshLabels();\n this.onQualitiesChanged();\n }\n\n update(options: RewardedUnlockOptions): void {\n const before = this.unlocked;\n this.options = options;\n if (before !== this.unlocked) this.ctx.onLockChange(false);\n this.onQualitiesChanged();\n }\n\n // ── Kilit durumu ────────────────────────────────────────────────────\n\n private get maxFreeHeight(): number {\n const h = this.options.maxFreeHeight;\n return typeof h === 'number' && h > 0 ? h : DEFAULT_MAX_FREE_HEIGHT;\n }\n\n private get storageKey(): string {\n return this.options.storageKey || DEFAULT_STORAGE_KEY;\n }\n\n private get unlockFor(): 'video' | 'session' | number {\n const u = this.options.unlockFor;\n return typeof u === 'number' && u > 0 ? u : u === 'video' ? 'video' : 'session';\n }\n\n get unlocked(): boolean {\n const mode = this.unlockFor;\n if (mode === 'video') return !!this.videoUnlockedKey && this.videoUnlockedKey === this.ctx.contentKey();\n try {\n if (mode === 'session') return sessionStorage.getItem(this.storageKey) === '1';\n const until = Number(localStorage.getItem(this.storageKey));\n return Number.isFinite(until) && until > Date.now();\n } catch {\n return false; // depolama kapalı (gizli mod vb.)\n }\n }\n\n private grant(): void {\n const mode = this.unlockFor;\n if (mode === 'video') this.videoUnlockedKey = this.ctx.contentKey();\n try {\n if (mode === 'session') sessionStorage.setItem(this.storageKey, '1');\n else if (typeof mode === 'number') localStorage.setItem(this.storageKey, String(Date.now() + mode * 60_000));\n } catch {\n // Depolama yoksa yalnızca bu video için açık kalır.\n this.videoUnlockedKey = this.ctx.contentKey();\n }\n }\n\n /** Player için: bu yükseklikteki kalite kilitli mi? */\n isLocked(height: number | null): boolean {\n if (this.unlocked) return false;\n return height !== null && height > this.maxFreeHeight;\n }\n\n /** Kaynak değişti: 'video' modunda kilit yeniden kapanır; süreli kilit dolduysa menüler güncellenir. */\n private readonly onSourceChange = (): void => {\n const key = this.ctx.contentKey();\n if (key === this.lastKey) return;\n this.lastKey = key;\n this.onQualitiesChanged();\n };\n\n /** Player kalite listesi değişince çağırır: buton yalnızca kilitli kalite varken görünür. */\n onQualitiesChanged(): void {\n const label = this.ctx.lockedQualityLabel();\n const show = this.options.button !== false && !!label && !this.unlocked;\n this.button.hidden = !show;\n if (show) this.button.innerHTML = `${LOCK_SVG}<span>${escapeHtml(this.fill(this.ctx.i18n.rewardedButton, label!))}</span>`;\n }\n\n // ── Akış ────────────────────────────────────────────────────────────\n\n /** Kilitli kaliteye ya da butona dokunuldu: onay penceresi. */\n requestUnlock(): void {\n if (this.unlocked || this.phase !== 'idle') return;\n const label = this.ctx.lockedQualityLabel() ?? 'HD';\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:rewardedprompt', { detail: { quality: label } }));\n this.showDialog('prompt', label);\n }\n\n private async watch(label: string): Promise<void> {\n const v = this.ctx.videoEl;\n const wasPlaying = !v.paused;\n v.pause();\n // GPT reklamı sayfanın kendi katmanında açılır — player tam ekrandaysa görünmez.\n this.ctx.exitFullscreen();\n this.showDialog('loading', label);\n let result: RewardedResult;\n try {\n result = await this.runProvider();\n } catch (err) {\n this.ctx.log({ message: `Rewarded ad failed: ${String(err)}` });\n result = 'nofill';\n }\n if (result === 'nofill' && this.options.grantOnNoFill) {\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:rewardednofill', { detail: { granted: true } }));\n result = 'granted';\n }\n if (result === 'granted') {\n this.grant();\n this.closeDialog();\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:rewardedgranted', { detail: { quality: label } }));\n this.ctx.onLockChange(true);\n this.onQualitiesChanged();\n this.showToast(this.fill(this.ctx.i18n.rewardedUnlocked, label));\n if (wasPlaying) this.ctx.play();\n return;\n }\n if (result === 'nofill') {\n this.ctx.log({ message: 'Rewarded ad: no ad available (no fill / unsupported page / timeout)' });\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:rewardednofill', { detail: { granted: false } }));\n this.showDialog('nofill', label);\n this.resumeAfterDialog = wasPlaying;\n return;\n }\n // Kullanıcı reklamı ödül kazanmadan kapattı — video kaldığı kalitede devam eder.\n this.closeDialog();\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:rewardedclosed', { detail: { granted: false } }));\n if (wasPlaying) this.ctx.play();\n }\n\n private resumeAfterDialog = false;\n\n private async runProvider(): Promise<RewardedResult> {\n const p = this.options.provider;\n if (p?.type === 'gpt') return showGptRewarded(p.adUnitPath, p.timeoutMs ?? DEFAULT_GPT_TIMEOUT_MS);\n if (p?.type === 'custom') {\n const r = await p.show();\n return r === true ? 'granted' : r === false ? 'closed' : r;\n }\n throw new Error('rewardedUnlock.provider is missing');\n }\n\n // ── Arayüz ─────────────────────────────────────────────────────────\n\n private fill(template: string, quality: string): string {\n const mode = this.unlockFor;\n const i = this.ctx.i18n;\n const duration =\n mode === 'video' ? i.rewardedForVideo : mode === 'session' ? i.rewardedForSession : i.rewardedForMinutes.replace('{n}', String(mode));\n return template.replace('{quality}', quality).replace('{duration}', duration);\n }\n\n private showDialog(phase: Exclude<Phase, 'idle'>, label: string): void {\n this.phase = phase;\n const i = this.ctx.i18n;\n if (!this.dialog) {\n const d = document.createElement('div');\n d.className = 'hp-rw-dialog';\n d.setAttribute('part', 'rewarded-dialog');\n d.setAttribute('role', 'dialog');\n d.setAttribute('aria-modal', 'true');\n for (const t of ['click', 'pointerdown', 'dblclick'] as const) d.addEventListener(t, (e) => e.stopPropagation());\n d.addEventListener('keydown', (e) => {\n e.stopPropagation();\n if (e.key === 'Escape' && this.phase !== 'loading') this.dismiss();\n });\n this.ctx.overlayEl.appendChild(d);\n this.dialog = d;\n }\n const d = this.dialog;\n d.setAttribute('data-phase', phase);\n d.innerHTML = '';\n const card = document.createElement('div');\n card.className = 'hp-rw-card';\n const icon = document.createElement('div');\n icon.className = 'hp-rw-icon';\n icon.innerHTML = LOCK_SVG;\n const title = document.createElement('div');\n title.className = 'hp-rw-title';\n const text = document.createElement('div');\n text.className = 'hp-rw-text';\n const actions = document.createElement('div');\n actions.className = 'hp-rw-actions';\n card.append(icon, title, text, actions);\n d.appendChild(card);\n\n const button = (labelText: string, primary: boolean, onClick: () => void): HTMLButtonElement => {\n const b = document.createElement('button');\n b.type = 'button';\n b.className = primary ? 'hp-rw-btn hp-rw-btn-primary' : 'hp-rw-btn';\n b.textContent = labelText;\n b.addEventListener('click', onClick);\n actions.appendChild(b);\n return b;\n };\n\n if (phase === 'prompt') {\n title.textContent = this.fill(i.rewardedTitle, label);\n // Ödül, reklamdan ÖNCE açıkça yazılır (politika şartı).\n text.textContent = this.fill(i.rewardedBody, label);\n button(i.rewardedDecline, false, () => this.dismiss());\n button(i.rewardedWatch, true, () => void this.watch(label)).focus();\n } else if (phase === 'loading') {\n title.textContent = i.rewardedLoading;\n const spin = document.createElement('div');\n spin.className = 'hp-rw-spinner';\n text.appendChild(spin);\n } else {\n title.textContent = this.fill(i.rewardedTitle, label);\n text.textContent = i.rewardedNoFill;\n button(i.rewardedOk, true, () => this.dismiss()).focus();\n }\n }\n\n private dismiss(): void {\n const wasNoFill = this.phase === 'nofill';\n this.closeDialog();\n if (!wasNoFill) this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:rewardedclosed', { detail: { granted: false, declined: true } }));\n if (this.resumeAfterDialog) this.ctx.play();\n this.resumeAfterDialog = false;\n }\n\n private closeDialog(): void {\n this.phase = 'idle';\n this.dialog?.remove();\n this.dialog = null;\n }\n\n private showToast(message: string): void {\n if (this.toastTimer) clearTimeout(this.toastTimer);\n this.toast?.remove();\n const t = document.createElement('div');\n t.className = 'hp-rw-toast';\n t.setAttribute('part', 'rewarded-toast');\n t.setAttribute('role', 'status');\n t.textContent = message;\n this.ctx.overlayEl.appendChild(t);\n this.toast = t;\n this.toastTimer = setTimeout(() => {\n this.toast?.remove();\n this.toast = null;\n }, TOAST_MS);\n }\n\n refreshLabels(): void {\n this.button.setAttribute('aria-label', this.ctx.i18n.rewardedButton.replace('{quality}', 'HD'));\n this.onQualitiesChanged();\n }\n\n destroy(): void {\n this.ctx.videoEl.removeEventListener('loadstart', this.onSourceChange);\n if (this.toastTimer) clearTimeout(this.toastTimer);\n this.toast?.remove();\n this.closeDialog();\n this.button.remove();\n }\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, (c) => ({ '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''' })[c]!);\n}\n","import { RewardedUnlock, type RewardedUnlockContext } from './RewardedUnlock';\nimport type { RewardedUnlockOptions } from '../../types';\n\n/** Ödüllü reklamla kalite kilidini kurar. */\nexport function installRewardedUnlock(ctx: RewardedUnlockContext, options: RewardedUnlockOptions): RewardedUnlock {\n return new RewardedUnlock(ctx, options);\n}\n\nexport { RewardedUnlock };\nexport type { RewardedUnlockContext };\n"],"names":["GPT_SRC","gptLoading","loadGpt","w","_a","resolve","reject","showGptRewarded","adUnitPath","timeoutMs","googletag","slot","pubads","granted","done","listeners","on","type","fn","finish","result","timer","e","DEFAULT_MAX_FREE_HEIGHT","DEFAULT_STORAGE_KEY","DEFAULT_GPT_TIMEOUT_MS","TOAST_MS","RewardedUnlock","ctx","options","__publicField","key","btn","before","h","u","mode","until","height","label","show","LOCK_SVG","escapeHtml","v","wasPlaying","err","p","r","template","quality","i","duration","phase","d","t","card","icon","title","text","actions","button","labelText","primary","onClick","b","spin","wasNoFill","message","s","c","installRewardedUnlock"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-f0vSgRIK.js","sources":["../../src/plugins/loop-section/LoopSection.ts","../../src/plugins/loop-section/index.ts"],"sourcesContent":["import type { LoopSectionOptions } from '../../types';\n\nexport interface LoopSeekBarMarkers {\n addMarker(ratio: number, extraClass?: string): HTMLDivElement;\n clearMarkers(): void;\n}\n\nexport interface LoopSectionState {\n active: boolean;\n loopStart: number | null;\n loopEnd: number | null;\n}\n\n/** A/B döngü motoru. */\nexport class LoopSection {\n private readonly seconds: number;\n loopStart: number | null = null;\n loopEnd: number | null = null;\n active = false;\n\n constructor(\n private readonly video: HTMLVideoElement,\n private readonly markers: LoopSeekBarMarkers,\n options: LoopSectionOptions = {}\n ) {\n this.seconds = options.seconds || 10;\n }\n\n /** currentTime'dan geriye doğru tam N saniyelik bir aralığı döngüye alır (video başına yakınsa ileri doğru taşar). */\n enableLastN(secs?: number): void {\n const now = this.video.currentTime;\n const duration = this.video.duration;\n const s = secs || this.seconds;\n this.loopStart = Math.max(0, now - s);\n this.loopEnd = Math.min(Number.isFinite(duration) ? duration : Infinity, this.loopStart + s);\n this.activate();\n this.updateMarkers();\n }\n\n setStart(time?: number): void {\n this.loopStart = time ?? this.video.currentTime;\n this.updateMarkers();\n }\n\n setEnd(time?: number): void {\n this.loopEnd = time ?? this.video.currentTime;\n if (this.loopStart !== null && this.loopEnd > this.loopStart) {\n this.activate();\n this.updateMarkers();\n }\n }\n\n toggle(): void {\n if (this.active) this.disable();\n else this.enableLastN();\n }\n\n disable(): void {\n this.active = false;\n this.loopStart = null;\n this.loopEnd = null;\n this.video.removeEventListener('timeupdate', this.onTimeUpdate);\n this.markers.clearMarkers();\n }\n\n getState(): LoopSectionState {\n return { active: this.active, loopStart: this.loopStart, loopEnd: this.loopEnd };\n }\n\n /** `installLoopSection` bunu gerçek buton etiketini tazeleyen bir implementasyonla override eder (bkz. index.ts) — `destroy`'un üzerine yazılma deseniyle aynı. */\n refreshLabels(): void {\n /* no-op varsayılan */\n }\n\n destroy(): void {\n this.disable();\n }\n\n private activate(): void {\n this.active = true;\n this.video.removeEventListener('timeupdate', this.onTimeUpdate);\n this.video.addEventListener('timeupdate', this.onTimeUpdate);\n }\n\n private readonly onTimeUpdate = (): void => {\n if (this.loopEnd !== null && this.video.currentTime >= this.loopEnd) {\n this.video.currentTime = this.loopStart ?? 0;\n }\n };\n\n private updateMarkers(): void {\n this.markers.clearMarkers();\n const duration = this.video.duration;\n if (!duration || !Number.isFinite(duration)) return;\n\n if (this.loopStart !== null) {\n this.markers.addMarker(this.loopStart / duration, 'hp:bg-accent');\n }\n if (this.loopEnd !== null) {\n this.markers.addMarker(this.loopEnd / duration, 'hp:bg-accent');\n }\n }\n}\n","import { LoopSection, type LoopSeekBarMarkers } from './LoopSection';\nimport type { LoopSectionOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\n\nexport interface LoopSectionPlayerContext {\n videoEl: HTMLVideoElement;\n seekBarEl: HTMLElement;\n markers: LoopSeekBarMarkers;\n addControlButton(label: string, iconName: string, onClick: () => void): { btn: HTMLButtonElement; icon: HTMLElement };\n i18n: HopeLocaleStrings;\n}\n\n/** Döngü motorunu kurar: kontrol çubuğuna toggle butonu, seek bar'da orta-tık ile A → B → kapat. */\nexport function installLoopSection(ctx: LoopSectionPlayerContext, options: LoopSectionOptions): LoopSection {\n const engine = new LoopSection(ctx.videoEl, ctx.markers, options);\n\n const { btn } = ctx.addControlButton(ctx.i18n.loop, 'loop', () => {\n engine.toggle();\n refresh();\n });\n\n const refresh = (): void => {\n btn.classList.toggle('hp:text-accent', engine.active);\n };\n\n engine.refreshLabels = () => {\n btn.setAttribute('aria-label', ctx.i18n.loop);\n };\n\n const onSeekBarMiddleClick = (e: MouseEvent): void => {\n if (e.button !== 1) return;\n e.preventDefault();\n\n const rect = ctx.seekBarEl.getBoundingClientRect();\n const ratio = Math.min(1, Math.max(0, (e.clientX - rect.left) / rect.width));\n const duration = ctx.videoEl.duration;\n const clickTime = Number.isFinite(duration) ? ratio * duration : undefined;\n\n const state = engine.getState();\n if (state.active) engine.disable();\n else if (state.loopStart === null) engine.setStart(clickTime);\n else engine.setEnd(clickTime);\n\n refresh();\n };\n ctx.seekBarEl.addEventListener('mousedown', onSeekBarMiddleClick);\n\n const originalDestroy = engine.destroy.bind(engine);\n engine.destroy = () => {\n ctx.seekBarEl.removeEventListener('mousedown', onSeekBarMiddleClick);\n originalDestroy();\n };\n\n return engine;\n}\n\nexport { LoopSection };\nexport type { LoopSeekBarMarkers };\n"],"names":["LoopSection","video","markers","options","__publicField","secs","now","duration","s","time","installLoopSection","ctx","engine","btn","refresh","onSeekBarMiddleClick","e","rect","ratio","clickTime","state","originalDestroy"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-rENB3n9O.js","sources":["../../src/plugins/countdown-screen/CountdownScreen.ts","../../src/plugins/countdown-screen/index.ts"],"sourcesContent":["import type { CountdownScreenOptions } from '../../types';\nimport type { GatePlayerContext } from '../shared/GatePlayerContext';\n\n/** Hedef tarihe kadar içeriği engelleyen geri sayım ekranı (blockChrome ile). */\nexport class CountdownScreen {\n private readonly wrapper: HTMLElement;\n private readonly timerLabel: HTMLElement;\n private readonly timerEl: HTMLElement;\n private interval: ReturnType<typeof setInterval> | null = null;\n private bgInterval: ReturnType<typeof setInterval> | null = null;\n private imageIndex = 0;\n private readonly targetTime: number;\n private resolved = false;\n private readonly completeCallbacks: Array<() => void> = [];\n\n constructor(\n private readonly ctx: GatePlayerContext,\n private readonly options: CountdownScreenOptions\n ) {\n this.targetTime = new Date(options.time).getTime();\n\n this.wrapper = document.createElement('div');\n this.wrapper.setAttribute('part', 'countdown-screen');\n this.wrapper.className =\n 'hp:absolute hp:inset-0 hp:z-40 hp:flex hp:items-end hp:bg-cover hp:bg-center hp:bg-surface hp:text-on-surface';\n\n const info = document.createElement('div');\n info.className = 'hp:p-4 hp:w-full hp:bg-gradient-to-t hp:from-black/80 hp:to-transparent';\n\n if (options.title) {\n const title = document.createElement('h3');\n title.className = 'hp:text-lg hp:font-semibold hp:m-0';\n title.textContent = options.title;\n info.appendChild(title);\n }\n if (options.spot) {\n const spot = document.createElement('p');\n spot.className = 'hp:text-sm hp:opacity-80 hp:m-0 hp:mt-1';\n spot.textContent = options.spot;\n info.appendChild(spot);\n }\n if (options.description) {\n const desc = document.createElement('p');\n desc.className = 'hp:text-xs hp:opacity-70 hp:m-0 hp:mt-1';\n desc.textContent = options.description;\n info.appendChild(desc);\n }\n\n this.timerLabel = document.createElement('span');\n this.timerLabel.className = 'hp:text-xs hp:opacity-70 hp:block hp:mt-2';\n this.timerLabel.textContent = ctx.i18n.countdownRemaining;\n info.appendChild(this.timerLabel);\n\n this.timerEl = document.createElement('div');\n this.timerEl.className = 'hp:text-2xl hp:font-mono hp:tabular-nums';\n info.appendChild(this.timerEl);\n\n this.wrapper.appendChild(info);\n this.updateBackground();\n ctx.overlayContainerEl.appendChild(this.wrapper);\n\n ctx.blockChrome();\n ctx.videoEl.addEventListener('play', this.onPlayWhileBlocked);\n\n if (Array.isArray(options.coverImage) && options.coverImage.length > 0) {\n this.bgInterval = setInterval(() => {\n this.imageIndex = (this.imageIndex + 1) % (options.coverImage as string[]).length;\n this.updateBackground();\n }, options.imageChangeInterval ?? 5000);\n }\n\n this.start();\n }\n\n refreshLabels(): void {\n this.timerLabel.textContent = this.ctx.i18n.countdownRemaining;\n }\n\n isComplete(): boolean {\n return this.resolved;\n }\n\n /** Geri sayım bitince çağrılır (zaten bittiyse anında). */\n onComplete(cb: () => void): void {\n if (this.resolved) cb();\n else this.completeCallbacks.push(cb);\n }\n\n destroy(): void {\n if (this.interval) clearInterval(this.interval);\n if (this.bgInterval) clearInterval(this.bgInterval);\n this.ctx.videoEl.removeEventListener('play', this.onPlayWhileBlocked);\n if (!this.resolved) this.ctx.unblockChrome();\n this.wrapper.remove();\n this.completeCallbacks.length = 0;\n }\n\n private readonly onPlayWhileBlocked = (): void => {\n if (!this.resolved) this.ctx.videoEl.pause();\n };\n\n private updateBackground(): void {\n const img = Array.isArray(this.options.coverImage) ? this.options.coverImage[this.imageIndex] : this.options.coverImage;\n this.wrapper.style.backgroundImage = img ? `url(\"${img}\")` : 'none';\n }\n\n private start(): void {\n const tick = () => {\n const diff = Math.max(this.targetTime - Date.now(), 0);\n const h = Math.floor(diff / 3600000);\n const m = Math.floor((diff / 60000) % 60);\n const s = Math.floor((diff / 1000) % 60);\n this.timerEl.textContent = `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`;\n\n if (diff <= 0) this.complete();\n };\n\n tick();\n if (this.targetTime - Date.now() > 0) {\n this.interval = setInterval(tick, 1000);\n } else {\n this.complete();\n }\n }\n\n private complete(): void {\n if (this.resolved) return;\n this.resolved = true;\n if (this.interval) clearInterval(this.interval);\n if (this.bgInterval) clearInterval(this.bgInterval);\n this.ctx.videoEl.removeEventListener('play', this.onPlayWhileBlocked);\n this.wrapper.remove();\n this.ctx.unblockChrome();\n const callbacks = this.completeCallbacks.splice(0);\n for (const cb of callbacks) cb();\n }\n}\n","import { CountdownScreen } from './CountdownScreen';\nimport type { GatePlayerContext } from '../shared/GatePlayerContext';\nimport type { CountdownScreenOptions } from '../../types';\n\nexport function installCountdownScreen(ctx: GatePlayerContext, options: CountdownScreenOptions): CountdownScreen {\n return new CountdownScreen(ctx, options);\n}\n\nexport { CountdownScreen };\nexport type { GatePlayerContext };\n"],"names":["CountdownScreen","ctx","options","__publicField","info","title","spot","desc","cb","img","tick","diff","h","m","callbacks","installCountdownScreen"],"mappings":"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"}
|