PageSourceSearch

https://canlitv.com/js/yayin-akisi.js?v=15

js canlitv.com collected 2026-10-02 19:09:34 UTC 12,031 bytes, 294 lines download raw bytes

1/* Yayın akışları sayfası (yeni tasarım, 2026-09)
2   İlk açılışta her kanalın şu an (diğer günlerde aynı saatte) yayındaki programı odak sütununa hizalıdır
3   (masaüstü 2., mobil 1. sütun). Kaydırınca tüm satırlar ve başlık birlikte, aynı miktarda kayar; bırakınca sütuna oturur. */
4(function(){
5	var kok=document.getElementById('ya');
6	if(!kok)return;
7	var govde=kok.querySelector('.ya-govde');
8	var kaydir=kok.querySelector('.ya-kaydir');
9	var ray=kok.querySelector('.ya-ray');
10	var tutamac=kok.querySelector('.ya-tutamac');
11	var mobil=kok.classList.contains('ya-mobil');
12
13	var tablo, satirlar=[], baslik=null, c=1, w=150, wr=250, g=6, gorunur=0;
14	var S=0, hedefS=0, Smin=0, Smax=0, anim=null, simdi0=0, t0=0, durum='bugun', fark=0;
15
16	// kalan süre metni (PHP ya_kalan ile aynı)
17	function kalanMetni(dk){return Math.max(1,Math.ceil(dk))+'dk';}
18	function simdi(){return simdi0+(Date.now()-t0)/60000;}
19	function adim(){return w+g;}
20
21	function kur(){
22		tablo=govde.querySelector('.ya-tablo');
23		if(!tablo)return;
24		c=+tablo.getAttribute('data-c');
25		durum=tablo.getAttribute('data-durum');
26		fark=+tablo.getAttribute('data-fark')||0; // seçilen günün bugüne göre farkı (dün -1, yarın 1…)
27		simdi0=+tablo.getAttribute('data-simdi');
28		t0=Date.now();
29		satirlar=[].slice.call(tablo.querySelectorAll('.ya-satir')).map(function(s){
30			return {
31				el:s, ic:s.querySelector('.ya-ic'), a:+s.getAttribute('data-a')||0,
32				bas:s.classList.contains('ya-baslik'),
33				h:[].slice.call(s.querySelectorAll('.ya-h[data-b]')).map(function(h){
34					return {el:h, b:+h.getAttribute('data-b'), e:+h.getAttribute('data-e')};
35				})
36			};
37		});
38		baslik=satirlar.filter(function(s){return s.bas;})[0]||null;
39		S=hedefS=0;
40		olc();
41		uygula();
42	}
43
44	function olc(){
45		var ic=tablo.querySelector('.ya-satir:not(.ya-baslik) .ya-ic');
46		if(!ic)return;
47		g=parseFloat(getComputedStyle(ic).columnGap)||0;
48		var n=tablo.querySelector('.ya-h[data-b]:not(.ya-odak)'), r=tablo.querySelector('.ya-h.ya-odak');
49		if(n)w=n.getBoundingClientRect().width;
50		if(r)wr=r.getBoundingClientRect().width;
51		gorunur=ic.parentNode.clientWidth;
52		// sınırlar (sütun cinsinden): her satırın ilk programı sola, son programı sağa gelebilmeli
53		var kmin=0,kmax=0;
54		satirlar.forEach(function(s){
55			if(s.bas||!s.h.length)return;
56			kmin=Math.min(kmin,c-s.a);
57			// son kutunun sağ kenarı görünür alana girene kadar ileri kaydırılabilir
58			var hedef=s.ic.children.length*adim()-g+(wr-w)-gorunur, k=0;
59			while(k<200 && konum(s.a,k)<hedef)k++;
60			if(k>0){var x0=konum(s.a,k-1), x1=konum(s.a,k); k=k-1+(hedef-x0)/Math.max(1,x1-x0);}
61			kmax=Math.max(kmax,k);
62		});
63		Smin=kmin*adim(); Smax=kmax*adim();
64		S=Math.min(Smax,Math.max(Smin,S));
65	}
66
67	// k sütun kaydırılmış bir satırın/başlığın kayma miktarı (odak sütunu wr genişliğinde, diğerleri w)
68	function konum(a,k){
69		var j=a-c+k, i=Math.floor(j), f=j-i;
70		var sol=i*adim()+(i>a?wr-w:0);
71		return sol+f*((i===a?wr:w)+g);
72	}
73
74	function uygula(){
75		if(!tablo)return;
76		satirlar.forEach(function(s){
77			s.ic.style.transform='translateX('+(-konum(s.a,S/adim()))+'px)';
78		});
79		tablo.classList.toggle('kaydi',Math.abs(S)>1);
80		// başlık yazıları: çubuğun görünen kısmının ortasında kalsın
81		if(baslik){
82			var serit=baslik.ic.parentNode.getBoundingClientRect();
83			[].forEach.call(baslik.ic.children,function(b){
84				var r=b.getBoundingClientRect(), sp=b.firstElementChild;
85				var sol=Math.max(r.left,serit.left), sag=Math.min(r.right,serit.right);
86				if(sag-sol<50){sp.style.visibility='hidden';return;}
87				sp.style.visibility='';
88				var yari=sp.offsetWidth/2+6, orta=(sol+sag)/2;
89				if(sag-sol>2*yari)orta=Math.min(Math.max(orta,sol+yari),sag-yari);
90				sp.style.left=(orta-r.left)+'px';
91			});
92		}
93		// kaydırma çubuğu
94		var aralik=Smax-Smin;
95		kaydir.classList.toggle('pasif',aralik<=0);
96		if(aralik>0){
97			var rg=ray.clientWidth, tg=Math.max(24,rg*gorunur/(gorunur+aralik));
98			tutamac.style.width=tg+'px';
99			tutamac.style.left=((S-Smin)/aralik*(rg-tg))+'px';
100		}
101	}
102
103	function git(h,yumusak){
104		h=Math.min(Smax,Math.max(Smin,h));
105		hedefS=h;
106		if(anim){cancelAnimationFrame(anim);anim=null;}
107		if(!yumusak || document.hidden){S=h;uygula();return;} // sekme arka plandaysa animasyon kareleri çalışmaz
108		var bas=S, fark=h-bas, t=null;
109		function kare(z){
110			if(t===null)t=z;
111			var p=Math.min(1,(z-t)/260), e=1-Math.pow(1-p,3);
112			S=bas+fark*e;uygula();
113			anim=p<1?requestAnimationFrame(kare):null;
114		}
115		anim=requestAnimationFrame(kare);
116	}
117	// en yakın sütun konumu; sağ sınır sütun ortasına denk gelebildiği için sona yakınsa sona oturur (geri kaymasın)
118	function oturt(x){
119		if(x>=Smax-adim()/2)return Smax;
120		return Math.round(x/adim())*adim();
121	}
122	// sütuna oturt: yon -1/1 bir sütun geri/ileri, 0 en yakın sütun
123	function yasla(yon){
124		var x=anim?hedefS:S, k=x/adim();
125		if(yon===0){git(oturt(x),true);return;}
126		k=yon>0?Math.floor(k+1e-6)+1:Math.ceil(k-1e-6)-1;
127		git(k*adim(),true);
128	}
129
130	// oklar, ray, tutamaç
131	kok.querySelector('.ya-geri').addEventListener('click',function(){yasla(-1);});
132	kok.querySelector('.ya-ileri').addEventListener('click',function(){yasla(1);});
133	ray.addEventListener('pointerdown',function(e){
134		if(e.target===tutamac)return;
135		var r=tutamac.getBoundingClientRect(), k=Math.max(1,Math.floor(gorunur/adim())-1);
136		git(oturt((anim?hedefS:S)+(e.clientX<r.left?-k:k)*adim()),true);
137	});
138	tutamac.addEventListener('pointerdown',function(e){
139		e.preventDefault();
140		var x0=e.clientX, s0=S, rg=ray.clientWidth-tutamac.offsetWidth;
141		try{tutamac.setPointerCapture(e.pointerId);}catch(x){}
142		function hareket(ev){git(s0+(ev.clientX-x0)/rg*(Smax-Smin));}
143		function bitti(){
144			tutamac.removeEventListener('pointermove',hareket);
145			tutamac.removeEventListener('pointerup',bitti);
146			tutamac.removeEventListener('pointercancel',bitti);
147			yasla(0);
148		}
149		tutamac.addEventListener('pointermove',hareket);
150		tutamac.addEventListener('pointerup',bitti);
151		tutamac.addEventListener('pointercancel',bitti);
152	});
153
154	// satırları sürükleme (fare + dokunma); dikey hareket sayfayı kaydırır
155	var sur=null, tiklamaEngel=false;
156	govde.addEventListener('pointerdown',function(e){
157		if(!e.target.closest('.ya-serit') || (e.pointerType==='mouse' && e.button!==0))return;
158		if(anim){cancelAnimationFrame(anim);anim=null;}
159		sur={x:e.clientX, y:e.clientY, s:S, id:e.pointerId, basladi:false, hiz:0, sx:e.clientX, st:e.timeStamp};
160	});
161	govde.addEventListener('pointermove',function(e){
162		if(!sur || e.pointerId!==sur.id)return;
163		var dx=e.clientX-sur.x;
164		if(!sur.basladi){
165			if(Math.abs(dx)<6)return;
166			if(Math.abs(e.clientY-sur.y)>Math.abs(dx)){sur=null;return;}
167			sur.basladi=true;
168			try{govde.setPointerCapture(e.pointerId);}catch(x){}
169			govde.classList.add('surukle');
170		}
171		var dt=e.timeStamp-sur.st;
172		if(dt>0){sur.hiz=(e.clientX-sur.sx)/dt; sur.sx=e.clientX; sur.st=e.timeStamp;}
173		git(sur.s-dx);
174	});
175	function surBitti(e){
176		if(!sur || e.pointerId!==sur.id)return;
177		if(sur.basladi){
178			tiklamaEngel=true; setTimeout(function(){tiklamaEngel=false;},50);
179			govde.classList.remove('surukle');
180			// savurma: hızlı bırakınca biraz daha git (en çok 3 sütun), sonra sütuna otur
181			var hiz=(e.timeStamp-sur.st<80)?Math.max(-2,Math.min(2,sur.hiz)):0;
182			var ek=Math.max(-3*adim(),Math.min(3*adim(),-hiz*180));
183			git(oturt(Math.min(Smax,S+ek)),true);
184		}
185		sur=null;
186	}
187	govde.addEventListener('pointerup',surBitti);
188	govde.addEventListener('pointercancel',surBitti);
189	govde.addEventListener('click',function(e){
190		if(tiklamaEngel){e.preventDefault();e.stopPropagation();return;}
191		if(e.target.closest('.ya-bh.ya-simdi'))git(0,true); // başa (şu ana) dön
192	},true);
193	govde.addEventListener('dragstart',function(e){e.preventDefault();});
194
195	// yatay tekerlek / touchpad, shift+tekerlek
196	var tekerZaman=null;
197	govde.addEventListener('wheel',function(e){
198		var d=Math.abs(e.deltaX)>Math.abs(e.deltaY)?e.deltaX:(e.shiftKey?e.deltaY:0);
199		if(!d)return;
200		e.preventDefault();
201		git(S+d);
202		clearTimeout(tekerZaman);
203		tekerZaman=setTimeout(function(){yasla(0);},160);
204	},{passive:false});
205
206	// klavye ← →
207	document.addEventListener('keydown',function(e){
208		var a=document.activeElement;
209		if(e.altKey||e.ctrlKey||e.metaKey||e.shiftKey)return; // Alt+← (geri) vb. tarayıcı kısayollarına karışma
210		if(a && (/INPUT|TEXTAREA|SELECT/.test(a.tagName)||a.isContentEditable))return;
211		if(e.key==='ArrowLeft')yasla(-1);
212		else if(e.key==='ArrowRight')yasla(1);
213	});
214
215	// tabloyu sunucudan (yeniden) yükle; koru=true ise kaydırma konumu korunur (canlı yenilemede)
216	var yukleniyor=false;
217	function yukle(gun,koru,hata){
218		if(yukleniyor)return;
219		yukleniyor=true;
220		var eskiS=S;
221		if(!koru)govde.classList.add('yukleniyor');
222		fetch('/modul/ajax-yayin-akislari.php?gun='+gun+(mobil?'&m=1':''),{cache:'no-store'})
223			.then(function(r){if(!r.ok)throw 0;return r.text();})
224			.then(function(h){
225				if(!/ya-tablo/.test(h))throw 0;
226				govde.innerHTML=h;
227				kur();
228				if(koru){S=hedefS=Math.min(Smax,Math.max(Smin,eskiS));uygula();}
229				govde.classList.remove('yukleniyor');
230				yukleniyor=false;
231				canli(true);
232			})
233			.catch(function(){yukleniyor=false;govde.classList.remove('yukleniyor');if(hata)hata();});
234	}
235
236	// gün değiştirme
237	var gunler=kok.querySelectorAll('.ya-gunler a');
238	[].forEach.call(gunler,function(a){
239		a.addEventListener('click',function(e){
240			e.preventDefault();
241			if(a.classList.contains('aktif'))return;
242			[].forEach.call(gunler,function(x){x.classList.toggle('aktif',x===a);});
243			var gun=a.getAttribute('data-gun');
244			yukle(gun,false,function(){location.href=a.href;});
245			try{history.replaceState(null,'',a.classList.contains('bugun')?location.pathname:'?ygun='+gun);}catch(x){}
246		});
247	});
248
249	// canlı güncelleme (her dakika başında, sunucu saatine göre): ilerleme çubukları, kalan dakika, renkler.
250	// Bugünün tablosunda bir kanalda yeni program başlarsa tablo sunucudan yeniden alınır: her satır yine
251	// "4 önceki + şu an + 5 sonraki" olur, kaydırma konumu korunur.
252	function canli(yeniYuklendi){
253		if(!tablo)return;
254		var saat=simdi();
255		if(saat>=1440){location.reload();return;} // gün değişti: sekme tarihleri de değişir
256		var n=saat-fark*1440, yenile=false;
257		satirlar.forEach(function(s){
258			if(s.bas)return;
259			s.h.forEach(function(p){
260				var h=p.el, yeni=p.e<=n?'ya-gecmis':(p.b<=n?'ya-simdi':'ya-gelecek');
261				if(!h.classList.contains(yeni)){
262					// odak dışındaki bir program yayına girdiyse (yeni program başladı) bugünün tablosu yeniden dizilmeli
263					if(yeni==='ya-simdi' && durum==='bugun' && !h.classList.contains('ya-odak'))yenile=true;
264					h.classList.remove('ya-gecmis','ya-simdi','ya-gelecek');
265					h.classList.add(yeni);
266					var bar=h.querySelector('.ya-bar'), em=h.querySelector('em');
267					if(bar)bar.remove(); if(em)em.remove();
268					if(yeni==='ya-simdi' && !h.hasAttribute('data-bilinmez'))h.insertAdjacentHTML('beforeend','<s class="ya-bar"><span></span></s><em></em>');
269				}
270				if(yeni==='ya-simdi' && !h.hasAttribute('data-bilinmez')){
271					var y=Math.max(0,Math.min(100,Math.floor((n-p.b)*100/Math.max(1,p.e-p.b))));
272					h.querySelector('.ya-bar span').style.width=y+'%';
273					h.querySelector('em').textContent=kalanMetni(p.e-n);
274				}
275			});
276		});
277		if(yenile && !yeniYuklendi)yukle(tablo.getAttribute('data-gun'),true);
278	}
279	// bir sonraki dakika başına kur (sunucu saatine göre), sonra her dakika
280	var dakikaZaman=null;
281	function planla(){
282		clearTimeout(dakikaZaman);
283		var n=simdi(), ms=Math.max(1000,(Math.floor(n)+1-n)*60000+500);
284		dakikaZaman=setTimeout(function(){canli();planla();},ms);
285	}
286	// arka plandaki sekmede zamanlayıcılar yavaşlar: sekmeye dönünce hemen güncelle
287	document.addEventListener('visibilitychange',function(){if(!document.hidden){canli();planla();}});
288
289	var boyutZaman=null;
290	window.addEventListener('resize',function(){clearTimeout(boyutZaman);boyutZaman=setTimeout(function(){if(tablo){olc();uygula();}},100);});
291
292	kur();
293	planla();
294})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.