64564.js 99 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117
  1. "use strict";
  2. exports.id = 64564;
  3. exports.ids = [64564];
  4. exports.modules = {
  5. /***/ 80701:
  6. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  7. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  8. /* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__),
  9. /* harmony export */ "u": () => (/* binding */ getRandomCuratedStationId)
  10. /* harmony export */ });
  11. /* harmony import */ var lodash_range__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64042);
  12. /* harmony import */ var lodash_range__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash_range__WEBPACK_IMPORTED_MODULE_0__);
  13. /* harmony import */ var lodash_sample__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(47657);
  14. /* harmony import */ var lodash_sample__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(lodash_sample__WEBPACK_IMPORTED_MODULE_1__);
  15. const QURAN_CHAPTERS_COUNT = 114;
  16. const popularRecitersId = [
  17. "7",
  18. "3",
  19. "10",
  20. "4"
  21. ];
  22. const generatePopularRecitersAudioTracks = ()=>{
  23. return popularRecitersId.map((reciter)=>lodash_range__WEBPACK_IMPORTED_MODULE_0___default()(1, QURAN_CHAPTERS_COUNT).map((chapter)=>({
  24. surah: chapter.toString(),
  25. reciterId: reciter.toString()
  26. }))).flat();
  27. };
  28. const JUZ_AMMA_FIRST_CHAPTER = 78;
  29. const generateJuzAmmaAudioTracks = ()=>{
  30. return popularRecitersId.map((reciter)=>lodash_range__WEBPACK_IMPORTED_MODULE_0___default()(JUZ_AMMA_FIRST_CHAPTER, QURAN_CHAPTERS_COUNT).map((chapter)=>({
  31. surah: chapter.toString(),
  32. reciterId: reciter.toString()
  33. }))).flat();
  34. };
  35. const generateSurahAlKahfAudioTracks = ()=>{
  36. return popularRecitersId.map((reciterId)=>({
  37. surah: "18",
  38. reciterId
  39. }));
  40. };
  41. const curatedStations = {
  42. "1": {
  43. title: "popular-recitations.title",
  44. description: "popular-recitations.description",
  45. bannerImgSrc: "/images/stations/1.jpeg",
  46. audioTracks: generatePopularRecitersAudioTracks()
  47. },
  48. "2": {
  49. title: "yaseen-alwaqiah-al-mulk.title",
  50. description: "yaseen-alwaqiah-al-mulk.description",
  51. bannerImgSrc: "/images/stations/2.jpg",
  52. audioTracks: [
  53. {
  54. surah: "36",
  55. reciterId: "7"
  56. },
  57. {
  58. surah: "96",
  59. reciterId: "7"
  60. },
  61. {
  62. surah: "67",
  63. reciterId: "7"
  64. },
  65. ]
  66. },
  67. "3": {
  68. title: "surah-al-kahf.title",
  69. description: "surah-al-kahf.description",
  70. bannerImgSrc: "/images/stations/3.jpeg",
  71. audioTracks: generateSurahAlKahfAudioTracks()
  72. },
  73. "4": {
  74. title: "juz-amma.title",
  75. description: "juz-amma.description",
  76. bannerImgSrc: "/images/stations/4.jpeg",
  77. audioTracks: generateJuzAmmaAudioTracks()
  78. }
  79. };
  80. const getRandomCuratedStationId = ()=>{
  81. return lodash_sample__WEBPACK_IMPORTED_MODULE_1___default()(Object.keys(curatedStations));
  82. };
  83. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (curatedStations);
  84. /***/ }),
  85. /***/ 16868:
  86. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  87. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  88. /* harmony export */ "T": () => (/* binding */ StationType)
  89. /* harmony export */ });
  90. var StationType;
  91. (function(StationType) {
  92. StationType["Curated"] = "curated";
  93. StationType["Reciter"] = "reciter";
  94. })(StationType || (StationType = {}));
  95. /***/ }),
  96. /***/ 64564:
  97. /***/ ((module, __webpack_exports__, __webpack_require__) => {
  98. __webpack_require__.a(module, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
  99. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  100. /* harmony export */ "P": () => (/* binding */ AudioPlayerMachineProvider),
  101. /* harmony export */ "c": () => (/* binding */ AudioPlayerMachineContext)
  102. /* harmony export */ });
  103. /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20997);
  104. /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__);
  105. /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16689);
  106. /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
  107. /* harmony import */ var _xstate_react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(59456);
  108. /* harmony import */ var _xstate_react__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_xstate_react__WEBPACK_IMPORTED_MODULE_2__);
  109. /* harmony import */ var next_translate_useTranslation__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(60866);
  110. /* harmony import */ var next_translate_useTranslation__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(next_translate_useTranslation__WEBPACK_IMPORTED_MODULE_3__);
  111. /* harmony import */ var _actors_audioPlayer_audioPlayerMachine__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(43882);
  112. /* harmony import */ var _actors_audioPlayer_audioPlayerPersistHelper__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(76133);
  113. /* harmony import */ var _dls_Toast_Toast__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(79717);
  114. /* harmony import */ var _redux_defaultSettings_defaultSettings__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(11854);
  115. var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_dls_Toast_Toast__WEBPACK_IMPORTED_MODULE_5__]);
  116. _dls_Toast_Toast__WEBPACK_IMPORTED_MODULE_5__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
  117. /* eslint-disable import/prefer-default-export */
  118. const AudioPlayerMachineContext = /*#__PURE__*/ (0,react__WEBPACK_IMPORTED_MODULE_1__.createContext)({});
  119. const LOCAL_STORAGE_PERSISTENCE_EVENT_TRIGGER = [
  120. "CHANGE_RECITER",
  121. "SET_PLAYBACK_SPEED",
  122. "UPDATE_VOLUME",
  123. ];
  124. const AudioPlayerMachineProvider = ({ children })=>{
  125. const toast = (0,_dls_Toast_Toast__WEBPACK_IMPORTED_MODULE_5__/* .useToast */ .pm)();
  126. const { t } = next_translate_useTranslation__WEBPACK_IMPORTED_MODULE_3___default()("common");
  127. const initialXstateContext = (0,_actors_audioPlayer_audioPlayerPersistHelper__WEBPACK_IMPORTED_MODULE_7__/* .getXstateStateFromLocalStorage */ .x)();
  128. const defaultLocaleContext = {
  129. reciterId: _redux_defaultSettings_defaultSettings__WEBPACK_IMPORTED_MODULE_6__/* .DEFAULT_RECITER.id */ .YS.id
  130. };
  131. const audioPlayerService = (0,_xstate_react__WEBPACK_IMPORTED_MODULE_2__.useInterpret)(_actors_audioPlayer_audioPlayerMachine__WEBPACK_IMPORTED_MODULE_4__/* .audioPlayerMachine */ .g, {
  132. context: {
  133. ..._actors_audioPlayer_audioPlayerMachine__WEBPACK_IMPORTED_MODULE_4__/* .audioPlayerMachine.initialState.context */ .g.initialState.context,
  134. ...defaultLocaleContext,
  135. ...initialXstateContext
  136. }
  137. }, (state)=>{
  138. const { playbackRate , reciterId , volume } = state.context;
  139. if (state.matches("VISIBLE.FAILED")) {
  140. toast(t("error.general"), {
  141. status: _dls_Toast_Toast__WEBPACK_IMPORTED_MODULE_5__/* .ToastStatus.Error */ .YZ.Error
  142. });
  143. }
  144. if (LOCAL_STORAGE_PERSISTENCE_EVENT_TRIGGER.includes(state.event.type)) {
  145. (0,_actors_audioPlayer_audioPlayerPersistHelper__WEBPACK_IMPORTED_MODULE_7__/* .persistXstateToLocalStorage */ .m)({
  146. playbackRate,
  147. reciterId,
  148. volume
  149. });
  150. }
  151. });
  152. return /*#__PURE__*/ react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx(AudioPlayerMachineContext.Provider, {
  153. value: audioPlayerService,
  154. children: children
  155. });
  156. };
  157. __webpack_async_result__();
  158. } catch(e) { __webpack_async_result__(e); } });
  159. /***/ }),
  160. /***/ 43882:
  161. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  162. // EXPORTS
  163. __webpack_require__.d(__webpack_exports__, {
  164. "g": () => (/* binding */ audioPlayerMachine)
  165. });
  166. // EXTERNAL MODULE: external "lodash/random"
  167. var random_ = __webpack_require__(35526);
  168. var random_default = /*#__PURE__*/__webpack_require__.n(random_);
  169. // EXTERNAL MODULE: external "xstate"
  170. var external_xstate_ = __webpack_require__(82522);
  171. // EXTERNAL MODULE: external "xstate/lib/actions"
  172. var actions_ = __webpack_require__(44549);
  173. // EXTERNAL MODULE: external "lodash/sample"
  174. var sample_ = __webpack_require__(47657);
  175. var sample_default = /*#__PURE__*/__webpack_require__.n(sample_);
  176. // EXTERNAL MODULE: ./src/components/Radio/curatedStations.ts
  177. var curatedStations = __webpack_require__(80701);
  178. // EXTERNAL MODULE: ./src/components/Radio/types.ts
  179. var types = __webpack_require__(16868);
  180. ;// CONCATENATED MODULE: ./src/xstate/actors/radio/radioMachine.ts
  181. /* eslint-disable react-func/max-lines-per-function */ /* eslint-disable import/prefer-default-export */
  182. const createRadioMachine = ()=>{
  183. return (0,external_xstate_.createMachine)({
  184. tsTypes: {},
  185. schema: {
  186. context: {},
  187. events: {}
  188. },
  189. id: "radioMachine",
  190. initial: "on",
  191. context: {
  192. type: types/* StationType.Curated */.T.Curated
  193. },
  194. states: {
  195. on: {
  196. on: {
  197. PLAY_STATION: {
  198. actions: [
  199. "setStation",
  200. "generateRadioAudioTrack"
  201. ]
  202. },
  203. TRACK_ENDED: {
  204. actions: "generateNextAudioTrack"
  205. }
  206. }
  207. }
  208. }
  209. }, {
  210. actions: {
  211. setStation: (0,external_xstate_.assign)({
  212. type: (context, event)=>event.stationType,
  213. id: (context, event)=>event.id
  214. }),
  215. generateNextAudioTrack: (0,actions_.sendParent)((context)=>{
  216. const { type , id } = context;
  217. let randomAudioTrack;
  218. if (type === types/* StationType.Curated */.T.Curated) {
  219. const station = curatedStations/* default */.Z[id];
  220. randomAudioTrack = sample_default()(station.audioTracks);
  221. } else {
  222. randomAudioTrack = {
  223. reciterId: id,
  224. surah: random_default()(1, 114).toString()
  225. };
  226. }
  227. return {
  228. type: "PLAY_RADIO_TRACK",
  229. shouldPlayFromRandomTimeStamp: false,
  230. reciterId: Number(randomAudioTrack.reciterId),
  231. surah: Number(randomAudioTrack.surah)
  232. };
  233. }),
  234. generateRadioAudioTrack: (0,actions_.sendParent)((context, event)=>{
  235. const { stationType , id } = event;
  236. let randomAudioTrack;
  237. if (stationType === types/* StationType.Curated */.T.Curated) {
  238. const station = curatedStations/* default */.Z[id];
  239. randomAudioTrack = sample_default()(station.audioTracks);
  240. } else {
  241. randomAudioTrack = {
  242. reciterId: id,
  243. surah: random_default()(1, 114).toString()
  244. };
  245. }
  246. return {
  247. type: "PLAY_RADIO_TRACK",
  248. shouldPlayFromRandomTimeStamp: true,
  249. reciterId: Number(randomAudioTrack.reciterId),
  250. surah: Number(randomAudioTrack.surah)
  251. };
  252. })
  253. }
  254. });
  255. };
  256. ;// CONCATENATED MODULE: ./src/xstate/actors/verseCycle/verseCycleMachine.ts
  257. /* eslint-disable jsdoc/check-tag-names */ /* eslint-disable camelcase */ /* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable react-func/max-lines-per-function */ /* eslint-disable import/prefer-default-export */
  258. const createVerseCycleMachine = ({ timestampFrom , timestampTo , totalVerseCycle })=>/** @xstate-layout N4IgpgJg5mDOIC5QDcwCdZgMIE8DGANmAIJ4AuA9mgHQCWAdgApoVRpywDEAqowCLEAKgFEA+oICSAWQkA5AOKJQABwqxaZWhXpKQAD0QBaAEwB2AJzULxgCznjAZgAMTgBxOLAGhA5EAVktzIKDXP2MARlsbJ3CAX1jvVAxsfCJSShokzGF6CEhOXVV1TW1dAwRwu2oANjdq8PqG41dmh29fBAdTcOpzU1C3G1dw8OdHeISQego8+CQQLJTCEnIqOiYWNg5CtQ0tHXnyw2qHG2obRwdRroHzNp9-B2o-Fxs32vDTCxtq+MT0TC4ZbpNaLHJ5CA7Yr7MqIYxuaiuIYudzhO7mEbtRDhJx+c6uaqmALdGxo0nmP4LAFLNKrGgAMwYtFgAAtIFC9qVDtiHK5eqY7Gi3F9og4-FiEPY+aYImZqh9zNU-KZKYsgbSMhySgdQEclXyLg4rkb+i87hLDGj8S8PFdXATusZfhMgA */ (0,external_xstate_.createMachine)({
  259. context: {
  260. timestampFrom,
  261. timestampTo,
  262. totalVerseCycle,
  263. currentVerseCycle: 1
  264. },
  265. tsTypes: {},
  266. id: "verseCycleActor",
  267. initial: "inProgress",
  268. states: {
  269. inProgress: {
  270. on: {
  271. UPDATE_VERSE_TIMING: {
  272. actions: "updateVerseTiming"
  273. },
  274. TIMESTAMP_UPDATED: {
  275. cond: "verseEnded",
  276. target: "verseEnded"
  277. }
  278. }
  279. },
  280. verseEnded: {
  281. always: [
  282. {
  283. actions: "repeatSameAyah",
  284. description: "Inc context.currentVerseCycleNumber and sendParent(REPEAT_SAME_AYAH)",
  285. cond: "verseRepeatOnProgress",
  286. target: "inProgress"
  287. },
  288. {
  289. description: "When repeat cycle is done, transition to finished state",
  290. target: "finished"
  291. },
  292. ]
  293. },
  294. finished: {
  295. entry: "sendVerseRepeatFinished",
  296. description: "Send VERSE_REPEAT_FINISHED event",
  297. type: "final"
  298. }
  299. }
  300. }, {
  301. guards: {
  302. verseEnded: (context, event)=>{
  303. return event.timestamp >= context.timestampTo - 200 // 200ms is a buffer for the verse end time
  304. ;
  305. },
  306. verseRepeatOnProgress: (context)=>{
  307. return context.currentVerseCycle < context.totalVerseCycle;
  308. }
  309. },
  310. actions: {
  311. updateVerseTiming: (0,actions_.pure)((context, event)=>{
  312. return (0,external_xstate_.assign)({
  313. timestampFrom: event.timestampFrom,
  314. timestampTo: event.timestampTo
  315. });
  316. }),
  317. sendVerseRepeatFinished: (0,actions_.sendParent)(()=>{
  318. return {
  319. type: "VERSE_REPEAT_FINISHED"
  320. };
  321. }),
  322. repeatSameAyah: (0,actions_.pure)((context)=>{
  323. return [
  324. (0,external_xstate_.assign)({
  325. currentVerseCycle: context.currentVerseCycle + 1
  326. }),
  327. (0,actions_.sendParent)({
  328. type: "REPEAT_SAME_AYAH"
  329. }),
  330. ];
  331. })
  332. }
  333. });
  334. ;// CONCATENATED MODULE: ./src/xstate/actors/rangeCycle/rangeCycleMachine.ts
  335. /* eslint-disable max-lines */ /* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable jsdoc/check-tag-names */ /* eslint-disable react-func/max-lines-per-function */ /* eslint-disable import/prefer-default-export */
  336. const createRangeCycleMachine = ({ totalRangeCycle , totalVerseCycle , verseTimings , fromVerseNumber , toVerseNumber , })=>/** @xstate-layout N4IgpgJg5mDOIC5QCcCGA7GBhAngYwBswBBPAFwHtkA6AS3QAVkKpk5YBiAFQEkBZAKIBlLsT4MA+gFUGAEWJcBsxKAAOFWLTK0K6FSAAeiAGwB2AIzUALACZTAVnMAOZ1fsAGYwBoQORI+pjAGYnKwBOELdw+2NjAF84nzRMMFxCEnIqOkZmVnYOACUBBgEFCSExAQliAE1iAAl9dU1tXX0jBCszajCnd3cnIKtPczDzUysfPwQAWnGransxoLD3GydTTatxhKSMbHwiUkoaeiYWNlhOIpKygDkBAA0uarrGpBBmrR09D46YsLUCY2MZhexDGz2KxOKaIWyWcxQjaOdzbIJBey7EDJA7pY5ZM65S7XYqlF4MIoANVeDSaGm+bT+-mMgOBoPBtiRsIQQVMQWoiOhDnMqPM6MxiWx+1ShwyJ2y5zyVw4lIEBSEVRuZIkADEeHceEJ6ko6S0fu1EDMbCyBcEgu4xZs7PZuXN3IFrWZwqZUT6nMYbFicTK8ZkaMGBOgIJAOKaGb9QB0hvyHGEbNb7FD3B5Jr44TbBciRWiMQlJegKNH4B9g2kjmGFUT2HHWgnDIh1gtzFYgnYwsZtmYzNzTE5Ar2QRYwtEVk4g9K63KshGo5AW+ambMMQswhFeQN+k5kdyzGPjODwTYMU4bOZ5ylF-iaAAzei0WAACzXHy+rYtW+zRZwhZUxgncXsb25MFLD6exIWCMUYicMJ71xesTnXRlE0tXkx13dE-UPY881mGwrFMRZQNCOw3HMMj1jLOIgA */ (0,external_xstate_.createMachine)({
  337. context: {
  338. verseCycleActor: null,
  339. totalVerseCycle,
  340. totalRangeCycle,
  341. currentRangeCycle: 1,
  342. fromVerseNumber,
  343. toVerseNumber,
  344. currentVerseNumber: fromVerseNumber,
  345. verseTimings: verseTimings
  346. },
  347. tsTypes: {},
  348. id: "rangeCycleActor",
  349. initial: "inProgress",
  350. states: {
  351. inProgress: {
  352. entry: "spawnVerseCycleActor",
  353. on: {
  354. UPDATE_VERSE_TIMINGS: {
  355. actions: "updateVerseTimings"
  356. },
  357. TIMESTAMP_UPDATED: {
  358. actions: "forwardtimestampToVerseActor",
  359. description: "Receive TIMESTAMP_UPDATED event from parent. Forward to verseCycleActor"
  360. },
  361. REPEAT_SAME_AYAH: {
  362. actions: "repeatSameAyah",
  363. description: "Event from verseCycleActor. forward sendParent(REPEAT_SAME_AYAH)"
  364. },
  365. REPEAT_NEXT_AYAH: {
  366. actions: "repeatNextAyah"
  367. },
  368. REPEAT_PREV_AYAH: {
  369. actions: "repeatPreviousAyah"
  370. },
  371. REPEAT_SELECTED_AYAH: {
  372. actions: "repeatSelectedAyah"
  373. },
  374. VERSE_REPEAT_FINISHED: [
  375. {
  376. cond: "rangeEnded",
  377. target: "rangeEnded"
  378. },
  379. {
  380. actions: "spawnNextAyahActor"
  381. },
  382. ]
  383. }
  384. },
  385. rangeEnded: {
  386. description: "State where we reached the end of the range. Deciding whether to repeat or finish",
  387. always: [
  388. {
  389. actions: "repeatCycle",
  390. description: "When range cycle is not finished yet. Inc context.currentRangeCycle, respawn verseCycleActor and sendPlayFromAyah",
  391. cond: "rangeCycleOnProgress",
  392. target: "inProgress"
  393. },
  394. {
  395. description: "When range cycle is finished, transition to finished state",
  396. cond: "rangeCycleFinished",
  397. target: "finished"
  398. },
  399. ]
  400. },
  401. finished: {
  402. entry: "sendRangeRepeatFinished",
  403. description: "Send RANGE_REPEAT_FINISHED to parent",
  404. type: "final"
  405. }
  406. }
  407. }, {
  408. guards: {
  409. rangeEnded: (context)=>{
  410. return context.currentVerseNumber === toVerseNumber;
  411. },
  412. rangeCycleOnProgress: (context)=>{
  413. return context.currentRangeCycle < context.totalRangeCycle;
  414. },
  415. rangeCycleFinished: (context)=>{
  416. return context.currentRangeCycle >= context.totalRangeCycle;
  417. }
  418. },
  419. actions: {
  420. repeatSelectedAyah: (0,actions_.pure)((context, event)=>{
  421. const { ayahNumber } = event;
  422. const selectedVerseTiming = context.verseTimings[ayahNumber - 1];
  423. return [
  424. (0,actions_.stop)(context.verseCycleActor.id),
  425. (0,actions_.assign)({
  426. currentVerseNumber: ayahNumber,
  427. verseCycleActor: (0,external_xstate_.spawn)(createVerseCycleMachine({
  428. timestampFrom: selectedVerseTiming.timestampFrom,
  429. timestampTo: selectedVerseTiming.timestampTo,
  430. totalVerseCycle: context.totalVerseCycle
  431. }))
  432. }),
  433. ];
  434. }),
  435. // @ts-ignore
  436. updateVerseTimings: (0,actions_.pure)((context, event)=>{
  437. const curentVerseTiming = event.verseTimings[context.currentVerseNumber - 1];
  438. return [
  439. (0,actions_.assign)({
  440. verseTimings: event.verseTimings
  441. }),
  442. (0,actions_.send)({
  443. type: "UPDATE_VERSE_TIMING",
  444. timestampFrom: curentVerseTiming.timestampFrom,
  445. timestampTo: curentVerseTiming.timestampTo
  446. }, {
  447. to: context.verseCycleActor.id
  448. }),
  449. ];
  450. }),
  451. repeatNextAyah: (0,actions_.pure)((context)=>{
  452. const currentIndex = context.currentVerseNumber - 1;
  453. const nextVerseTiming = context.verseTimings[currentIndex + 1];
  454. const nextVerseNumber = context.currentVerseNumber + 1;
  455. if (nextVerseNumber > toVerseNumber) {
  456. return [
  457. (0,actions_.stop)(context.verseCycleActor.id),
  458. (0,actions_.sendParent)({
  459. type: "RANGE_REPEAT_FINISHED"
  460. }),
  461. ];
  462. }
  463. return [
  464. (0,actions_.stop)(context.verseCycleActor.id),
  465. (0,actions_.assign)({
  466. currentVerseNumber: nextVerseNumber,
  467. verseCycleActor: (0,external_xstate_.spawn)(createVerseCycleMachine({
  468. timestampFrom: nextVerseTiming.timestampFrom,
  469. timestampTo: nextVerseTiming.timestampTo,
  470. totalVerseCycle: context.totalVerseCycle
  471. }))
  472. }),
  473. ];
  474. }),
  475. repeatPreviousAyah: (0,actions_.pure)((context)=>{
  476. const currentIndex = context.currentVerseNumber - 1;
  477. const prevVerseTiming = context.verseTimings[currentIndex - 1];
  478. const prevVerseNumber = context.currentVerseNumber - 1;
  479. return [
  480. (0,actions_.stop)(context.verseCycleActor.id),
  481. (0,actions_.assign)({
  482. currentVerseNumber: prevVerseNumber,
  483. verseCycleActor: (0,external_xstate_.spawn)(createVerseCycleMachine({
  484. timestampFrom: prevVerseTiming.timestampFrom,
  485. timestampTo: prevVerseTiming.timestampTo,
  486. totalVerseCycle: context.totalVerseCycle
  487. }))
  488. }),
  489. ];
  490. }),
  491. spawnNextAyahActor: (0,actions_.pure)((context)=>{
  492. const currentIndex = context.currentVerseNumber - 1;
  493. const currentVerseTiming = context.verseTimings[currentIndex];
  494. const nextVerseTiming = context.verseTimings[currentIndex + 1];
  495. const nextVerseNumber = context.currentVerseNumber + 1;
  496. const previousVerseDuration = Math.abs(currentVerseTiming.duration);
  497. return [
  498. (0,actions_.stop)(context.verseCycleActor.id),
  499. (0,actions_.sendParent)({
  500. type: "REPEAT_AYAH",
  501. verseNumber: nextVerseNumber,
  502. verseDuration: previousVerseDuration
  503. }),
  504. (0,actions_.assign)({
  505. verseCycleActor: (0,external_xstate_.spawn)(createVerseCycleMachine({
  506. timestampFrom: nextVerseTiming.timestampFrom,
  507. timestampTo: nextVerseTiming.timestampTo,
  508. totalVerseCycle: context.totalVerseCycle
  509. })),
  510. currentVerseNumber: nextVerseNumber
  511. }),
  512. ];
  513. }),
  514. /**
  515. * forward TIMESTAMP_UPDATED event to verseCycleActor
  516. */ forwardtimestampToVerseActor: (0,actions_.forwardTo)((context)=>{
  517. return context.verseCycleActor;
  518. }),
  519. /**
  520. * Forward the event to parent
  521. */ repeatSameAyah: (0,actions_.sendParent)((context)=>{
  522. const verseTiming = context.verseTimings[context.currentVerseNumber - 1];
  523. const verseDuration = verseTiming.duration;
  524. return {
  525. type: "REPEAT_AYAH",
  526. verseNumber: context.currentVerseNumber,
  527. verseDuration
  528. };
  529. }),
  530. /**
  531. * Repeat Cycle
  532. * - Increment currentRangeCycle
  533. * - respawn verseCycleActor
  534. * - send to parent PLAY_FROM_AYAH
  535. */ repeatCycle: (0,actions_.pure)((context)=>{
  536. const verseTiming = context.verseTimings[fromVerseNumber - 1];
  537. const verseDuration = verseTiming.duration;
  538. return [
  539. (0,actions_.stop)(context.verseCycleActor.id),
  540. (0,actions_.assign)({
  541. currentRangeCycle: context.currentRangeCycle + 1,
  542. verseCycleActor: (0,external_xstate_.spawn)(createVerseCycleMachine({
  543. timestampFrom: verseTiming.timestampFrom,
  544. timestampTo: verseTiming.timestampTo,
  545. totalVerseCycle: context.totalVerseCycle
  546. })),
  547. currentVerseNumber: fromVerseNumber
  548. }),
  549. (0,actions_.sendParent)({
  550. type: "REPEAT_AYAH",
  551. verseNumber: context.fromVerseNumber,
  552. verseDuration
  553. }),
  554. ];
  555. }),
  556. sendRangeRepeatFinished: (0,actions_.pure)(()=>{
  557. return (0,actions_.sendParent)({
  558. type: "RANGE_REPEAT_FINISHED"
  559. });
  560. }),
  561. /**
  562. * Spawn verseCycleActor, and assign it to context
  563. */ spawnVerseCycleActor: (0,actions_.assign)({
  564. verseCycleActor: (context)=>{
  565. const curentVerseTiming = context.verseTimings[context.currentVerseNumber - 1];
  566. return (0,external_xstate_.spawn)(createVerseCycleMachine({
  567. timestampFrom: curentVerseTiming.timestampFrom,
  568. timestampTo: curentVerseTiming.timestampTo,
  569. totalVerseCycle: context.totalVerseCycle
  570. }));
  571. }
  572. })
  573. }
  574. });
  575. ;// CONCATENATED MODULE: ./src/xstate/actors/repeatMachine/repeatMachine.ts
  576. /* eslint-disable jsdoc/check-tag-names */ /* eslint-disable react-func/max-lines-per-function */ /* eslint-disable import/prefer-default-export */
  577. const createRepeatMachine = ({ totalRangeCycle , totalVerseCycle , verseTimings , fromVerseNumber , toVerseNumber , delayMultiplier , })=>/** @xstate-layout N4IgpgJg5mDOIC5QCcwAcwEMAuBZTAxgBYCWAdmAHTkAKyA9lKrLAMQT0XVkBu9A1lWSYyMAMIBPAgBsw+YuTCJQaerBLYSnZSAAeiACwGAzJQAcARgAMAVmMWzATmOOrZswBoQExNceVHdwB2CwsbCwMguwA2AF94rzJ6CDgdVAwceVIuWgYmOHgkEFV1TW0i-QQrLx8EaLjYr3SsPEJsqgAzchJYIkgdEo0tMh1Kg0cLSisAJgMbRyC3aKsgoLmaxGMzA0pohetZ6LszNZsEkGbMtsUBtSHy0EqAWlmNhCfogLMbOZsbbbszlm8XiQA */ (0,external_xstate_.createMachine)({
  578. context: {
  579. verseTimings,
  580. fromVerseNumber,
  581. toVerseNumber,
  582. delayMultiplier,
  583. repeatSettings: {
  584. totalRangeCycle,
  585. totalVerseCycle
  586. },
  587. rangeCycleActor: null
  588. },
  589. tsTypes: {},
  590. id: "repeatMachine",
  591. initial: "inProgress",
  592. states: {
  593. inProgress: {
  594. entry: "spawnRangeCycleActor",
  595. on: {
  596. UPDATE_VERSE_TIMINGS: {
  597. actions: "updateVerseTimings"
  598. },
  599. TIMESTAMP_UPDATED: {
  600. actions: "forwardToRangeCycleActor"
  601. },
  602. REPEAT_AYAH: {
  603. actions: "repeatAyah"
  604. },
  605. RANGE_REPEAT_FINISHED: {
  606. target: "finished"
  607. },
  608. REPEAT_NEXT_AYAH: {
  609. actions: "repeatNextAyah"
  610. },
  611. REPEAT_PREV_AYAH: {
  612. actions: "repeatPreviousAyah"
  613. },
  614. REPEAT_SELECTED_AYAH: [
  615. {
  616. cond: "selectedAyahIsNotInRange",
  617. target: "finished"
  618. },
  619. {
  620. actions: "repeatSelectedAyah"
  621. },
  622. ]
  623. }
  624. },
  625. finished: {
  626. type: "final",
  627. entry: "sendRepeatFinished"
  628. }
  629. }
  630. }, {
  631. guards: {
  632. selectedAyahIsNotInRange: (context, event)=>{
  633. const { ayahNumber } = event;
  634. return ayahNumber < fromVerseNumber || ayahNumber > toVerseNumber;
  635. }
  636. },
  637. actions: {
  638. repeatSelectedAyah: (0,actions_.pure)((context, event)=>{
  639. return (0,actions_.send)({
  640. type: "REPEAT_SELECTED_AYAH",
  641. ayahNumber: event.ayahNumber
  642. }, {
  643. to: context.rangeCycleActor.id
  644. });
  645. }),
  646. repeatNextAyah: (0,actions_.pure)(()=>{
  647. return (0,actions_.send)({
  648. type: "REPEAT_NEXT_AYAH"
  649. }, {
  650. to: (context)=>context.rangeCycleActor
  651. });
  652. }),
  653. repeatPreviousAyah: (0,actions_.pure)(()=>{
  654. return (0,actions_.send)({
  655. type: "REPEAT_PREV_AYAH"
  656. }, {
  657. to: (context)=>context.rangeCycleActor
  658. });
  659. }),
  660. sendRepeatFinished: (0,actions_.sendParent)({
  661. type: "REPEAT_FINISHED"
  662. }),
  663. repeatAyah: (0,actions_.pure)((context, event)=>{
  664. const verseDelay = event.verseDuration * context.delayMultiplier;
  665. return (0,actions_.sendParent)({
  666. type: "REPEAT_AYAH",
  667. ayahNumber: event.verseNumber,
  668. verseDelay
  669. });
  670. }),
  671. forwardToRangeCycleActor: (0,actions_.forwardTo)((context)=>{
  672. return context.rangeCycleActor;
  673. }),
  674. updateVerseTimings: (0,actions_.pure)((context, event)=>[
  675. (0,external_xstate_.assign)({
  676. verseTimings: event.verseTimings
  677. }),
  678. (0,actions_.send)({
  679. type: "UPDATE_VERSE_TIMINGS",
  680. verseTimings: event.verseTimings
  681. }, {
  682. to: context.rangeCycleActor.id
  683. }),
  684. ]),
  685. spawnRangeCycleActor: (0,external_xstate_.assign)({
  686. rangeCycleActor: (context)=>{
  687. return (0,external_xstate_.spawn)(createRangeCycleMachine({
  688. totalRangeCycle: context.repeatSettings.totalRangeCycle,
  689. totalVerseCycle: context.repeatSettings.totalVerseCycle,
  690. verseTimings: context.verseTimings,
  691. fromVerseNumber: context.fromVerseNumber,
  692. toVerseNumber: context.toVerseNumber
  693. }));
  694. }
  695. })
  696. }
  697. });
  698. // EXTERNAL MODULE: ./src/xstate/actors/audioPlayer/audioPlayerMachineHelper.ts + 1 modules
  699. var audioPlayerMachineHelper = __webpack_require__(93608);
  700. // EXTERNAL MODULE: ./src/utils/datetime.ts
  701. var datetime = __webpack_require__(76410);
  702. ;// CONCATENATED MODULE: ./src/xstate/actors/audioPlayer/audioPlayerMachine.ts
  703. /* eslint-disable no-param-reassign */ /* eslint-disable import/prefer-default-export */ /* eslint-disable no-restricted-syntax */ /* eslint-disable jsdoc/check-tag-names */ /* eslint-disable max-lines */
  704. /**
  705. * Note on Safari `onWaiting` hack.
  706. * ----
  707. * ISSUES
  708. * 1) Safari does not fire `onWaiting` event when audio is buffering.
  709. * It will just triggger `PAUSE` and immediately followed by `ENDED` state.
  710. * as the result, the audio player will enter the `ended` state.
  711. *
  712. * If we `.play()` the audio player again, it will start playing from the beginning.
  713. *
  714. * 2) If we set the currentTime to be, audioplayer.currentTime = context.elapsed - 000.1
  715. * And then do `.play()`
  716. * - The audio player will continue playing the audio, the onTimeUpdate event will continue to be triggered
  717. * - But there will be no sound. Since the data is actually not yet available
  718. * - On the background, safari will attempt to continue fetch mp3 data. Once the data is available. PROGRESS event will be triggered
  719. * - and then the audio player will continue from the last played position (based on `context.elapsed`)
  720. *
  721. * Workaround we do right now
  722. * 1) When the audio PAUSE, is trigger, we enter PAUSED.ACTIVE state.
  723. * 2) Followed by an END state, we just trigger `continueFromLastTimestamp`. Which basically set the currentTime to be `context.elapsed` + `.play()`
  724. * 3) The audio will enter PLAYING.LOADING, (and then enter PLAYING.ACTIVE for a split second caused by SEEKED, and the enter PLAYING.LOADING again caused by WAITING event)
  725. * 4) The audioplayer will continue download progress in the background. And then CAN_PLAY will be triggered. -> The audio player will enter PLAYING.ACTIVE again
  726. *
  727. * Note
  728. * - CAN_PLAY and WAITING here. Are not natively triggered by the browser. It's artifial/simulated @see AudioPlayer.tsx onTimeUpdate for the implementation details
  729. * - continueFromLastTimestamp will not be called when the audio is `isAudioAlmostEnded`. Because in this case the safari behavior is correct. The audio is ended.
  730. * so no need to continue downloading and playing the audio
  731. *
  732. */ const audioPlayerMachine = /** @xstate-layout N4IgpgJg5mDOIC5QEMCuECWB7ACgG2QE8wAnAOgAkBJAERoFEA5AYhwBkBBATQH0AlDjSoB5RKAAOWWBgAu2AHZiQAD0QAOAJxkADJo0A2DWu0B2AIxqTAZgBMAGhCFEAVltkALBq-7DJ5140rAF8ghzRMXAJicmo6JlZOXgEhYR4AFQEAYQBpJUlpOSxFJBVEK20zMhNNGzV9GzN3bWcLBycEG2sPAM99E20GmytnELD0bHwiUkpaBhZ2bh5uDgo8qVkFJVUEcsrqjVr6xubWx0R3KzVur2H9Y2MbZ3dRkHCJqOnYuYTFgGUAVQEqxK+Q2RS2ZQqVRqdQaTRaajaiH0Zkqni87mM7gad2eoVe40iUxis3iv3oaR4Cy4ACEODkeL8cPR6DQ1gVNiVtmZtFYyGp-O4fEN9M41FYDEidmoruiNCYbF5nNptEKTC83kTojM4ixMhQOIwAOL0fj0TJUNL0PjssHFUDcixkMxWXH+ZV+Mz+KU2dzua4GEw3cVeDWEybagBqVF+VBpbHoZABQJ4AFkY6mOGl9cxMsJGAAxKh8VNUxJpjNZ-WsxmAla2wr20oIVGi508-qGMz6Wx1KUtCVVF0yqyuoXisMRCPTaOx+OJ5MrCu-TPZii5w2ZehsMuLdMrqsUGuL4ESdaNiEtizOdumbRdnuHKVex5kALmKx+J4KtST97EshZzjBMyA4f4Ul3LhrR4KhGEtKgs1ZMgcDA8kaFAzI0ioSN6GYNJhCNI0EwbTkHUhfRtDIRUFU8MwNG7FUTB9GUTCo45nBsQY+ncdV8U1adyCA+dQPAkRIOg2D4MQ9CUP+NCMKwnDmHJehchBc9SObR5zB0ao-B4lFDF9H0-T2F1+gefplTxMYpw+QSY2AxMwIg6kJLgrDpOQ1CkPpRTcN+NIODYNgSPBLlEG0ypTEsb9DIOdwfUMf0P3MDR3DMGxtA0Zo-y1GdHOElyxLcvgYI8hCrRknz0L87DcOpMKm22coKKo+VfXo+iKNMKVyi6BpLiMCpdDo4I+PDezAMKkDitSUryqkqrvLk3zMPq5gmDZdSOXCsidlVSjqM6uiGN6s4dkCG9UvFXozGqfQ8oE6a51m0T5sSdylqQ2T5LYYRBFgo1mEYegAA1KWWU8QFBC8Io6awbwFLK1B49xnCDEy7iHT9UYeTKnqmoS3tcz6yskzzlt+pD-sB41WD4ehIyWLh6x2u1L06YZ+Q43Q0YxjQfSy1iP1FTRVXS0dCYA4nnPe8TyYqrzqfQ2mhHpgsOCoUL2bh-b0fo517mcayeKGZ8Whvd9MRldLON-Ca7Jlma5dJ7gvspn6arINWgY3RhIKazmKJsMhXAMUVamol0fQlPkP00YwXVsIZpajF2RLdqDFe+9CGESP3QYhlm2bPXbmshYx2porqzqYi77pla4rMVQxmhsNOCte12SrJxbPbz7duD9nBGeZqGg-h8oq+O2jusYkzLDYiV-DUIYcod2z-3T7vM9792c4Hsh8+H+nlFgGRkBkMAyGQAAza+SAAChwvhyR4E+uAASmYfiiYzuaCt+6VSQp-IGk99qtSOh1OeddmKDkGrbE2wxVSdwcrvQBC0KYgJkgXY0CkNr4UIsRXWmkWqfi0CYC4qIYTUT6llLQg1rD3isNiAYaCXpOT3h9A+wDlZ4KNAQpSjNmRZhLtDWGZCygUKqNQiwBw17yj6tif0TDOjNB4mKXiW98roK4Zgvu2D+Gn0EXVJSKk1Jlw5lPUUlQJRGA0MqCUMV67tAaPeHmfQvCmGcD2DhstuFAKMVTARQiApBRChA5sroWhkHsZoJxOU9Kx38J4tQPIhT3m0QSJ2O99HyywUrEJJiwmbUYNtKxetmwZTaiiHK6U-BGAVElV8ApuJZJysg-xACCmGKKT9UJZjcL-BwDQRC6QqDpmNFElqQoUpyNoUoi6jwPG3B8LCRothHqO23l3fJWcPY4OQoM9aSlqYzOkUGWRVgaEKLoRdV0zRl4mFFC8u4SpukYN6bw4JAySm+3pkXSGrMJEaT2tE8U+hnTWE4sqIY90MY+k2W+LwVl6gDBRJ8-Z+9s58OKVwIGPsAbq2BqPJm4iLnSldNClOcKbl+FcYgCwa8UXyl8aqMUzRsl-2dl8g5h8jnUkJQC4GmttaUsyZUCwugTaqjNlYZ8tgrZeFRmKYYDDuWTV5dinhuLfm4P+cSv2mRDSB1IeClqdxQ51F0M0dlwxGUdGaFcNpDj7x0XYTs3RnCirfL1f09CW1WTKRZJYmGYKK4dFYVcAwBgZTZXSfdBVF0mgHBxmvAUHETYaCxb6-leKkJBpoD8LglLRxXKoTc+RUclntE-K4HG+h0amFYd+XNJMcWHK8kWktFLzWRuvFoVULzeydBNj2KUmJfTpruDKROm8cm7L0XmztAru3lODdSWsQJKWDp0AZUdX4J0psuNdYc9j62hi9c9AJBifkBrID2ohRF6ASuOGQOp2VNFNPsA3DirF0RBmsPUG5fjr3-z5augtgaN3Fq3ckMSGR6RhskRaplAoh0Hqjke5N7RXCqhnT4DJJhNW5L2Su3VXaqrMBEfQMRRY4K-CPBU8N5dObdi0J4WoK8m2OPuj6JJ-IDg9lMPKIw2ydE3p6fm-VINwbAtLqx6xkDWofvKIqV0jjXR+ClAcViAR5SjkMmvUjS6fUdso2u6jZLx4grLapkTGnDCuD6M4fsfhWWOO-KYGwYHJMQa4SKs0ForRlTGUFZgEAig3wwPIAAblgAA1jfO+YAZAAGMAAWfAwDpdkKQXdGH90juw+O3DTKfB8nfAOVuHZ22JiC4zEL0FwscGYKQEgWByDiAIDIO+XWAC2ZBUsZey7l-LJBCupOHY+EzZX+zKjMpcZtGNuL1aJXTI0ZpRGUla5F6LZBYsJeS8NtLWWcviDAFfGgV9kC7oqHyC4zqjAZU4ulfsFxPOpsCCRxx63Gv0B2x-LMbWOtdbID1q+-WSBDZG+dsAl3ru3fuy6Dw5QxQvcyoqRKKbuyecMA0vo5QbKLu9bLXM-1ySUqeNa+iVavF9EVFKTQnnqjpMuCR8a-ntXzhDZSakdIGRMhZCx1DkbOiBHap+HibPfPin7OKMyTRm3o14-V3MBpjSmia5aa0lLDJhweq89KfoXkfcMOmjiRwsnq-g4DVISGcj67xxjOoxu-QGX7MTwjKJh2mbJy7XtE9+2XgN67nwAsPdm4bncSovim3WBuba-3Unu69pPM7qF4f3em-0M+HilF48OrXsMQMtvywIdECH+GnRqhh19I8F0YpLC-rw1Qs9lxuINA+eB4kfOljy0ZgWSljfWIJJdIYWwnuLo9TPRlcwcu7gjF79EfvtGxHkjSFhaZ1f9qIobi81nmgXnSoMCEfE8gsAQDgEoHl2ovhMH1635EQwAxWpeYEBo62TzLlXPqSl8olEzKyovI5gPYdwFsJscSqKTwhmnEfo62d6-qucK08kQyI+FwMahgs6CaqI1gAm6Mzo2I46ji942IXOpOqeOqQSD6KsG2JKI+Lyqi8KXoicIBbmyy1gKULo9E94XgrciBfqVGXsq0ouEanMGU-osaOBRgeB5WTqRgOMTBPYziy+3OeSFGNBKBYCO+lSUiHQHG3Q3GjivGLQjqdEyo0BgYlwzQoGFBd+5GFmWhR8Qq+C6Bu+0Sng-oLQvgMSHq94SUUBtwQYmIHuhgghMmtBoSIqZadQ3hfoFEMog0TOyyqarKPELEdEf2K+jhPclm0GxyJiZafolElatyNa5hCooc1sc6ds9hWqGhThhSKB1AgUwgfApaHh2wDQVCRhIYvingZhFslwzchmIG3Y9RZGy6TRfSKBRaEq1COgvo1gMoxBMofUQYVwTCBsnEh0KeAWmhzRA8I+jQN4XG-Rph-GDcTQUKcovI2UmU1QHcOR0xiYYqCYYhbG8MQo8oukXUoon45QgsDcgJzoKqFQAop03Y-2RqxowWuuYWIOu6WaQ4DCKoEokceeF0rgqOCc1QpgQYX+Lx5mDWsJW26+u2SJXRL+ceRukeuek6GUnma87ywsOaxJss1Oaa2e9J0+biji+O34ngo47J6hBW1JOw8hUKKoMpspspjQ5+QQQAA */ (0,external_xstate_.createMachine)({
  733. context: {
  734. audioPlayer: null,
  735. reciterId: 7,
  736. ayahNumber: 1,
  737. elapsed: 0,
  738. downloadProgress: 0,
  739. duration: 0,
  740. audioData: undefined,
  741. playbackRate: 1,
  742. shouldPlayFromRandomTimeStamp: false,
  743. surahVersesCount: 0,
  744. repeatActor: null,
  745. radioActor: null,
  746. verseDelay: 0,
  747. volume: 1
  748. },
  749. tsTypes: {},
  750. schema: {
  751. context: {},
  752. events: {},
  753. services: {}
  754. },
  755. id: "audioPlayer",
  756. initial: "HIDDEN",
  757. states: {
  758. HIDDEN: {
  759. description: "Audio player is hidden in the UI",
  760. on: {
  761. PLAY_RADIO: {
  762. actions: [
  763. "stopRepeatActor",
  764. "forwardPlayToRadioMachine"
  765. ]
  766. },
  767. CLOSE_RADIO: {
  768. actions: [
  769. "pauseAudio",
  770. "exitRadio"
  771. ]
  772. },
  773. PLAY_RADIO_TRACK: {
  774. actions: "setRadioStationDetails",
  775. description: "User opens the audio player to play radio of a certain station",
  776. target: "VISIBLE"
  777. },
  778. PLAY_AYAH: [
  779. {
  780. actions: [
  781. "setSurahAndAyahNumbers",
  782. "exitRadio"
  783. ],
  784. description: "User opens the audio player to play an Ayah",
  785. cond: "isUsingCustomReciterId",
  786. target: "VISIBLE.LOADING_CUSTOM_RECITER_DATA"
  787. },
  788. {
  789. actions: [
  790. "setSurahAndAyahNumbers",
  791. "exitRadio"
  792. ],
  793. description: "User opens the audio player to play an Ayah",
  794. target: "VISIBLE"
  795. },
  796. ],
  797. PLAY_SURAH: [
  798. {
  799. actions: [
  800. "setSurahAndResetAyahNumber",
  801. "exitRadio"
  802. ],
  803. cond: "isUsingCustomReciterId",
  804. target: "VISIBLE.LOADING_CUSTOM_RECITER_DATA"
  805. },
  806. {
  807. actions: [
  808. "setSurahAndResetAyahNumber",
  809. "exitRadio"
  810. ],
  811. description: "User opens the audio player to play a Surah",
  812. target: "VISIBLE"
  813. },
  814. ],
  815. SET_PLAYBACK_SPEED: {
  816. actions: "setPlaybackRate",
  817. description: "User change the playback speed"
  818. },
  819. CHANGE_RECITER: [
  820. {
  821. actions: "setReciterId",
  822. description: "User changes the reciter"
  823. },
  824. ]
  825. }
  826. },
  827. VISIBLE: {
  828. description: "Audio player is visible in the UI",
  829. initial: "LOADING_RECITER_DATA",
  830. states: {
  831. AUDIO_PLAYER_INITIATED: {
  832. description: "File has been loaded and is ready to be played",
  833. initial: "PAUSED",
  834. invoke: {
  835. src: "initMediaSession"
  836. },
  837. states: {
  838. PAUSED: {
  839. description: "Default state of the audio player",
  840. initial: "ACTIVE",
  841. states: {
  842. ACTIVE: {
  843. on: {
  844. TOGGLE: {
  845. actions: "setElapsedTime",
  846. description: "User either clicks on the play button or presses the space key",
  847. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.PLAYING.ACTIVE"
  848. },
  849. SEEKING: {
  850. description: "When the mouse or keyboard keys are clicked to jump forward/backward 5 or 10 seconds or when the user wants to navigate to a specific time.",
  851. target: "LOADING"
  852. },
  853. WAITING: {
  854. description: "Waiting for the buffer to be filled",
  855. target: "LOADING"
  856. },
  857. PLAY: {
  858. description: "Play the audio again",
  859. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.PLAYING.ACTIVE"
  860. },
  861. END: [
  862. {
  863. cond: "isAudioAlmostEnded",
  864. actions: "forwardEndedToRadioMachine",
  865. description: "Current file ended playing",
  866. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.ENDED"
  867. },
  868. {
  869. /**
  870. * This is a hack for safari.
  871. * In safari. The audio goes to ended state once the there's not enough data to play the audio.
  872. */ actions: "continueFromLastTimestamp",
  873. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.PLAYING.LOADING"
  874. },
  875. ]
  876. }
  877. },
  878. LOADING: {
  879. description: "Audio data is being fetched",
  880. tags: "loading",
  881. on: {
  882. NEXT_AYAH: [
  883. {
  884. actions: "repeatNextAyah",
  885. cond: "canRepeatNextAyah"
  886. },
  887. {
  888. actions: [
  889. "incrementAyah",
  890. "setAudioPlayerCurrentTime"
  891. ],
  892. description: "User clicks the next ayah button and it's not the last ayah of the surah already",
  893. cond: "isNotLastVerse"
  894. },
  895. ],
  896. PREV_AYAH: [
  897. {
  898. actions: "repeatPreviousAyah",
  899. cond: "canRepeatPrevAyah"
  900. },
  901. {
  902. actions: [
  903. "decrementAyah",
  904. "setAudioPlayerCurrentTime"
  905. ],
  906. description: "User clicks the previous ayah button and it's not the first ayah of the surah already",
  907. cond: "isNotFirstVerse"
  908. },
  909. ],
  910. FAIL: {
  911. description: "The audio file failed to load",
  912. target: "#audioPlayer.VISIBLE.FAILED"
  913. },
  914. CAN_PLAY: {
  915. target: "ACTIVE"
  916. },
  917. SEEKED: {
  918. target: "ACTIVE"
  919. },
  920. END: {
  921. actions: "forwardEndedToRadioMachine",
  922. description: "Current file ended playing",
  923. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.ENDED"
  924. }
  925. }
  926. }
  927. }
  928. },
  929. DELAYING: {
  930. after: {
  931. VERSE_DELAY: {
  932. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.PLAYING.ACTIVE"
  933. }
  934. },
  935. on: {
  936. TOGGLE: {
  937. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.PLAYING.ACTIVE"
  938. },
  939. NEXT_AYAH: [
  940. {
  941. actions: "repeatNextAyah",
  942. cond: "canRepeatNextAyah",
  943. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.PLAYING.ACTIVE"
  944. },
  945. {
  946. actions: [
  947. "incrementAyah",
  948. "setAudioPlayerCurrentTime"
  949. ],
  950. description: "User clicks the next ayah button and it's not the last ayah of the surah already",
  951. cond: "isNotLastVerse"
  952. },
  953. ],
  954. PREV_AYAH: [
  955. {
  956. actions: "repeatPreviousAyah",
  957. cond: "canRepeatPrevAyah",
  958. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.PLAYING.ACTIVE"
  959. },
  960. {
  961. actions: [
  962. "decrementAyah",
  963. "setAudioPlayerCurrentTime"
  964. ],
  965. description: "User clicks the previous ayah button and it's not the first ayah of the surah already",
  966. cond: "isNotFirstVerse"
  967. },
  968. ]
  969. }
  970. },
  971. PLAYING: {
  972. invoke: {
  973. id: "playAudio",
  974. src: "playAudio",
  975. onError: {
  976. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.PAUSED.ACTIVE"
  977. }
  978. },
  979. description: "The audio player is playing the audio",
  980. initial: "ACTIVE",
  981. on: {
  982. PLAY_AYAH: [
  983. {
  984. actions: [
  985. "setSurahAndAyahNumbers",
  986. "exitRadio",
  987. "stopRepeatActor"
  988. ],
  989. description: "When the user chooses to play an Ayah of another Surah",
  990. cond: "isDifferentSurahAndReciter",
  991. target: "#audioPlayer.VISIBLE.LOADING_CUSTOM_RECITER_DATA"
  992. },
  993. {
  994. actions: [
  995. "setSurahAndAyahNumbers",
  996. "exitRadio",
  997. "stopRepeatActor"
  998. ],
  999. description: "When the user chooses to play an Ayah of another Surah",
  1000. cond: "isDifferentSurah",
  1001. target: "#audioPlayer.VISIBLE.LOADING_RECITER_DATA"
  1002. },
  1003. {
  1004. actions: [
  1005. "setSurahAndAyahNumbers",
  1006. "setAudioPlayerCurrentTime"
  1007. ]
  1008. },
  1009. ],
  1010. CHANGE_RECITER: [
  1011. {
  1012. actions: [
  1013. "pauseAudio",
  1014. "setReciterId",
  1015. "resetElapsedTime"
  1016. ],
  1017. description: "User changes the reciter while the audio player is visible and might be playing",
  1018. target: "#audioPlayer.VISIBLE.LOADING_RECITER_DATA"
  1019. },
  1020. ]
  1021. },
  1022. states: {
  1023. ACTIVE: {
  1024. on: {
  1025. TOGGLE: {
  1026. actions: [
  1027. "setElapsedTime",
  1028. "pauseAudio"
  1029. ],
  1030. description: "User either clicks on the pause button or presses the space key",
  1031. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.PAUSED.ACTIVE"
  1032. },
  1033. REPEAT_AYAH: {
  1034. actions: [
  1035. (0,external_xstate_.assign)({
  1036. ayahNumber: (context, event)=>event.ayahNumber,
  1037. verseDelay: (context, event)=>event.verseDelay
  1038. }),
  1039. "pauseAudio",
  1040. "setAudioPlayerCurrentTime",
  1041. ],
  1042. description: "Repeat the current ayah",
  1043. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.DELAYING"
  1044. },
  1045. SEEKING: {
  1046. description: "When the mouse or keyboard keys are clicked to jump forward/backward 5 or 10 seconds or when the user wants to navigate to a specific time.",
  1047. target: "LOADING"
  1048. },
  1049. WAITING: {
  1050. description: "Waiting for the buffer to be filled",
  1051. target: "LOADING"
  1052. },
  1053. END: {
  1054. actions: "forwardEndedToRadioMachine",
  1055. description: "The audio finished played",
  1056. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.ENDED"
  1057. },
  1058. UPDATE_TIMING: {
  1059. actions: "updateTiming",
  1060. description: "Update the elapsed time "
  1061. },
  1062. PAUSE: {
  1063. description: "Pause the audio",
  1064. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.PAUSED.ACTIVE"
  1065. }
  1066. }
  1067. },
  1068. LOADING: {
  1069. description: "Audio data is being fetched",
  1070. tags: "loading",
  1071. on: {
  1072. NEXT_AYAH: [
  1073. {
  1074. actions: "repeatNextAyah",
  1075. cond: "canRepeatNextAyah"
  1076. },
  1077. {
  1078. actions: [
  1079. "incrementAyah",
  1080. "setAudioPlayerCurrentTime"
  1081. ],
  1082. description: "User clicks the next ayah button and it's not the last ayah of the surah already",
  1083. cond: "isNotLastVerse"
  1084. },
  1085. ],
  1086. PREV_AYAH: [
  1087. {
  1088. actions: "repeatPreviousAyah",
  1089. cond: "canRepeatPrevAyah"
  1090. },
  1091. {
  1092. actions: [
  1093. "decrementAyah",
  1094. "setAudioPlayerCurrentTime"
  1095. ],
  1096. description: "User clicks the previous ayah button and it's not the first ayah of the surah already",
  1097. cond: "isNotFirstVerse"
  1098. },
  1099. ],
  1100. FAIL: {
  1101. description: "The audio file failed to load",
  1102. target: "#audioPlayer.VISIBLE.FAILED"
  1103. },
  1104. CAN_PLAY: {
  1105. target: "ACTIVE"
  1106. },
  1107. PAUSE: {
  1108. description: "Pause the audio",
  1109. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.PAUSED.ACTIVE"
  1110. },
  1111. SEEKED: {
  1112. target: "ACTIVE"
  1113. }
  1114. }
  1115. }
  1116. }
  1117. },
  1118. HISTORY: {
  1119. history: "shallow",
  1120. type: "history"
  1121. },
  1122. ENDED: {
  1123. on: {
  1124. SEEKING: {
  1125. description: "When the mouse or keyboard keys are clicked to jump forward/backward 5 or 10 seconds or when the user wants to navigate to a specific time.",
  1126. target: "PAUSED"
  1127. },
  1128. PLAY: {
  1129. description: "Play the audio again",
  1130. target: "PLAYING"
  1131. },
  1132. PLAY_AYAH: [
  1133. {
  1134. actions: [
  1135. "setSurahAndAyahNumbers",
  1136. "exitRadio",
  1137. "stopRepeatActor"
  1138. ],
  1139. description: "When the user chooses to play an Ayah of another Surah",
  1140. cond: "isDifferentSurahAndReciter",
  1141. target: "#audioPlayer.VISIBLE.LOADING_CUSTOM_RECITER_DATA"
  1142. },
  1143. {
  1144. actions: [
  1145. "setSurahAndAyahNumbers",
  1146. "exitRadio",
  1147. "stopRepeatActor"
  1148. ],
  1149. description: "When the user chooses to play an Ayah of another Surah",
  1150. cond: "isDifferentSurah",
  1151. target: "#audioPlayer.VISIBLE.LOADING_RECITER_DATA"
  1152. },
  1153. {
  1154. actions: [
  1155. "setAyahNumber",
  1156. "setAudioPlayerCurrentTime",
  1157. "exitRadio",
  1158. "updateRepeatAyah",
  1159. ],
  1160. description: "When the user chooses to play an Ayah of the same Surah. (can be the same Ayah being recited)",
  1161. cond: "isSameSurahAndReciter",
  1162. target: "PLAYING"
  1163. },
  1164. ],
  1165. PLAY_SURAH: [
  1166. {
  1167. actions: [
  1168. "setSurahAndResetAyahNumber",
  1169. "exitRadio",
  1170. "stopRepeatActor"
  1171. ],
  1172. cond: "isUsingCustomReciterId",
  1173. target: "#audioPlayer.VISIBLE.LOADING_CUSTOM_RECITER_DATA"
  1174. },
  1175. {
  1176. actions: [
  1177. "setSurahAndResetAyahNumber",
  1178. "exitRadio",
  1179. "stopRepeatActor"
  1180. ],
  1181. description: "When the user chooses to play another Surah",
  1182. cond: "isDifferentSurah",
  1183. target: "#audioPlayer.VISIBLE.LOADING_RECITER_DATA"
  1184. },
  1185. {
  1186. actions: [
  1187. "exitRadio"
  1188. ],
  1189. description: "When the user chooses to play an Ayah of the same Surah. (can be the same Ayah being recited)",
  1190. cond: "isSameSurahAndReciter",
  1191. target: "PLAYING"
  1192. },
  1193. ],
  1194. TOGGLE: {
  1195. description: "User clicks on the play button or presses the space key",
  1196. target: "PLAYING"
  1197. },
  1198. PLAY_RADIO_TRACK: {
  1199. actions: "setRadioStationDetails",
  1200. description: "User opens the audio player to play radio of a certain station",
  1201. target: "#audioPlayer.VISIBLE.LOADING_RECITER_DATA"
  1202. }
  1203. }
  1204. }
  1205. },
  1206. on: {
  1207. PROGRESS: {
  1208. actions: "updateDownloadProgress"
  1209. },
  1210. REPEAT_FINISHED: {
  1211. actions: [
  1212. "stopRepeatActor",
  1213. "pauseAudio"
  1214. ],
  1215. target: ".PAUSED.ACTIVE"
  1216. },
  1217. NEXT_AYAH: [
  1218. {
  1219. actions: "repeatNextAyah",
  1220. cond: "canRepeatNextAyah"
  1221. },
  1222. {
  1223. actions: [
  1224. "incrementAyah",
  1225. "setAudioPlayerCurrentTime"
  1226. ],
  1227. description: "User clicks the next ayah button and it's not the last ayah of the surah already",
  1228. cond: "isNotLastVerse"
  1229. },
  1230. ],
  1231. NEXT_AUDIO_TRACK: {
  1232. actions: "nextAudioTrack"
  1233. },
  1234. SEEK_TO: [
  1235. {
  1236. cond: "isRepeatActive",
  1237. actions: "seekToAndRepeat"
  1238. },
  1239. {
  1240. actions: "seekTo"
  1241. },
  1242. ],
  1243. PREV_AYAH: [
  1244. {
  1245. actions: "repeatPreviousAyah",
  1246. cond: "canRepeatPrevAyah"
  1247. },
  1248. {
  1249. actions: [
  1250. "decrementAyah",
  1251. "setAudioPlayerCurrentTime"
  1252. ],
  1253. description: "User clicks the previous ayah button and it's not the first ayah of the surah already",
  1254. cond: "isNotFirstVerse"
  1255. },
  1256. ]
  1257. }
  1258. },
  1259. FAILED: {
  1260. description: "Either the audio file failed to load or the API to fetch the reciter + Surah data failed",
  1261. after: {
  1262. 500: {
  1263. target: "#audioPlayer.HIDDEN"
  1264. }
  1265. }
  1266. },
  1267. LOADING_RECITER_DATA: {
  1268. description: "The reciter + Surah data are being fetched",
  1269. invoke: {
  1270. src: "fetchReciter",
  1271. id: "fetchReciter",
  1272. onDone: [
  1273. {
  1274. actions: [
  1275. "setAudioData",
  1276. "setAudioPlayerSource",
  1277. "setAudioPlayerCurrentTime",
  1278. "updateRepeatVerseTimings",
  1279. ],
  1280. description: "The API call to get the selected chapter + Surah succeeded",
  1281. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.PLAYING.LOADING"
  1282. },
  1283. ],
  1284. onError: [
  1285. {
  1286. description: "The API call to get the selected chapter + Surah failed",
  1287. target: "FAILED"
  1288. },
  1289. ]
  1290. },
  1291. tags: "loading"
  1292. },
  1293. LOADING_RECITER_DATA_AND_PAUSE: {
  1294. description: "The reciter + Surah data are being fetched",
  1295. invoke: {
  1296. src: "fetchReciter",
  1297. id: "fetchReciter",
  1298. onDone: [
  1299. {
  1300. actions: [
  1301. "setAudioData",
  1302. "setAudioPlayerSource",
  1303. "setAudioPlayerCurrentTime",
  1304. "updateRepeatVerseTimings",
  1305. ],
  1306. description: "The API call to get the selected chapter + Surah succeeded",
  1307. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.PAUSED.LOADING"
  1308. },
  1309. ],
  1310. onError: [
  1311. {
  1312. description: "The API call to get the selected chapter + Surah failed",
  1313. target: "FAILED"
  1314. },
  1315. ]
  1316. },
  1317. tags: "loading"
  1318. },
  1319. LOADING_CUSTOM_RECITER_DATA: {
  1320. description: "The reciter + Surah data are being fetched",
  1321. invoke: {
  1322. src: "fetchCustomReciter",
  1323. id: "fetchCustomReciter",
  1324. onDone: [
  1325. {
  1326. actions: [
  1327. "setAudioData",
  1328. "setAudioPlayerSource",
  1329. "setAudioPlayerCurrentTime",
  1330. "updateRepeatVerseTimings",
  1331. ],
  1332. description: "The API call to get the selected chapter + Surah succeeded",
  1333. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.PLAYING.LOADING"
  1334. },
  1335. ],
  1336. onError: [
  1337. {
  1338. description: "The API call to get the selected chapter + Surah failed",
  1339. target: "FAILED"
  1340. },
  1341. ]
  1342. },
  1343. tags: "loading"
  1344. },
  1345. LOADING_REPEAT_DATA: {
  1346. invoke: {
  1347. src: "fetchRepeatData",
  1348. id: "fetchRepeatData",
  1349. onDone: [
  1350. {
  1351. actions: [
  1352. "setAudioData",
  1353. "setAudioPlayerSource",
  1354. "setAudioPlayerCurrentTime",
  1355. (0,external_xstate_.assign)({
  1356. surah: (context, event)=>event.data.surah,
  1357. ayahNumber: (context, event)=>event.data.from,
  1358. repeatActor: (context, event)=>{
  1359. return (0,external_xstate_.spawn)(createRepeatMachine({
  1360. fromVerseNumber: event.data.from,
  1361. toVerseNumber: event.data.to,
  1362. totalRangeCycle: event.data.repeatRange,
  1363. totalVerseCycle: event.data.repeatEachVerse,
  1364. verseTimings: context.audioData.verseTimings,
  1365. delayMultiplier: event.data.delayMultiplier
  1366. }));
  1367. }
  1368. }),
  1369. ],
  1370. description: "The API call to get the selected chapter + Surah succeeded",
  1371. target: "#audioPlayer.VISIBLE.AUDIO_PLAYER_INITIATED.PLAYING.LOADING"
  1372. },
  1373. ],
  1374. onError: [
  1375. {
  1376. description: "The API call to get the selected chapter + Surah failed",
  1377. target: "FAILED"
  1378. },
  1379. ]
  1380. },
  1381. tags: "loading"
  1382. }
  1383. },
  1384. on: {
  1385. CLOSE: {
  1386. actions: [
  1387. "resetElapsedTime",
  1388. "resetAyahNumber",
  1389. "pauseAudio"
  1390. ],
  1391. description: "User closes the audio player",
  1392. target: "HIDDEN"
  1393. },
  1394. SET_PLAYBACK_SPEED: {
  1395. actions: "setPlaybackRate",
  1396. description: "User change the playback speed"
  1397. },
  1398. CHANGE_RECITER: [
  1399. {
  1400. cond: "isRadioActive",
  1401. actions: "forwardChangeReciterToRadioMachine"
  1402. },
  1403. {
  1404. actions: [
  1405. "pauseAudio",
  1406. "setReciterId",
  1407. "resetElapsedTime"
  1408. ],
  1409. description: "User changes the reciter while the audio player is visible and might be playing",
  1410. target: ".LOADING_RECITER_DATA_AND_PAUSE"
  1411. },
  1412. ],
  1413. PLAY_RADIO_TRACK: {
  1414. actions: "setRadioStationDetails",
  1415. description: "User opens the audio player to play radio of a certain station",
  1416. target: ".LOADING_RECITER_DATA"
  1417. },
  1418. PLAY_AYAH: [
  1419. {
  1420. description: "When the user is clicking play ayah. On the currently playing ayah, resume it",
  1421. cond: "isSameAyah",
  1422. target: ".AUDIO_PLAYER_INITIATED.PLAYING.ACTIVE"
  1423. },
  1424. {
  1425. actions: [
  1426. "setSurahAndAyahNumbers",
  1427. "exitRadio",
  1428. "stopRepeatActor"
  1429. ],
  1430. description: "When the user chooses to play an Ayah of another Surah",
  1431. cond: "isDifferentSurah",
  1432. target: "VISIBLE.LOADING_RECITER_DATA"
  1433. },
  1434. {
  1435. actions: [
  1436. "setAyahNumber",
  1437. "setAudioPlayerCurrentTime",
  1438. "exitRadio",
  1439. "updateRepeatAyah",
  1440. ],
  1441. description: "When the user chooses to play an Ayah of the same Surah. (can be the same Ayah being recited)",
  1442. cond: "isSameSurahAndReciter",
  1443. target: ".AUDIO_PLAYER_INITIATED.PLAYING.LOADING"
  1444. },
  1445. ],
  1446. PLAY_SURAH: [
  1447. {
  1448. description: "When the users is playing the same surah. Just resume it",
  1449. cond: "isSameSurahAndReciter",
  1450. target: ".AUDIO_PLAYER_INITIATED.PLAYING.ACTIVE"
  1451. },
  1452. {
  1453. actions: [
  1454. "setSurahAndResetAyahNumber",
  1455. "exitRadio",
  1456. "stopRepeatActor"
  1457. ],
  1458. cond: "isUsingCustomReciterId",
  1459. target: "VISIBLE.LOADING_CUSTOM_RECITER_DATA"
  1460. },
  1461. {
  1462. actions: [
  1463. "setSurahAndResetAyahNumber",
  1464. "exitRadio",
  1465. "stopRepeatActor"
  1466. ],
  1467. description: "When the user chooses to play another Surah",
  1468. cond: "isDifferentSurah",
  1469. target: "VISIBLE.LOADING_RECITER_DATA"
  1470. },
  1471. ],
  1472. PLAY_RADIO: {
  1473. actions: [
  1474. "stopRepeatActor",
  1475. "forwardPlayToRadioMachine"
  1476. ]
  1477. },
  1478. CLOSE_RADIO: {
  1479. actions: [
  1480. "pauseAudio",
  1481. "exitRadio"
  1482. ],
  1483. target: "HIDDEN"
  1484. },
  1485. UPDATE_VOLUME: {
  1486. actions: "updateVolume",
  1487. description: "User updates the volume"
  1488. }
  1489. }
  1490. }
  1491. },
  1492. on: {
  1493. SET_AUDIO_REF: {
  1494. actions: "setAudioRef"
  1495. },
  1496. SET_REPEAT_SETTING: {
  1497. actions: [
  1498. "exitRadio"
  1499. ],
  1500. target: ".VISIBLE.LOADING_REPEAT_DATA"
  1501. },
  1502. SET_INITIAL_CONTEXT: {
  1503. actions: "setInitialContext"
  1504. },
  1505. SET_RECITERS_LIST: {
  1506. actions: "setRecitersList"
  1507. }
  1508. }
  1509. }, {
  1510. actions: {
  1511. continueFromLastTimestamp: (context)=>{
  1512. /**
  1513. * This is hack for safari where the audioplayer goes to ended, instead of waiting for the buffer data
  1514. */ context.audioPlayer.currentTime = context.elapsed - 0.0001;
  1515. context.audioPlayer.play();
  1516. },
  1517. setRecitersList: (0,external_xstate_.assign)({
  1518. recitersList: (context, event)=>event.recitersList
  1519. }),
  1520. setInitialContext: (0,external_xstate_.assign)({
  1521. reciterId: (context, event)=>event.reciterId,
  1522. playbackRate: (context, event)=>event.playbackRate,
  1523. volume: (context, event)=>event.volume
  1524. }),
  1525. updateRepeatAyah: (0,actions_.pure)((context, event)=>{
  1526. if (context.repeatActor) {
  1527. return (0,external_xstate_.send)({
  1528. type: "REPEAT_SELECTED_AYAH",
  1529. ayahNumber: event.ayahNumber
  1530. }, {
  1531. to: context.repeatActor.id
  1532. });
  1533. }
  1534. return [];
  1535. }),
  1536. exitRadio: (0,actions_.pure)((context)=>{
  1537. const { radioActor } = context;
  1538. let actions = [];
  1539. if (radioActor) {
  1540. actions = [
  1541. // @ts-ignore
  1542. (0,actions_.stop)(radioActor),
  1543. (0,external_xstate_.assign)({
  1544. radioActor: ()=>null,
  1545. shouldPlayFromRandomTimeStamp: ()=>false
  1546. }),
  1547. ];
  1548. }
  1549. return actions;
  1550. }),
  1551. forwardEndedToRadioMachine: (0,actions_.pure)((context)=>{
  1552. let actions = [];
  1553. const { radioActor } = context;
  1554. if (radioActor) {
  1555. actions = [
  1556. (0,external_xstate_.assign)({
  1557. ayahNumber: 1
  1558. }),
  1559. (0,external_xstate_.send)({
  1560. type: "TRACK_ENDED"
  1561. }, {
  1562. // @ts-ignore
  1563. to: radioActor
  1564. }),
  1565. ];
  1566. }
  1567. return actions;
  1568. }),
  1569. setRadioStationDetails: (0,external_xstate_.assign)({
  1570. shouldPlayFromRandomTimeStamp: (context, event)=>event.shouldPlayFromRandomTimeStamp,
  1571. reciterId: (context, event)=>event.reciterId,
  1572. surah: (context, event)=>event.surah
  1573. }),
  1574. decrementAyah: (0,external_xstate_.assign)({
  1575. ayahNumber: (context)=>context.ayahNumber - 1
  1576. }),
  1577. incrementAyah: (0,external_xstate_.assign)({
  1578. ayahNumber: (context)=>context.ayahNumber + 1
  1579. }),
  1580. setSurahAndResetAyahNumber: (0,external_xstate_.assign)({
  1581. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  1582. surah: (context, event)=>event.surah,
  1583. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  1584. ayahNumber: (context)=>1
  1585. }),
  1586. setAyahNumber: (0,external_xstate_.assign)({
  1587. ayahNumber: (context, event)=>event.ayahNumber
  1588. }),
  1589. setSurahAndAyahNumbers: (0,external_xstate_.assign)({
  1590. surah: (context, event)=>event.surah,
  1591. ayahNumber: (context, event)=>event.ayahNumber
  1592. }),
  1593. setAudioRef: (0,external_xstate_.assign)({
  1594. audioPlayer: (context, event)=>event.audioPlayerRef
  1595. }),
  1596. setAudioData: (0,external_xstate_.assign)({
  1597. duration: (context, event)=>{
  1598. return (0,datetime/* milliSecondsToSeconds */.Rp)(event.data.duration);
  1599. },
  1600. audioData: (context, event)=>event.data,
  1601. surahVersesCount: (context, event)=>event.data.verseTimings.length
  1602. }),
  1603. setAudioPlayerSource: (context)=>{
  1604. const { audioData: { audioUrl } , } = context;
  1605. context.audioPlayer.src = audioUrl;
  1606. },
  1607. setAudioPlayerCurrentTime: (context)=>{
  1608. const { ayahNumber , audioData: { verseTimings } , duration , shouldPlayFromRandomTimeStamp , } = context;
  1609. if (shouldPlayFromRandomTimeStamp) {
  1610. const randomTimestamp = random_default()(0, duration);
  1611. context.audioPlayer.currentTime = randomTimestamp;
  1612. } else {
  1613. const ayahTimestamps = verseTimings[ayahNumber - 1];
  1614. const { timestampFrom } = ayahTimestamps;
  1615. context.audioPlayer.currentTime = (0,datetime/* milliSecondsToSeconds */.Rp)(timestampFrom);
  1616. }
  1617. },
  1618. resetElapsedTime: (0,external_xstate_.assign)({
  1619. elapsed: 0
  1620. }),
  1621. updateDownloadProgress: (0,external_xstate_.assign)({
  1622. downloadProgress: (context, event)=>event.timestamp
  1623. }),
  1624. // @ts-ignore
  1625. setElapsedTime: (0,actions_.pure)((context)=>{
  1626. const activeVerseTiming = (0,audioPlayerMachineHelper/* getActiveVerseTiming */.yr)(context);
  1627. const ayahNumber = (0,audioPlayerMachineHelper/* getActiveAyahNumber */.m9)(activeVerseTiming);
  1628. const wordLocation = (0,audioPlayerMachineHelper/* getActiveWordLocation */.Mb)(activeVerseTiming, context.audioPlayer.currentTime * 1000);
  1629. return (0,external_xstate_.assign)({
  1630. elapsed: context.audioPlayer.currentTime,
  1631. ayahNumber,
  1632. wordLocation
  1633. });
  1634. }),
  1635. setReciterId: (0,external_xstate_.assign)({
  1636. reciterId: (context, event)=>event.reciterId
  1637. }),
  1638. resetAyahNumber: (0,external_xstate_.assign)({
  1639. ayahNumber: 1
  1640. }),
  1641. pauseAudio: (context)=>{
  1642. context.audioPlayer.pause();
  1643. },
  1644. setPlaybackRate: (0,actions_.pure)((context, event)=>{
  1645. const { playbackRate } = event;
  1646. // eslint-disable-next-line no-param-reassign
  1647. context.audioPlayer.playbackRate = playbackRate;
  1648. return (0,external_xstate_.assign)({
  1649. playbackRate
  1650. });
  1651. }),
  1652. updateTiming: (0,actions_.pure)((context)=>{
  1653. const actions = [];
  1654. actions.push("setElapsedTime");
  1655. if (context.repeatActor) {
  1656. actions.push((0,external_xstate_.send)({
  1657. type: "TIMESTAMP_UPDATED",
  1658. timestamp: context.audioPlayer.currentTime * 1000
  1659. }, {
  1660. to: context.repeatActor.id
  1661. }));
  1662. }
  1663. return actions;
  1664. }),
  1665. forwardPlayToRadioMachine: (0,actions_.pure)((context, event)=>{
  1666. const actions = [];
  1667. let { radioActor } = context;
  1668. // if the radioActor doesn't exist, spawn a new one
  1669. if (!radioActor) {
  1670. radioActor = (0,external_xstate_.spawn)(createRadioMachine());
  1671. actions.push((0,external_xstate_.assign)({
  1672. radioActor
  1673. }));
  1674. }
  1675. actions.push((0,external_xstate_.send)({
  1676. type: "PLAY_STATION",
  1677. stationType: event.stationType,
  1678. id: event.stationId
  1679. }, {
  1680. to: radioActor.id
  1681. }));
  1682. return actions;
  1683. }),
  1684. forwardChangeReciterToRadioMachine: (0,actions_.pure)((context, event)=>{
  1685. const actions = [];
  1686. let { radioActor } = context;
  1687. // if the radioActor doesn't exist, spawn a new one
  1688. if (!radioActor) {
  1689. radioActor = (0,external_xstate_.spawn)(createRadioMachine());
  1690. actions.push((0,external_xstate_.assign)({
  1691. radioActor
  1692. }));
  1693. }
  1694. actions.push((0,external_xstate_.send)({
  1695. type: "PLAY_STATION",
  1696. stationType: types/* StationType.Reciter */.T.Reciter,
  1697. id: event.reciterId
  1698. }, {
  1699. to: radioActor.id
  1700. }));
  1701. return actions;
  1702. }),
  1703. stopRepeatActor: (0,actions_.pure)((context)=>{
  1704. if (context.repeatActor) {
  1705. return [
  1706. (0,actions_.stop)(context.repeatActor.id),
  1707. (0,external_xstate_.assign)({
  1708. repeatActor: null
  1709. }),
  1710. ];
  1711. }
  1712. return [];
  1713. }),
  1714. // @ts-ignore
  1715. repeatNextAyah: (0,actions_.pure)((context)=>[
  1716. (0,external_xstate_.send)({
  1717. type: "REPEAT_NEXT_AYAH"
  1718. }, {
  1719. to: context.repeatActor.id
  1720. }),
  1721. "incrementAyah",
  1722. "setAudioPlayerCurrentTime",
  1723. ]),
  1724. // @ts-ignore
  1725. repeatPreviousAyah: (0,actions_.pure)((context)=>{
  1726. if (context.repeatActor) {
  1727. return [
  1728. (0,external_xstate_.send)({
  1729. type: "REPEAT_PREV_AYAH"
  1730. }, {
  1731. to: context.repeatActor.id
  1732. }),
  1733. "decrementAyah",
  1734. "setAudioPlayerCurrentTime",
  1735. ];
  1736. }
  1737. return [];
  1738. }),
  1739. updateRepeatVerseTimings: (0,actions_.pure)((context)=>{
  1740. const actions = [];
  1741. if (context.repeatActor) {
  1742. actions.push((0,external_xstate_.send)({
  1743. type: "UPDATE_VERSE_TIMINGS",
  1744. verseTimings: context.audioData.verseTimings
  1745. }, {
  1746. to: context.repeatActor.id
  1747. }));
  1748. }
  1749. return actions;
  1750. }),
  1751. nextAudioTrack: (0,actions_.pure)((context)=>{
  1752. if (context.radioActor) {
  1753. return (0,external_xstate_.send)({
  1754. type: "TRACK_ENDED"
  1755. }, {
  1756. to: context.radioActor.id
  1757. });
  1758. }
  1759. return [];
  1760. }),
  1761. seekTo: (0,actions_.pure)((context, event)=>{
  1762. // eslint-disable-next-line no-param-reassign
  1763. context.audioPlayer.currentTime = event.timestamp;
  1764. return (0,external_xstate_.assign)({
  1765. elapsed: event.timestamp
  1766. });
  1767. }),
  1768. seekToAndRepeat: (0,actions_.pure)((context, event)=>{
  1769. const actions = [];
  1770. const ayahNumber = (0,audioPlayerMachineHelper/* getAyahNumberByTimestamp */.SQ)(context.audioData.verseTimings, (0,datetime/* secondsToMilliSeconds */.pE)(event.timestamp));
  1771. if (context.repeatActor) {
  1772. actions.push((0,external_xstate_.send)({
  1773. type: "REPEAT_SELECTED_AYAH",
  1774. ayahNumber
  1775. }, {
  1776. to: context.repeatActor.id
  1777. }));
  1778. }
  1779. actions.push("seekTo");
  1780. return actions;
  1781. }),
  1782. updateVolume: (0,actions_.pure)((context, { volume })=>{
  1783. context.audioPlayer.volume = volume;
  1784. return (0,external_xstate_.assign)({
  1785. volume
  1786. });
  1787. })
  1788. },
  1789. guards: {
  1790. isRadioActive: (context)=>!!context.radioActor,
  1791. isNotLastVerse: (context)=>context.ayahNumber < context.surahVersesCount,
  1792. isNotFirstVerse: (context)=>context.ayahNumber !== 1,
  1793. canRepeatPrevAyah: (context)=>context.ayahNumber !== 1 && !!context.repeatActor,
  1794. canRepeatNextAyah: (context)=>context.ayahNumber < context.surahVersesCount && !!context.repeatActor,
  1795. isDifferentSurah: (context, event)=>context.surah !== event.surah,
  1796. isDifferentSurahAndReciter: (context, event)=>{
  1797. const reciterId = event.reciterId || context.reciterId;
  1798. return context.surah !== event.surah && reciterId !== context.audioData?.reciterId;
  1799. },
  1800. isSameAyah: (context, event)=>context.ayahNumber === event.ayahNumber && context.surah === event.surah,
  1801. isSameSurahAndReciter: (context, event)=>{
  1802. // @ts-ignore
  1803. const reciterId = event.reciterId || context.reciterId;
  1804. return context.surah === event.surah && reciterId === context.audioData?.reciterId;
  1805. },
  1806. isRepeatActive: (context)=>!!context.repeatActor,
  1807. isUsingCustomReciterId: (context, event)=>!!event.reciterId,
  1808. isAudioAlmostEnded: (context)=>{
  1809. const { currentTime } = context.audioPlayer;
  1810. const duration = (0,datetime/* milliSecondsToSeconds */.Rp)(context.audioData.duration);
  1811. const durationWithTolerancePeriod = duration - 3;
  1812. return currentTime > durationWithTolerancePeriod;
  1813. }
  1814. },
  1815. services: {
  1816. playAudio: (context)=>{
  1817. context.audioPlayer.playbackRate = context.playbackRate;
  1818. context.audioPlayer.volume = context.volume;
  1819. return context.audioPlayer.play();
  1820. },
  1821. fetchReciter: (context)=>(0,audioPlayerMachineHelper/* executeFetchReciter */.B2)(context),
  1822. fetchCustomReciter: (context, event)=>{
  1823. // @ts-ignore
  1824. return (0,audioPlayerMachineHelper/* executeFetchReciter */.B2)({
  1825. surah: event.surah,
  1826. reciterId: event.reciterId
  1827. });
  1828. },
  1829. fetchRepeatData: (context, event)=>(0,audioPlayerMachineHelper/* executeFetchReciterFromEvent */.aB)(context, event),
  1830. // eslint-disable-next-line react-func/max-lines-per-function
  1831. initMediaSession: (context)=>(callback)=>{
  1832. if ("mediaSession" in navigator) {
  1833. (0,audioPlayerMachineHelper/* getRecitersList */.KA)(context).then((recitersList)=>{
  1834. callback({
  1835. type: "SET_RECITERS_LIST",
  1836. recitersList
  1837. });
  1838. (0,audioPlayerMachineHelper/* getMediaSessionMetaData */.Gq)(context, recitersList).then((metaData)=>{
  1839. navigator.mediaSession.metadata = metaData;
  1840. });
  1841. });
  1842. }
  1843. const actionHandlers = [
  1844. [
  1845. "play",
  1846. ()=>callback("TOGGLE")
  1847. ],
  1848. [
  1849. "pause",
  1850. ()=>callback("TOGGLE")
  1851. ],
  1852. [
  1853. "previoustrack",
  1854. ()=>{
  1855. if (context.radioActor) {
  1856. callback("NEXT_AUDIO_TRACK");
  1857. }
  1858. callback("PREV_AYAH");
  1859. },
  1860. ],
  1861. [
  1862. "nexttrack",
  1863. ()=>{
  1864. if (context.radioActor) {
  1865. callback("NEXT_AUDIO_TRACK");
  1866. }
  1867. callback("NEXT_AYAH");
  1868. },
  1869. ],
  1870. [
  1871. "stop",
  1872. ()=>{
  1873. callback("END");
  1874. },
  1875. ],
  1876. ];
  1877. for (const [action, handler] of actionHandlers){
  1878. try {
  1879. navigator.mediaSession.setActionHandler(action, handler);
  1880. } catch (error) {
  1881. // eslint-disable-next-line no-console
  1882. console.log(`The media session action "${action}" is not supported yet.`);
  1883. }
  1884. }
  1885. }
  1886. },
  1887. delays: {
  1888. VERSE_DELAY: (context)=>{
  1889. return context.verseDelay;
  1890. }
  1891. }
  1892. });
  1893. /***/ }),
  1894. /***/ 93608:
  1895. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  1896. // EXPORTS
  1897. __webpack_require__.d(__webpack_exports__, {
  1898. "B2": () => (/* binding */ executeFetchReciter),
  1899. "aB": () => (/* binding */ executeFetchReciterFromEvent),
  1900. "m9": () => (/* binding */ getActiveAyahNumber),
  1901. "yr": () => (/* binding */ getActiveVerseTiming),
  1902. "Mb": () => (/* binding */ getActiveWordLocation),
  1903. "SQ": () => (/* binding */ getAyahNumberByTimestamp),
  1904. "Gq": () => (/* binding */ getMediaSessionMetaData),
  1905. "KA": () => (/* binding */ getRecitersList),
  1906. "Po": () => (/* binding */ getWordTimeSegment)
  1907. });
  1908. ;// CONCATENATED MODULE: ./src/components/AudioPlayer/hooks/isCurrentTimeInRange.ts
  1909. /**
  1910. * check if currentTime is within range timestampFrom and timestampTo
  1911. *
  1912. * example:
  1913. * - timestampFrom = 10, timestampTo = 20, currentTime = 10 should return true
  1914. * - timestampFrom = 10, timestampTo = 20, currentTime = 11 should return true
  1915. * - timestampFrom = 10, timestampTo = 20, currentTime = 20 should return false
  1916. *
  1917. * @param {number} currentTime
  1918. * @param {number} timestampFrom
  1919. * @param {number} timestampTo
  1920. * @returns {boolean} isWithinRange
  1921. */ const isCurrentTimeInRange = (currentTime, timestampFrom, timestampTo)=>currentTime >= timestampFrom && currentTime < timestampTo;
  1922. /* harmony default export */ const hooks_isCurrentTimeInRange = (isCurrentTimeInRange);
  1923. // EXTERNAL MODULE: ./src/utils/verse.ts
  1924. var verse = __webpack_require__(44519);
  1925. // EXTERNAL MODULE: ./src/api.ts
  1926. var api = __webpack_require__(92684);
  1927. ;// CONCATENATED MODULE: ./src/xstate/actors/audioPlayer/audioPlayerMachineHelper.ts
  1928. const getAyahNumberByTimestamp = (verseTimings, timestamp)=>{
  1929. const verseTiming = verseTimings.find((timing)=>timestamp >= timing.timestampFrom && timestamp <= timing.timestampTo);
  1930. if (!verseTiming) return null;
  1931. return (0,verse/* getVerseNumberFromKey */.tR)(verseTiming.verseKey);
  1932. };
  1933. /**
  1934. * There's an issue on mobile safari. Where the audio doesn't start from the correct timestamp.
  1935. * For example
  1936. * verse 1: timestamp : 0 - 1000ms;
  1937. * verse 2: timestamp: 1000ms - 2000ms;
  1938. *
  1939. * When we seek to verse timestamp 1000ms, safari reports that the timestamp is 850ms.
  1940. * And the UI highlights verse 1. Which is incorrect. Since the user intended to play verse 2 (timestamp 1000)
  1941. *
  1942. */ const TOLERANCE_PERIOD = 200; // ms
  1943. const getActiveVerseTiming = (context)=>{
  1944. const { audioData: { verseTimings } , ayahNumber , } = context;
  1945. const { currentTime } = context.audioPlayer;
  1946. const currentTimeMS = currentTime * 1000;
  1947. const lastAyahOfSurahTimestampTo = verseTimings[verseTimings.length - 1].timestampTo;
  1948. // if the reported time exceeded the maximum timestamp of the Surah from BE, just return the current Ayah which should be the last
  1949. if (currentTimeMS > lastAyahOfSurahTimestampTo - TOLERANCE_PERIOD) {
  1950. return verseTimings[ayahNumber - 1];
  1951. }
  1952. const activeVerseTiming = verseTimings.find((ayah)=>{
  1953. const isAyahBeingRecited = hooks_isCurrentTimeInRange(currentTimeMS, ayah.timestampFrom - TOLERANCE_PERIOD, ayah.timestampTo - TOLERANCE_PERIOD);
  1954. return isAyahBeingRecited;
  1955. });
  1956. return activeVerseTiming;
  1957. };
  1958. const getActiveWordLocation = (activeVerseTiming, currentTime)=>{
  1959. const activeAudioSegment = activeVerseTiming.segments.find((segment)=>{
  1960. const [, timestampFrom, timestampTo] = segment; // the structure of the segment is: [wordLocation, timestampFrom, timestampTo]
  1961. return hooks_isCurrentTimeInRange(currentTime, timestampFrom, timestampTo);
  1962. });
  1963. const wordLocation = activeAudioSegment ? activeAudioSegment[0] : 0;
  1964. return wordLocation;
  1965. };
  1966. const getTimingSegment = (verseTiming, wordPosition)=>verseTiming.segments.find(([location])=>wordPosition === location);
  1967. const getWordTimeSegment = (verseTimings, word)=>{
  1968. const verseTiming = verseTimings.find((timing)=>timing.verseKey === word.verseKey);
  1969. if (!verseTiming) return null;
  1970. const segment = getTimingSegment(verseTiming, word.position);
  1971. if (segment) return [
  1972. segment[1],
  1973. segment[2]
  1974. ];
  1975. return null;
  1976. };
  1977. const getActiveAyahNumber = (activeVerseTiming)=>{
  1978. const [, verseNumber] = activeVerseTiming.verseKey.split(":");
  1979. return Number(verseNumber);
  1980. };
  1981. const executeFetchReciter = async (context)=>{
  1982. const { reciterId , surah } = context;
  1983. return (0,api/* getChapterAudioData */.lt)(reciterId, surah, true);
  1984. };
  1985. const executeFetchReciterFromEvent = async (context, event)=>{
  1986. const { surah } = event;
  1987. const { reciterId } = context;
  1988. // @ts-ignore
  1989. const data = await executeFetchReciter({
  1990. reciterId,
  1991. surah
  1992. });
  1993. return {
  1994. ...data,
  1995. ...event
  1996. };
  1997. };
  1998. const getMediaSessionMetaData = async (context, recitersList)=>{
  1999. const reciterName = recitersList.find((reciter)=>reciter.id === context.audioData.reciterId).name;
  2000. return new MediaMetadata({
  2001. title: `Surah ${context.audioData.chapterId}`,
  2002. artist: reciterName,
  2003. album: "Quran.com",
  2004. artwork: [
  2005. {
  2006. src: "https://quran.com/images/logo/Logo@192x192.png",
  2007. type: "image/png",
  2008. sizes: "192x192"
  2009. },
  2010. ]
  2011. });
  2012. };
  2013. const getRecitersList = async (context)=>{
  2014. const { recitersList } = context;
  2015. if (recitersList) return recitersList;
  2016. // TODO: localize this
  2017. return (0,api/* getAvailableReciters */.tS)("en").then((res)=>res.reciters);
  2018. };
  2019. /***/ }),
  2020. /***/ 76133:
  2021. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  2022. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  2023. /* harmony export */ "m": () => (/* binding */ persistXstateToLocalStorage),
  2024. /* harmony export */ "x": () => (/* binding */ getXstateStateFromLocalStorage)
  2025. /* harmony export */ });
  2026. const AUDIO_PLAYER_LOCAL_STORAGE_KEY = "audio-player-state";
  2027. const persistXstateToLocalStorage = (newState)=>{
  2028. try {
  2029. const previousState = JSON.parse(localStorage.getItem(AUDIO_PLAYER_LOCAL_STORAGE_KEY)) || {};
  2030. const nextState = {
  2031. ...previousState,
  2032. ...newState
  2033. };
  2034. localStorage.setItem(AUDIO_PLAYER_LOCAL_STORAGE_KEY, JSON.stringify(nextState));
  2035. } catch (error) {
  2036. // TODO: log error
  2037. }
  2038. };
  2039. const getXstateStateFromLocalStorage = ()=>{
  2040. try {
  2041. const stateString = localStorage.getItem(AUDIO_PLAYER_LOCAL_STORAGE_KEY);
  2042. if (stateString) {
  2043. return JSON.parse(stateString) || {};
  2044. }
  2045. return {};
  2046. } catch (e) {
  2047. // TODO: log error
  2048. return {};
  2049. }
  2050. };
  2051. /***/ })
  2052. };
  2053. ;
  2054. //# sourceMappingURL=64564.js.map