import jsonpatch from 'fast-json-patch/src/json-patch'; angular.module('footyroom') .factory('livescores', ['$filter', '$rootScope', function ($filter, $rootScope) { var socket; var dayReportCb; var matchReportCb; var updateMatchCb; var updateDayCb; var subscribedMatchId; var subscribedMatch; var subscribedDay; var timezone; var dayReportDataVersion = 0; var matchReportDataVersion = 0; var subscribedDayDate; return { connect: connect, subMatch: subMatch, subDay: subDay, }; // ////////// function connect() { if (!socket) { socket = io(window.SITEURL, { path: '/livescores/socket.io/ws' }); socket.on('full-data', onFullData); socket.on('match-report', onMatchReport); socket.on('update', onUpdate); } return socket; } function subMatch(matchId, reportCb, updateCb) { matchReportCb = reportCb; updateMatchCb = updateCb; subscribedMatchId = matchId; socket.emit('subscribe-match', { matchId: matchId }); } function subDay(date, tz, reportCb, updateCb) { dayReportCb = reportCb; updateDayCb = updateCb; subscribedDayDate = date; timezone = tz; socket.emit('subscribe-day', { date: $filter('date')(date, 'yyyy-MM-dd'), timezone }); } function preprocessMatches(matches) { _(matches).each(function (match) { if (match.incidents === undefined) { match.incidents = []; } if (match.lineup === undefined) { match.lineup = []; } }); } function onFullData(data) { subscribedDay = data; dayReportDataVersion = data.version; preprocessMatches(subscribedDay.matchesById); dayReportCb(subscribedDay); $rootScope.$apply(); } function onMatchReport(matchReport) { if (subscribedMatchId !== matchReport.match.matchId) { return; } subscribedMatch = matchReport.match; matchReportDataVersion = matchReport.version; matchReportCb && matchReportCb(subscribedMatch); $rootScope.$broadcast('formation-update'); $rootScope.$apply(); } function onUpdate(data) { if (data.matches) { onDayUpdate(data); } else if (subscribedMatch) { onMatchUpdate(data); } } function onDayUpdate(data) { if (data.version !== dayReportDataVersion + 1) { // Resubscribe to get full data socket.emit('subscribe-day', { date: $filter('date')(subscribedDayDate, 'yyyy-MM-dd'), timezone, }); } else { dayReportDataVersion++; // Increment current data version } var oldMatchesLength = subscribedDay.matchesById.length; jsonpatch.apply(subscribedDay.matchesById, data.matches); if (subscribedDay.matchesById.length != oldMatchesLength) { preprocessMatches(subscribedDay.matchesById); } updateDayCb && updateDayCb(subscribedDay, data); $rootScope.$apply(); } function onMatchUpdate(data) { if (data.version !== 'undefined' && data.version !== matchReportDataVersion + 1) { // Emit subscribe match event again to get full match report data again socket.emit('subscribe-match', { matchId: subscribedMatch.matchId }); } else { matchReportDataVersion++; } jsonpatch.apply(subscribedMatch, data.patches); updateMatchCb && updateMatchCb(subscribedMatch, data.patches); $rootScope.$broadcast('formation-update'); $rootScope.$apply(); } }]);