source : StandingsBannerClassVertical.js

  1. 'use strict';
  2. /**
  3. * This widget displays a TV style banner showing the standings for your class.
  4. * Designed to be used as an overlay with OBS.
  5. *
  6. * By default, the session type is displayed as the title.
  7. * The default sponsor is SIMRacingApps.
  8. * To change either, create a file called "StandingsBanner.json" in the "Documents/SIMRacingApps" folder
  9. * with the following entries.
  10. * <pre>
  11. * {
  12. * "title": "DAYTONA 500",
  13. * "fontSize": "100%",
  14. * "sponsorImageUrls": ["Sponsors/Sponsor1.png","Sponsors/Sponsor2.png","sra"],
  15. * "sponsorSeconds": [60,120,60]
  16. * }
  17. * </pre>
  18. * In the example, the sponsor logos is an array of files that are stored in the "Documents/SIMRacingApps/Sponsors" folder.
  19. * The ratio of a sponsor file should be 4x1. The default window size calculates that to be 200x50 pixels, but it will scale up and down.
  20. * Each sponsor can have their own display time using the seconds array.
  21. * The first sponsor will be displayed for 60 seconds, the second for 120 seconds, then start over.
  22. * You can add more sponsors and seconds to display as needed.
  23. * Any image that cannot be found will be replaced with the stock SRA logo.
  24. * <p>
  25. * Example list of the files.
  26. * <pre>
  27. * Documents\SIMRacingApps\StandingsBanner.json
  28. * Documents\SIMRacingApps\Sponsors\Sponsor1.png
  29. * Documents\SIMRacingApps\Sponsors\Sponsor2.png
  30. * </pre>
  31. * <p>
  32. * Example:
  33. * <p><b>
  34. * <sra-standings-banner-class-vertical></sra-standings-banner-class-vertical><br />
  35. * </b>
  36. * <img src="../widgets/StandingsBannerClassVertical/icon.png" alt="Image goes here"/>
  37. * @ngdoc directive
  38. * @name sra-standings-banner-class-vertical
  39. * @param show-short-name Set to true to show the short name. Default is false.
  40. * @param show-team-name Set to false to not show the team name. Default is true.
  41. * @param {integer} data-sra-args-interval The interval, in milliseconds, that this widget will update from the server. Default is 500.
  42. * @author Jeffrey Gilliam
  43. * @since 1.6
  44. * @copyright Copyright (C) 2015 - 2024 Jeffrey Gilliam
  45. * @license Apache License 2.0
  46. */
  47. define(['SIMRacingApps'
  48. ,'css!widgets/StandingsBannerClassVertical/StandingsBannerClassVertical'
  49. ,'widgets/LapsBanner/LapsBanner'
  50. ,'widgets/CarNumber/CarNumber'
  51. ],function(SIMRacingApps) {
  52. var self = {
  53. name: "sraStandingsBannerClassVertical",
  54. url: 'StandingsBannerClassVertical',
  55. template: 'StandingsBannerClassVertical.html',
  56. defaultWidth: 210,
  57. defaultHeight: 340,
  58. defaultInterval: 500 //initialize with the default interval
  59. };
  60. self.module = angular.module('SIMRacingApps'); //get the main module
  61. self.module.directive(self.name,
  62. ['sraDispatcher', '$filter', '$rootScope', '$timeout', '$http',
  63. function(sraDispatcher, $filter, $rootScope, $timeout, $http) {
  64. return {
  65. restrict: 'EA',
  66. scope: true,
  67. templateUrl: sraDispatcher.getWidgetUrl(self.url) + '/' + self.template,
  68. controller: [ '$scope', function($scope) {
  69. $scope.directiveName = self.name;
  70. $scope.defaultWidth = self.defaultWidth;
  71. $scope.defaultHeight = self.defaultHeight;
  72. $scope.defaultInterval = self.defaultInterval;
  73. //load translations, if you have any comment out if you do not so it will not look for them
  74. sraDispatcher.loadTranslations(sraDispatcher.getWidgetUrl(self.url),'text',function(path) {
  75. $scope.translations = sraDispatcher.getTranslation(path);
  76. });
  77. /** your code goes here **/
  78. $scope.showShortName = false;
  79. $scope.numberOfPages = 10; //need enough for 60 cars
  80. $scope.numberOfBoxes = 3; //must match number of tables in the HTML
  81. $scope.numberOfLines = 3; //This must match what's in the HTML table rows repeat
  82. $scope.numberOfGreenPages = 16; //need enough for 60 cars
  83. $scope.numberOfGreenBoxes = 1;
  84. $scope.numberOfGreenLines = 4; //This must match what's in the HTML table rows repeat
  85. $scope.pageDelay = 10000;
  86. $scope.boxDelay = 1000;
  87. $scope.currentPage = 0;
  88. $scope.boxes = [];
  89. $scope.showBox = [];
  90. $scope.greenBoxes = [];
  91. $scope.showGreenBox = [];
  92. $scope.showLeaders = false;
  93. $scope.showTeamName = true;
  94. $scope.displayTeamName = false;
  95. for (var i=0; i < ($scope.numberOfPages * $scope.numberOfBoxes); i++) {
  96. $scope.boxes.push(i);
  97. $scope.showBox.push(false);
  98. }
  99. for (var i=0; i < ($scope.numberOfGreenPages * $scope.numberOfGreenBoxes); i++) {
  100. $scope.greenBoxes.push(i);
  101. $scope.showGreenBox.push(false);
  102. }
  103. $scope.showTeams = function() {
  104. if ($scope.showTeamName)
  105. $scope.displayTeamName = true;
  106. };
  107. $scope.updateYellowPages = function() {
  108. $scope.prevPage = $scope.currentPage;
  109. //go to the next page
  110. if (++$scope.currentPage >= $scope.numberOfPages )
  111. $scope.currentPage = 0;
  112. //but only if there are drivers on that page
  113. if ((($scope.currentPage * $scope.numberOfLines * $scope.numberOfBoxes) + 1) > $scope.data.Session.Cars.Value
  114. || !$scope.data.Car['PC'+(($scope.currentPage * $scope.numberOfLines * $scope.numberOfBoxes) + 1)]
  115. || !$scope.data.Car['PC'+(($scope.currentPage * $scope.numberOfLines * $scope.numberOfBoxes) + 1)].Number.Value
  116. )
  117. $scope.currentPage = 0;
  118. if ($scope.prevPage != $scope.currentPage) {
  119. for (var i=0; i < $scope.numberOfBoxes; i++) {
  120. // var updateShowBox = function(prevPage,currentPage,box) {
  121. // $scope.showBox[(currentPage * $scope.numberOfBoxes) + box] = true;
  122. // $scope.showBox[(prevPage * $scope.numberOfBoxes) + box] = false;
  123. // };
  124. // $timeout(updateShowBox.bind(null,$scope.prevPage,$scope.currentPage,i),$scope.boxDelay * i);
  125. $timeout( function(scope,prevPage,currentPage,box,numberOfBoxes) {
  126. scope.showBox[(currentPage * numberOfBoxes) + box] = true;
  127. scope.showBox[(prevPage * numberOfBoxes) + box] = false;
  128. },$scope.boxDelay * i,true,$scope,$scope.prevPage,$scope.currentPage,i,$scope.numberOfBoxes);
  129. }
  130. }
  131. $scope.displayTeamName = false;
  132. $timeout($scope.showTeams,$scope.pageDelay / 2);
  133. $scope.yellowTimer = $timeout($scope.updateYellowPages,$scope.pageDelay);
  134. };
  135. $scope.startYellowPages = function() {
  136. if ($scope.greenTimer) {
  137. $timeout.cancel($scope.greenTimer);
  138. $scope.greenTimer = null;
  139. }
  140. $scope.showLeaders = false;
  141. for (var i=0; i < $scope.showGreenBox.length; i++)
  142. $scope.showGreenBox[i] = false;
  143. if (!$scope.yellowTimer) {
  144. $scope.currentPage = 0;
  145. $scope.displayTeamName = false;
  146. //initially turn on the boxes on the first page
  147. for (var i=0; i < $scope.numberOfBoxes; i++)
  148. $scope.showBox[i] = true;
  149. $timeout($scope.showTeams,$scope.pageDelay / 2);
  150. $scope.yellowTimer = $timeout($scope.updateYellowPages,$scope.pageDelay);
  151. }
  152. };
  153. $scope.updateGreenPages = function() {
  154. $scope.prevPage = $scope.currentPage;
  155. //go to the next page
  156. if (++$scope.currentPage >= ($scope.numberOfGreenPages * $scope.numberOfGreenBoxes) )
  157. $scope.currentPage = 0;
  158. //but only if there are drivers on that page
  159. if ((($scope.currentPage * $scope.numberOfGreenLines * $scope.numberOfGreenBoxes) + 1 + 3/*NumLeaders*/) > $scope.data.Session.Cars.Value
  160. || !$scope.data.Car['PC'+(($scope.currentPage * $scope.numberOfGreenLines * $scope.numberOfGreenBoxes) + 1 + 3/*NumLeaders*/)]
  161. || !$scope.data.Car['PC'+(($scope.currentPage * $scope.numberOfGreenLines * $scope.numberOfGreenBoxes) + 1 + 3/*NumLeaders*/)].Number.Value
  162. )
  163. $scope.currentPage = 0;
  164. if ($scope.prevPage != $scope.currentPage) {
  165. for (var i=0; i < $scope.numberOfGreenBoxes; i++) {
  166. $timeout( function(scope,prevPage,currentPage,box,numberOfGreenBoxes) {
  167. scope.showGreenBox[(currentPage * numberOfGreenBoxes) + box] = true;
  168. scope.showGreenBox[(prevPage * numberOfGreenBoxes) + box] = false;
  169. },$scope.boxDelay * i,true,$scope,$scope.prevPage,$scope.currentPage,i,$scope.numberOfGreenBoxes);
  170. }
  171. }
  172. $scope.displayTeamName = false;
  173. $timeout($scope.showTeams,$scope.pageDelay / 4);
  174. $scope.greenTimer = $timeout($scope.updateGreenPages,$scope.pageDelay / 2);
  175. };
  176. $scope.startGreenPages = function() {
  177. if ($scope.yellowTimer) {
  178. $timeout.cancel($scope.yellowTimer);
  179. $scope.yellowTimer = null;
  180. }
  181. for (var i=0; i < $scope.showBox.length; i++)
  182. $scope.showBox[i] = false;
  183. if (!$scope.greenTimer) {
  184. $scope.currentPage = 0;
  185. $scope.displayTeamName = false;
  186. //initially turn on the leaders and the first box
  187. $scope.showLeaders = true;
  188. $scope.showGreenBox[0] = true;
  189. $timeout($scope.showTeams,$scope.pageDelay / 4);
  190. $scope.greenTimer = $timeout($scope.updateGreenPages,$scope.pageDelay / 2);
  191. }
  192. };
  193. $scope.updateFlag = function() {
  194. /**
  195. if ($scope.data.Car.REFERENCE.Messages.Value.indexOf(";REPAIR;") >= 0) {
  196. $scope.data.Session.IsCautionFlag.Value = true;
  197. }
  198. /**/
  199. if ($scope.data.Session.IsGreenFlag.Value) {
  200. $scope.startGreenPages();
  201. }
  202. else
  203. if ($scope.data.Session.IsCautionFlag.Value) {
  204. $scope.startYellowPages();
  205. }
  206. else
  207. if ($scope.data.Session.IsCheckeredFlag.Value) {
  208. $scope.startGreenPages();
  209. }
  210. else
  211. if ($scope.data.Session.IsWhiteFlag.Value) {
  212. $scope.startGreenPages();
  213. }
  214. else
  215. if ($scope.data.Session.IsRedFlag.Value) {
  216. $scope.startYellowPages();
  217. }
  218. else {
  219. $scope.startGreenPages();
  220. }
  221. };
  222. }]
  223. , link: function($scope,$element,$attrs) {
  224. //copy arguments to our scope. First if using attribute, second tag, else default to something.
  225. $attrs.sraArgsData = $attrs.sraArgsData || "";
  226. $scope.value =
  227. $scope[self.name] = sraDispatcher.getTruthy($scope.sraArgsVALUE, $attrs[self.name], $attrs.sraArgsValue, "DefaultValue");
  228. $scope.showShortName = sraDispatcher.getBoolean($scope.sraArgsSHOWSHORTNAME,$attrs.sraArgsShowShortName,$scope.showShortName);
  229. $scope.showTeamName = sraDispatcher.getBoolean($scope.sraArgsSHOWTEAMNAME,$attrs.sraArgsShowTeamName,$scope.showTeamName);
  230. /** your code goes here **/
  231. /**
  232. //For testing, Since I don't have a yellow flag in my test file
  233. //I will simulate it here when I get the meat-ball.
  234. $attrs.sraArgsData += ";Car/REFERENCE/Messages";
  235. $scope.$watch("data.Car.REFERENCE.Messages.Value",$scope.updateFlag);
  236. /**/
  237. /**standard code that should be in every directive **/
  238. $rootScope.$on('sraResize', sraDispatcher.resize($scope,$element,self.defaultWidth,self.defaultHeight));
  239. //register with the dispatcher
  240. $scope.names = sraDispatcher.subscribe($scope,$attrs,self.defaultInterval); //register subscriptions and options to the dispatcher
  241. /**watches go here **/
  242. $scope.$watch("data.Session.IsCautionFlag.Value",$scope.updateFlag);
  243. $scope.$watch("data.Session.IsCheckeredFlag.Value",$scope.updateFlag);
  244. $scope.$watch("data.Session.IsWhiteFlag.Value",$scope.updateFlag);
  245. $scope.$watch("data.Session.IsRedFlag.Value",$scope.updateFlag);
  246. $scope.$watch("data.Session.IsGreenFlag.Value",$scope.updateFlag);
  247. }
  248. };
  249. }]);
  250. return self;
  251. });