<commit_before>'use strict';

/**
 * 
 * @typedef {Object} EpisodePlayerInfo
 * @property {EpisodeId} episodeId
 * @property {Object} audioTags
 */

(function(){
	angular
		.module('podstationBackgroundApp')
		.factory('audioBuilderService', audioBuilderService);
		
	function audioBuilderService() {
		const service = {
			buildAudio: buildAudio
		};

		return service;

		/**
		 * @param {string} audioUrl 
		 * @returns {HTMLAudioElement}
		 */
		function buildAudio(audioUrl) {
			return new Audio(audioUrl);
		};
	}
})();

(function(){
	angular
		.module('podstationBackgroundApp')
		.factory('audioPlayerService', ['$injector', '$interval', 'browser', 'messageService', 'audioBuilderService', 'podcastDataService', 'podcastStorageService', 'analyticsService', audioPlayerService]);

	function audioPlayerService($injector, $interval, browserService, messageService, audioBuilderService, podcastDataService, podcastStorageService, _analyticsService) {
		/**
		 * @type {HTMLAudioElement}
		 */ 
		var audioPlayer;
		
		/** 
		 * @type {EpisodePlayerInfo}
		 */
		var episodeInfo;
		
		/**
		 * @type {Promise}
		 */
		var playingTimeOutID;
		var timeOutCounter = 0;

		function loadPlayerOptions(storage, loaded) {
			storage.get('playerOptions', function(storageObject) {
				var playerOptions;

				if(typeof storageObject.playerOptions === "undefined") {
					playerOptions = {};
				}
				else {
					playerOptions = storageObject.playerOptions;
				}

				if( loaded(playerOptions) ) {
					storage.set({'playerOptions': playerOptions});
				}
			});
		}

		function loadLocalPlayerOptions(loaded) {
			loadPlayerOptions(browserService.storage.local, loaded);
		}

		function loadSyncPlayerOptions(loaded) {
			loadPlayerOptions(browserService.storage.sync, function(playerOptions) {
				// handling of default values
				
				if(!playerOptions.order)
					playerOptions.order = 'from_podcast';
				
				if(typeof playerOptions.removeWhenFinished === 'undefined')
					playerOptions.removeWhenFinished = true;

				return loaded(playerOptions);
			});
		};

		function getPodcastAndEpisode(episodeId) {
			return $injector.get('podcastManager').getPodcastAndEpisode(episodeId);
		}

		/**
		 * @returns {string}
		 */
		function imageUrl() {
			if(episodeInfo && episodeInfo.audioTags && episodeInfo.audioTags.imageDataUrl) {
				return episodeInfo.audioTags.imageDataUrl;
			}
			else if(episodeInfo) {
				var podcastAndEpisode = getPodcastAndEpisode(episodeInfo.episodeId);

				return podcastAndEpisode.podcast ? podcastAndEpisode.podcast.image : 'images/rss-alt-8x.png';
			}

			return undefined;
		}

		function showBrowserNotification(options) {
			switch(options.event) {
				case 'playing':
					browserService.notifications.clear('paused');
					break;
				case 'paused':
					browserService.notifications.clear('playing');
					break;
			}

			var podcastAndEpisode = getPodcastAndEpisode(episodeInfo.episodeId);

			browserService.notifications.create(options.event, {
				type: 'progress',
				iconUrl: imageUrl(),
				title: browserService.i18n.getMessage(options.event),
				message: podcastAndEpisode.episode.title,
				progress: Math.round(audioPlayer.duration ? ( audioPlayer.currentTime / audioPlayer.duration ) * 100 : 0)
			});
		}

		function getAudioTags(callback) {
			new jsmediatags.Reader(audioPlayer.src)
			.setTagsToRead(["PIC", "APIC"])
			.read({
				onSuccess: function(tag) {
					var tags = tag.tags;

					if( "picture" in tags ) {
						var image = tags.picture;
						var base64String = "";
						for (var i = 0; i < image.data.length; i++) {
								base64String += String.fromCharCode(image.data[i]);
						}

						tags.imageDataUrl = "data:" + image.format + ";base64," + window.btoa(base64String);

						callback(tags);
					}
				}
			});
		}

		function buildAudioInfo() {
			var podcastAndEpisode;
			
			podcastAndEpisode = episodeInfo ? getPodcastAndEpisode(episodeInfo.episodeId) : {};

			return {
				audio: {
					url: audioPlayer ? audioPlayer.src : '',
					imageUrl: imageUrl(),
					currentTime: audioPlayer ? audioPlayer.currentTime : 0,
					duration: audioPlayer ? audioPlayer.duration : 0,
					playbackRate: audioPlayer ? audioPlayer.playbackRate : 1.0,
					volume: audioPlayer ? audioPlayer.volume : 0,
					error: audioPlayer ? audioPlayer.error : 0,
					paused: audioPlayer.paused
				},
				episodeId: episodeInfo ? episodeInfo.episodeId : null
			}
		}

		function setEpisodeInProgress(episodeInfo, currentTime) {
			podcastStorageService.storeEpisodeUserData(episodeInfo.episodeId, {
				currentTime: currentTime
			});
		}

		function setCurrentTimeFromEpisode() {
			if(!episodeInfo) {
				return;
			}

			podcastStorageService.getEpisodeUserData(episodeInfo.episodeId).then(function(episodeUserData) {
				if(episodeUserData.currentTime >= 0 && Math.abs(episodeUserData.currentTime - audioPlayer.currentTime) > 20) {
					audioPlayer.currentTime = episodeUserData.currentTime;
				}
			});
		}

		function playingTimeOut() {
			playingTimeOutID = $interval(function() {
				messageService.for('audioPlayer').sendMessage('playing', { episodePlayerInfo: buildAudioInfo() });

				timeOutCounter++;

				if(timeOutCounter === 10) {
					timeOutCounter = 0;
					setEpisodeInProgress(episodeInfo, audioPlayer.currentTime);
				}
			}, 1000);
		}

		function pauseTimeOut() {
			if(playingTimeOutID) {
				$interval.cancel(playingTimeOutID);
				playingTimeOutID = undefined;
				timeOutCounter = 0;
			}
		}

		function refresh() {
			// it will be cleared at the stop, so we need to 
			// save it here<commit_msg>Immediate playing message on play<commit_after>'use strict';

/**
 * 
 * @typedef {Object} EpisodePlayerInfo
 * @property {EpisodeId} episodeId
 * @property {Object} audioTags
 */

(function(){
	angular
		.module('podstationBackgroundApp')
		.factory('audioBuilderService', audioBuilderService);
		
	function audioBuilderService() {
		const service = {
			buildAudio: buildAudio
		};

		return service;

		/**
		 * @param {string} audioUrl 
		 * @returns {HTMLAudioElement}
		 */
		function buildAudio(audioUrl) {
			return new Audio(audioUrl);
		};
	}
})();

(function(){
	angular
		.module('podstationBackgroundApp')
		.factory('audioPlayerService', ['$injector', '$interval', 'browser', 'messageService', 'audioBuilderService', 'podcastDataService', 'podcastStorageService', 'analyticsService', audioPlayerService]);

	function audioPlayerService($injector, $interval, browserService, messageService, audioBuilderService, podcastDataService, podcastStorageService, _analyticsService) {
		/**
		 * @type {HTMLAudioElement}
		 */ 
		var audioPlayer;
		
		/** 
		 * @type {EpisodePlayerInfo}
		 */
		var episodeInfo;
		
		/**
		 * @type {Promise}
		 */
		var playingTimeOutID;
		var timeOutCounter = 0;

		function loadPlayerOptions(storage, loaded) {
			storage.get('playerOptions', function(storageObject) {
				var playerOptions;

				if(typeof storageObject.playerOptions === "undefined") {
					playerOptions = {};
				}
				else {
					playerOptions = storageObject.playerOptions;
				}

				if( loaded(playerOptions) ) {
					storage.set({'playerOptions': playerOptions});
				}
			});
		}

		function loadLocalPlayerOptions(loaded) {
			loadPlayerOptions(browserService.storage.local, loaded);
		}

		function loadSyncPlayerOptions(loaded) {
			loadPlayerOptions(browserService.storage.sync, function(playerOptions) {
				// handling of default values
				
				if(!playerOptions.order)
					playerOptions.order = 'from_podcast';
				
				if(typeof playerOptions.removeWhenFinished === 'undefined')
					playerOptions.removeWhenFinished = true;

				return loaded(playerOptions);
			});
		};

		function getPodcastAndEpisode(episodeId) {
			return $injector.get('podcastManager').getPodcastAndEpisode(episodeId);
		}

		/**
		 * @returns {string}
		 */
		function imageUrl() {
			if(episodeInfo && episodeInfo.audioTags && episodeInfo.audioTags.imageDataUrl) {
				return episodeInfo.audioTags.imageDataUrl;
			}
			else if(episodeInfo) {
				var podcastAndEpisode = getPodcastAndEpisode(episodeInfo.episodeId);

				return podcastAndEpisode.podcast ? podcastAndEpisode.podcast.image : 'images/rss-alt-8x.png';
			}

			return undefined;
		}

		function showBrowserNotification(options) {
			switch(options.event) {
				case 'playing':
					browserService.notifications.clear('paused');
					break;
				case 'paused':
					browserService.notifications.clear('playing');
					break;
			}

			var podcastAndEpisode = getPodcastAndEpisode(episodeInfo.episodeId);

			browserService.notifications.create(options.event, {
				type: 'progress',
				iconUrl: imageUrl(),
				title: browserService.i18n.getMessage(options.event),
				message: podcastAndEpisode.episode.title,
				progress: Math.round(audioPlayer.duration ? ( audioPlayer.currentTime / audioPlayer.duration ) * 100 : 0)
			});
		}

		function getAudioTags(callback) {
			new jsmediatags.Reader(audioPlayer.src)
			.setTagsToRead(["PIC", "APIC"])
			.read({
				onSuccess: function(tag) {
					var tags = tag.tags;

					if( "picture" in tags ) {
						var image = tags.picture;
						var base64String = "";
						for (var i = 0; i < image.data.length; i++) {
								base64String += String.fromCharCode(image.data[i]);
						}

						tags.imageDataUrl = "data:" + image.format + ";base64," + window.btoa(base64String);

						callback(tags);
					}
				}
			});
		}

		function buildAudioInfo() {
			var podcastAndEpisode;
			
			podcastAndEpisode = episodeInfo ? getPodcastAndEpisode(episodeInfo.episodeId) : {};

			return {
				audio: {
					url: audioPlayer ? audioPlayer.src : '',
					imageUrl: imageUrl(),
					currentTime: audioPlayer ? audioPlayer.currentTime : 0,
					duration: audioPlayer ? audioPlayer.duration : 0,
					playbackRate: audioPlayer ? audioPlayer.playbackRate : 1.0,
					volume: audioPlayer ? audioPlayer.volume : 0,
					error: audioPlayer ? audioPlayer.error : 0,
					paused: audioPlayer.paused
				},
				episodeId: episodeInfo ? episodeInfo.episodeId : null
			}
		}

		function setEpisodeInProgress(episodeInfo, currentTime) {
			podcastStorageService.storeEpisodeUserData(episodeInfo.episodeId, {
				currentTime: currentTime
			});
		}

		function setCurrentTimeFromEpisode() {
			if(!episodeInfo) {
				return;
			}

			podcastStorageService.getEpisodeUserData(episodeInfo.episodeId).then(function(episodeUserData) {
				if(episodeUserData.currentTime >= 0 && Math.abs(episodeUserData.currentTime - audioPlayer.currentTime) > 20) {
					audioPlayer.currentTime = episodeUserData.currentTime;
				}
			});
		}

		function playingTimeOut() {
			messageService.for('audioPlayer').sendMessage('playing', { episodePlayerInfo: buildAudioInfo() });
			
			playingTimeOutID = $interval(function() {
				messageService.for('audioPlayer').sendMessage('playing', { episodePlayerInfo: buildAudioInfo() });

				timeOutCounter++;

				if(timeOutCounter === 10) {
					timeOutCounter = 0;
					setEpisodeInProgress(episodeInfo, audioPlayer.currentTime);
				}
			}, 1000);
		}

		function pauseTimeOut() {
			if(playingTimeOutID) {
				$interval.cancel(playingTimeOutID);
				playingTimeOutID = undefined;
				timeOutCounter = 0;
			}
		}

		function refresh() {
			// it will be cleared at the stop, so we need to 
			// save it here
{'fraction_non_alphanumeric': 0.12219473405195264, 'fraction_numerical': 0.006008128644636862, 'mean_word_length': 3.7578814627994954, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 40, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '360231', 'n_tokens_mistral': 4362, 'n_tokens_neox': 3371, 'n_words': 600}