@everymatrix/casino-game-page 1.43.4 → 1.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,1120 +0,0 @@
1
- <svelte:options tag={null} />
2
-
3
- <script lang="ts">
4
- import { beforeUpdate, onMount } from "svelte";
5
- import { isMobile, checkSession, getDevice } from 'rvhelper';
6
- import { _, addNewMessages, setLocale, setupI18n } from './i18n';
7
- import { TRANSLATIONS } from './translations';
8
-
9
- import moment from 'moment';
10
-
11
- export let endpoint:string = '';
12
- export let lang:string = ''; // Language
13
- export let session:string = ''; // Value for sessionID
14
- export let userid:string = ''; // Value for UserID;
15
- export let clientstyling:string = '';
16
- export let clientstylingurl:string = '';
17
- export let translationurl:string = '';
18
- export let favorites:string = '';
19
-
20
- export let loginurl:string = '';
21
- export let registerurl:string = '';
22
- export let depositurl:string = '';
23
- export let loginevent:string = '';
24
- export let registerevent:string = '';
25
- export let depositevent:string = '';
26
- export let shortcashierenabled: string = '';
27
-
28
- export let clockformat:string = '';
29
- export let haspanicbutton:string = 'false';
30
- export let playforfun:string = 'true';
31
- export let checksession:string = 'true';
32
- export let integratedgameframedesktop:string = 'false';
33
- export let integratedgameframemobile:string = 'false';
34
- export let gameid:string = '';
35
-
36
- let time:Object;
37
- let iframe:any;
38
-
39
- let isLoggedIn:boolean = false;
40
- // should be true while we have userid/session props, but the async events which set isLoggedIn haven't completed
41
- let determiningIsLoggedIn:boolean = false;
42
- let isFavLoading:boolean = false;
43
- let hasErrors:boolean = false;
44
- let isLoading:boolean = true;
45
-
46
- let playerID:string;
47
- let sessionID:string;
48
-
49
- let panicButton:HTMLElement;
50
- let panicLoading:boolean = false;
51
- let timer: number = 0;
52
- let timerInterval:any;
53
-
54
- let game:any;
55
- let detailsObtained:boolean = false;
56
- let funMode:boolean = false;
57
- let anonymousFunMode:boolean = false;
58
- let isModal:boolean = true;
59
-
60
- let gameFrameContainer:HTMLElement;
61
- let gameInnerContainer:HTMLElement;
62
- let gamePageBackground:HTMLElement;
63
- let isFullscreen:boolean = false;
64
- let modalFrameWidth:number;
65
- let modalFrameHeight:number;
66
- let gameFrameWidth:number;
67
- let gameFrameHeight:number;
68
- let definitiveIframeWidth:string;
69
- let definitiveIframeHeight:string;
70
- let userAgent:any = window.navigator.userAgent;
71
- let mobileView:boolean = false;
72
- let favoriteGames: Array<Object> = [];
73
- let listOfGamesIDs:Array<string> = [];
74
- let customStylingContainer:HTMLElement;
75
- let buttonsContainer:HTMLElement;
76
- let timeContainer:HTMLElement;
77
- let showModal:string = 'false';
78
-
79
- let gameStyle = '';
80
- let gameRationedHeight: number;
81
-
82
- setupI18n({ withLocale: 'en', translations: {}});
83
-
84
- const setTranslationUrl = ():void => {
85
- let url:string = translationurl;
86
-
87
- fetch(url).then((res:any) => res.json())
88
- .then((res) => {
89
- Object.keys(res).forEach((item:any):void => {
90
- addNewMessages(item, res[item]);
91
- });
92
- }).catch((err:any) => {
93
- console.log(err);
94
- });
95
- }
96
-
97
- Object.keys(TRANSLATIONS).forEach((item) => {
98
- addNewMessages(item, TRANSLATIONS[item]);
99
- });
100
-
101
- // @TODO game typescript model type
102
- const formatGameLaunchUrl = (game:any):void => {
103
- let url:URL = new URL(game.launchUrl);
104
-
105
- url.searchParams.append('language', lang);
106
- // @TODO wtf? session check or go home
107
- // Maybe we should check if the session is valid, somehow?
108
-
109
- if (sessionID && sessionID.length > 0) {
110
- isLoggedIn = true;
111
-
112
- url.searchParams.append('_sid', sessionID)
113
- url.searchParams.append('funMode', 'false')
114
- }
115
-
116
- game.launchUrl = url;
117
-
118
- return game;
119
- }
120
-
121
- const createGameURL = (gameId:string, modal?:boolean):void => {
122
- let url:URL = new URL(`${endpoint}/v1/casino/games/${gameId}`);
123
-
124
- url.searchParams.append('language', lang);
125
- url.searchParams.append('expand', 'vendor');
126
-
127
- isModal = modal || false;
128
-
129
- fetch(url.href)
130
- .then((res:any) => res.json())
131
- .then((data:any) => {
132
- game = formatGameLaunchUrl(data[0]);
133
- isLoading = false;
134
- if (game.launchUrl) {
135
- game.isFavorite = setGameData(game, game.hasFunMode);
136
- isFavLoading = false;
137
- }
138
- }, (err:any) => {
139
- console.error('There was an error', err);
140
- hasErrors = true;
141
- }).then(() => {
142
- if (gameFrameContainer) {
143
- if (isModal) {
144
- keepIframeRatio();
145
- } else {
146
- maximizeGameFrame();
147
- }
148
- }
149
- }).finally(() => {
150
- isLoading = false;
151
- });
152
- window.postMessage({ type: 'RequestModalSize' }, window.location.href);
153
- getFavoritesGames(session, userid)
154
- }
155
-
156
- const addEventsToDisplayedElements = () => {
157
- panicButton?.addEventListener("mousedown", startInterval, false);
158
- panicButton?.addEventListener('touchstart', startInterval, false)
159
-
160
- // on mouseup stop interval count
161
- panicButton?.addEventListener("mouseup", endInterval, false);
162
- panicButton?.addEventListener("touchend", endInterval, false);
163
- }
164
-
165
- const removeEventsToDisplayedElements = ():void => {
166
- panicLoading = false;
167
- panicButton?.removeEventListener("mousedown", startInterval);
168
- panicButton?.removeEventListener('touchstart', startInterval)
169
-
170
- // on mouseup stop interval count
171
- panicButton?.removeEventListener("mouseup", endInterval);
172
- panicButton?.removeEventListener("touchend", endInterval);
173
- }
174
-
175
- const messageHandler = (e:any):void => {
176
- switch (e.data.type) {
177
- case 'GameLaunchID':
178
- createGameURL(e.data.gameId, true);
179
- break;
180
-
181
- case 'LaunchGameFrame':
182
- openGameFrame(e.data.gameId, e.data.gameFunMode);
183
- break;
184
-
185
- case 'ModalClosed':
186
- if (integratedgameframedesktop === 'true' || isMobile(userAgent)) {
187
- // the timeout is necessary in order to sync with the closing of the modal frame and provide a smoother transition
188
- showModal = 'false';
189
-
190
- removeEventsToDisplayedElements();
191
- if(isMobile(userAgent)) {
192
- setTimeout(() => { detailsObtained = integratedgameframemobile === "true";}, 500);
193
- } else {
194
- setTimeout(() => { detailsObtained = integratedgameframedesktop === "true";}, 500);
195
- }
196
- }
197
- else if (integratedgameframedesktop === 'false' && e.data?.closeIntegratedGameFrameDesktop !== true) {
198
- window.postMessage({ type: 'DisableScroll'}, window.location.href);
199
- }
200
-
201
- break;
202
-
203
- case 'UserSessionID':
204
- if (e.data.session.length > 0) {
205
- sessionID = e.data.session;
206
- playerID = e.data.userID;
207
- isLoggedIn = true;
208
-
209
- let interval = setInterval(() => {
210
- if (game) {
211
- let url:any = new URL(game.launchUrl);
212
-
213
- if (!url.searchParams.get('_sid')) {
214
- url.searchParams.append('_sid', sessionID);
215
- }
216
-
217
- if (!url.searchParams.get('funMode')) {
218
- url.searchParams.append('funMode', false);
219
- }
220
-
221
- if (!url.searchParams.get('_sid')) {
222
- url.searchParams.append('language', lang);
223
- }
224
-
225
- game.launchUrl = url;
226
-
227
- clearInterval(interval);
228
- }
229
- }, 250);
230
- }
231
- break;
232
-
233
- case 'ModalSize':
234
- modalFrameWidth = e.data.modalContainerSize.modalWidth;
235
- modalFrameHeight = e.data.modalContainerSize.modalHeight;
236
- break;
237
- }
238
- }
239
-
240
- //Get favorites games list and update the favorites category
241
- const getFavoritesGames = (sessionID:string, playerID:string) => {
242
- let url = `${endpoint}/v1/player/${playerID}/favorites/`;
243
-
244
- isLoading = true;
245
- let options = {
246
- method: "GET",
247
- headers: {
248
- 'X-SessionID': sessionID,
249
- }
250
- };
251
-
252
- return new Promise((resolve, reject) => {
253
- fetch(url, options)
254
- .then((res:any) => res.json())
255
- .then((updatedArray:any) => {
256
- isLoading = false;
257
- favoriteGames = updatedArray.items;
258
- if (favoriteGames) {
259
- if (game && game.id) game.isFavorite = checkFavorite(game.id); isFavLoading = false;
260
- favoriteGames.forEach((fav:any) => {
261
- if (!listOfGamesIDs.includes(fav.id)) listOfGamesIDs.push(fav.id);
262
- });
263
- } else {
264
- favoriteGames = [];
265
- }
266
-
267
- resolve(favoriteGames);
268
-
269
- }).catch((err:any) => {
270
- console.error(err);
271
-
272
- reject(err);
273
- });
274
- });
275
- }
276
-
277
- //Add / Remove favorites games
278
- const toggleFavoriteGame = (id:any):void => {
279
- if (game.isFavorite) {
280
- removeFavoredGame(`${endpoint}/v1/player/${userid}/favorites`, session, game.id);
281
- } else {
282
- addFavoredGame(`${endpoint}/v1/player/${userid}/favorites`, session, game);
283
- }
284
- }
285
-
286
- let addFavoredGame = async (url, sessionID, game) => {
287
- // When adding new favored games, the api requires an array with all the current favored games due to the fact that it overwrites the old ones with the ones found in the body of the POST request
288
- if (!listOfGamesIDs.includes(game.id)) listOfGamesIDs.push(game.id);
289
-
290
- let data = {items: listOfGamesIDs};
291
-
292
- let options = {
293
- method: "POST",
294
- headers: {
295
- 'X-SessionID': sessionID,
296
- 'Content-Type': 'application/json',
297
- 'Accept': 'application/json',
298
- },
299
- body: JSON.stringify(data)
300
- };
301
-
302
- fetch(url, options)
303
- .then((res:any) => res.json())
304
- .then((res) => {
305
- window.postMessage({ type: `AddFavoriteThumbnail_${game.id}` }, window.location.href);
306
- //Make a get for a new list to update the view
307
- window.postMessage({ type: 'UpdateFavoredList', url, sessionID});
308
- if( res.items ) favoriteGames = res.items; game.isFavorite = checkFavorite(game.id);
309
- })
310
- .catch((err:any) => {
311
- console.error('Err', err);
312
- });
313
- }
314
-
315
- const removeFavoredGame = (url, sessionID, gameID) => {
316
- let options = {
317
- method: "DELETE",
318
- headers: {
319
- 'X-SessionID': sessionID,
320
- }
321
- };
322
-
323
- fetch(`${url}/${gameID}`, options)
324
- .then((res:any) => res.json())
325
- .then((res) => {
326
- window.postMessage({ type: `RemoveFavoriteThumbnail_${gameID}` }, window.location.href);
327
- //Make a get for a new list to update the view
328
- window.postMessage({ type: 'UpdateFavoredList', url, sessionID});
329
- if(res.items) favoriteGames = res.items; game.isFavorite = checkFavorite(game.id);
330
- });
331
-
332
- if (listOfGamesIDs.includes(gameID)) {
333
- listOfGamesIDs = listOfGamesIDs.filter(x => {
334
- return x != gameID;
335
- });
336
- }
337
- }
338
-
339
- const checkFavorite = (gameId:string):boolean => {
340
- return favoriteGames.findIndex(obj => obj.id == gameId) !== -1;
341
- }
342
-
343
- const setGameData = (game, gameFunMode) => {
344
- anonymousFunMode = playforfun == 'true' ? game.hasAnonymousFunMode : false;
345
- funMode = playforfun == 'true' ? gameFunMode : false;
346
- detailsObtained = true;
347
- return checkFavorite(game.id);
348
- }
349
-
350
- const openGameFrame = (gameId:string, gameFunMode:boolean):void => {
351
- let url:URL = new URL(`${endpoint}/v1/casino/games/${gameId}`);
352
- url.searchParams.append('language', lang);
353
- fetch(url.href)
354
- .then((res:any) => res.json())
355
- .then((data:any) => {
356
- game = formatGameLaunchUrl(data[0]);
357
- isLoading = false;
358
- if (game.launchUrl) {
359
- game.isFavorite = setGameData(game, gameFunMode);
360
- isFavLoading = false;
361
- }
362
- }).finally(() => {
363
- isLoading = false;
364
- });;
365
- }
366
-
367
- const resizeIframeIfNotVisible = (): void => {
368
- if (isFullscreen) return;
369
-
370
- const resizeCallback = (entries, observer): void => {
371
- const maxIntersectionRatio = 0.5;
372
- const intersectionRatio = entries[0].intersectionRatio;
373
- const isIntersecting = entries[0].isIntersecting;
374
- const gameFrameContainerHeight = parseInt(
375
- getComputedStyle(gameFrameContainer).height
376
- );
377
-
378
- if (!gameRationedHeight)
379
- gameRationedHeight =
380
- gameFrameContainerHeight *
381
- Math.max(intersectionRatio, maxIntersectionRatio);
382
-
383
- gameFrameContainer.style.height = `${gameRationedHeight}px`;
384
- gameInnerContainer.style.height = `${gameRationedHeight}px`;
385
-
386
- if(isIntersecting){
387
- gamePageBackground.style.height = `${gameFrameContainer.style.height}px`;
388
- }
389
-
390
- observer.unobserve(gameFrameContainer);
391
- };
392
-
393
- const options = {
394
- threshold: 0,
395
- };
396
-
397
- const observer = new IntersectionObserver(resizeCallback, options);
398
- observer.observe(gameFrameContainer);
399
- };
400
-
401
- const maximizeGameFrame = ():void => {
402
- modalFrameWidth = game.width;
403
- modalFrameHeight = game.height;
404
-
405
- definitiveIframeWidth = `${game.width}px`;
406
- definitiveIframeHeight = `${game.height}px`;
407
-
408
- gameFrameWidth = game.width;
409
- gameFrameHeight = game.height;
410
-
411
- keepIframeRatio();
412
- }
413
-
414
- // Start section: keep aspect ratio for iframe on resize
415
- const keepIframeRatio = ():void => {
416
- let iframeContainer = getComputedStyle(gameFrameContainer);
417
- let gameFrame = getComputedStyle(gameInnerContainer);
418
- let gameContainerWidth = parseInt(iframeContainer.width.slice(0, -2));
419
- let gameContainerHeight = parseInt(iframeContainer.height.slice(0, -2));
420
- const iframeRatio = game.width/(game.height + 100);
421
-
422
-
423
- gameFrameWidth = parseInt(game.width) * iframeRatio;
424
- gameFrameHeight = parseInt(game.height);
425
-
426
- definitiveIframeWidth = gameFrameWidth ? `${Math.floor(gameFrameWidth)}px` : "1280px";
427
- definitiveIframeHeight = gameFrameHeight ? `${Math.floor(gameFrameHeight)}px` : "720px";
428
-
429
- calculateFrameProportions();
430
- }
431
-
432
- const openGameWindow = (game:any):void => {
433
- isMobile(userAgent) ? determineGameFrameState(integratedgameframemobile) : determineGameFrameState(integratedgameframedesktop);
434
- }
435
-
436
- const determineGameFrameState = (gameState:string):void => {
437
- if(gameState == 'false') {
438
- window.open(game.launchUrl, '_blank');
439
- } else if(gameState == 'true') {
440
- window.postMessage({ type: 'OpenIntegratedGameFrame', subVendor: game.subVendor, gameId: game.id, launchUrl: game.launchUrl?.href }, window.location.href);
441
- }
442
- }
443
-
444
- const resizeHandler = ():void => {
445
- // sent to modal component a flag (detailsObtained) by witch to determine if a game is open
446
- window.postMessage({ type: 'GameStateOnResize', detailsObtained }, window.location.href);
447
- // make sure that a game is open before trying to get the element properties
448
- if (detailsObtained) {
449
- if (gameFrameContainer) {
450
- keepIframeRatio();
451
- }
452
- window.addEventListener('ModalSize', messageHandler, false);
453
- }
454
- }
455
-
456
- // End section: keep aspect ratio for iframe on resize
457
- const toggleLogin = ():void => {
458
- if (loginevent) {
459
- if (isMobile(userAgent)) {
460
- window.postMessage({ type: 'ModalClosed' }, window.location.href);
461
- }
462
- window.postMessage({ type: loginevent, transition: 'Login' }, window.location.href);
463
- }
464
-
465
- if (loginurl) {
466
- // @ts-ignore
467
- window.location = loginurl;
468
- }
469
-
470
- //Analytics event
471
- if(typeof gtag == 'function'){
472
- gtag('event', 'OpenLoginModal', {
473
- 'context': 'GeneralPlayerRegisterForm'
474
- });
475
- }
476
- }
477
-
478
- const toggleRegister = ():void => {
479
- if (registerevent) {
480
- if (isMobile(userAgent)) {
481
- window.postMessage({ type: 'ModalClosed' }, window.location.href);
482
- }
483
- window.postMessage({ type: registerevent, transition: 'Register' }, window.location.href);
484
- }
485
-
486
- if (registerurl) {
487
- // @ts-ignore
488
- window.location = registerurl;
489
- }
490
-
491
- //Analytics event
492
- if(typeof gtag == 'function'){
493
- gtag('event', 'OpenRegisterModal', {
494
- 'context': 'GeneralPlayerRegisterForm'
495
- });
496
- }
497
- }
498
-
499
- const toggleDeposit = (mobileView:boolean):void => {
500
-
501
- if (isShortCashierEnabled && !mobileView) {
502
- window.postMessage({ type: 'OpenShortCashier' }, window.location.href);
503
- } else if (depositevent) {
504
- window.postMessage({ type: depositevent }, window.location.href);
505
- window.postMessage({ type: 'ModalClosed' }, window.location.href);
506
- }
507
-
508
- //Analytics event
509
- if(typeof gtag == 'function'){
510
- gtag('event', 'GoToDeposit', {
511
- 'context': 'IntegratedGamePage'
512
- });
513
- }
514
-
515
- if (depositurl && !isShortCashierEnabled) {
516
- // @ts-ignore
517
- window.location = depositurl;
518
- }
519
- }
520
-
521
- if (document.addEventListener) {
522
- document.addEventListener('webkitfullscreenchange', exitHandler, false);
523
- document.addEventListener('mozfullscreenchange', exitHandler, false);
524
- document.addEventListener('fullscreenchange', exitHandler, false);
525
- document.addEventListener('MSFullscreenChange', exitHandler, false);
526
- }
527
-
528
- function exitHandler() {
529
- if (!document.webkitIsFullScreen && !document.mozFullScreen && !document.msFullscreenElement && isFullscreen) {
530
- handleIframeSize();
531
- }
532
- }
533
-
534
- const handleIframeSize = () => {
535
- if ((document as any).fullscreenEnabled ||
536
- (document as any).webkitFullscreenEnabled ||
537
- (document as any).mozFullScreenEnabled ||
538
- (document as any).msFullscreenEnabled) {
539
- if (isFullscreen) {
540
- if (document.exitFullscreen) {
541
- document.exitFullscreen(); // firefox uses the same exit function
542
- } else if ( document.webkitExitFullscreen) {
543
- document.webkitExitFullscreen();
544
- } else if ( document.msExitFullscreen) {
545
- document.msExitFullscreen();
546
- }
547
- isFullscreen = false;
548
- } else {
549
- if (gameFrameContainer.requestFullscreen) {
550
- gameFrameContainer.requestFullscreen();
551
- } else if (gameFrameContainer.webkitRequestFullscreen) {
552
- gameFrameContainer.webkitRequestFullscreen();
553
- } else if (gameFrameContainer.mozRequestFullScreen) {
554
- gameFrameContainer.mozRequestFullScreen();
555
- } else if (gameFrameContainer.msRequestFullscreen) {
556
- gameFrameContainer.msRequestFullscreen();
557
- }
558
- isFullscreen = true;
559
- }
560
- }
561
- }
562
-
563
- const refreshTime = ():void => {
564
- if (clockformat) {
565
- time = moment().format(clockformat);
566
- } else {
567
- time = moment().format('LTS');
568
- }
569
- }
570
-
571
- const timeInterval = setInterval(():void => {
572
- refreshTime();
573
- }, 100);
574
-
575
- const setActiveLanguage = ():void => {
576
- setLocale(lang);
577
-
578
- mobileView = isMobile(userAgent);
579
- }
580
-
581
- const setSession = ():void => {
582
- if (checksession == 'true') {
583
- checkSession(endpoint, session).then((res:any) => {
584
- sessionID = res.Guid;
585
- playerID = res.UserID;
586
- isLoggedIn = true;
587
- }, (err:any) => {
588
- isLoggedIn = false;
589
- console.error('err on session', err);
590
- });
591
- } else {
592
- sessionID = session;
593
- isLoggedIn = true;
594
- }
595
- }
596
-
597
- const startInterval = (e:any):void => {
598
- timer = 0;
599
-
600
- timerInterval = setInterval(() => {
601
- timer += 1;
602
- panicLoading = true;
603
-
604
- if (timer >= 3) {
605
- window.postMessage({type: 'PanicButtonClicked'}, window.location.href);
606
- clearInterval(timerInterval)
607
- }
608
- }, 1000);
609
- }
610
-
611
- const endInterval = (e:any):void => {
612
- if (timer < 3) {
613
- panicLoading = false;
614
- }
615
- clearInterval(timerInterval);
616
- }
617
-
618
-
619
- const calculateFrameProportions = (): void => {
620
- let w = isFullscreen ? '100%' : definitiveIframeWidth;
621
- let h = isFullscreen ? '100%' : definitiveIframeHeight;
622
- let mW = isFullscreen || !isModal ? 'none' : (game.width ? `${Math.floor(game.width)}px`: '1280px');
623
- let mH = isFullscreen || !isModal ? 'none' : (game.height ? `${(Math.floor(game.height) + 100)}px` : '720px');
624
-
625
- gameStyle = `width: ${w}; height: ${h}; max-width: ${mW}; max-height: ${mH}`;
626
- resizeIframeIfNotVisible();
627
- }
628
-
629
- const setClientStyling = ():void => {
630
- let sheet = document.createElement('style');
631
- sheet.innerHTML = clientstyling;
632
- customStylingContainer.appendChild(sheet);
633
- }
634
-
635
- const setClientStylingURL = ():void => {
636
- let cssFile:HTMLElement = document.createElement('style');
637
-
638
- if (clientstylingurl) {
639
- let url:URL = new URL(clientstylingurl);
640
-
641
- fetch(url.href)
642
- .then((res:any) => res.text())
643
- .then((data:any) => {
644
- cssFile.innerHTML = data
645
-
646
- setTimeout(() => { customStylingContainer.appendChild(cssFile); }, 1);
647
- });
648
- }
649
- }
650
-
651
- beforeUpdate(() => {
652
- determiningIsLoggedIn = (session || userid) && !isLoggedIn;
653
- })
654
-
655
- onMount(() => {
656
- window.addEventListener('resize', resizeHandler, false);
657
- window.addEventListener('message', messageHandler, false);
658
-
659
- return () => {
660
- removeEventsToDisplayedElements();
661
- window.removeEventListener('resize', resizeHandler);
662
- window.removeEventListener('message', messageHandler);
663
- }
664
- });
665
-
666
-
667
- const setFavLoading = ():void => {
668
- isFavLoading = true;
669
- }
670
-
671
- $: lang && setActiveLanguage();
672
- $: isShortCashierEnabled = shortcashierenabled.toLocaleLowerCase() === 'true';
673
- $: endpoint && gameid && lang && createGameURL(gameid, true);
674
- $: session && userid && endpoint && setSession();
675
- $: checksession == 'false' && session && endpoint && setSession();
676
- $: translationurl && setTranslationUrl();
677
- $: favorites && setFavLoading();
678
- $: clientstyling && customStylingContainer && setClientStyling();
679
- $: clientstylingurl && customStylingContainer && setClientStylingURL();
680
- $: (showModal == 'true') && panicButton && addEventsToDisplayedElements();
681
- $: panicButton && addEventsToDisplayedElements();
682
- </script>
683
-
684
- <div bind:this={customStylingContainer}>
685
- {#if isLoading}
686
- <p class="SearchLoading">{$_('loading')}</p>
687
- {:else}
688
- {#if hasErrors}
689
- <p class="SearchLoading">500 Error - Internal Server Error.</p>
690
- {:else}
691
- <div class="GamePageBackground" style="background:{!mobileView? `url(${game?.backgroundImageUrl})`: ''}; background-size: cover" bind:this={gamePageBackground}>
692
- <div class="CasinoGamePageContainer" style="background: rgba(0, 0, 0, 0.5)">
693
- {#if detailsObtained}
694
- {#if mobileView}
695
- {#if isLoggedIn}
696
- {#if favorites == 'true'}
697
- {#if !isFavLoading}
698
- {#if game.isFavorite}
699
- <div class="FavIconContainer {haspanicbutton == 'true' ? 'FavIconPanicButton' : ''}" on:click="{() => toggleFavoriteGame(game.id)}">
700
- <svg version="1.1" class="FavoredIcon" part="FavoredIcon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.481 19.481" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 19.481 19.481">
701
- <path style="fill: var(--emfe-w-color-white, #FFFFFF);" d="m10.201,.758l2.478,5.865 6.344,.545c0.44,0.038 0.619,0.587 0.285,0.876l-4.812,4.169 1.442,6.202c0.1,0.431-0.367,0.77-0.745,0.541l-5.452-3.288-5.452,3.288c-0.379,0.228-0.845-0.111-0.745-0.541l1.442-6.202-4.813-4.17c-0.334-0.289-0.156-0.838 0.285-0.876l6.344-.545 2.478-5.864c0.172-0.408 0.749-0.408 0.921,0z"/>
702
- </svg>
703
- </div>
704
- {:else}
705
- <div class="FavIconContainer {haspanicbutton == 'true' ? 'FavIconPanicButton' : ''}" on:click="{() => toggleFavoriteGame(game.id)}">
706
- <svg version="1.1" class="UnfavoredIcon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="20px" y="20px"
707
- viewBox="0 0 512.001 512.001" style="enable-background:new 0 0 512.001 512.001;" xml:space="preserve"><path style="fill: var(--emfe-w-color-white, #FFFFFF);" d="M511.266,197.256c-1.764-5.431-6.458-9.388-12.108-10.209l-158.722-23.065L269.452,20.155
708
- c-2.527-5.12-7.741-8.361-13.451-8.361c-5.709,0-10.924,3.242-13.451,8.361l-70.988,143.828L12.843,187.047
709
- c-5.65,0.821-10.344,4.779-12.108,10.209c-1.765,5.43-0.293,11.391,3.795,15.376l114.848,111.955L92.27,482.67
710
- c-0.965,5.627,1.349,11.315,5.968,14.67c4.618,3.355,10.74,3.798,15.797,1.142L256,423.846l141.961,74.637
711
- c2.195,1.154,4.591,1.723,6.979,1.723c3.11,0,6.206-0.966,8.818-2.865c4.619-3.356,6.933-9.043,5.968-14.671L392.61,324.587
712
- l114.86-111.954C511.559,208.647,513.031,202.686,511.266,197.256z M366.023,308.608c-3.536,3.446-5.15,8.412-4.314,13.278
713
- l23.311,135.898l-122.038-64.162c-4.37-2.297-9.591-2.297-13.961,0l-122.045,64.163l23.304-135.9
714
- c0.834-4.866-0.779-9.83-4.313-13.276l-98.731-96.244l136.445-19.829c4.886-0.71,9.108-3.778,11.294-8.205L256,60.685
715
- l61.023,123.645c2.186,4.427,6.408,7.496,11.294,8.206l136.447,19.828L366.023,308.608z"/></svg>
716
- </div>
717
- {/if}
718
- {:else}
719
- <div class="LoaderRipple {haspanicbutton == 'true' ? 'LoaderWithPanicButton' : ''}"><div></div><div></div></div>
720
- {/if}
721
- {/if}
722
- <div class="GameDetails">
723
- <h3>{game.name}</h3>
724
- <img src={game.thumbnail} class="GameThumbnail" alt="game thumbnail" loading="lazy" />
725
- <div class="ButtonsContainer">
726
- <button class="DepositButton" on:click='{() => toggleDeposit(mobileView)}'>{$_('deposit')}</button>
727
- <button class="PlayNowButton" on:click='{() => {openGameWindow(game)}}'>{$_('playNow')}</button>
728
- </div>
729
- {#if haspanicbutton === "true"}
730
- <div class="PanicSection {(getDevice(userAgent) !== 'PC') ? 'PanicSectionMobile' : ''}">
731
- <button class="PanicButton {(getDevice(userAgent) !== 'PC') ? 'PanicButtonMobile' : ''}" class:PanicButtonAnimation={panicLoading} bind:this={panicButton}>{$_('breakButton')}</button>
732
- </div>
733
- {/if}
734
- <p>{time}</p>
735
- </div>
736
- {:else if anonymousFunMode && !determiningIsLoggedIn}
737
- <div class="GameDetails">
738
- <h3>{game.name}</h3>
739
- <img src={game.thumbnail} class="GameThumbnail" alt="game thumbnail" loading="lazy" />
740
- <div class="ButtonsContainer">
741
- <button class="LoginButton" on:click='{() => toggleLogin()}'>{$_('signIn')}</button>
742
- <button class="RegisterButton" on:click='{() => toggleRegister()}'>{$_('register')}</button>
743
- <button class="FullWidthButton" on:click='{() => {openGameWindow(game)}}'>{$_('playForFun')}</button>
744
- </div>
745
- <p>{time}</p>
746
- </div>
747
- {:else if !determiningIsLoggedIn}
748
- <div class="GameDetails" part="GameDetails">
749
- <h3>{game.name}</h3>
750
- <img src={game.thumbnail} class="GameThumbnail" alt="game thumbnail" loading="lazy" />
751
- <div class="ButtonsContainer">
752
- <button class="LoginButton" on:click='{() => toggleLogin()}'>{$_('signIn')}</button>
753
- <button class="RegisterButton" on:click='{() => toggleRegister()}'>{$_('register')}</button>
754
- </div>
755
- <p>{time}</p>
756
- </div>
757
- {/if}
758
- {:else}
759
- {#if isLoggedIn}
760
- <div id="IframeContainer" bind:this={gameFrameContainer} class:FullsScreenLayout={isFullscreen} style="width: {modalFrameWidth}; height: {modalFrameHeight}">
761
- <div id="IframeGame" bind:this={gameInnerContainer} style="{gameStyle}">
762
- <iframe title="Games" id="IframeGame" class="GamesContainer" aria-hidden="false" src={game.launchUrl} bind:this={iframe}/>
763
- <div class="BottomGame {haspanicbutton == 'true' ? 'BottomGamePanicSection' : ''}" bind:this={buttonsContainer}>
764
- <button class="DepositButton" on:click='{() => toggleDeposit(mobileView)}'>{$_('deposit')}</button>
765
- <p class="Time" bind:this={timeContainer}><span>{time}</span></p>
766
- {#if haspanicbutton === "true"}
767
- <div class="PanicSection">
768
- <button class="Button" class:PanicButtonAnimation={panicLoading} bind:this={panicButton}>{$_('breakButton')}</button>
769
- </div>
770
- {/if}
771
- {#if isFullscreen}
772
- <button class="FullscreenButton" on:click='{() => handleIframeSize()}'>
773
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 31 31"><polygon style="fill:var(--emfe-w-button-typography, var(--emfe-w-color-white, #FFFFFF));" points="24.586,27.414 29.172,32 32,29.172 27.414,24.586 32,20 20,20 20,32 "/><polygon style="fill:var(--emfe-w-button-typography, var(--emfe-w-color-white, #FFFFFF));" points="0,12 12,12 12,0 7.414,4.586 2.875,0.043 0.047,2.871 4.586,7.414 "/><polygon style="fill:var(--emfe-w-button-typography, var(--emfe-w-color-white, #FFFFFF));" points="0,29.172 2.828,32 7.414,27.414 12,32 12,20 0,20 4.586,24.586 "/><polygon style="fill:var(--emfe-w-button-typography, var(--emfe-w-color-white, #FFFFFF));" points="20,12 32,12 27.414,7.414 31.961,2.871 29.133,0.043 24.586,4.586 20,0 "/></svg>
774
- </button>
775
- {:else}
776
- <button class="FullscreenButton" on:click='{() => handleIframeSize()}'>
777
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M21.414 18.586l2.586-2.586v8h-8l2.586-2.586-5.172-5.172 2.828-2.828 5.172 5.172zm-13.656-8l2.828-2.828-5.172-5.172 2.586-2.586h-8v8l2.586-2.586 5.172 5.172zm10.828-8l-2.586-2.586h8v8l-2.586-2.586-5.172 5.172-2.828-2.828 5.172-5.172zm-8 13.656l-2.828-2.828-5.172 5.172-2.586-2.586v8h8l-2.586-2.586 5.172-5.172z"/></svg>
778
- </button>
779
- {/if}
780
- </div>
781
- </div>
782
- </div>
783
- {:else if !determiningIsLoggedIn}
784
- {#if funMode}
785
- <div id="IframeContainer" bind:this={gameFrameContainer} class:FullsScreenLayout={isFullscreen} style="width: {modalFrameWidth}; height: {modalFrameHeight};">
786
- <div id="IframeGame" bind:this={gameInnerContainer} style="{gameStyle}">
787
- <iframe title="Games" id="IframeGame" class="GamesContainer" aria-hidden="false" src={game.launchUrl} bind:this={iframe}/>
788
- <div class="BottomGame" bind:this={buttonsContainer}>
789
- <div class="ButtonsContainer">
790
- <button class="LoginButton" on:click='{() => toggleLogin()}'>{$_('signIn')}</button>
791
- <button class="RegisterButton" on:click='{() => toggleRegister()}'>{$_('register')}</button>
792
- </div>
793
- <p class="Time" bind:this={timeContainer}><span>{time}</span></p>
794
- {#if isFullscreen}
795
- <button class="FullscreenButton" on:click='{() => handleIframeSize()}'>
796
- <svg width="24" height="24" viewBox="0 0 31 31"><polygon style="fill:#fff;" points="24.586,27.414 29.172,32 32,29.172 27.414,24.586 32,20 20,20 20,32 "/><polygon style="fill: var(--emfe-w-button-typography, var(--emfe-w-color-white, #FFFFFF));" points="0,12 12,12 12,0 7.414,4.586 2.875,0.043 0.047,2.871 4.586,7.414 "/><polygon style="fill:var(--emfe-w-button-typography, var(--emfe-w-color-white, #FFFFFF));" points="0,29.172 2.828,32 7.414,27.414 12,32 12,20 0,20 4.586,24.586 "/><polygon style="fill:var(--emfe-w-button-typography, var(--emfe-w-color-white, #FFFFFF));" points="20,12 32,12 27.414,7.414 31.961,2.871 29.133,0.043 24.586,4.586 20,0 "/></svg>
797
- </button>
798
- {:else}
799
- <button class="FullscreenButton" on:click='{() => handleIframeSize()}'>
800
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M21.414 18.586l2.586-2.586v8h-8l2.586-2.586-5.172-5.172 2.828-2.828 5.172 5.172zm-13.656-8l2.828-2.828-5.172-5.172 2.586-2.586h-8v8l2.586-2.586 5.172 5.172zm10.828-8l-2.586-2.586h8v8l-2.586-2.586-5.172 5.172-2.828-2.828 5.172-5.172zm-8 13.656l-2.828-2.828-5.172 5.172-2.586-2.586v8h8l-2.586-2.586 5.172-5.172z"/></svg>
801
- </button>
802
- {/if}
803
- </div>
804
- </div>
805
- </div>
806
- {:else}
807
- <div class="GameDetails" part="GameDetails">
808
- <h3>{game.name}</h3>
809
- <img src={game.thumbnail} class="GameThumbnail" alt="game thumbnail" loading="lazy" />
810
- <div class="ButtonsContainer">
811
- <button class="LoginButton" on:click='{() => toggleLogin()}'>{$_('signIn')}</button>
812
- <button class="RegisterButton" on:click='{() => toggleRegister()}'>{$_('register')}</button>
813
- </div>
814
- <p>{time}</p>
815
- </div>
816
- {/if}
817
- {/if}
818
- {/if}
819
- {/if}
820
- </div>
821
- </div>
822
- {/if}
823
- {/if}
824
- </div>
825
-
826
- <style lang="scss">
827
- .CasinoGamePageContainer {
828
- background: var(--emfe-w-casino-color-bg, var(--emfe-w-color-background, #07072A));
829
- margin: 0 auto;
830
- height: 100%;
831
- max-width: 100%;
832
- padding: 0;
833
- display: flex;
834
- flex-direction: column;
835
- justify-content: center;
836
- align-items: center;
837
- }
838
-
839
- .BottomGame {
840
- padding: 4px 16px;
841
- min-height: 85px;
842
- background-color: var(--emfe-w-casino-color-bg, var(--emfe-w-color-background, #07072A));
843
- align-items: center;
844
- display: grid;
845
- grid-auto-columns: 1fr;
846
- grid-auto-rows: 1fr;
847
- grid-template-columns: 1fr 1fr 1fr;
848
- grid-template-rows: 1fr;
849
- gap: 0px 0px;
850
- justify-items: center;
851
- border-radius:0 0 6px 6px;
852
- button {
853
- cursor: pointer;
854
- }
855
-
856
- &.BottomGamePanicSection {
857
- grid-template-columns: 1fr 1fr 1fr 1fr;
858
- }
859
-
860
- }
861
-
862
- .DepositButton, .PlayNowButton {
863
- border: none;
864
- justify-self: left;
865
- width: 130px;
866
- height: 60px;
867
- background-color: var(--emfe-w-casino-color-primary, var(--emfe-w-color-primary, #D0046C));
868
- color: var(--emfe-w-button-typography, var(--emfe-w-color-white, #FFFFFF));
869
- border-radius: 2px;
870
- }
871
- .GameThumbnail {
872
- border-radius: 2px;
873
- width: 270px;
874
- height: 180px;
875
- margin-bottom: 20px;
876
- }
877
- .FullscreenButton {
878
- border-radius: 5px;
879
- justify-self: end;
880
- border: none;
881
- width: 60px;
882
- height: 60px;
883
- background-color: var(--emfe-w-casino-color-primary, var(--emfe-w-color-primary, #D0046C));
884
- }
885
- .GameDetails {
886
- display: flex;
887
- flex-direction: column;
888
- align-items: center;
889
- }
890
- .GameDetails h3 {
891
- color: var(--emfe-w-color-white, #FFFFFF);
892
- font-size: 18px;
893
- text-align: center;
894
- padding: 0 10px;
895
- }
896
-
897
- .ButtonsContainer {
898
- display: grid;
899
- grid-gap: 16px;
900
- grid-template-columns: 1fr 1fr;
901
- }
902
- .FullWidthButton {
903
- grid-column: span 2;
904
- }
905
-
906
- .BottomGame .ButtonsContainer {
907
- width: 275px;
908
- display: flex;
909
- justify-self: start;
910
- flex-direction: row;
911
- justify-content: space-between;
912
-
913
- button {
914
- cursor: pointer;
915
- }
916
- }
917
-
918
- .RegisterButton {
919
- color: var(--emfe-w-button-typography, var(--emfe-w-color-white, #FFFFFF));
920
- background-color: var(--emfe-w-casino-color-primary, var(--emfe-w-color-primary, #D0046C));
921
- border-radius: 5px;
922
- border: none;
923
- width: 129px;
924
- height: 60px;
925
- }
926
- .LoginButton {
927
- color: var(--emfe-w-button-typography, var(--emfe-w-color-white, #FFFFFF));;
928
- background-color: var(--emfe-w-casino-contrast, var(--emfe-w-color-background, #07072A));
929
- border-radius: 5px;
930
- border: 1px solid var(--emfe-w-button-typography, var(--emfe-w-color-white, #FFFFFF));
931
- width: 129px;
932
- height: 60px;
933
- }
934
- .FullWidthButton {
935
- color: var(--emfe-w-casino-color-primary, var(--emfe-w-color-primary, #D0046C));
936
- background-color: var(--emfe-w-casino-contrast, var(--emfe-w-color-background, #07072A));
937
- border-radius: 5px;
938
- border: 1px solid var(--emfe-w-casino-color-primary, var(--emfe-w-color-primary, #D0046C));
939
- width: 100%;
940
- height: 60px;
941
- }
942
-
943
- .GamesContainer {
944
- width: calc(100% - 4px);
945
- height: 100%;
946
- max-width: calc(100% - 4px);
947
- max-height: calc(100% - 100px);
948
- }
949
- .Time {
950
- height: 20px;
951
- margin: 0;
952
- display: flex;
953
- align-items: center;
954
- justify-content: center;
955
- }
956
- svg {
957
- fill: var(--emfe-w-button-typography, var(--emfe-w-color-white, #FFFFFF));
958
- }
959
- p {
960
- color: var(--emfe-w-casino-typography, var(--emfe-w-color-contrast, #FFFFFF));
961
- }
962
- #IframeContainer {
963
- height:100%;
964
- max-width:1300px;
965
- margin: 10px;
966
- display: flex;
967
- align-items: center;
968
- justify-content: center;
969
- }
970
- .FullsScreenLayout .GamesContainer {
971
- // the use of !important is necessary in order to override the dynamic inline width/height, when in fullscreen mode
972
- width: 100%!important;
973
- height: calc(100% - 100px)!important;
974
- }
975
- .FavoredIcon, .UnfavoredIcon {
976
- width: 35px;
977
- height: 35px;
978
- }
979
- .FavIconContainer {
980
- position: absolute;
981
- top: 15px;
982
- left: 15px;
983
- cursor: pointer;
984
- }
985
-
986
- .FavIconPanicButton {
987
- margin-top: 45px;
988
- }
989
-
990
- .PanicSection {
991
- display: flex;
992
- align-items: center;
993
- gap: 10px;
994
- margin: 20px 0;
995
-
996
- .Button {
997
- border-radius: 5px;
998
- border: 1px solid var(--emfe-w-casino-color-primary, var(--emfe-w-color-primary, #D0046C));
999
- background-color: var(--emfe-w-casino-color-primary, var(--emfe-w-color-primary, #D0046C));
1000
- width: 280px;
1001
- height: 60px;
1002
- color: var(--emfe-w-button-typography, var(--emfe-w-color-white, #FFFFFF));
1003
- cursor: pointer;
1004
- }
1005
- }
1006
-
1007
- // the use of !important is necessary in order to override margin from .PanicSection
1008
- .PanicSectionMobile {
1009
- position: absolute;
1010
- top: 0;
1011
- left: 0;
1012
- width: 100%;
1013
- text-align: center;
1014
- margin: 10px 0 0 0 !important;
1015
- }
1016
-
1017
- .PanicButtonMobile {
1018
- border-radius: 5px;
1019
- margin: 0 10px;
1020
- border: 1px solid var(--emfe-w-casino-color-primary, var(--emfe-w-color-primary, #D0046C));
1021
- background-color: var(--emfe-w-casino-color-primary, var(--emfe-w-color-primary, #D0046C));
1022
- width: 100% !important;
1023
- height: 30px;
1024
- color: var(--emfe-w-button-typography, var(--emfe-w-color-white, #FFFFFF));
1025
- cursor: pointer;
1026
-
1027
- //Remove text selection for panic button on mobile
1028
- -webkit-touch-callout: none; /* iOS Safari */
1029
- -webkit-user-select: none; /* Safari */
1030
- -moz-user-select: none; /* Old versions of Firefox */
1031
- -ms-user-select: none; /* Internet Explorer/Edge */
1032
- user-select: none;
1033
- // End of removing selection properties
1034
- }
1035
-
1036
- .PanicButtonAnimation {
1037
- background: -webkit-linear-gradient(
1038
- 135deg,
1039
- rgba(20, 20, 20, 0) 55%, rgba(20, 20, 20, 0.3) 100%
1040
- );
1041
-
1042
- background: -moz-linear-gradient(
1043
- 135deg,
1044
- rgba(20, 20, 20, 0) 55%, rgba(20, 20, 20, 0.3) 100%
1045
- );
1046
-
1047
- background: -o-linear-gradient(
1048
- 135deg,
1049
- rgba(20, 20, 20, 0) 55%, rgba(20, 20, 20, 0.3) 100%
1050
- );
1051
-
1052
- background-color: var(--emfe-w-casino-color-primary, var(--emfe-w-color-primary, #D0046C));
1053
- width: 280px;
1054
- color: var(--emfe-w-button-typography, var(--emfe-w-color-white, #FFFFFF));
1055
-
1056
- -webkit-animation: bar-animation 2s linear;
1057
- }
1058
-
1059
- @-webkit-keyframes bar-animation {
1060
- 0% {
1061
- background-position: 0;
1062
- }
1063
- 100% {
1064
- background-position: 280px;
1065
- }
1066
- }
1067
-
1068
- // Loader for favorites
1069
- .LoaderRipple {
1070
- width: 80px;
1071
- height: 80px;
1072
- position: absolute;
1073
- top: 0;
1074
- left: -8px;
1075
- div {
1076
- position: absolute;
1077
- border: 4px solid #fff;
1078
- opacity: 1;
1079
- border-radius: 50%;
1080
- animation: ripple-effect 1s cubic-bezier(0, 0.2, 0.8, 1) infinite;
1081
- &:nth-child(2) {
1082
- animation-delay: -0.5s;
1083
- }
1084
- }
1085
- &.LoaderWithPanicButton {
1086
- top: 40px;
1087
- }
1088
- }
1089
-
1090
- @keyframes ripple-effect {
1091
- 0% {
1092
- top: 36px;
1093
- left: 36px;
1094
- width: 0;
1095
- height: 0;
1096
- opacity: 0;
1097
- }
1098
- 4.9% {
1099
- top: 36px;
1100
- left: 36px;
1101
- width: 0;
1102
- height: 0;
1103
- opacity: 0;
1104
- }
1105
- 5% {
1106
- top: 36px;
1107
- left: 36px;
1108
- width: 0;
1109
- height: 0;
1110
- opacity: 1;
1111
- }
1112
- 100% {
1113
- top: 0px;
1114
- left: 0px;
1115
- width: 72px;
1116
- height: 72px;
1117
- opacity: 0;
1118
- }
1119
- }
1120
- </style>