PageSourceSearch

https://qfilms.ru/resource/js/audio.js

js qfilms.ru collected 2026-10-07 22:55:05 UTC 24,768 bytes, 723 lines download raw bytes

1/*--------------------------------------------------------------------------------------------------
2	Media
3--------------------------------------------------------------------------------------------------*/
4
5function audio_playlist_getItemIndex(list, id) {
6	for(var i in list) if(list[i].id != undefined && list[i].id == id) return parseInt(i);
7	return -1;
8}
9
10//--------------------------------------------------------------------------------------------------
11
12function audio_playBy(button) {
13	audio_play(audio_getData(button), audio_getList(button));
14}
15
16//--------------------------------------------------------------------------------------------------
17
18function audio_play(d, list_id) {
19	var list = (Static.playing.list_id != list_id) ? audio_list2Array(list_id) : Static.playing.list;
20	var path = '#' + list_id + ' .audio-' + d.id;
21
22	if(Static.playing.id == d.id && Static.playing.list_id == list_id && Static.playing.status != -1) { //same list, same element
23		audio_TogglePause();
24		return false;
25	}
26
27	if(Static.playing.status >= 0) {
28		$('#audio-static-player').remove();
29		$('#audio-flash-container').remove();
30		$('#audio-controls-secondary').remove();
31		$(Static.playing.path + ' #play').attr('src','/resource/image/audio/play.png');
32	}
33
34	if(Static.playing.list_id != list_id) {
35		if(Static.playing.shuffle) Static.playing.list_shuffled = array_Shuffle(list); //Åñëè âêëþ÷åí øàôë è ëèñò äðóãîé, îáíîâèì
36		Static.playing.list = list;
37		Static.playing.type = $('#'+list_id).data().type;
38	}
39
40	Static.playing.id = d.id;
41	Static.playing.status = 1;
42
43	Static.playing.path = path;
44	Static.playing.list_id = list_id;
45
46	$(path + ' #play').attr('src','/resource/image/audio/pause.png');
47
48	if(Static.playing.type == 'audio') {
49		var info = "<small>" + (d.artist ? "<a href='/audio/tag/" + d.artist + "'>" + d.artist + "</a>" : 'Íåèçâåñòíûé èñïîëíèòåëü') + "<br>" + d.title + "</small>";
50		var logo = '';
51	} else {
52		var info = "<small><a href='/radio/" + d.id + "'>" + d.title + "</a><br><span></span></small>";
53		var logo = "<img src='" + ( d.logo ? "/content/radio-image/" + d.logo : "/resource/image/audio/radio-no-logo.png") + "'>";
54	}
55
56	var player = "<div id='audio-flash-container'></div><div id='audio-static-player'" + (logo ? " class='radio-player'" : "") + ">" +
57	"<div class='control'><nobr>\
58		<img src='/resource/image/audio/pause.png' class='button' id='audio-toggle' onClick='audio_TogglePause();'> &nbsp;&nbsp; \
59		<img src='/resource/image/audio/prev.png' class='button' onClick='audio_playerGo(-1);'> " +
60		(Static.playing.type == 'audio' ? "<img src='/resource/image/audio/shuffle" + (!Static.playing.shuffle ? '_off' : '') + ".png' class='button' id='audio-shuffle' onClick='audio_playerShuffle();' title='Èãðàòü â ñëó÷àéíîì ïîðÿäêå'> " : '') +
61		"<img src='/resource/image/audio/next.png' class='button' onClick='audio_playerGo(1);'></div></nobr>" +
62	( logo ? "<div class='logo'>" + logo + "</div>" : '') +
63	"<div id='info'>" + info + "</div>" +
64	"<div id='controls'></div><div class='close'><a href='#' onClick='return audio_playerClose();'><img src='/resource/image/icon/close.png'></a></div>" +
65	"<div id='playlist'></div></div>";
66
67	$('#static-content').before(player);
68
69	if(document.createElement('audio').canPlayType('audio/mpeg')) { // html5
70		Static.playing.mode = 'html5';
71
72		$('#audio-flash-container').html("<audio id='audio-flash'><source src='" + d.url + "' type='audio/mpeg'></source></audio>");
73		Static.audio = $('#audio-flash').get(0);
74
75		$(Static.audio).bind('timeupdate', function() {
76			audio_Info(Static.audio.currentTime, Static.audio.duration);
77		});
78
79		if(Static.playing.volume != undefined && !isNaN(Static.playing.volume)) audio_playerVolume(Static.playing.volume);
80		Static.audio.play();
81	} else { // flash
82		$('#audio-flash-container').flash({
83			id: 'audio-flash',
84			swf: '/resource/swf/audio.swf?v=1.0.1',
85			width: '1px',
86			height: '1px',
87			wmode : 'transparent',
88			allowScriptAccess : 'true',
89			flashvars: {url : d.url, volume : Static.playing.volume, stream : (Static.playing.type == 'radio')}
90		});
91		Static.playing.mode = 'flash';
92	}
93
94	if(Static.playing.type == 'audio') {
95		media_controlsInsert(true,true,!$('#' + list_id).hasClass('side'));
96	} else {
97		media_controlsInsert(false,true,false);
98		radio_updatePlaying();
99	}
100
101	if(!localStorage.audio_play) localStorage.audio_play = 1;
102	else localStorage.audio_play = localStorage.audio_play + 1;
103	window.addEventListener("storage", function(e) {if(!e) e = window.event; if(Static.playing.status && e.key == 'audio_play') audio_TogglePause();}, false);
104
105	$('#user-bar-after').css({'padding-top': '90px'});
106	if($("#user-bar").hasClass('heads-up')) $("#audio-static-player").css('top', '0');
107	return false;
108}
109
110//--------------------------------------------------------------------------------------------------
111
112function media_controlsInsert(seek,primary,secondary) {
113	if(primary) {
114		$('#audio-static-player #controls').html(
115		"<div id='audio-controls-primary' class='audio-controls'>" +
116			(seek ? "<div id='seek-primary' class='left seek-slider'></div>" : '') +
117			"<div id='volume-primary' class='right volume-slider'></div>\
118		</div>");
119	}
120
121	if(secondary) $(Static.playing.path).after(
122		"<div id='audio-controls-secondary' class='audio-controls secondary'>" +
123			(seek ? "<div id='seek-secondary' class='left seek-slider'></div> " : '') +
124			"<div id='volume-secondary' class='right volume-slider'></div>\
125		</div>");
126
127	if(seek)
128	$('.seek-slider').slider({
129		width: !Static.mobile ? 190 : 100,
130		min: 0,
131		position: 0,
132		max: 100,
133		connectedWith: '.seek-slider',
134		points: false,
135		onDrag: function(position) {audio_playerPos(position);}
136	});
137
138	if(!Static.mobile) {
139		$('.volume-slider').slider({
140			width: 80,
141			min: 0,
142			position: Static.playing.volume,
143			max: 1,
144			connectedWith: '.volume-slider',
145			points: true,
146			onDrag: function(position) {audio_playerVolume(position);}
147		});
148	}
149}
150
151/*--------------------------------------------------------------------------------------------------
152	Audio Playing Controlling
153--------------------------------------------------------------------------------------------------*/
154
155function audio_updatePlayingList(list_id,data) {
156	if(Static.playing.list_id != list_id) return false;
157	Static.playing.list = data;
158	if(Static.playing.shuffle) {
159		// Â list_shuffle íàäî ïî-õðîøåìó äîáàâèòü èòåìû, êîòîðûõ òàì íåò, è óäàëèòü òå, êîòîðûõ íåò â íîâîì ëèñòå.
160		// Íî ìû ñäåëàåì ïîêà ïðîùå. Ïåðåñîçäàäèì ëèñò.
161		Static.playing.list_shuffled = array_Shuffle(data);
162	}
163}
164
165function audio_playerClose() {
166	$('#audio-static-player').remove();
167	$('#audio-flash-container').remove();
168	$('#audio-controls-secondary').remove();
169	$(Static.playing.path + ' #play').attr('src','/resource/image/audio/play.png');
170	Static.playing.status = -1;
171	Static.playing.type = '';
172	Static.playing.list = [];
173	Static.playing.list_id = '';
174	Static.playing.list_shuffled = [];
175	$('#user-bar-after').css({'padding-top': '75px'});
176	return false;
177}
178
179function audio_playerShuffle() {
180	if(Static.playing.shuffle) {
181		$('#audio-shuffle').attr('src','/resource/image/audio/shuffle_off.png');
182		Static.playing.shuffle = false;
183		cookie_set('playing.shuffle',0);
184	} else {
185		$('#audio-shuffle').attr('src','/resource/image/audio/shuffle.png');
186		Static.playing.shuffle = true;
187		cookie_set('playing.shuffle',1);
188		Static.playing.list_shuffled = array_Shuffle(Static.playing.list);
189
190	}
191}
192
193function audio_TogglePause() {
194	if(Static.playing.mode == 'flash') getFlash('audio-flash').callPause(); else {
195		if(Static.audio.paused) Static.audio.play(); else Static.audio.pause();
196	}
197
198	if(Static.playing.status) {
199		Static.playing.status = 0;
200		$('#audio-toggle').attr('src','/resource/image/audio/play.png');
201		$(Static.playing.path + ' #play').attr('src','/resource/image/audio/play.png');
202	} else {
203		localStorage.audio_play = localStorage.audio_play + 1;
204		Static.playing.status = 1;
205		$('#audio-toggle').attr('src','/resource/image/audio/pause.png');
206		$(Static.playing.path + ' #play').attr('src','/resource/image/audio/pause.png');
207	}
208	return false;
209}
210
211function audio_Ended() {
212	if(Static.playing.type != 'audio') return;
213	audio_playerGo(1);
214}
215
216function audio_playerGo(delta) {
217	var list = Static.playing.shuffle ? Static.playing.list_shuffled : Static.playing.list;
218	var index = audio_playlist_getItemIndex(list,Static.playing.id);
219
220	var ni = index + delta;
221	if(ni == list.length) ni = 0;
222	if(ni == -1) ni = list.length-1;
223	if(ni == index) return false;
224
225	var data = list[ni];
226	if(data) audio_play(data,Static.playing.list_id);
227
228	return false;
229}
230
231function audio_playerPos(val) {
232	if(isNaN(val)) return false;
233	if(Static.playing.status == 0) audio_TogglePause();
234
235	if(Static.playing.mode == 'flash') {
236		getFlash('audio-flash').callPos(Static.playing.duration / 100 * val);
237	} else {
238		Static.audio.currentTime = Static.playing.duration / 100 * val;
239		Static.audio.play();
240	}
241}
242
243function audio_Info(pos,dur) {
244	Static.playing.position = pos;
245	Static.playing.duration = dur;
246	if(Static.playing.type == 'audio') $('.seek-slider').slider({position: 100 / dur * pos});
247
248	if(Static.playing.mode == 'html5' && Static.audio.currentTime == Static.audio.duration) audio_Ended();
249}
250
251/*--------------------------------------------------------------------------------------------------
252	Audio
253--------------------------------------------------------------------------------------------------*/
254
255function audio_list2Array(list_id) {
256	var list = [];
257	$('#'+list_id+' li').each(function() {
258		list.push($(this).data());
259	});
260	return list;
261}
262
263function audio_listKeys(list_id) {
264	var list = {};
265	$('#'+list_id+' li').each(function() {
266		list[$(this).data().id] = 1;
267	});
268	return list;
269}
270
271/*--------------------------------------------------------------------------------------------------
272	Audio Menu
273--------------------------------------------------------------------------------------------------*/
274
275function audio_getData(button) {
276	return $(button).parent().parent().data();
277}
278
279function audio_getList(button) {
280	return $(button).parent().parent().parent().attr('id');
281}
282
283function audio_Menu(button) {
284	var menu = $('#audio-menu');
285	if(!menu.length) {
286		$('#static-content').append("<div id='audio-menu' class='audio-menu'></div>");
287		menu = $('#audio-menu');
288		menu.mouseleave(function() {$(this).fadeOut('fast');});
289	}
290
291	var data = audio_getData(button);
292	var list_id = audio_getList(button);
293	Static.selectedItem = [list_id, data];
294
295	var my = $('#' + list_id).data().user_id == Static.user.id || data.user_id == Static.user.id || list_id == 'audio-my';
296
297	menu.html(
298		"<a href='" + data.url +"' download='' target='_blank' class='ext'>Ñêà÷àòü</a>" +
299		(my ? "<a href='#' onClick=\"return audio_Edit();\">Ðåäàêòèðîâàòü</a>" : '') +
300		(my && list_id != 'audio-my' ? "<a href='#' onClick=\"return audio_deleteFromPlaylist();\">Óäàëèòü</a>" : '') +
301		(my && list_id == 'audio-my' ? "<a href='#' onClick=\"return audio_deleteFromAll();\">Óäàëèòü èç âñåõ ïëåéëèñòîâ</a>" : '') +
302		(Static.user.id && !my && list_id != 'audio-my' ? "<a href='#' onClick=\"return audio_addToBasicPlaylist();\">Äîáàâèòü ê ñåáå</a>" : '') //+
303		//(Static.playing.status != -1 ? "<a href='#' onClick=\"return audio_playNext();\">Èãðàòü ñëåäóþùåé</a>" : '')
304	);
305
306	var p = $(button).offset(), offset = !Static.mobile ? 5 : menu.width() + 50;
307	menu.css('left', p.left - offset).css('top', p.top - 5).show();
308}
309
310function audio_deleteFromPlaylist() {
311	$('#audio-menu').hide();
312	var s = Static.selectedItem;
313	$('#' + s[0] + ' .audio-' + s[1].id).fadeOut('fast',function() {
314		$(this).remove();
315		audio_updatePlayingList(s[0],audio_list2Array(s[0]));
316		audio_playlistCheckEmpty(Static.selectedItem[0]);
317	});
318
319	if($('#audio-my').length) {
320		$('#audio-my .audio-' + s[1].id).fadeOut('fast',function() {
321			$(this).remove();
322			audio_updatePlayingList('audio-my',audio_list2Array('audio-my'));
323			audio_playlistCheckEmpty(Static.selectedItem[0]);
324		});
325	}
326
327	$.ajax('/audio/?mode=ajax_audio_delete&id=' + $('#' + s[0]).data().id + '&aid=' + s[1].id);
328
329	return false;
330}
331
332function audio_deleteFromAll() {
333	$('#audio-menu').hide();
334	var s = Static.selectedItem;
335
336	$('.audio-' + s[1].id).fadeOut('fast',function() {
337		var list_id = $(this).parent().attr('id');
338		$(this).remove();
339		audio_updatePlayingList(list_id,audio_list2Array(list_id));
340		audio_playlistCheckEmpty(list_id);
341
342	});
343
344	$.ajax('/audio/?mode=ajax_audio_delete_from_all&aid=' + s[1].id);
345
346	return false;
347}
348
349function audio_addToBasicPlaylist() {
350	$('#audio-menu').hide();
351
352	var s = Static.selectedItem;
353
354	$.getJSON('/audio/?mode=ajax_audio_add_basic&aid=' + s[1].id, function(data) {
355		if(!data.added_to) return;
356		var list_id = 'pl-'+data.added_to;
357		var original = $('#' + Static.selectedItem[0] + ' .audio-' + Static.selectedItem[1].id);
358		if(data.added_to) {
359			if(!$('#'+list_id).length) {
360				//Åñëè ëèñòà íåò, ìèãíåì íàøèì òðåêîì
361				original.fadeOut('fast', function() {$(this).fadeIn('fast');});
362			} else {
363				//Åñëè æå ëèñò åñòü, íàäî ïðîâåðèòü, íåò ëè òàì òàêîãî òðåêà
364				if ($('#' + list_id + ' #audio' + Static.selectedItem[1].id).length) return;
365
366				original.clone().data(original.data()).appendTo('#'+list_id);
367				original.fadeTo('fast', 0.5);
368				audio_playlistCheckEmpty(list_id);
369			}
370		}
371	});
372
373	return false;
374}
375
376function audio_Edit() {
377	$('#audio-menu').hide();
378
379	var s = $.extend({},Static.selectedItem);
380
381	$('#static-content').dialog({
382		title: 'Ðåäàêòèðîâàòü àóäèîçàïèñü',
383		fields: {
384			'artist': ['text','Èñïîëíèòåëü',s[1].artist],
385			'title': ['text','Íàçâàíèå',s[1].title],
386			'album': ['text','Àëüáîì',s[1].album],
387			'year': ['text','Ãîä',s[1].year]
388		},
389		buttons: {
390			'save' : ['submit','Ñîõðàíèòü'],
391			'cancel' : ['cancel','Îòìåíà']
392		},
393		action: '/audio/?mode=ajax_audio_update&aid=' + s[1].id,
394		method: 'post',
395		ajax: true,
396
397		onSuccess: function() {
398			s[1].artist = this.values.artist;
399			s[1].title = this.values.title;
400			s[1].album = this.values.album;
401			s[1].year = this.values.year;
402			$('.audio-'+s[1].id).each(function() {
403				$(this).replaceWith(audio_getRow(s[1]));
404			});
405		}
406	});
407}
408
409//--------------------------------------------------------------------------------------------------
410
411function audio_playlist_showMenu(button) {
412	var menu = $('#audio-menu');
413	if(!menu.length) {
414		$('#dynamic-content').before("<div id='audio-menu' class='audio-menu'></div>");
415		menu.mouseleave(function() {$(this).fadeOut('fast');});
416	}
417
418	var list_id = $(button).parent().parent().attr('id');
419	list_id = list_id.substr(0,list_id.length-1);
420	Static.selectedItem = list_id;
421
422	menu.html(
423		"<a href='#' onClick=\"return playlist_rename();\">Ïåðåèìåíîâàòü</a>" +
424		(!$('#' + list_id).data().basic ? " <a href='#' onClick=\"return playlist_del();\">Óäàëèòü</a>" : '')
425	);
426
427	var p = $(button).offset();
428	menu.css('left',p.left-5).css('top',p.top-5).show();
429}
430
431/*--------------------------------------------------------------------------------------------------
432	Audio lists
433--------------------------------------------------------------------------------------------------*/
434
435function audio_renderList(list) {
436	load_jquery_ui(function() {audio_renderListExec(list);});
437}
438function audio_renderListExec(list) {
439	$('#' + list.list_id).hide().html('');
440	for (var i in list.data) audio_renderRow(list.data[i],list.list_id);
441
442	list.loaded = true;
443	$('#' + list.list_id).data(list);
444
445	audio_updatePlayingList(list.list_id,list.data);
446
447	if(list.list_id != 'audio-search') audio_playlistCheckEmpty(list.list_id);
448
449	if(Static.mobile) {}
450	else if(list.user_id != Static.user.id) { // Ýòî îáû÷íûé ñïèñîê ìóçûêè, èç êîòîðîãî ìîæíî òàñêàòü â ïëåéëèñòû
451		$('#' + list.list_id + ' li').draggable( {connectToSortable: ".audio-list-dynamic", helper: "clone", revert: "invalid", revertDuration : 100});
452	} else {
453
454	$('#' + list.list_id).addClass('audio-list-dynamic').sortable({
455		connectWith: '.audio-list-dynamic',
456
457		activate: function() {
458			$(this).data('keys',audio_listKeys($(this).attr('id'))); //Ïåðåä íà÷àëîì ñîðòèðîâîê è ïåðåíîñîâ ñîõðàíÿåì ñïèñîê ïåñåí
459		},
460
461		beforeStop: function(event, ui) { //Òóò îòëàâëèâàì òðåêè èç fixed ëèñòà
462			var from = $(ui.helper).parent().attr('id');
463			var to = $(this).attr('id');
464			var n = $(ui.item).parent().attr('id');
465
466			if(to == n && to != from) {
467				var aid = $(ui.helper).attr('value');
468				var original = $($('#' + from + ' .audio-' + aid)[0]);
469				var c = $(this).data().keys;
470				if(c[aid]) {$(ui.item).remove(); return;}
471				$(ui.item).data(original.data());
472				original.fadeTo('fast',0.5);
473			}
474
475			$(this).data('changed',true);
476		},
477
478		remove: function() {
479			$(this).data('changed',true);
480		},
481
482		receive: function(event, ui) { //Òóò îòëàâëèâàåì ïåðåíîñ èç äðóãîãî ïëåéëèñòà
483			if($(ui.sender).hasClass('audio-list')) {
484				var aid = $(ui.item).data().id;
485				var keys = $(this).data().keys;
486				if(keys[aid]) {$(ui.sender).sortable( "cancel" );return;}
487				$(this).data('changed',true);
488			}
489		},
490
491		deactivate: function () {
492			var to = $(this).attr('id');
493			var ords = $(this).sortable('toArray');
494			for(var i in ords) ords[i] = ords[i];
495
496			audio_updatePlayingList(to,audio_list2Array(to)); //Åñëè ïëåéëèñò èãðàåò â ïëååðå, òî îáíîâèì
497
498			if ($(this).data().changed) { //Îáíîâèì âñå â áàçå
499				var keys = $(this).data().keys; //Ñòàðûé ñïèñîê ïåñåí
500				var keys_new = audio_listKeys(to); //Íîâûé ñïèñîê ïåñåí
501
502				for(var aid in keys) if (!keys_new[aid]) $.ajax('/audio/?mode=ajax_audio_delete&id=' + $(this).data().id + '&aid=' + aid);
503				for(var aid in keys_new) if (!keys[aid]) $.ajax('/audio/?mode=ajax_audio_add&id=' + $(this).data().id + '&aid=' + aid);
504					$.post('/audio/?mode=ajax_playlist_reorder&id=' + $(this).data().id, {ordering : ords});
505
506				audio_playlistCheckEmpty(to);
507			}
508		}
509	});
510	}
511
512	$('#' + list.list_id).show();
513}
514
515function audio_getRow(d) {
516	return $("<li id='" + d.id + "' class='audio-" + d.id + "' value='" + d.id + "'>" +
517	"<div class='play'><img id='play' src='/resource/image/audio/play.png' class='button' onClick=\"audio_playBy(this);\"></a></div>" +
518	"<div class='info'>" + ( d.artist ? "<a href='/audio/tag/" + d.artist + "'>" + d.artist + "</a>" : 'Íåèçâåñòíûé èñïîëíèòåëü') +
519	"<br><small>" + d.title + "</small><div id='c'></div></div>" +
520	"<div class='opts'><img src='/resource/image/audio/opt.png' class='button' onClick=\"audio_Menu(this);\"></div>" +
521	"<div class='len'><small>" +
522	(d.user_id && d.user_login ? "<small> äîáàâëåíî <a href='/audio/user/" + d.user_id + "'>" + d.user_login + "</a></small>&nbsp;&nbsp;" : '') +
523	(d.listed && d.listed != 0 ? "<span class='p'>+" + d.listed + "</span> " : '') +
524	"<a href='/audio/" + d.id + "' title='Ïîñòîÿííàÿ ññûëêà'>#</a> " + str_TimeLen(d.len) + "</small></div>" +
525	"</li>").data(d);
526}
527
528function audio_renderRow(d,list_id) {
529	audio_getRow(d).appendTo('#' + list_id);
530
531	if(Static.playing.list_id == list_id && Static.playing.id == d.id && Static.playing.status >= 0) {
532		if(Static.playing.status == 1) $(Static.playing.path + ' #play').attr('src','/resource/image/audio/pause.png');
533		if(!$('#' + list_id).hasClass('side')) media_controlsInsert(true,'',Static.playing.path + ' #c');
534	}
535}
536
537function audio_renderPlaylists(data) {
538	for(var i in data) audio_renderPlaylist(data[i]);
539}
540
541function audio_renderPlaylist(data) {
542	var list_id = data.list_id;
543
544	$('#audio-playlists').append(
545		"<div id='" + data.list_id + "h' value='" + data.id + "' class='audio-playlist-header'>" +
546		"<div class='left' onClick=\"return audio_togglePlaylist('" + list_id + "');\">" + data.title + (data.basic ? '<i> (îñíîâíîé)</i>' : '') + "</div>" +
547		"<div class='right'><img src='/resource/image/audio/opt.png' class='button' onClick=\"audio_playlist_showMenu(this);\"></div>" +
548		"<div class='right'><a href='/audio/playlist/" + data.id + "'>#</a></div>" +
549		"</div>"
550	);
551
552	$("<ul id='" + list_id + "' class='audio-list side'></ul>").data(data).appendTo('#audio-playlists');
553
554	if(data.loaded) {
555		audio_renderList(data);
556		$('#'+data.list_id+'h').addClass('no-border-radius-bottom');
557	}
558}
559
560function audio_togglePlaylist(list_id) {
561	var el = $('#'+list_id);
562
563	if(!el.data().loaded) {
564		$.getJSON('/audio?mode=ajax_playlist&id=' + el.data().id, function(data) {
565			audio_renderList(data);
566			cookie_set('expanded-'+list_id,1);
567			$('#'+data.list_id+'h').addClass('no-border-radius-bottom');
568		});
569	} else {
570		el.toggle();
571		$('#'+list_id+'h').toggleClass('no-border-radius-bottom');
572		cookie_set('expanded-'+list_id, el.is(':visible') ? 1 : 0);
573	}
574}
575
576function audio_playlistCheckEmpty(list_id) {
577	if($('#' + list_id).html() != '') {
578	$('#' + list_id).removeClass('audio-list-place');
579	} else {
580		$('#' + list_id).addClass('audio-list-place');
581	}
582}
583
584//--------------------------------------------------------------------------------------------------
585
586function audio_Search(field) {
587	var q = $(field).val();
588	if(!q || q.length < 3) {
589		$('#audio-search').remove();
590		$('#audio-global').show();
591		return;
592	}
593
594	$.post('/audio?mode=ajax_search', {query : q}, function(data) {
595		try {
596			data = JSON.parse(data);
597			$('#audio-global').hide();
598			if(!$('#audio-search').length) $('#audio-global').after("<ul id='audio-search' class='audio-list'></ul>");
599			audio_renderList(data);
600		} catch(e) { }
601	});
602}
603
604/*--------------------------------------------------------------------------------------------------
605	Radio
606--------------------------------------------------------------------------------------------------*/
607
608function radio_renderList(list) {
609	Static.radio.hide_nl = false;
610
611	$('#' + list.list_id).hide().html('');
612	for(var i in list.data) radio_renderRow(list.data[i],list.list_id);
613	$('#' + list.list_id).show();
614
615	$('#' + list.list_id).data(list);
616
617	Static.radio.list_id = list.list_id;
618	audio_updatePlayingList(list.list_id,list.data);
619}
620
621function radio_sortTop(list) {
622	var d, ss, sorted = [];
623
624	for(var i in list.data) {
625		d = list.data[i];
626		ss = radio_getStat(d.id);
627		if(!ss[0]) continue;
628		d.l = ss[0];
629		sorted.push(d);
630	}
631
632	sorted.sort(function(h1, h2) {return h1.l > h2.l ? -1 : 1}); //h1.l < h2.l ? -1 : ( h1.l == h2.l ? 0 : 1); } );
633
634	return $.extend({},list, {data: sorted});
635}
636
637function radio_renderTop() {
638	radio_renderList(radio_sortTop(Static.radio.top));
639}
640
641function radio_getRow(d) {
642	var ss = radio_getStat(d.id);
643
644	return $("<li id='" + d.id + "' class='audio-" + d.id + "' value='" + d.id + "'>" +
645	"<div class='play'><img id='play' src='/resource/image/audio/play.png' " + (ss[3] == 0 ? "class='button inactive' " : "class='button' onClick=\"audio_playBy(this);\"") + "></a></div>" +
646	"<div class='logo'><a href='/radio/" + d.id + "'><img src='" + ( d.logo ? "/content/radio-image/" + d.logo : "/resource/image/audio/radio-no-logo.png") + "'></a></div>" +
647	"<div class='info'><a href='/radio/" + d.id + "'>" + d.title + "</a>" +
648	"<br><small>" + ss[4] + "</small></div>" +
649	"</li>").data(d);
650}
651
652function radio_renderRow(d,list_id) {
653	radio_getRow(d).appendTo('#' + list_id);
654
655	if(Static.playing.list_id == list_id && Static.playing.id == d.id && Static.playing.status >= 0) {
656		if(Static.playing.status == 1) $(Static.playing.path + ' #play').attr('src','/resource/image/audio/pause.png');
657	}
658}
659
660function radio_updatePlaying() {
661	if(Static.playing.status == -1) return false;
662	var ss = radio_getStat(Static.playing.id);
663	$('#audio-static-player span').html(ss[4]);
664}
665
666function radio_initStats(stats) {
667	Static.radio.stats = stats;
668
669	if(!Static.radio.updater) Static.radio.updater = setInterval(function() {
670		$.getJSON('/radio?mode=ajax_stats', function(data) {
671			Static.radio.stats = data;
672			radio_updatePlaying();
673
674			var $o = $('#' + Static.radio.list_id);
675			if($o.length) { //åñòü ðàäèî ëèñò
676				var list = $o.data();
677				if(list.list_id == 'radio-top') {
678					radio_renderTop(list);
679				} else {
680					radio_renderList(list);
681					delete Static.radio.top;
682				}
683			} else {
684				if(Static.playing.type != 'radio') {
685					clearInterval(Static.radio.updater);
686					Static.radio.updater = 0;
687				}
688			}
689		});
690	},30000);
691}
692
693function radio_getStat(id) {
694	if(typeof Static.radio.stats[id] != 'undefined') {
695		var s = Static.radio.stats[id];
696		// listeners, song, bitrate, status, text for render
697		return [
698			s[0],
699			s[1],
700			s[2],
701			s[3],
702			(s[3] == 0 ? 'Îòêëþ÷åíî' : (s[0] > 0 ? str_Numeral(s[0],'ñëóøàòåë|ü|ÿ|åé') : 'Íå ñëóøàþò') + (s[1] ? ' — èãðàåò ' + s[1] : ''))
703		];
704	} else {return [0,'',0,0,''];}
705}
706
707function radio_Search(field) {
708	var q = $(field).val();
709	if(!q || q.length < 3) {
710		$('#radio-search').remove();
711		$('#radio-global').show();
712		return;
713	}
714
715	$.post('/radio?mode=ajax_search', {query: q}, function(data) {
716		try {
717			data = JSON.parse(data);
718			$('#radio-global').hide();
719			if(!$('#radio-search').length) $('#radio-global').after("<ul id='radio-search' class='radio-list'></ul>");
720			radio_renderList(data);
721		} catch(e) { }
722	});
723}

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.