@everymatrix/casino-page 0.0.365 → 0.0.367

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,1720 +1,1720 @@
1
- <svelte:options tag={null} />
2
-
3
- <script lang="ts">
4
- import { onMount } from "svelte";
5
- import { isMobile, getDevice } from 'rvhelper';
6
- import { _, addNewMessages, setupI18n, setLocale } from './i18n';
7
- import { CasinoPageTranslations } from './translations';
8
- import type {
9
- CategoriesData,
10
- CasinoData,
11
- CategoriesItems,
12
- CasinoItems,
13
- } from './CasinoPage.types';
14
-
15
- import '@everymatrix/casino-games-category-section';
16
- import '@everymatrix/casino-random-game';
17
- import '@everymatrix/jackpot-banner';
18
-
19
- export let endpoint:string = '';
20
- export let datasource:string = '';
21
- export let currency:string = '';
22
- export let lang:string = ''; // Language
23
- export let session:string = ''; // Value for sessionID
24
- export let userid:string = ''; // Value for UserID;
25
- export let clientstyling:string = '';
26
- export let clientstylingurl:string = '';
27
-
28
- export let categorybackground:string = '';
29
- export let visiblegames:string;
30
- export let alternativesearch:string = 'false';
31
- export let favorites:string = '';
32
- export let mostplayed:string = '';
33
- export let containermaxwidth:string = '1300';
34
- export let lobbyid:string = 'casinodefault'; // identifier for recent searched
35
- export let haspanicbutton:string = 'false';
36
-
37
- export let mostplayedrounds:string = '';
38
- export let activecategory:string = '';
39
- export let livecasino:string = 'false';
40
- export let playrandomgame:string = 'false';
41
- export let gamepagemodalurl:string = 'false';
42
- export let enablecasinowinners:string = 'true';
43
- export let enablejackpotbanner:string = 'true';
44
-
45
- export let tabsorder:string = '';
46
- export let enableautoscroll:string = '';
47
- export let istopavailable:string = '';
48
- export let isrecentavailable:string = '';
49
-
50
- // Button icon for random game widget
51
- export let randombuttonicon:string = '';
52
-
53
- let userAgent:any = window.navigator.userAgent;
54
- let gameevent:string;
55
-
56
- if (!isMobile(userAgent)) {
57
- gameevent = 'ShowGameModal';
58
- } else {
59
- gameevent = 'OpenGameFrame';
60
- }
61
-
62
- // CasinoPage loading state
63
- let isLoading:boolean = false;
64
- let hasErrors:boolean = false;
65
- let isLoggedIn:boolean = false;
66
- let error:string = '';
67
-
68
- let playerID:string;
69
- let sessionID:string;
70
-
71
- let panicButton:HTMLElement;
72
- let panicLoading:boolean = false;
73
- let timer: number = 0;
74
- let timerInterval:any;
75
-
76
- // CasinoPage state
77
- let favoritesScreen:boolean = false;
78
- let recentSearches:boolean = false;
79
- let initialLoaded:boolean = true;
80
- let searched:boolean = false;
81
- let gameFocus:boolean = false;
82
- let lobbyViewAux:boolean = false;
83
- let closeSearch:boolean = false;
84
- let searchFocus:boolean = false;
85
- let lobbyScreen:boolean = true;
86
- let mostPlayedScreen:boolean = false;
87
- let mostPlayedEmpty:boolean = false;
88
- let adjustingScroll:boolean = false;
89
- let searchBarCleared:boolean = true;
90
-
91
- // Needs to be checked if there are relevant
92
- let gamesArray = [];
93
- let searchArray:Array<CasinoItems>;
94
- let categories:Array<CategoriesItems> = [];
95
- let shownCategories:Array<CategoriesItems> = [];
96
- let activeCategory:string;
97
-
98
- let searchValue:string = '';
99
- let searchWrapper:HTMLElement;
100
- let searchElementWrapper:HTMLElement;
101
- let searchPositionTop:number;
102
- let searchedGamesCache:Object = {};
103
-
104
- // const scrollOffset:number = getDevice(userAgent) !== 'PC' ? operatorDetail.scrollOffset[0] : operatorDetail.scrollOffset[1];
105
- const scrollOffset:number = 0;
106
-
107
- let scrollTop:boolean = false;
108
- let mostPlayedGames:Array<any> = [];
109
-
110
- let favoredGamesCollection:Array<string> = [];
111
- let categoriesData;
112
- let receivedFavoriteResults:Object;
113
- let updatedFavoriteResultsIds:Array<string>;
114
- let searchElement:HTMLElement;
115
- let mobileSearchViewActive:boolean = false;
116
- let searchedValues:any = [];
117
- let mostPlayedValues:any = [];
118
- let filterVendorsArray:Array<Object> = [];
119
- let numberOfFilters:number = 0;
120
- let filteredGamesArray:Array<Object> = [];
121
- let currentCategoryId:string = '';
122
- let activeCategoryAux:any = undefined;
123
- let customStylingContainer:HTMLElement;
124
- let urlCasino:any;
125
- let firstLoad:boolean = false;
126
-
127
-
128
- setupI18n({ withLocale: 'en', translations: {}});
129
-
130
- Object.keys(CasinoPageTranslations).forEach((item) => {
131
- addNewMessages(item, CasinoPageTranslations[item]);
132
- });
133
-
134
- const CategoryChangeHandler = (categoryEvent:any) => {
135
- searched = false;
136
- searchValue = '';
137
- scrollTop = true;
138
- // needs to be executed after the page has been populated
139
- setTimeout(() => {
140
- window.postMessage({ type: 'WidgetTopReference', scrollTop }, window.location.href);
141
- });
142
- switch(categoryEvent.data.itemId) {
143
- case 'LOBBY':
144
- lobbyScreen = true;
145
- favoritesScreen = false;
146
- activeCategory = '';
147
- mostPlayedScreen = false;
148
- break;
149
-
150
- case 'FAVORITES':
151
- lobbyScreen = false;
152
- favoritesScreen = true;
153
- mostPlayedScreen = false;
154
- activeCategory = '';
155
- break;
156
-
157
- case 'MOSTPLAYED':
158
- if (mostplayed == 'true') {
159
- isLoading = true;
160
-
161
- getMostPlayedGames({
162
- limit: 100,
163
- device: getDevice(userAgent),
164
- rounds: 10
165
- }).then((res:any) => {
166
- isLoading = false;
167
-
168
- if (res.count > 0) {
169
- let promises:any = [];
170
-
171
- res.items.forEach((item:any) => {
172
- let url:URL = new URL(`${endpoint}/casino/games/${item.gameId}`);
173
-
174
- url.searchParams.append('datasource', datasource);
175
- if (livecasino) {
176
- promises.push(fetch(url.href).then((res:any) => res.json()));
177
- } else {
178
- promises.push(fetch(url.href).then((res:any) => res.json()));
179
- }
180
- });
181
-
182
- Promise.all(promises).then((values:any) => {
183
- mostPlayedGames = values.map((item:any) => item[0]);
184
-
185
- window.postMessage({ type: 'MostPlayedData', mostPlayedGames }, window.location.href);
186
- });
187
- } else {
188
- mostPlayedEmpty = true;
189
- }
190
- });
191
-
192
- activeCategory = '';
193
- lobbyScreen = false;
194
- favoritesScreen = false;
195
- mostPlayedScreen = true;
196
- }
197
- break;
198
-
199
- default:
200
- lobbyScreen = false;
201
- favoritesScreen = false;
202
- mostPlayedScreen = false;
203
- activeCategory = categoryEvent.data.itemId;
204
- //@TODO: if we remove the settimeout, the postmessage does not execute, at all - weird behaviour
205
- setTimeout(() => {
206
- window.postMessage({ type: 'CategoryUpdate', itemId: activeCategory }, window.location.href);
207
- }, 500);
208
-
209
-
210
- break;
211
- }
212
- }
213
-
214
- const messageHandler = (e:any) => {
215
- if (e.data) {
216
- switch(e.data.type) {
217
- // @TODO: removed and tested, but kept in case unforeseen issues occur - reason: multiple calls on category change
218
- // case 'CategoryChange':
219
- // CategoryChangeHandler(e);
220
- // break;
221
-
222
- case 'UserSessionID':
223
- sessionID = e.data.session;
224
- playerID = e.data.userID;
225
-
226
- if (playerID && playerID.length && sessionID && sessionID.length > 0) {
227
- getFavoredGames(endpoint, sessionID, playerID);
228
- }
229
- break;
230
-
231
- // @TODO dis should be removed
232
- case 'CategoriesLoadedForSlider':
233
- window.postMessage({ type: 'SetSliderIndex', index: 0, categoryData: { id: 'LOBBY' } }, window.location.href);
234
- break;
235
-
236
- case 'SetUnfavoredGame':
237
- removeFavoredGame(`${endpoint}/player/${playerID}/favorites`, sessionID, playerID, e.data.id, e.data.triggerFactor);
238
- break;
239
-
240
- case 'SetFavoredGame':
241
- addFavoredGame(`${endpoint}/player/${playerID}/favorites`, sessionID, playerID, e.data.id, e.data.triggerFactor);
242
- break;
243
-
244
- case 'GetFavoredGame':
245
- if (playerID && playerID.length && sessionID && sessionID.length > 0) {
246
- getFavoredGames(endpoint, sessionID, playerID);
247
- }
248
- break;
249
-
250
- case 'SearchedItemClicked':
251
- addSearchedItem(e.data.gameId);
252
- break;
253
-
254
- case 'UpdateFilters':
255
- updateFilters(e.data.vendorsArray);
256
- setFilterNumberValue();
257
- break;
258
-
259
- case 'ClearFilters':
260
- submitFilters(e.data.vendorsArray);
261
- setFilterNumberValue();
262
- break;
263
-
264
- case 'ApplyFilters':
265
- window.postMessage({ type: 'CategoryUpdate', itemId: currentCategoryId }, window.location.href);
266
- setFilterNumberValue();
267
- break;
268
-
269
- case 'CategoryVendors':
270
- currentCategoryId = e.data.categoryid;
271
- setFilterNumberValue();
272
- break;
273
-
274
- case 'GameHovered':
275
- gameFocus = true;
276
- break;
277
-
278
- case 'GameBlur':
279
- gameFocus = false;
280
- break;
281
-
282
- default:
283
- // Nothing to do here
284
- break;
285
- }
286
- }
287
- }
288
-
289
- const getMostPlayedGames = (options:any) => {
290
- let url = new URL(`${endpoint}/player/${playerID}/games/most-played`);
291
-
292
- if (options.limit) {
293
- url.searchParams.append('limit', options.limit);
294
- }
295
-
296
- if (options.order) {
297
- url.searchParams.append('order', options.order);
298
- }
299
-
300
- let device = options.device;
301
-
302
- if (device) {
303
- if (device === 'PC') {
304
- url.searchParams.append('device', 'Desktop');
305
- } else {
306
- url.searchParams.append('device', 'Mobile');
307
- }
308
- } else {
309
- url.searchParams.append('device', 'All');
310
- }
311
-
312
- if (options.rounds) {
313
- url.searchParams.append('rounds', options.rounds);
314
- }
315
-
316
- urlCasino = livecasino ? url : url.href;
317
- return new Promise((resolve, reject) => {
318
- fetch(urlCasino)
319
- .then((res:any) => res.json())
320
- .then((data:any) => {
321
- resolve(data);
322
-
323
- window.postMessage({ type: 'AddNewCategory', category: { name: 'Most Played', id: 'MOSTPLAYED' }}, window.location.href);
324
- window.postMessage({ type: 'MostPlayedGames', data }, window.location.href);
325
- }).catch((err:any) => {
326
- console.error(err);
327
-
328
- reject(err);
329
- });
330
- });
331
- }
332
-
333
- //
334
- // --- START of Favorites section
335
- //
336
- let getFavoredGames = (url:string, sessionID:string, playerID:string) => {
337
- if (favorites == 'true') {
338
- if (session && playerID) {
339
- let options = {
340
- method: "GET",
341
- headers: {
342
- 'X-SessionID': sessionID,
343
- }
344
- };
345
-
346
- fetch(`${url}/player/${playerID}/favorites/`, options)
347
- .then((res:any) => res.json())
348
- .then((updatedArray:Object) => {
349
- receivedFavoriteResults = updatedArray;
350
-
351
- if (receivedFavoriteResults) {
352
- window.postMessage({ type: "UpdateCategoryFavoriteGames", receivedFavoriteResults }, window.location.href);
353
-
354
- updatedFavoriteResultsIds = getGamesIds(receivedFavoriteResults.items);
355
- }
356
-
357
- return receivedFavoriteResults;
358
- }).then((favResults) => {
359
- if (favoritesScreen) {
360
- showFavoriteGames();
361
- }
362
- return favResults;
363
- }).catch((err:any) => {
364
- console.error(err);
365
- });
366
- }
367
- }
368
- }
369
-
370
- let updateFavoredList = (url:string, sessionID:string, playerID:string) => {
371
- let options = {
372
- method: "GET",
373
- headers: {
374
- 'X-SessionID': sessionID,
375
- }
376
- };
377
-
378
- fetch(url, options)
379
- .then((res:any) => res.json())
380
- .then((updatedArray:Object) => {
381
- receivedFavoriteResults = updatedArray;
382
-
383
- if (favoritesScreen) {
384
- showFavoriteGames();
385
- }
386
-
387
- if (receivedFavoriteResults) {
388
- window.postMessage({ type: "UpdateCategoryFavoriteGames", receivedFavoriteResults}, window.location.href);
389
- }
390
-
391
- return receivedFavoriteResults;
392
- }).catch((err:any) => {
393
- console.error(err);
394
- });
395
- }
396
-
397
- const getGamesIds = (favoritesArray:any = []) => {
398
- // construct favorite array used to check if game id is not already present in fav list
399
- favoredGamesCollection = [];
400
-
401
- if (favoritesArray.length > 0) {
402
- favoritesArray.forEach((fav:any) => {
403
- favoredGamesCollection.push(fav.id);
404
- });
405
- }
406
-
407
- return favoredGamesCollection;
408
- }
409
-
410
- let addFavoredGame = (url:string, sessionID:string, playerID:string, gameID:string, triggerFactor:string) => {
411
- // 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
412
- if (!favoredGamesCollection.includes(gameID)) {
413
- favoredGamesCollection.push(gameID);
414
- }
415
-
416
- let data = {
417
- items: favoredGamesCollection
418
- };
419
-
420
- let options = {
421
- method: "POST",
422
- headers: {
423
- 'X-SessionID': sessionID,
424
- 'Content-Type': 'application/json',
425
- 'Accept': 'application/json',
426
- },
427
- body: JSON.stringify(data)
428
- };
429
-
430
- fetch(url, options)
431
- .then((res:any) => res.json())
432
- .then((increasedFavArray:any) => {
433
- window.postMessage({ type: `AddFavoriteThumbnail_${gameID}` }, window.location.href);
434
-
435
- updateFavoredList(url, sessionID, playerID);
436
- })
437
- .catch((err:any) => {
438
- console.error('Err', err);
439
- });
440
- }
441
-
442
- const removeFavoredGame = (url:string, sessionID:string, playerID:string, gameID:string, triggerFactor:string) => {
443
- if (favoredGamesCollection.includes(gameID)) {
444
- favoredGamesCollection = favoredGamesCollection.filter(x => {
445
- return x != gameID;
446
- });
447
- }
448
-
449
- let options = {
450
- method: "DELETE",
451
- headers: {
452
- 'X-SessionID': sessionID,
453
- }
454
- };
455
-
456
- fetch(`${url}/${gameID}`, options)
457
- .then((res:any) => res.json())
458
- .then((decreasedFavArray:any) => {
459
- window.postMessage({ type: `RemoveFavoriteThumbnail_${gameID}` }, window.location.href);
460
-
461
- updateFavoredList(url, sessionID, playerID);
462
- });
463
- }
464
-
465
- const showFavoriteGames = () => {
466
- window.postMessage({ type: "ShowFavoriteSection", receivedFavoriteResults}, window.location.href);
467
- }
468
- //
469
- // --- END of Favorites section
470
- //
471
-
472
- const getCategories = (url:any) => {
473
- return new Promise((resolve, reject) => {
474
- isLoading = true;
475
-
476
- fetch(url)
477
- .then((res:any) => res.json())
478
- .then((data:CategoriesData) => {
479
- isLoading = false;
480
-
481
- resolve(data);
482
- }).catch((err:any) => {
483
- hasErrors = true;
484
- isLoading = false;
485
-
486
- console.error(err);
487
-
488
- reject(err);
489
- });
490
- });
491
- }
492
-
493
- const getGames = (url:any) => {
494
- return new Promise((resolve, reject) => {
495
- isLoading = true;
496
-
497
- fetch(url)
498
- .then((res:any) => res.json())
499
- .then((categoryData:CasinoData) => {
500
- isLoading = false;
501
-
502
- resolve(categoryData);
503
- }).catch((err:any) => {
504
- hasErrors = true;
505
- isLoading = false;
506
-
507
- console.error(err);
508
-
509
- reject(err);
510
- });
511
- });
512
- }
513
-
514
- const getGame = (url:any, gameId?:string):Promise<any> => {
515
- return new Promise((resolve, reject) => {
516
- isLoading = true;
517
-
518
- if(gameId && Object.keys(searchedGamesCache).indexOf(gameId) >= 0){
519
- isLoading = false;
520
-
521
- resolve(searchedGamesCache[gameId]);
522
- } else {
523
- fetch(url)
524
- .then((res:any) => res.json())
525
- .then((gameData:any) => {
526
- isLoading = false;
527
-
528
- searchedGamesCache[gameData[0].id] = gameData[0];
529
-
530
- resolve(gameData[0]);
531
- }).catch((err:any) => {
532
- hasErrors = true;
533
- isLoading = false;
534
-
535
- console.error(err);
536
-
537
- reject(err);
538
- });
539
- }
540
- });
541
- }
542
-
543
- const getCookieValue = (name:string) => {
544
- let match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
545
-
546
- if (match) {
547
- return match[2];
548
- }
549
- }
550
-
551
- const onFocus = () => {
552
- if (endpoint && datasource && lang) {
553
- searchFocus = true;
554
-
555
- if (searchValue.length < 2) {
556
- let recentSearchedGames = getCookieValue(`searchedGamesWds_${lobbyid}`);
557
- let recentSearchedGamesArray:Array<any> = [];
558
-
559
- if (recentSearchedGames) {
560
- recentSearchedGamesArray = recentSearchedGames.split(',');
561
- }
562
-
563
- if (lobbyScreen == true && !initialLoaded) {
564
- lobbyViewAux = lobbyScreen;
565
- lobbyScreen = false;
566
- }
567
-
568
- let promises:Array<any> = [];
569
- let index = 0;
570
- let length = recentSearchedGamesArray.length;
571
-
572
- if (length > 0) {
573
- for (index = 0; index < length; index++) {
574
- let url:any = new URL(`${endpoint}/casino/games/${recentSearchedGamesArray[index]}`);
575
-
576
- url.searchParams.append('language', lang);
577
- url.searchParams.append('datasource', datasource);
578
- url.searchParams.append('platform', getDevice(userAgent));
579
-
580
- promises.push(getGame(url, recentSearchedGamesArray[index]));
581
- }
582
-
583
- Promise.all(promises).then((res:any) => {
584
- searchArray = res;
585
-
586
- sendRecentSearchData({}, searchArray)
587
- });
588
- } else {
589
- sendRecentSearchData({}, {})
590
- }
591
- }
592
- }
593
- }
594
-
595
- const onBlur = () => {
596
- searchFocus = false;
597
-
598
- if (searchValue.length < 2 && !gameFocus) {
599
- searched = false;
600
- searchArray = [];
601
- recentSearches = false;
602
- lobbyScreen = lobbyViewAux;
603
- lobbyViewAux = false;
604
- if (lobbyScreen === false) {
605
- window.postMessage({ type: 'CategoryUpdate', itemId: activeCategory }, window.location.href);
606
- }
607
-
608
- window.postMessage({ type: 'OutOfRecentSearches' }, window.location.href);
609
- }
610
- }
611
-
612
- const addSearchedItem = (gameID:any) => {
613
- searchedValues = getCookieValue(`searchedGamesWds_${lobbyid}`);
614
-
615
- if (searchedValues) {
616
- searchedValues = searchedValues.split(',');
617
- } else {
618
- searchedValues = [];
619
- }
620
- if (searchedValues.indexOf(gameID) === -1) {
621
- let value;
622
-
623
- searchedValues.push(gameID);
624
- value = searchedValues.join(',');
625
- document.cookie = `searchedGamesWds_${lobbyid}=` + value;
626
- }
627
- }
628
-
629
- // @TODO let's do some small changes around here in order to have this search functionality pretty written, 'cuz right now is kinda shitty
630
- const searchValueChanged = () => {
631
- if (searchValue.length >= 2) {
632
- searchBarCleared = true;
633
- } else {
634
- searchBarCleared = false;
635
- }
636
- }
637
-
638
- $: searchValue && searchValueChanged();
639
-
640
- $: if (searchValue.length >= 2) {
641
- searched = true;
642
-
643
- let searchUrl:any = new URL(`${endpoint}/casino/games`);
644
-
645
- searchUrl.searchParams.append("datasource", datasource);
646
- searchUrl.searchParams.append("expand", "vendor");
647
- searchUrl.searchParams.append("platform", getDevice(userAgent));
648
- searchUrl.searchParams.append("language", lang);
649
- searchUrl.searchParams.append("pagination", "offset=0,limit=30");
650
- searchUrl.searchParams.append("filter", `name=${searchValue}`);
651
-
652
- getGames(searchUrl).then((searchData:any) => {
653
- searchArray = searchData;
654
-
655
- sendSearchData({}, searchData);
656
- });
657
- } else {
658
- if (!searchBarCleared) {
659
- onFocus();
660
- }
661
-
662
- if (initialLoaded) {
663
- initialLoaded = false;
664
- }
665
- }
666
-
667
- const setFilterNumberValue = () => {
668
- let vendors = JSON.parse(sessionStorage.getItem('vendorFiltersByCategory'));
669
-
670
- if (vendors) {
671
- if(currentCategoryId) {
672
- if(vendors[currentCategoryId]) {
673
- numberOfFilters = vendors[currentCategoryId].length;
674
- } else {
675
- numberOfFilters = 0;
676
- }
677
- }
678
- }
679
- }
680
-
681
- const searchActivated = () => {
682
- window.postMessage({ type: "scroll" }, window.location.href);
683
- }
684
-
685
- const clearSearchbar = () => {
686
- searchBarCleared = true;
687
- searchValue = '';
688
- searchArray = [];
689
- recentSearches = false;
690
-
691
- onBlur();
692
- }
693
-
694
- //
695
- // --- START of communication with other widgets
696
- //
697
- const sendMostPlayed = (node:any, mostPlayedData:CategoriesData) => {
698
- window.postMessage({ type: 'MostPlayedData', mostPlayedData }, window.location.href);
699
- }
700
-
701
- const submitFilters = (venArray:Array<Object>) => {
702
- window.postMessage({ type: "AvailableVendors", venArray}, window.location.href);
703
- }
704
-
705
- const updateFilters = (venArray:Array<Object>) => {
706
- window.postMessage({ type: "UpdateSelectedVendorFilters", venArray}, window.location.href);
707
- }
708
-
709
- const sendRecentSearchData = (node:any, searchData:any) => {
710
- window.postMessage({ type: "RecentSearchData", searchData }, window.location.href);
711
- }
712
-
713
- const openFiltersModal = () => {
714
- window.postMessage({ type: "ShowFilterModal" }, window.location.href);
715
- }
716
-
717
- const clearVendorFilter = () => {
718
- window.postMessage({ type: "ClearVendorFilters" }, window.location.href);
719
- }
720
-
721
- const sendCategoryData = (node:any, categoryId:string) => {
722
- currentCategoryId = categoryId;
723
- window.postMessage({ type: `CategoryData_${categoryId}`, categoryId, visiblegames, receivedFavoriteResults }, window.location.href);
724
- }
725
-
726
- const sendSearchData = (node:any, searchData:CategoriesData) => {
727
- if (searchData) {
728
- window.postMessage({ type: "SearchData", searchData, receivedFavoriteResults }, window.location.href);
729
- }
730
- }
731
-
732
- //
733
- // --- END of communication with other widgets
734
- //
735
-
736
- /* Listen for scroll */
737
- const scrollHandler = () => {
738
- if(searchElementWrapper) {
739
- searchPositionTop = searchElementWrapper.getBoundingClientRect().top + document.body.getBoundingClientRect().top;
740
- }
741
- if (document.documentElement.scrollTop > searchPositionTop || searchPositionTop > 130) {
742
- adjustingScroll = true;
743
- } else {
744
- adjustingScroll = false;
745
- }
746
- }
747
-
748
- const checkAttrs = () => {
749
- if (!endpoint) {
750
- error = "Endpoint is missing! Please provide a valid endpointURL.";
751
- hasErrors = true;
752
- isLoading = false;
753
-
754
- console.error(error);
755
- }
756
-
757
- if (!datasource) {
758
- error = "Datasource is missing! Please provide a valid datasource.";
759
- hasErrors = true;
760
- isLoading = false;
761
-
762
- console.error(error);
763
- }
764
-
765
- if (!lang || lang.length < 2) {
766
- error = "Language is missing! Please provide a valid language (alpha2code)";
767
- hasErrors = true;
768
- isLoading = false;
769
-
770
- console.error(error);
771
- }
772
-
773
- return hasErrors;
774
- }
775
- const updateCategoriesLanguage = () => {
776
- if(firstLoad) {
777
- setTimeout(() => {
778
- window.postMessage({ type: 'CategoryUpdate', itemId: activeCategory}, window.location.href);
779
- }, 500);
780
- }
781
- firstLoad = false;
782
- }
783
-
784
- const initialSetup = () => {
785
- if (!checkAttrs()) {
786
- isLoading = true;
787
-
788
- if (favorites == 'true') {
789
- getFavoredGames(endpoint, sessionID, playerID);
790
- }
791
-
792
- setLocale(lang);
793
-
794
- let categoriesUrl = new URL(`${endpoint}/casino/groups/${datasource}`);
795
-
796
- categoriesUrl.searchParams.append('language', lang);
797
- categoriesUrl.searchParams.append('platform', getDevice(userAgent));
798
-
799
- getCategories(categoriesUrl).then((data:CategoriesData) => {
800
- if (data) {
801
- categoriesData = data.items.filter((item:any) => {
802
- return item.games.total > 0;
803
- });
804
-
805
- shownCategories = categories = categoriesData.map((item:any) => {
806
- return item.id;
807
- });
808
-
809
- isLoading = false;
810
- }
811
- });
812
-
813
- if (getDevice(userAgent) !== 'PC') {
814
- searchElement.addEventListener('focusin', (event) => {
815
- mobileSearchViewActive = true;
816
- });
817
-
818
- searchElement.addEventListener('focusout', (event) => {
819
- mobileSearchViewActive = false;
820
- });
821
- }
822
-
823
- setFilterNumberValue();
824
-
825
- searchElementWrapper = searchWrapper;
826
-
827
- if (searchElementWrapper) {
828
- searchPositionTop = searchElementWrapper.getBoundingClientRect().top - document.body.getBoundingClientRect().top;
829
- }
830
- }
831
- }
832
-
833
- const setActiveCategory = ():void => {
834
- activeCategory = activecategory;
835
- CategoryChangeHandler({ data: { itemId: activeCategory }});
836
- }
837
-
838
- const setSession = () => {
839
- isLoggedIn = true;
840
- sessionID = session;
841
- playerID = userid;
842
- if (playerID && playerID.length && sessionID && sessionID.length > 0) {
843
- getFavoredGames(endpoint, sessionID, playerID);
844
- }
845
- }
846
-
847
- const setClientStyling = () => {
848
- let sheet = document.createElement('style');
849
- sheet.innerHTML = clientstyling;
850
- customStylingContainer.appendChild(sheet);
851
- }
852
-
853
- const setClientStylingURL = () => {
854
- let cssFile:HTMLElement = document.createElement('style');
855
-
856
- fetch(new URL(clientstylingurl))
857
- .then((res:any) => res.text())
858
- .then((data:any) => {
859
- cssFile.innerHTML = data
860
-
861
- if (customStylingContainer) {
862
- setTimeout(() => { customStylingContainer.appendChild(cssFile); }, 1);
863
- }
864
- });
865
- }
866
-
867
- const startInterval = (e:any):void => {
868
- timer = 0;
869
-
870
- timerInterval = setInterval(() => {
871
- timer += 1;
872
- panicLoading = true;
873
-
874
- if (timer >= 3) {
875
- window.postMessage({type: 'PanicButtonClicked'}, window.location.href);
876
- clearInterval(timerInterval)
877
- }
878
- }, 1000);
879
- }
880
-
881
- const endInterval = (e:any):void => {
882
- if (timer < 3) {
883
- panicLoading = false;
884
- }
885
- clearInterval(timerInterval);
886
- }
887
-
888
- const addEventsToDisplayedElements = () => {
889
- panicButton?.addEventListener("mousedown", startInterval, false);
890
- panicButton?.addEventListener('touchstart', startInterval, false);
891
-
892
- // on mouseup stop interval count
893
- panicButton?.addEventListener("mouseup", endInterval, false);
894
- panicButton?.addEventListener("touchend", endInterval, false);
895
- }
896
-
897
- const removeEventsToDisplayedElements = ():void => {
898
- panicLoading = false;
899
- panicButton?.removeEventListener("mousedown", startInterval);
900
- panicButton?.removeEventListener('touchstart', startInterval);
901
-
902
- // on mouseup stop interval count
903
- panicButton?.removeEventListener("mouseup", endInterval);
904
- panicButton?.removeEventListener("touchend", endInterval);
905
- }
906
-
907
- onMount(() => {
908
- window.addEventListener('scroll', scrollHandler, false);
909
- window.addEventListener('message', messageHandler, false);
910
-
911
- return () => {
912
- window.removeEventListener('scroll', scrollHandler);
913
- window.removeEventListener('message', messageHandler);
914
-
915
- removeEventsToDisplayedElements();
916
- }
917
- });
918
-
919
- $: lang && activecategory && setActiveCategory();
920
- $: session && userid && endpoint && setSession();
921
- $: endpoint && datasource && lang && alternativesearch && initialSetup();
922
- $: lang && updateCategoriesLanguage();
923
- $: clientstyling && setClientStyling();
924
- $: clientstylingurl && setClientStylingURL();
925
- $: panicButton && addEventsToDisplayedElements();
926
- </script>
927
-
928
- {#if hasErrors}
929
- <p class="SearchLoading" part="SearchLoading">{$_('casinoPage.500')}</p>
930
- {:else}
931
- <section class="CategoriesLobby" part="CategoriesLobby" bind:this={customStylingContainer} style="max-width: {containermaxwidth}px;">
932
- {#if (getDevice(userAgent) !== 'PC') && (alternativesearch === 'false') && mobileSearchViewActive}
933
- <div class="SearchBarPlaceholder" part="SearchBarPlaceholder"></div>
934
- {/if}
935
-
936
- {#if alternativesearch === 'false'}
937
- <!-- main search layout -->
938
- <div bind:this={searchWrapper} class="CategoriesHeaderSection {(getDevice(userAgent) !== 'PC') ? 'CategoriesHeaderMobileSection' : ''} {mobileSearchViewActive ? 'SearchMobileActive' : ''} {mobileSearchViewActive || (searched && !(getDevice(userAgent) === 'PC') && !closeSearch) ? 'CategoriesHeaderSearchActive' : ''} {(adjustingScroll && mobileSearchViewActive) ? 'SearchStickTop' : ''}"
939
- style="top: {adjustingScroll && mobileSearchViewActive ? scrollOffset + 'px' : ''}"
940
- part="CategoriesHeaderSection {(getDevice(userAgent) !== 'PC') ? 'CategoriesHeaderMobileSection' : ''} {mobileSearchViewActive ? 'SearchMobileActive' : ''} {mobileSearchViewActive || (searched && !(getDevice(userAgent) === 'PC') && !closeSearch) ? 'CategoriesHeaderSearchActive' : ''} {(adjustingScroll && mobileSearchViewActive) ? 'SearchStickTop' : ''}">
941
- <div class="SearchContainer { (!lobbyScreen && !favoritesScreen && !mostPlayedScreen && !lobbyViewAux) ? 'SearchTruncated' : ''}" part="SearchContainer { (!lobbyScreen && !favoritesScreen && !mostPlayedScreen && !lobbyViewAux) ? 'SearchTruncated' : ''}">
942
- <label for="search" class="SrOnly" part="SrOnly">{$_('casinoPage.searchGames')}</label>
943
- <div class="SearchWrapper" part="SearchWrapper">
944
- {#if !mobileSearchViewActive}
945
- <div class="SearchIcon" part="SearchIcon">
946
- <svg role="presentation" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" aria-hidden="true">
947
- <path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd" />
948
- </svg>
949
- </div>
950
- {/if}
951
- <input id="SearchField" class="SearchInput" part="SearchInput" on:focus={onFocus} on:blur={onBlur} bind:this={searchElement} bind:value={searchValue} placeholder="{(getDevice(userAgent) === 'PC') ? $_('casinoPage.search') : $_('casinoPage.searchMobile')}" type="search" on:focus={searchActivated} />
952
- {#if ((getDevice(userAgent) === 'PC') && searchValue.length) || (getDevice(userAgent) !== 'PC') }
953
- <span class="{(getDevice(userAgent) === 'PC') ? 'ClearSearchButton' : 'ClearSearchButtonMobile'}" part="{(getDevice(userAgent) === 'PC') ? 'ClearSearchButton' : 'ClearSearchButtonMobile'}" on:click="{() => clearSearchbar()}">
954
- <div class="CloseIconContainer" part="CloseIconContainer">
955
- <div class="CloseIconWrapper" part="CloseIconWrapper">
956
- <div class="CloseIcon" part="CloseIcon"></div>
957
- </div>
958
- </div>
959
- </span>
960
- {/if}
961
- </div>
962
- </div>
963
- {#if !favoritesScreen && !lobbyScreen && !mobileSearchViewActive && !mostPlayedScreen && !recentSearches && !searched && !searchFocus && !lobbyViewAux}
964
- <div class="FiltersButtonsContainer" part="FiltersButtonsContainer">
965
- {#if numberOfFilters}
966
- <div class="ClearFilterButtonWrapper" part="ClearFilterButtonWrapper" on:click="{() => clearVendorFilter()}">
967
- <div class="ClearButton" part="ClearButton">{$_('casinoPage.clear')}
968
- <span class="ClearIcon" part="ClearIcon">
969
- <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
970
- viewBox="0 0 378.303 378.303" style="enable-background:new 0 0 378.303 378.303;" xml:space="preserve">
971
- <polygon style="fill:var(--emfe-w-color-secondary, #FD2839);" points="378.303,28.285 350.018,0 189.151,160.867 28.285,0 0,28.285 160.867,189.151 0,350.018
972
- 28.285,378.302 189.151,217.436 350.018,378.302 378.303,350.018 217.436,189.151 "/>
973
- </svg>
974
- </span>
975
- </div>
976
- </div>
977
- {/if}
978
- {#if !searched || !recentSearches}
979
- {#if !mostPlayedScreen}
980
- <div class="FilterButtonWrapper" part="FilterButtonWrapper" on:click='{() => {openFiltersModal()}}'>
981
- <div class="FilterButton" part="FilterButton">{$_('casinoPage.filters')}</div>
982
- <div class="FilterIconContainer" part="FilterIconContainer">
983
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 26 26"><defs><style>.a{fill:var(--emfe-w-color-white, #FFFFFF);}</style></defs><path class="a" d="M16.7,32.2a1.654,1.654,0,0,1-.636-.148,1.526,1.526,0,0,1-.867-1.393V20.578L5.433,10.588A1.543,1.543,0,0,1,5,9.491V7.742A1.512,1.512,0,0,1,6.5,6.2h23A1.512,1.512,0,0,1,31,7.742V9.491a1.543,1.543,0,0,1-.433,1.1L20.8,20.578v7.738a1.594,1.594,0,0,1-.52,1.156l-2.6,2.312A1.461,1.461,0,0,1,16.7,32.2ZM6.618,9.431l9.764,10.02a1.543,1.543,0,0,1,.433,1.1v9.813l2.34-2.075V20.519a1.543,1.543,0,0,1,.433-1.1L29.353,9.4V7.831H6.618Z" transform="translate(-5 -6.2)"/></svg>
984
- <div class="NumberOfFiltersContainer" part="NumberOfFiltersContainer">
985
- <span class="NumberOfFilters" part="NumberOfFilters">{numberOfFilters}</span>
986
- </div>
987
- </div>
988
- </div>
989
- {/if}
990
- {/if}
991
- </div>
992
- {/if}
993
- </div>
994
- {:else}
995
- <!-- start alternative search layout-->
996
- <div bind:this={searchWrapper} class="CategoriesHeaderSection CategoriesHeaderSectionAltDesign {(getDevice(userAgent) !== 'PC') ? 'CategoriesHeaderMobileSection' : ''} {mobileSearchViewActive ? 'SearchMobileActive' : ''} {mobileSearchViewActive || (searched && !(getDevice(userAgent) === 'PC') && !closeSearch) ? 'CategoriesHeaderSearchActive' : ''}{(adjustingScroll && mobileSearchViewActive) ? 'SearchStickTop' : ''}"
997
- part="CategoriesHeaderSection CategoriesHeaderSectionAltDesign {(getDevice(userAgent) !== 'PC') ? 'CategoriesHeaderMobileSection' : ''} {mobileSearchViewActive ? 'SearchMobileActive' : ''} {mobileSearchViewActive || (searched && !(getDevice(userAgent) === 'PC') && !closeSearch) ? 'CategoriesHeaderSearchActive' : ''}{(adjustingScroll && mobileSearchViewActive) ? 'SearchStickTop' : ''}"
998
- style="top: {adjustingScroll && mobileSearchViewActive ? scrollOffset + 'px' : ''}">
999
- <div class="SearchContainer { (!lobbyScreen && !favoritesScreen && !mostPlayedScreen && !lobbyViewAux) ? 'SearchTruncated' : ''}" part="SearchContainer { (!lobbyScreen && !favoritesScreen && !mostPlayedScreen && !lobbyViewAux) ? 'SearchTruncated' : ''}">
1000
- <label for="search" class="SrOnly" part="SrOnly">{$_('casinoPage.searchGames')}</label>
1001
- <div class="SearchWrapper" part="SearchWrapper">
1002
- {#if !mobileSearchViewActive}
1003
- <div class="SearchIcon" part="SearchWrapper">
1004
- <svg role="presentation" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" aria-hidden="true">
1005
- <path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd" />
1006
- </svg>
1007
- </div>
1008
- {/if}
1009
-
1010
- <input id="SearchField" class="SearchInput" part="SearchInput" on:focus={onFocus} on:blur={onBlur} bind:this={searchElement} bind:value={searchValue} placeholder="{(getDevice(userAgent) === 'PC') ? $_('casinoPage.search') : $_('casinoPage.searchMobile')}" type="search" on:focus={searchActivated} />
1011
- {#if ((getDevice(userAgent) === 'PC') && searchValue.length) || (getDevice(userAgent) !== 'PC')}
1012
- <span class="{(getDevice(userAgent) === 'PC') ? 'ClearSearchButton' : 'ClearSearchButtonMobile'}" part="{(getDevice(userAgent) === 'PC') ? 'ClearSearchButton' : 'ClearSearchButtonMobile'}" on:click="{() => clearSearchbar()}">
1013
- <div class="CloseIconContainer" part="CloseIconContainer">
1014
- <div class="CloseIconWrapper" part="CloseIconWrapper">
1015
- <div class="CloseIcon" part="CloseIcon"></div>
1016
- </div>
1017
- </div>
1018
- </span>
1019
- {/if}
1020
- </div>
1021
- </div>
1022
- {#if !favoritesScreen && !lobbyScreen && !mobileSearchViewActive && !mostPlayedScreen && !recentSearches && !searchFocus && !searched && !lobbyViewAux}
1023
- <div class="FiltersButtonsContainer" part="FiltersButtonsContainer">
1024
- {#if numberOfFilters}
1025
- <div class="ClearFilterButtonWrapper {numberOfFilters ? 'FiltersActive' : ''}" part="ClearFilterButtonWrapper {numberOfFilters ? 'FiltersActive' : ''}" on:click="{() => clearVendorFilter()}">
1026
- <div class="ClearButton" part="ClearButton">{$_('casinoPage.clear')}
1027
- <span class="ClearIcon" part="ClearIcon">
1028
- <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
1029
- viewBox="0 0 378.303 378.303" style="enable-background:new 0 0 378.303 378.303;" xml:space="preserve">
1030
- <polygon style="fill:var(--emfe-w-color-secondary, #FD2839);" points="378.303,28.285 350.018,0 189.151,160.867 28.285,0 0,28.285 160.867,189.151 0,350.018
1031
- 28.285,378.302 189.151,217.436 350.018,378.302 378.303,350.018 217.436,189.151 "/>
1032
- </svg>
1033
- </span>
1034
- </div>
1035
- </div>
1036
- {/if}
1037
- {#if !searched || !recentSearches}
1038
- {#if !mostPlayedScreen}
1039
- <div class="FilterButtonWrapper" part="FilterButtonWrapper" on:click='{() => {openFiltersModal()}}'>
1040
- <div class="FilterButton" part="FilterButton">{$_('casinoPage.filters')}</div>
1041
- <div class="FilterIconContainer" part="FilterIconContainer">
1042
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 26 26"><defs><style>.a{fill:var(--emfe-w-color-white, #FFFFFF);}</style></defs><path class="a" d="M16.7,32.2a1.654,1.654,0,0,1-.636-.148,1.526,1.526,0,0,1-.867-1.393V20.578L5.433,10.588A1.543,1.543,0,0,1,5,9.491V7.742A1.512,1.512,0,0,1,6.5,6.2h23A1.512,1.512,0,0,1,31,7.742V9.491a1.543,1.543,0,0,1-.433,1.1L20.8,20.578v7.738a1.594,1.594,0,0,1-.52,1.156l-2.6,2.312A1.461,1.461,0,0,1,16.7,32.2ZM6.618,9.431l9.764,10.02a1.543,1.543,0,0,1,.433,1.1v9.813l2.34-2.075V20.519a1.543,1.543,0,0,1,.433-1.1L29.353,9.4V7.831H6.618Z" transform="translate(-5 -6.2)"/></svg>
1043
- {#if numberOfFilters > 0}
1044
- <div class="NumberOfFiltersContainer" part="NumberOfFiltersContainer">
1045
- <span class="NumberOfFilters" part="NumberOfFilters">{numberOfFilters}</span>
1046
- </div>
1047
- {/if}
1048
- </div>
1049
- </div>
1050
- {/if}
1051
- {/if}
1052
- </div>
1053
- {/if}
1054
- </div>
1055
- <!-- end alternative search layout-->
1056
- {/if}
1057
-
1058
- {#if playrandomgame == 'true' && searchFocus == false}
1059
- <casino-random-game {datasource} {endpoint} {lang} {gameevent} {randombuttonicon}>
1060
- </casino-random-game>
1061
- {/if}
1062
-
1063
- {#if isLoading}
1064
- <p class="SearchLoading" part="SearchLoading">{$_('casinoPage.loading')}</p>
1065
- {:else}
1066
- {#if searched}
1067
- <casino-games-category-section
1068
- endpoint={endpoint}
1069
- datasource={datasource}
1070
- lang={lang}
1071
- currency={currency}
1072
- session={session}
1073
- userid={userid}
1074
- use:sendSearchData={searchArray}
1075
- categoryid="Search"
1076
- favorites={favorites}
1077
- categoryindex="0"
1078
- class="CategoryContainer"
1079
- {clientstyling}
1080
- {clientstylingurl}
1081
- {livecasino}
1082
- {visiblegames}
1083
- {gamepagemodalurl}
1084
- {enablecasinowinners}
1085
- {enableautoscroll}
1086
- {tabsorder}
1087
- {isrecentavailable}
1088
- {istopavailable}
1089
- />
1090
- {:else}
1091
- {#if lobbyScreen}
1092
- {#each shownCategories as category, index}
1093
- {#if index === 4}
1094
- <br>
1095
- <jackpot-banner
1096
- visualstructure="typeSpread"
1097
- lang="gr"
1098
- title="Jackpot Cards"
1099
- backgroundsrc="../mock_rsrc/background0.png"
1100
- backgroundsrcmobile=""
1101
- currency = {currency || 'RON'}
1102
- gameid = "999"
1103
- endpoint = "https://winmasters-ro-api.stage.norway.everymatrix.com/v1/casino/jackpots"
1104
-
1105
- titlelogopath = "../mock_rsrc/jackpots_logo.svg"
1106
-
1107
- caticon0="../../jackpot-banner/mock_rsrc/icon0.svg"
1108
- caticon1="../mock_rsrc/icon1.svg"
1109
- caticon2="../mock_rsrc/icon2.svg"
1110
- caticon3="../mock_rsrc/icon3.svg"
1111
- ></jackpot-banner>
1112
- {:else if index === 6}
1113
- <br>
1114
- <jackpot-banner
1115
- visualstructure="typeLeft"
1116
- lang="en"
1117
- title="Egypt Quest"
1118
- backgroundsrc="../mock_rsrc/background_egypt.svg"
1119
- backgroundsrcmobile="../mock_rsrc/background0.png"
1120
- currency = {currency || 'RON'}
1121
- gameid = "998"
1122
- endpoint = "https://winmasters-ro-api.stage.norway.everymatrix.com/v1/casino/jackpots"
1123
-
1124
- titlelogopath = "../mock_rsrc/egypt_logo.svg"
1125
-
1126
- caticon0="../mock_rsrc/egypt_icon0.svg"
1127
- caticon1="../mock_rsrc/egypt_icon0.svg"
1128
- caticon2="../mock_rsrc/egypt_icon0.svg"
1129
- caticon3="../mock_rsrc/egypt_icon0.svg"
1130
- iconlabels="platinum, gold, silver, bronze"
1131
- ></jackpot-banner>
1132
- {/if}
1133
- <casino-games-category-section
1134
- session={session}
1135
- userid={userid}
1136
- endpoint={endpoint}
1137
- datasource={datasource}
1138
- lang={lang}
1139
- currency={currency}
1140
- use:sendCategoryData={category}
1141
- categoryid={category}
1142
- categoryindex={index}
1143
- categorygames="9"
1144
- favorites={favorites}
1145
- class="CategoryContainer"
1146
- style="background-color: {(index % 2 !== 0) ? categorybackground : 'transparent'}"
1147
- {clientstyling}
1148
- {clientstylingurl}
1149
- {livecasino}
1150
- {visiblegames}
1151
- {gamepagemodalurl}
1152
- {enablecasinowinners}
1153
- />
1154
- {/each}
1155
- {:else if favoritesScreen}
1156
- <casino-games-category-section
1157
- session={session}
1158
- userid={userid}
1159
- endpoint={endpoint}
1160
- datasource={datasource}
1161
- lang={lang}
1162
- currency={currency}
1163
- favorites={favorites}
1164
- use:getFavoredGames={`${endpoint}/player/${playerID}/favorites/`, sessionID, playerID}
1165
- categoryid={"FAVORITES"}
1166
- class="CategoryContainer"
1167
- {clientstyling}
1168
- {clientstylingurl}
1169
- {livecasino}
1170
- {visiblegames}
1171
- {gamepagemodalurl}
1172
- {enablecasinowinners}
1173
- />
1174
- {:else if mostPlayedScreen}
1175
- {#if mostPlayedEmpty}
1176
- <p class="SearchLoading" part="SearchLoading">{$_('casinoPage.noGamesPlayed')}</p>
1177
- {:else}
1178
- <casino-games-category-section
1179
- session={session}
1180
- userid={userid}
1181
- endpoint={endpoint}
1182
- datasource={datasource}
1183
- lang={lang}
1184
- currency={currency}
1185
- favorites={favorites}
1186
- categoryid="MOSTPLAYED"
1187
- categoryindex="1"
1188
- categorygames="9"
1189
- class="CategoryContainer"
1190
- {clientstyling}
1191
- {clientstylingurl}
1192
- {livecasino}
1193
- {visiblegames}
1194
- {gamepagemodalurl}
1195
- {enablecasinowinners}
1196
- />
1197
- {/if}
1198
- {:else}
1199
- {#if !recentSearches}
1200
- <casino-games-category-section
1201
- userid={userid}
1202
- endpoint={endpoint}
1203
- datasource={datasource}
1204
- favorites={favorites}
1205
- lang={lang}
1206
- currency={currency}
1207
- session={session}
1208
- categoryid={activeCategory}
1209
- categorygames="9"
1210
- class="CategoryContainer"
1211
- {clientstyling}
1212
- {clientstylingurl}
1213
- {livecasino}
1214
- {visiblegames}
1215
- {gamepagemodalurl}
1216
- {enablecasinowinners}
1217
- />
1218
- {/if}
1219
- {/if}
1220
- {/if}
1221
- {/if}
1222
- {#if isLoggedIn && haspanicbutton == "true"}
1223
- <div class="PanicSection {(getDevice(userAgent) !== 'PC') ? 'PanicSectionMobile' : ''}" part="PanicSection {(getDevice(userAgent) !== 'PC') ? 'PanicSectionMobile' : ''}">
1224
- <button class="PanicButton {(getDevice(userAgent) !== 'PC') ? 'PanicButtonMobile ' : ''}" class:PanicButtonAnimation={panicLoading} part="PanicButton {(getDevice(userAgent) !== 'PC') ? 'PanicButtonMobile' : ''}" bind:this={panicButton} >{$_('casinoPage.breakButton')}</button>
1225
- </div>
1226
- {/if}
1227
- </section>
1228
- {/if}
1229
-
1230
- <style lang="scss">
1231
-
1232
- :host {
1233
- font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
1234
- }
1235
-
1236
- *, *::before, *::after {
1237
- margin: 0;
1238
- padding: 0;
1239
- box-sizing: border-box;
1240
- }
1241
-
1242
- .CategoriesLobby {
1243
- margin: 0 auto;
1244
- }
1245
-
1246
- .PanicSectionMobile {
1247
- flex-direction: column;
1248
- margin: 20px 0;
1249
- }
1250
-
1251
- .PanicSection {
1252
- display: flex;
1253
- justify-content: center;
1254
- align-items: center;
1255
- gap: 10px;
1256
- margin-top: 20px;
1257
- }
1258
-
1259
- .PanicButton {
1260
- border-radius: 5px;
1261
- border: 1px solid var(--emfe-w-color-primary, #D0046C);
1262
- background-color: var(--emfe-w-color-primary, #D0046C);
1263
- width: 280px;
1264
- height: 48px;
1265
- line-height: 18px;
1266
- color: var(--emfe-w-color-white, #FFFFFF);
1267
- cursor: pointer;
1268
- }
1269
-
1270
- .PanicButtonAnimation {
1271
- background: -webkit-linear-gradient(
1272
- 135deg,
1273
- rgba(20, 20, 20, 0) 55%, rgba(20, 20, 20, 0.3) 100%
1274
- );
1275
-
1276
- background: -moz-linear-gradient(
1277
- 135deg,
1278
- rgba(20, 20, 20, 0) 55%, rgba(20, 20, 20, 0.3) 100%
1279
- );
1280
-
1281
- background: -o-linear-gradient(
1282
- 135deg,
1283
- rgba(20, 20, 20, 0) 55%, rgba(20, 20, 20, 0.3) 100%
1284
- );
1285
-
1286
- background-color: var(--emfe-w-color-primary, #D0046C);
1287
- width: 280px;
1288
- color: #fff;
1289
-
1290
- -webkit-animation: bar-animation 2s linear;
1291
- }
1292
-
1293
- .PanicButtonMobile {
1294
- width: 280px;
1295
- padding: 0 5px;
1296
-
1297
- //Remove text selection for panic button on mobile
1298
- -webkit-touch-callout: none; /* iOS Safari */
1299
- -webkit-user-select: none; /* Safari */
1300
- -moz-user-select: none; /* Old versions of Firefox */
1301
- -ms-user-select: none; /* Internet Explorer/Edge */
1302
- user-select: none;
1303
- // End of removing selection properties
1304
- }
1305
-
1306
- @-webkit-keyframes bar-animation {
1307
- 0% {
1308
- background-position: 0;
1309
- }
1310
- 100% {
1311
- background-position: 280px;
1312
- }
1313
- }
1314
-
1315
-
1316
- [type="search"] {
1317
- appearance: none;
1318
- }
1319
-
1320
- .SrOnly {
1321
- position: absolute;
1322
- width: 1px;
1323
- height: 1px;
1324
- padding: 0;
1325
- margin: -1px;
1326
- overflow: hidden;
1327
- clip: rect(0, 0, 0, 0);
1328
- white-space: nowrap;
1329
- border-width: 0;
1330
- }
1331
-
1332
- .CategoryContainer {
1333
- display: block;
1334
-
1335
- @media screen and (max-width: 1300px) {
1336
- padding: 0 2.4%
1337
- }
1338
- }
1339
-
1340
- .SearchLoading {
1341
- color: var(--emfe-w-color-white, #FFFFFF);
1342
- font-size: 14px;
1343
- margin-top: 16px;
1344
- text-align: center;
1345
- }
1346
-
1347
- .SearchContainer {
1348
- flex: 3;
1349
- width: 100%;
1350
- max-width: 600px;
1351
- margin: auto 0 auto 30%;
1352
- &.SearchTruncated {
1353
- margin: auto 0 auto 30%;
1354
- .SearchInput {
1355
- tabindex: 999;
1356
- padding: 20px 12px 20px 40px;
1357
- }
1358
- }
1359
- .SearchWrapper {
1360
- position: relative;
1361
- display: inline-flex;
1362
- color: rgba(199, 210, 254, 1);
1363
-
1364
- .SearchIcon {
1365
- position: absolute;
1366
- display: flex;
1367
- align-items: center;
1368
- top: 0;
1369
- bottom: 0;
1370
- left: 1.2%;
1371
- pointer-events: none;
1372
-
1373
- svg {
1374
- width: 26px;
1375
- height: 26px;
1376
- display: block;
1377
- vertical-align: middle;
1378
- fill: rgba(199, 210, 254, 1);
1379
- }
1380
- }
1381
- .SearchInput {
1382
- width: 520px;
1383
- display: block;
1384
- padding: 12px 12px 12px 40px;
1385
- border-radius: 6px;
1386
- border-color: transparent;
1387
- font-size: 16px;
1388
- background-color: rgba(156, 163, 175, 0.25);
1389
- color: rgba(224, 231, 255, 1);
1390
- &::-webkit-search-decoration,
1391
- &::-webkit-search-cancel-button,
1392
- &::-webkit-search-results-button,
1393
- &::-webkit-search-results-decoration {
1394
- -webkit-appearance:none;
1395
- }
1396
-
1397
- &::placeholder {
1398
- color:rgba(255, 255, 255, 1);
1399
- }
1400
-
1401
- &:focus {
1402
- background-color: rgba(255, 255, 255, 1);
1403
- color: rgba(17, 24, 39, 1);
1404
- outline: 2px solid transparent;
1405
- outline-offset: 2px;
1406
-
1407
- &::placeholder {
1408
- color: rgba(156, 163, 175, 1);
1409
- }
1410
- }
1411
- }
1412
-
1413
- &:focus-within {
1414
- color: rgba(156, 163, 175, 1);
1415
-
1416
- .SearchIcon svg {
1417
- fill: rgba(156, 163, 175, 1);
1418
- }
1419
- }
1420
- }
1421
- }
1422
-
1423
- .FiltersButtonsContainer {
1424
- display: inline-flex;
1425
- flex-direction: row-reverse;
1426
- flex: 1;
1427
- grid-gap: 20px;
1428
- flex-direction: row-reverse;
1429
- }
1430
- .FilterButtonWrapper, .ClearFilterButtonWrapper {
1431
- display: inline-flex;
1432
- padding: 10px;
1433
- border: 1px solid var(--emfe-w-color-gray-300, #58586B);
1434
- border-radius: 5px;
1435
- text-transform: uppercase;
1436
- color: var(--emfe-w-color-white, #FFFFFF);
1437
- cursor: pointer;
1438
- }
1439
- .ClearFilterButtonWrapper {
1440
- border: 1px solid var(--emfe-w-color-secondary, #FD2839);
1441
- color: var(--emfe-w-color-secondary, #FD2839);
1442
- }
1443
- .FilterIconContainer, .ClearIcon {
1444
- position: relative;
1445
- padding-left: 5px;
1446
- }
1447
- .FilterIconContainer {
1448
- top: 2px;
1449
- }
1450
- .ClearIcon {
1451
- position: relative;
1452
- top: 1px;
1453
- svg {
1454
- width: 14px;
1455
- }
1456
- }
1457
- .FilterButtonWrapper, .ClearFilterButtonWrapper {
1458
- display: inline-flex;
1459
- justify-content: center;
1460
- align-items: center;
1461
- }
1462
- .NumberOfFiltersContainer {
1463
- display: block;
1464
- line-height: 0px;
1465
- border-radius: 50%;
1466
- border: 2px solid var(--emfe-w-color-primary, #D0046C);
1467
- background: var(--emfe-w-color-primary, #D0046C);
1468
- color: var(--emfe-w-color-white, #FFFFFF);
1469
- font-size: 12px;
1470
- position: absolute;
1471
- top: -5px;
1472
- left: 18px;
1473
- .NumberOfFilters {
1474
- display: inline-block;
1475
- padding-top: 50%;
1476
- padding-bottom: 50%;
1477
- margin-left: 3px;
1478
- margin-right: 3px;
1479
- }
1480
- }
1481
-
1482
- .CategoriesHeaderSection {
1483
- width: 100%;
1484
- display: inline-flex;
1485
- flex-direction: row;
1486
- margin-top: 30px;
1487
- }
1488
- .CategoriesHeaderMobileSection {
1489
- position: fixed;
1490
- bottom: 0;
1491
- left: 0;
1492
- flex-direction: row-reverse;
1493
- z-index: 1;
1494
- .ClearFilterButtonWrapper {
1495
- display: none;
1496
- }
1497
- .SearchContainer {
1498
- flex: 1;
1499
- max-width: unset;
1500
- margin: unset;
1501
- background-color: rgba(208, 5, 108, 1);
1502
- z-index: 1;
1503
- .SearchWrapper {
1504
- display: flex;
1505
- color: var(--emfe-w-color-white, #FFFFFF);
1506
- .SearchIcon {
1507
- left: 2.4%;
1508
- }
1509
- .SearchInput {
1510
- padding: 12px;
1511
- border-radius: 0;
1512
- background-color: rgba(208, 5, 108, 1);
1513
- color: var(--emfe-w-color-white, #FFFFFF);
1514
- text-align: center;
1515
- opacity: 1;
1516
- &::placeholder, &:-ms-input-placeholder, &::-ms-input-placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
1517
- color: rgba(255, 255, 255, 1);
1518
- opacity: 1; /* Firefox */
1519
- }
1520
- }
1521
- path {
1522
- fill: var(--emfe-w-color-white, #FFFFFF);
1523
- }
1524
- }
1525
- }
1526
- .FiltersButtonsContainer {
1527
- flex: 1;
1528
- .FilterButtonWrapper {
1529
- position: relative;
1530
- width: 100%;
1531
- display: flex;
1532
- flex-direction: row-reverse;
1533
- border: 1px solid var(--emfe-w-color-white, #FFFFFF);
1534
- border-radius: 0;
1535
- background: var(--emfe-w-color-white, #FFFFFF);
1536
- color: var(--emfe-w-color-primary, #D0046C);
1537
- }
1538
- .FilterIconContainer {
1539
- position: absolute;
1540
- left: 40px;
1541
- top: revert;
1542
- padding-left: 0;
1543
- path {
1544
- fill: var(--emfe-w-color-primary, #D0046C);
1545
- }
1546
- }
1547
- }
1548
- .NumberOfFiltersContainer {
1549
- font-size: 8px;
1550
- left: 15px;
1551
- }
1552
- }
1553
-
1554
- // start alternative search design
1555
- .CategoriesHeaderSectionAltDesign {
1556
- &.CategoriesHeaderMobileSection {
1557
- flex-direction: row;
1558
- position: relative;
1559
- margin-top: 30px;
1560
- .SearchContainer {
1561
- background-color: var(--emfe-w-color-contrast, #07072A);
1562
-
1563
- padding: 0 2.4%;
1564
- .SearchWrapper {
1565
- justify-content: center;
1566
- .SearchInput {
1567
- width: 100%;
1568
- border: 1px solid var(--emfe-w-color-gray-300, #58586B);
1569
- border-radius: 6.4px;
1570
- background-color: transparent;
1571
- color: var(--emfe-w-color-white, #FFFFFF);
1572
- padding: 12px 3.6%;
1573
- &:active, &:focus {
1574
- width: 100%;
1575
- }
1576
- }
1577
- }
1578
- }
1579
- .FiltersButtonsContainer {
1580
- position: absolute;
1581
- top: 160px;
1582
- font-size: 13px;
1583
- gap: 6px;
1584
-
1585
- @media screen and (max-width: 1300px) {
1586
- right: 2.4%;
1587
- }
1588
-
1589
- .FilterIconContainer {
1590
- display: none;
1591
- }
1592
- .FilterButtonWrapper {
1593
- border-radius: 5px;
1594
- border: 1px solid var(--emfe-w-color-white, #FFFFFF);
1595
- background: transparent;
1596
- color: var(--emfe-w-color-white, #FFFFFF);
1597
- padding: 6px 16px;
1598
- }
1599
- .ClearFilterButtonWrapper {
1600
- padding: 6px 16px;
1601
- .ClearIcon {
1602
- display: none;
1603
- }
1604
- }
1605
- }
1606
- &.CategoriesHeaderSearchActive {
1607
- top: 0;
1608
- }
1609
- }
1610
- .FiltersActive.ClearFilterButtonWrapper {
1611
- display: inline-flex;
1612
- }
1613
- .ClearSearchButton {
1614
- right: 2.4%;
1615
- top: 11px;
1616
- }
1617
- .ClearSearchButtonMobile {
1618
- right: 2.4%;
1619
- top: 9px;
1620
- }
1621
- }
1622
- // end alternative search design
1623
- .ClearFilterMobileButtonWrapper {
1624
- position: absolute;
1625
- right: 5px;
1626
- padding: 8px 18px;
1627
- display: inline-flex;
1628
- border: 1px solid var(--emfe-w-color-gray-300, #58586B);
1629
- border-radius: 5px;
1630
- border: 1px solid var(--emfe-w-color-secondary, #FD2839);
1631
- text-transform: uppercase;
1632
- color: var(--emfe-w-color-white, #FFFFFF);
1633
- cursor: pointer;
1634
- color: var(--emfe-w-color-secondary, #FD2839);
1635
- font-size: 14px;
1636
- .ClearIcon svg {
1637
- width: 12px;
1638
- }
1639
- }
1640
- .CategoriesHeaderSearchActive {
1641
- position: fixed;
1642
- bottom: unset;
1643
- top: 70px;
1644
- margin-top: 0;
1645
- .SearchContainer {
1646
- background-color:rgba(255, 255, 255, 1);
1647
- .SearchWrapper {
1648
- .SearchInput {
1649
- background-color: rgba(255, 255, 255, 1);
1650
- color: var(--emfe-w-color-black, #000000);
1651
- }
1652
- }
1653
- }
1654
- }
1655
- .SearchStickTop {
1656
- margin-top: 0;
1657
- }
1658
- @media (max-width: 768px) {
1659
- .SearchContainer {
1660
- margin: auto 3% auto 0%;
1661
- }
1662
- }
1663
- // push content lower when on mobile and search is active
1664
- .SearchBarPlaceholder {
1665
- display: block;
1666
- width: 100%;
1667
- height: 46px;
1668
- }
1669
- // push content lower when on mobile and search is active
1670
- .SearchBarPlaceholder {
1671
- display: block;
1672
- width: 100%;
1673
- height: 46px;
1674
- }
1675
-
1676
- .ClearSearchButton, .ClearSearchButtonMobile {
1677
- cursor: pointer;
1678
- position: absolute;
1679
- right: 14px;
1680
- top: 11px;
1681
- .CloseIconContainer {
1682
- width: 25px;
1683
- height: 25px;
1684
- }
1685
-
1686
- .CloseIconWrapper {
1687
- height: 25px;
1688
- width: 3px;
1689
- margin-left: 12px;
1690
- background-color:var(--emfe-w-color-white, #FFFFFF);
1691
- transform: rotate(45deg);
1692
- Z-index: 1;
1693
- }
1694
-
1695
- .CloseIcon {
1696
- height: 25px;
1697
- width: 3px;
1698
- background-color:var(--emfe-w-color-white, #FFFFFF);
1699
- transform: rotate(90deg);
1700
- Z-index: 2;
1701
- }
1702
- }
1703
- .SearchContainer {
1704
- .CloseIconWrapper, .CloseIcon {
1705
- background-color: var(--emfe-w-color-secondary, #FD2839);
1706
- }
1707
- }
1708
- .ClearSearchButtonMobile {
1709
- display: none;
1710
- }
1711
- .CategoriesHeaderSearchActive {
1712
- .ClearSearchButtonMobile {
1713
- display: block;
1714
- .CloseIconWrapper, .CloseIcon {
1715
- background-color: var(--emfe-w-color-secondary, #FD2839);
1716
- }
1717
- }
1718
- }
1719
-
1720
- </style>
1
+ <svelte:options tag={null} />
2
+
3
+ <script lang="ts">
4
+ import { onMount } from "svelte";
5
+ import { isMobile, getDevice } from 'rvhelper';
6
+ import { _, addNewMessages, setupI18n, setLocale } from './i18n';
7
+ import { CasinoPageTranslations } from './translations';
8
+ import type {
9
+ CategoriesData,
10
+ CasinoData,
11
+ CategoriesItems,
12
+ CasinoItems,
13
+ } from './CasinoPage.types';
14
+
15
+ import '@everymatrix/casino-games-category-section';
16
+ import '@everymatrix/casino-random-game';
17
+ import '@everymatrix/jackpot-banner';
18
+
19
+ export let endpoint:string = '';
20
+ export let datasource:string = '';
21
+ export let currency:string = '';
22
+ export let lang:string = ''; // Language
23
+ export let session:string = ''; // Value for sessionID
24
+ export let userid:string = ''; // Value for UserID;
25
+ export let clientstyling:string = '';
26
+ export let clientstylingurl:string = '';
27
+
28
+ export let categorybackground:string = '';
29
+ export let visiblegames:string;
30
+ export let alternativesearch:string = 'false';
31
+ export let favorites:string = '';
32
+ export let mostplayed:string = '';
33
+ export let containermaxwidth:string = '1300';
34
+ export let lobbyid:string = 'casinodefault'; // identifier for recent searched
35
+ export let haspanicbutton:string = 'false';
36
+
37
+ export let mostplayedrounds:string = '';
38
+ export let activecategory:string = '';
39
+ export let livecasino:string = 'false';
40
+ export let playrandomgame:string = 'false';
41
+ export let gamepagemodalurl:string = 'false';
42
+ export let enablecasinowinners:string = 'true';
43
+ export let enablejackpotbanner:string = 'true';
44
+
45
+ export let tabsorder:string = '';
46
+ export let enableautoscroll:string = '';
47
+ export let istopavailable:string = '';
48
+ export let isrecentavailable:string = '';
49
+
50
+ // Button icon for random game widget
51
+ export let randombuttonicon:string = '';
52
+
53
+ let userAgent:any = window.navigator.userAgent;
54
+ let gameevent:string;
55
+
56
+ if (!isMobile(userAgent)) {
57
+ gameevent = 'ShowGameModal';
58
+ } else {
59
+ gameevent = 'OpenGameFrame';
60
+ }
61
+
62
+ // CasinoPage loading state
63
+ let isLoading:boolean = false;
64
+ let hasErrors:boolean = false;
65
+ let isLoggedIn:boolean = false;
66
+ let error:string = '';
67
+
68
+ let playerID:string;
69
+ let sessionID:string;
70
+
71
+ let panicButton:HTMLElement;
72
+ let panicLoading:boolean = false;
73
+ let timer: number = 0;
74
+ let timerInterval:any;
75
+
76
+ // CasinoPage state
77
+ let favoritesScreen:boolean = false;
78
+ let recentSearches:boolean = false;
79
+ let initialLoaded:boolean = true;
80
+ let searched:boolean = false;
81
+ let gameFocus:boolean = false;
82
+ let lobbyViewAux:boolean = false;
83
+ let closeSearch:boolean = false;
84
+ let searchFocus:boolean = false;
85
+ let lobbyScreen:boolean = true;
86
+ let mostPlayedScreen:boolean = false;
87
+ let mostPlayedEmpty:boolean = false;
88
+ let adjustingScroll:boolean = false;
89
+ let searchBarCleared:boolean = true;
90
+
91
+ // Needs to be checked if there are relevant
92
+ let gamesArray = [];
93
+ let searchArray:Array<CasinoItems>;
94
+ let categories:Array<CategoriesItems> = [];
95
+ let shownCategories:Array<CategoriesItems> = [];
96
+ let activeCategory:string;
97
+
98
+ let searchValue:string = '';
99
+ let searchWrapper:HTMLElement;
100
+ let searchElementWrapper:HTMLElement;
101
+ let searchPositionTop:number;
102
+ let searchedGamesCache:Object = {};
103
+
104
+ // const scrollOffset:number = getDevice(userAgent) !== 'PC' ? operatorDetail.scrollOffset[0] : operatorDetail.scrollOffset[1];
105
+ const scrollOffset:number = 0;
106
+
107
+ let scrollTop:boolean = false;
108
+ let mostPlayedGames:Array<any> = [];
109
+
110
+ let favoredGamesCollection:Array<string> = [];
111
+ let categoriesData;
112
+ let receivedFavoriteResults:Object;
113
+ let updatedFavoriteResultsIds:Array<string>;
114
+ let searchElement:HTMLElement;
115
+ let mobileSearchViewActive:boolean = false;
116
+ let searchedValues:any = [];
117
+ let mostPlayedValues:any = [];
118
+ let filterVendorsArray:Array<Object> = [];
119
+ let numberOfFilters:number = 0;
120
+ let filteredGamesArray:Array<Object> = [];
121
+ let currentCategoryId:string = '';
122
+ let activeCategoryAux:any = undefined;
123
+ let customStylingContainer:HTMLElement;
124
+ let urlCasino:any;
125
+ let firstLoad:boolean = false;
126
+
127
+
128
+ setupI18n({ withLocale: 'en', translations: {}});
129
+
130
+ Object.keys(CasinoPageTranslations).forEach((item) => {
131
+ addNewMessages(item, CasinoPageTranslations[item]);
132
+ });
133
+
134
+ const CategoryChangeHandler = (categoryEvent:any) => {
135
+ searched = false;
136
+ searchValue = '';
137
+ scrollTop = true;
138
+ // needs to be executed after the page has been populated
139
+ setTimeout(() => {
140
+ window.postMessage({ type: 'WidgetTopReference', scrollTop }, window.location.href);
141
+ });
142
+ switch(categoryEvent.data.itemId) {
143
+ case 'LOBBY':
144
+ lobbyScreen = true;
145
+ favoritesScreen = false;
146
+ activeCategory = '';
147
+ mostPlayedScreen = false;
148
+ break;
149
+
150
+ case 'FAVORITES':
151
+ lobbyScreen = false;
152
+ favoritesScreen = true;
153
+ mostPlayedScreen = false;
154
+ activeCategory = '';
155
+ break;
156
+
157
+ case 'MOSTPLAYED':
158
+ if (mostplayed == 'true') {
159
+ isLoading = true;
160
+
161
+ getMostPlayedGames({
162
+ limit: 100,
163
+ device: getDevice(userAgent),
164
+ rounds: 10
165
+ }).then((res:any) => {
166
+ isLoading = false;
167
+
168
+ if (res.count > 0) {
169
+ let promises:any = [];
170
+
171
+ res.items.forEach((item:any) => {
172
+ let url:URL = new URL(`${endpoint}/casino/games/${item.gameId}`);
173
+
174
+ url.searchParams.append('datasource', datasource);
175
+ if (livecasino) {
176
+ promises.push(fetch(url.href).then((res:any) => res.json()));
177
+ } else {
178
+ promises.push(fetch(url.href).then((res:any) => res.json()));
179
+ }
180
+ });
181
+
182
+ Promise.all(promises).then((values:any) => {
183
+ mostPlayedGames = values.map((item:any) => item[0]);
184
+
185
+ window.postMessage({ type: 'MostPlayedData', mostPlayedGames }, window.location.href);
186
+ });
187
+ } else {
188
+ mostPlayedEmpty = true;
189
+ }
190
+ });
191
+
192
+ activeCategory = '';
193
+ lobbyScreen = false;
194
+ favoritesScreen = false;
195
+ mostPlayedScreen = true;
196
+ }
197
+ break;
198
+
199
+ default:
200
+ lobbyScreen = false;
201
+ favoritesScreen = false;
202
+ mostPlayedScreen = false;
203
+ activeCategory = categoryEvent.data.itemId;
204
+ //@TODO: if we remove the settimeout, the postmessage does not execute, at all - weird behaviour
205
+ setTimeout(() => {
206
+ window.postMessage({ type: 'CategoryUpdate', itemId: activeCategory }, window.location.href);
207
+ }, 500);
208
+
209
+
210
+ break;
211
+ }
212
+ }
213
+
214
+ const messageHandler = (e:any) => {
215
+ if (e.data) {
216
+ switch(e.data.type) {
217
+ // @TODO: removed and tested, but kept in case unforeseen issues occur - reason: multiple calls on category change
218
+ // case 'CategoryChange':
219
+ // CategoryChangeHandler(e);
220
+ // break;
221
+
222
+ case 'UserSessionID':
223
+ sessionID = e.data.session;
224
+ playerID = e.data.userID;
225
+
226
+ if (playerID && playerID.length && sessionID && sessionID.length > 0) {
227
+ getFavoredGames(endpoint, sessionID, playerID);
228
+ }
229
+ break;
230
+
231
+ // @TODO dis should be removed
232
+ case 'CategoriesLoadedForSlider':
233
+ window.postMessage({ type: 'SetSliderIndex', index: 0, categoryData: { id: 'LOBBY' } }, window.location.href);
234
+ break;
235
+
236
+ case 'SetUnfavoredGame':
237
+ removeFavoredGame(`${endpoint}/player/${playerID}/favorites`, sessionID, playerID, e.data.id, e.data.triggerFactor);
238
+ break;
239
+
240
+ case 'SetFavoredGame':
241
+ addFavoredGame(`${endpoint}/player/${playerID}/favorites`, sessionID, playerID, e.data.id, e.data.triggerFactor);
242
+ break;
243
+
244
+ case 'GetFavoredGame':
245
+ if (playerID && playerID.length && sessionID && sessionID.length > 0) {
246
+ getFavoredGames(endpoint, sessionID, playerID);
247
+ }
248
+ break;
249
+
250
+ case 'SearchedItemClicked':
251
+ addSearchedItem(e.data.gameId);
252
+ break;
253
+
254
+ case 'UpdateFilters':
255
+ updateFilters(e.data.vendorsArray);
256
+ setFilterNumberValue();
257
+ break;
258
+
259
+ case 'ClearFilters':
260
+ submitFilters(e.data.vendorsArray);
261
+ setFilterNumberValue();
262
+ break;
263
+
264
+ case 'ApplyFilters':
265
+ window.postMessage({ type: 'CategoryUpdate', itemId: currentCategoryId }, window.location.href);
266
+ setFilterNumberValue();
267
+ break;
268
+
269
+ case 'CategoryVendors':
270
+ currentCategoryId = e.data.categoryid;
271
+ setFilterNumberValue();
272
+ break;
273
+
274
+ case 'GameHovered':
275
+ gameFocus = true;
276
+ break;
277
+
278
+ case 'GameBlur':
279
+ gameFocus = false;
280
+ break;
281
+
282
+ default:
283
+ // Nothing to do here
284
+ break;
285
+ }
286
+ }
287
+ }
288
+
289
+ const getMostPlayedGames = (options:any) => {
290
+ let url = new URL(`${endpoint}/player/${playerID}/games/most-played`);
291
+
292
+ if (options.limit) {
293
+ url.searchParams.append('limit', options.limit);
294
+ }
295
+
296
+ if (options.order) {
297
+ url.searchParams.append('order', options.order);
298
+ }
299
+
300
+ let device = options.device;
301
+
302
+ if (device) {
303
+ if (device === 'PC') {
304
+ url.searchParams.append('device', 'Desktop');
305
+ } else {
306
+ url.searchParams.append('device', 'Mobile');
307
+ }
308
+ } else {
309
+ url.searchParams.append('device', 'All');
310
+ }
311
+
312
+ if (options.rounds) {
313
+ url.searchParams.append('rounds', options.rounds);
314
+ }
315
+
316
+ urlCasino = livecasino ? url : url.href;
317
+ return new Promise((resolve, reject) => {
318
+ fetch(urlCasino)
319
+ .then((res:any) => res.json())
320
+ .then((data:any) => {
321
+ resolve(data);
322
+
323
+ window.postMessage({ type: 'AddNewCategory', category: { name: 'Most Played', id: 'MOSTPLAYED' }}, window.location.href);
324
+ window.postMessage({ type: 'MostPlayedGames', data }, window.location.href);
325
+ }).catch((err:any) => {
326
+ console.error(err);
327
+
328
+ reject(err);
329
+ });
330
+ });
331
+ }
332
+
333
+ //
334
+ // --- START of Favorites section
335
+ //
336
+ let getFavoredGames = (url:string, sessionID:string, playerID:string) => {
337
+ if (favorites == 'true') {
338
+ if (session && playerID) {
339
+ let options = {
340
+ method: "GET",
341
+ headers: {
342
+ 'X-SessionID': sessionID,
343
+ }
344
+ };
345
+
346
+ fetch(`${url}/player/${playerID}/favorites/`, options)
347
+ .then((res:any) => res.json())
348
+ .then((updatedArray:Object) => {
349
+ receivedFavoriteResults = updatedArray;
350
+
351
+ if (receivedFavoriteResults) {
352
+ window.postMessage({ type: "UpdateCategoryFavoriteGames", receivedFavoriteResults }, window.location.href);
353
+
354
+ updatedFavoriteResultsIds = getGamesIds(receivedFavoriteResults.items);
355
+ }
356
+
357
+ return receivedFavoriteResults;
358
+ }).then((favResults) => {
359
+ if (favoritesScreen) {
360
+ showFavoriteGames();
361
+ }
362
+ return favResults;
363
+ }).catch((err:any) => {
364
+ console.error(err);
365
+ });
366
+ }
367
+ }
368
+ }
369
+
370
+ let updateFavoredList = (url:string, sessionID:string, playerID:string) => {
371
+ let options = {
372
+ method: "GET",
373
+ headers: {
374
+ 'X-SessionID': sessionID,
375
+ }
376
+ };
377
+
378
+ fetch(url, options)
379
+ .then((res:any) => res.json())
380
+ .then((updatedArray:Object) => {
381
+ receivedFavoriteResults = updatedArray;
382
+
383
+ if (favoritesScreen) {
384
+ showFavoriteGames();
385
+ }
386
+
387
+ if (receivedFavoriteResults) {
388
+ window.postMessage({ type: "UpdateCategoryFavoriteGames", receivedFavoriteResults}, window.location.href);
389
+ }
390
+
391
+ return receivedFavoriteResults;
392
+ }).catch((err:any) => {
393
+ console.error(err);
394
+ });
395
+ }
396
+
397
+ const getGamesIds = (favoritesArray:any = []) => {
398
+ // construct favorite array used to check if game id is not already present in fav list
399
+ favoredGamesCollection = [];
400
+
401
+ if (favoritesArray.length > 0) {
402
+ favoritesArray.forEach((fav:any) => {
403
+ favoredGamesCollection.push(fav.id);
404
+ });
405
+ }
406
+
407
+ return favoredGamesCollection;
408
+ }
409
+
410
+ let addFavoredGame = (url:string, sessionID:string, playerID:string, gameID:string, triggerFactor:string) => {
411
+ // 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
412
+ if (!favoredGamesCollection.includes(gameID)) {
413
+ favoredGamesCollection.push(gameID);
414
+ }
415
+
416
+ let data = {
417
+ items: favoredGamesCollection
418
+ };
419
+
420
+ let options = {
421
+ method: "POST",
422
+ headers: {
423
+ 'X-SessionID': sessionID,
424
+ 'Content-Type': 'application/json',
425
+ 'Accept': 'application/json',
426
+ },
427
+ body: JSON.stringify(data)
428
+ };
429
+
430
+ fetch(url, options)
431
+ .then((res:any) => res.json())
432
+ .then((increasedFavArray:any) => {
433
+ window.postMessage({ type: `AddFavoriteThumbnail_${gameID}` }, window.location.href);
434
+
435
+ updateFavoredList(url, sessionID, playerID);
436
+ })
437
+ .catch((err:any) => {
438
+ console.error('Err', err);
439
+ });
440
+ }
441
+
442
+ const removeFavoredGame = (url:string, sessionID:string, playerID:string, gameID:string, triggerFactor:string) => {
443
+ if (favoredGamesCollection.includes(gameID)) {
444
+ favoredGamesCollection = favoredGamesCollection.filter(x => {
445
+ return x != gameID;
446
+ });
447
+ }
448
+
449
+ let options = {
450
+ method: "DELETE",
451
+ headers: {
452
+ 'X-SessionID': sessionID,
453
+ }
454
+ };
455
+
456
+ fetch(`${url}/${gameID}`, options)
457
+ .then((res:any) => res.json())
458
+ .then((decreasedFavArray:any) => {
459
+ window.postMessage({ type: `RemoveFavoriteThumbnail_${gameID}` }, window.location.href);
460
+
461
+ updateFavoredList(url, sessionID, playerID);
462
+ });
463
+ }
464
+
465
+ const showFavoriteGames = () => {
466
+ window.postMessage({ type: "ShowFavoriteSection", receivedFavoriteResults}, window.location.href);
467
+ }
468
+ //
469
+ // --- END of Favorites section
470
+ //
471
+
472
+ const getCategories = (url:any) => {
473
+ return new Promise((resolve, reject) => {
474
+ isLoading = true;
475
+
476
+ fetch(url)
477
+ .then((res:any) => res.json())
478
+ .then((data:CategoriesData) => {
479
+ isLoading = false;
480
+
481
+ resolve(data);
482
+ }).catch((err:any) => {
483
+ hasErrors = true;
484
+ isLoading = false;
485
+
486
+ console.error(err);
487
+
488
+ reject(err);
489
+ });
490
+ });
491
+ }
492
+
493
+ const getGames = (url:any) => {
494
+ return new Promise((resolve, reject) => {
495
+ isLoading = true;
496
+
497
+ fetch(url)
498
+ .then((res:any) => res.json())
499
+ .then((categoryData:CasinoData) => {
500
+ isLoading = false;
501
+
502
+ resolve(categoryData);
503
+ }).catch((err:any) => {
504
+ hasErrors = true;
505
+ isLoading = false;
506
+
507
+ console.error(err);
508
+
509
+ reject(err);
510
+ });
511
+ });
512
+ }
513
+
514
+ const getGame = (url:any, gameId?:string):Promise<any> => {
515
+ return new Promise((resolve, reject) => {
516
+ isLoading = true;
517
+
518
+ if(gameId && Object.keys(searchedGamesCache).indexOf(gameId) >= 0){
519
+ isLoading = false;
520
+
521
+ resolve(searchedGamesCache[gameId]);
522
+ } else {
523
+ fetch(url)
524
+ .then((res:any) => res.json())
525
+ .then((gameData:any) => {
526
+ isLoading = false;
527
+
528
+ searchedGamesCache[gameData[0].id] = gameData[0];
529
+
530
+ resolve(gameData[0]);
531
+ }).catch((err:any) => {
532
+ hasErrors = true;
533
+ isLoading = false;
534
+
535
+ console.error(err);
536
+
537
+ reject(err);
538
+ });
539
+ }
540
+ });
541
+ }
542
+
543
+ const getCookieValue = (name:string) => {
544
+ let match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
545
+
546
+ if (match) {
547
+ return match[2];
548
+ }
549
+ }
550
+
551
+ const onFocus = () => {
552
+ if (endpoint && datasource && lang) {
553
+ searchFocus = true;
554
+
555
+ if (searchValue.length < 2) {
556
+ let recentSearchedGames = getCookieValue(`searchedGamesWds_${lobbyid}`);
557
+ let recentSearchedGamesArray:Array<any> = [];
558
+
559
+ if (recentSearchedGames) {
560
+ recentSearchedGamesArray = recentSearchedGames.split(',');
561
+ }
562
+
563
+ if (lobbyScreen == true && !initialLoaded) {
564
+ lobbyViewAux = lobbyScreen;
565
+ lobbyScreen = false;
566
+ }
567
+
568
+ let promises:Array<any> = [];
569
+ let index = 0;
570
+ let length = recentSearchedGamesArray.length;
571
+
572
+ if (length > 0) {
573
+ for (index = 0; index < length; index++) {
574
+ let url:any = new URL(`${endpoint}/casino/games/${recentSearchedGamesArray[index]}`);
575
+
576
+ url.searchParams.append('language', lang);
577
+ url.searchParams.append('datasource', datasource);
578
+ url.searchParams.append('platform', getDevice(userAgent));
579
+
580
+ promises.push(getGame(url, recentSearchedGamesArray[index]));
581
+ }
582
+
583
+ Promise.all(promises).then((res:any) => {
584
+ searchArray = res;
585
+
586
+ sendRecentSearchData({}, searchArray)
587
+ });
588
+ } else {
589
+ sendRecentSearchData({}, {})
590
+ }
591
+ }
592
+ }
593
+ }
594
+
595
+ const onBlur = () => {
596
+ searchFocus = false;
597
+
598
+ if (searchValue.length < 2 && !gameFocus) {
599
+ searched = false;
600
+ searchArray = [];
601
+ recentSearches = false;
602
+ lobbyScreen = lobbyViewAux;
603
+ lobbyViewAux = false;
604
+ if (lobbyScreen === false) {
605
+ window.postMessage({ type: 'CategoryUpdate', itemId: activeCategory }, window.location.href);
606
+ }
607
+
608
+ window.postMessage({ type: 'OutOfRecentSearches' }, window.location.href);
609
+ }
610
+ }
611
+
612
+ const addSearchedItem = (gameID:any) => {
613
+ searchedValues = getCookieValue(`searchedGamesWds_${lobbyid}`);
614
+
615
+ if (searchedValues) {
616
+ searchedValues = searchedValues.split(',');
617
+ } else {
618
+ searchedValues = [];
619
+ }
620
+ if (searchedValues.indexOf(gameID) === -1) {
621
+ let value;
622
+
623
+ searchedValues.push(gameID);
624
+ value = searchedValues.join(',');
625
+ document.cookie = `searchedGamesWds_${lobbyid}=` + value;
626
+ }
627
+ }
628
+
629
+ // @TODO let's do some small changes around here in order to have this search functionality pretty written, 'cuz right now is kinda shitty
630
+ const searchValueChanged = () => {
631
+ if (searchValue.length >= 2) {
632
+ searchBarCleared = true;
633
+ } else {
634
+ searchBarCleared = false;
635
+ }
636
+ }
637
+
638
+ $: searchValue && searchValueChanged();
639
+
640
+ $: if (searchValue.length >= 2) {
641
+ searched = true;
642
+
643
+ let searchUrl:any = new URL(`${endpoint}/casino/games`);
644
+
645
+ searchUrl.searchParams.append("datasource", datasource);
646
+ searchUrl.searchParams.append("expand", "vendor");
647
+ searchUrl.searchParams.append("platform", getDevice(userAgent));
648
+ searchUrl.searchParams.append("language", lang);
649
+ searchUrl.searchParams.append("pagination", "offset=0,limit=30");
650
+ searchUrl.searchParams.append("filter", `name=${searchValue}`);
651
+
652
+ getGames(searchUrl).then((searchData:any) => {
653
+ searchArray = searchData;
654
+
655
+ sendSearchData({}, searchData);
656
+ });
657
+ } else {
658
+ if (!searchBarCleared) {
659
+ onFocus();
660
+ }
661
+
662
+ if (initialLoaded) {
663
+ initialLoaded = false;
664
+ }
665
+ }
666
+
667
+ const setFilterNumberValue = () => {
668
+ let vendors = JSON.parse(sessionStorage.getItem('vendorFiltersByCategory'));
669
+
670
+ if (vendors) {
671
+ if(currentCategoryId) {
672
+ if(vendors[currentCategoryId]) {
673
+ numberOfFilters = vendors[currentCategoryId].length;
674
+ } else {
675
+ numberOfFilters = 0;
676
+ }
677
+ }
678
+ }
679
+ }
680
+
681
+ const searchActivated = () => {
682
+ window.postMessage({ type: "scroll" }, window.location.href);
683
+ }
684
+
685
+ const clearSearchbar = () => {
686
+ searchBarCleared = true;
687
+ searchValue = '';
688
+ searchArray = [];
689
+ recentSearches = false;
690
+
691
+ onBlur();
692
+ }
693
+
694
+ //
695
+ // --- START of communication with other widgets
696
+ //
697
+ const sendMostPlayed = (node:any, mostPlayedData:CategoriesData) => {
698
+ window.postMessage({ type: 'MostPlayedData', mostPlayedData }, window.location.href);
699
+ }
700
+
701
+ const submitFilters = (venArray:Array<Object>) => {
702
+ window.postMessage({ type: "AvailableVendors", venArray}, window.location.href);
703
+ }
704
+
705
+ const updateFilters = (venArray:Array<Object>) => {
706
+ window.postMessage({ type: "UpdateSelectedVendorFilters", venArray}, window.location.href);
707
+ }
708
+
709
+ const sendRecentSearchData = (node:any, searchData:any) => {
710
+ window.postMessage({ type: "RecentSearchData", searchData }, window.location.href);
711
+ }
712
+
713
+ const openFiltersModal = () => {
714
+ window.postMessage({ type: "ShowFilterModal" }, window.location.href);
715
+ }
716
+
717
+ const clearVendorFilter = () => {
718
+ window.postMessage({ type: "ClearVendorFilters" }, window.location.href);
719
+ }
720
+
721
+ const sendCategoryData = (node:any, categoryId:string) => {
722
+ currentCategoryId = categoryId;
723
+ window.postMessage({ type: `CategoryData_${categoryId}`, categoryId, visiblegames, receivedFavoriteResults }, window.location.href);
724
+ }
725
+
726
+ const sendSearchData = (node:any, searchData:CategoriesData) => {
727
+ if (searchData) {
728
+ window.postMessage({ type: "SearchData", searchData, receivedFavoriteResults }, window.location.href);
729
+ }
730
+ }
731
+
732
+ //
733
+ // --- END of communication with other widgets
734
+ //
735
+
736
+ /* Listen for scroll */
737
+ const scrollHandler = () => {
738
+ if(searchElementWrapper) {
739
+ searchPositionTop = searchElementWrapper.getBoundingClientRect().top + document.body.getBoundingClientRect().top;
740
+ }
741
+ if (document.documentElement.scrollTop > searchPositionTop || searchPositionTop > 130) {
742
+ adjustingScroll = true;
743
+ } else {
744
+ adjustingScroll = false;
745
+ }
746
+ }
747
+
748
+ const checkAttrs = () => {
749
+ if (!endpoint) {
750
+ error = "Endpoint is missing! Please provide a valid endpointURL.";
751
+ hasErrors = true;
752
+ isLoading = false;
753
+
754
+ console.error(error);
755
+ }
756
+
757
+ if (!datasource) {
758
+ error = "Datasource is missing! Please provide a valid datasource.";
759
+ hasErrors = true;
760
+ isLoading = false;
761
+
762
+ console.error(error);
763
+ }
764
+
765
+ if (!lang || lang.length < 2) {
766
+ error = "Language is missing! Please provide a valid language (alpha2code)";
767
+ hasErrors = true;
768
+ isLoading = false;
769
+
770
+ console.error(error);
771
+ }
772
+
773
+ return hasErrors;
774
+ }
775
+ const updateCategoriesLanguage = () => {
776
+ if(firstLoad) {
777
+ setTimeout(() => {
778
+ window.postMessage({ type: 'CategoryUpdate', itemId: activeCategory}, window.location.href);
779
+ }, 500);
780
+ }
781
+ firstLoad = false;
782
+ }
783
+
784
+ const initialSetup = () => {
785
+ if (!checkAttrs()) {
786
+ isLoading = true;
787
+
788
+ if (favorites == 'true') {
789
+ getFavoredGames(endpoint, sessionID, playerID);
790
+ }
791
+
792
+ setLocale(lang);
793
+
794
+ let categoriesUrl = new URL(`${endpoint}/casino/groups/${datasource}`);
795
+
796
+ categoriesUrl.searchParams.append('language', lang);
797
+ categoriesUrl.searchParams.append('platform', getDevice(userAgent));
798
+
799
+ getCategories(categoriesUrl).then((data:CategoriesData) => {
800
+ if (data) {
801
+ categoriesData = data.items.filter((item:any) => {
802
+ return item.games.total > 0;
803
+ });
804
+
805
+ shownCategories = categories = categoriesData.map((item:any) => {
806
+ return item.id;
807
+ });
808
+
809
+ isLoading = false;
810
+ }
811
+ });
812
+
813
+ if (getDevice(userAgent) !== 'PC') {
814
+ searchElement.addEventListener('focusin', (event) => {
815
+ mobileSearchViewActive = true;
816
+ });
817
+
818
+ searchElement.addEventListener('focusout', (event) => {
819
+ mobileSearchViewActive = false;
820
+ });
821
+ }
822
+
823
+ setFilterNumberValue();
824
+
825
+ searchElementWrapper = searchWrapper;
826
+
827
+ if (searchElementWrapper) {
828
+ searchPositionTop = searchElementWrapper.getBoundingClientRect().top - document.body.getBoundingClientRect().top;
829
+ }
830
+ }
831
+ }
832
+
833
+ const setActiveCategory = ():void => {
834
+ activeCategory = activecategory;
835
+ CategoryChangeHandler({ data: { itemId: activeCategory }});
836
+ }
837
+
838
+ const setSession = () => {
839
+ isLoggedIn = true;
840
+ sessionID = session;
841
+ playerID = userid;
842
+ if (playerID && playerID.length && sessionID && sessionID.length > 0) {
843
+ getFavoredGames(endpoint, sessionID, playerID);
844
+ }
845
+ }
846
+
847
+ const setClientStyling = () => {
848
+ let sheet = document.createElement('style');
849
+ sheet.innerHTML = clientstyling;
850
+ customStylingContainer.appendChild(sheet);
851
+ }
852
+
853
+ const setClientStylingURL = () => {
854
+ let cssFile:HTMLElement = document.createElement('style');
855
+
856
+ fetch(new URL(clientstylingurl))
857
+ .then((res:any) => res.text())
858
+ .then((data:any) => {
859
+ cssFile.innerHTML = data
860
+
861
+ if (customStylingContainer) {
862
+ setTimeout(() => { customStylingContainer.appendChild(cssFile); }, 1);
863
+ }
864
+ });
865
+ }
866
+
867
+ const startInterval = (e:any):void => {
868
+ timer = 0;
869
+
870
+ timerInterval = setInterval(() => {
871
+ timer += 1;
872
+ panicLoading = true;
873
+
874
+ if (timer >= 3) {
875
+ window.postMessage({type: 'PanicButtonClicked'}, window.location.href);
876
+ clearInterval(timerInterval)
877
+ }
878
+ }, 1000);
879
+ }
880
+
881
+ const endInterval = (e:any):void => {
882
+ if (timer < 3) {
883
+ panicLoading = false;
884
+ }
885
+ clearInterval(timerInterval);
886
+ }
887
+
888
+ const addEventsToDisplayedElements = () => {
889
+ panicButton?.addEventListener("mousedown", startInterval, false);
890
+ panicButton?.addEventListener('touchstart', startInterval, false);
891
+
892
+ // on mouseup stop interval count
893
+ panicButton?.addEventListener("mouseup", endInterval, false);
894
+ panicButton?.addEventListener("touchend", endInterval, false);
895
+ }
896
+
897
+ const removeEventsToDisplayedElements = ():void => {
898
+ panicLoading = false;
899
+ panicButton?.removeEventListener("mousedown", startInterval);
900
+ panicButton?.removeEventListener('touchstart', startInterval);
901
+
902
+ // on mouseup stop interval count
903
+ panicButton?.removeEventListener("mouseup", endInterval);
904
+ panicButton?.removeEventListener("touchend", endInterval);
905
+ }
906
+
907
+ onMount(() => {
908
+ window.addEventListener('scroll', scrollHandler, false);
909
+ window.addEventListener('message', messageHandler, false);
910
+
911
+ return () => {
912
+ window.removeEventListener('scroll', scrollHandler);
913
+ window.removeEventListener('message', messageHandler);
914
+
915
+ removeEventsToDisplayedElements();
916
+ }
917
+ });
918
+
919
+ $: lang && activecategory && setActiveCategory();
920
+ $: session && userid && endpoint && setSession();
921
+ $: endpoint && datasource && lang && alternativesearch && initialSetup();
922
+ $: lang && updateCategoriesLanguage();
923
+ $: clientstyling && setClientStyling();
924
+ $: clientstylingurl && setClientStylingURL();
925
+ $: panicButton && addEventsToDisplayedElements();
926
+ </script>
927
+
928
+ {#if hasErrors}
929
+ <p class="SearchLoading" part="SearchLoading">{$_('casinoPage.500')}</p>
930
+ {:else}
931
+ <section class="CategoriesLobby" part="CategoriesLobby" bind:this={customStylingContainer} style="max-width: {containermaxwidth}px;">
932
+ {#if (getDevice(userAgent) !== 'PC') && (alternativesearch === 'false') && mobileSearchViewActive}
933
+ <div class="SearchBarPlaceholder" part="SearchBarPlaceholder"></div>
934
+ {/if}
935
+
936
+ {#if alternativesearch === 'false'}
937
+ <!-- main search layout -->
938
+ <div bind:this={searchWrapper} class="CategoriesHeaderSection {(getDevice(userAgent) !== 'PC') ? 'CategoriesHeaderMobileSection' : ''} {mobileSearchViewActive ? 'SearchMobileActive' : ''} {mobileSearchViewActive || (searched && !(getDevice(userAgent) === 'PC') && !closeSearch) ? 'CategoriesHeaderSearchActive' : ''} {(adjustingScroll && mobileSearchViewActive) ? 'SearchStickTop' : ''}"
939
+ style="top: {adjustingScroll && mobileSearchViewActive ? scrollOffset + 'px' : ''}"
940
+ part="CategoriesHeaderSection {(getDevice(userAgent) !== 'PC') ? 'CategoriesHeaderMobileSection' : ''} {mobileSearchViewActive ? 'SearchMobileActive' : ''} {mobileSearchViewActive || (searched && !(getDevice(userAgent) === 'PC') && !closeSearch) ? 'CategoriesHeaderSearchActive' : ''} {(adjustingScroll && mobileSearchViewActive) ? 'SearchStickTop' : ''}">
941
+ <div class="SearchContainer { (!lobbyScreen && !favoritesScreen && !mostPlayedScreen && !lobbyViewAux) ? 'SearchTruncated' : ''}" part="SearchContainer { (!lobbyScreen && !favoritesScreen && !mostPlayedScreen && !lobbyViewAux) ? 'SearchTruncated' : ''}">
942
+ <label for="search" class="SrOnly" part="SrOnly">{$_('casinoPage.searchGames')}</label>
943
+ <div class="SearchWrapper" part="SearchWrapper">
944
+ {#if !mobileSearchViewActive}
945
+ <div class="SearchIcon" part="SearchIcon">
946
+ <svg role="presentation" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" aria-hidden="true">
947
+ <path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd" />
948
+ </svg>
949
+ </div>
950
+ {/if}
951
+ <input id="SearchField" class="SearchInput" part="SearchInput" on:focus={onFocus} on:blur={onBlur} bind:this={searchElement} bind:value={searchValue} placeholder="{(getDevice(userAgent) === 'PC') ? $_('casinoPage.search') : $_('casinoPage.searchMobile')}" type="search" on:focus={searchActivated} />
952
+ {#if ((getDevice(userAgent) === 'PC') && searchValue.length) || (getDevice(userAgent) !== 'PC') }
953
+ <span class="{(getDevice(userAgent) === 'PC') ? 'ClearSearchButton' : 'ClearSearchButtonMobile'}" part="{(getDevice(userAgent) === 'PC') ? 'ClearSearchButton' : 'ClearSearchButtonMobile'}" on:click="{() => clearSearchbar()}">
954
+ <div class="CloseIconContainer" part="CloseIconContainer">
955
+ <div class="CloseIconWrapper" part="CloseIconWrapper">
956
+ <div class="CloseIcon" part="CloseIcon"></div>
957
+ </div>
958
+ </div>
959
+ </span>
960
+ {/if}
961
+ </div>
962
+ </div>
963
+ {#if !favoritesScreen && !lobbyScreen && !mobileSearchViewActive && !mostPlayedScreen && !recentSearches && !searched && !searchFocus && !lobbyViewAux}
964
+ <div class="FiltersButtonsContainer" part="FiltersButtonsContainer">
965
+ {#if numberOfFilters}
966
+ <div class="ClearFilterButtonWrapper" part="ClearFilterButtonWrapper" on:click="{() => clearVendorFilter()}">
967
+ <div class="ClearButton" part="ClearButton">{$_('casinoPage.clear')}
968
+ <span class="ClearIcon" part="ClearIcon">
969
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
970
+ viewBox="0 0 378.303 378.303" style="enable-background:new 0 0 378.303 378.303;" xml:space="preserve">
971
+ <polygon style="fill:var(--emfe-w-color-secondary, #FD2839);" points="378.303,28.285 350.018,0 189.151,160.867 28.285,0 0,28.285 160.867,189.151 0,350.018
972
+ 28.285,378.302 189.151,217.436 350.018,378.302 378.303,350.018 217.436,189.151 "/>
973
+ </svg>
974
+ </span>
975
+ </div>
976
+ </div>
977
+ {/if}
978
+ {#if !searched || !recentSearches}
979
+ {#if !mostPlayedScreen}
980
+ <div class="FilterButtonWrapper" part="FilterButtonWrapper" on:click='{() => {openFiltersModal()}}'>
981
+ <div class="FilterButton" part="FilterButton">{$_('casinoPage.filters')}</div>
982
+ <div class="FilterIconContainer" part="FilterIconContainer">
983
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 26 26"><defs><style>.a{fill:var(--emfe-w-color-white, #FFFFFF);}</style></defs><path class="a" d="M16.7,32.2a1.654,1.654,0,0,1-.636-.148,1.526,1.526,0,0,1-.867-1.393V20.578L5.433,10.588A1.543,1.543,0,0,1,5,9.491V7.742A1.512,1.512,0,0,1,6.5,6.2h23A1.512,1.512,0,0,1,31,7.742V9.491a1.543,1.543,0,0,1-.433,1.1L20.8,20.578v7.738a1.594,1.594,0,0,1-.52,1.156l-2.6,2.312A1.461,1.461,0,0,1,16.7,32.2ZM6.618,9.431l9.764,10.02a1.543,1.543,0,0,1,.433,1.1v9.813l2.34-2.075V20.519a1.543,1.543,0,0,1,.433-1.1L29.353,9.4V7.831H6.618Z" transform="translate(-5 -6.2)"/></svg>
984
+ <div class="NumberOfFiltersContainer" part="NumberOfFiltersContainer">
985
+ <span class="NumberOfFilters" part="NumberOfFilters">{numberOfFilters}</span>
986
+ </div>
987
+ </div>
988
+ </div>
989
+ {/if}
990
+ {/if}
991
+ </div>
992
+ {/if}
993
+ </div>
994
+ {:else}
995
+ <!-- start alternative search layout-->
996
+ <div bind:this={searchWrapper} class="CategoriesHeaderSection CategoriesHeaderSectionAltDesign {(getDevice(userAgent) !== 'PC') ? 'CategoriesHeaderMobileSection' : ''} {mobileSearchViewActive ? 'SearchMobileActive' : ''} {mobileSearchViewActive || (searched && !(getDevice(userAgent) === 'PC') && !closeSearch) ? 'CategoriesHeaderSearchActive' : ''}{(adjustingScroll && mobileSearchViewActive) ? 'SearchStickTop' : ''}"
997
+ part="CategoriesHeaderSection CategoriesHeaderSectionAltDesign {(getDevice(userAgent) !== 'PC') ? 'CategoriesHeaderMobileSection' : ''} {mobileSearchViewActive ? 'SearchMobileActive' : ''} {mobileSearchViewActive || (searched && !(getDevice(userAgent) === 'PC') && !closeSearch) ? 'CategoriesHeaderSearchActive' : ''}{(adjustingScroll && mobileSearchViewActive) ? 'SearchStickTop' : ''}"
998
+ style="top: {adjustingScroll && mobileSearchViewActive ? scrollOffset + 'px' : ''}">
999
+ <div class="SearchContainer { (!lobbyScreen && !favoritesScreen && !mostPlayedScreen && !lobbyViewAux) ? 'SearchTruncated' : ''}" part="SearchContainer { (!lobbyScreen && !favoritesScreen && !mostPlayedScreen && !lobbyViewAux) ? 'SearchTruncated' : ''}">
1000
+ <label for="search" class="SrOnly" part="SrOnly">{$_('casinoPage.searchGames')}</label>
1001
+ <div class="SearchWrapper" part="SearchWrapper">
1002
+ {#if !mobileSearchViewActive}
1003
+ <div class="SearchIcon" part="SearchWrapper">
1004
+ <svg role="presentation" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" aria-hidden="true">
1005
+ <path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd" />
1006
+ </svg>
1007
+ </div>
1008
+ {/if}
1009
+
1010
+ <input id="SearchField" class="SearchInput" part="SearchInput" on:focus={onFocus} on:blur={onBlur} bind:this={searchElement} bind:value={searchValue} placeholder="{(getDevice(userAgent) === 'PC') ? $_('casinoPage.search') : $_('casinoPage.searchMobile')}" type="search" on:focus={searchActivated} />
1011
+ {#if ((getDevice(userAgent) === 'PC') && searchValue.length) || (getDevice(userAgent) !== 'PC')}
1012
+ <span class="{(getDevice(userAgent) === 'PC') ? 'ClearSearchButton' : 'ClearSearchButtonMobile'}" part="{(getDevice(userAgent) === 'PC') ? 'ClearSearchButton' : 'ClearSearchButtonMobile'}" on:click="{() => clearSearchbar()}">
1013
+ <div class="CloseIconContainer" part="CloseIconContainer">
1014
+ <div class="CloseIconWrapper" part="CloseIconWrapper">
1015
+ <div class="CloseIcon" part="CloseIcon"></div>
1016
+ </div>
1017
+ </div>
1018
+ </span>
1019
+ {/if}
1020
+ </div>
1021
+ </div>
1022
+ {#if !favoritesScreen && !lobbyScreen && !mobileSearchViewActive && !mostPlayedScreen && !recentSearches && !searchFocus && !searched && !lobbyViewAux}
1023
+ <div class="FiltersButtonsContainer" part="FiltersButtonsContainer">
1024
+ {#if numberOfFilters}
1025
+ <div class="ClearFilterButtonWrapper {numberOfFilters ? 'FiltersActive' : ''}" part="ClearFilterButtonWrapper {numberOfFilters ? 'FiltersActive' : ''}" on:click="{() => clearVendorFilter()}">
1026
+ <div class="ClearButton" part="ClearButton">{$_('casinoPage.clear')}
1027
+ <span class="ClearIcon" part="ClearIcon">
1028
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
1029
+ viewBox="0 0 378.303 378.303" style="enable-background:new 0 0 378.303 378.303;" xml:space="preserve">
1030
+ <polygon style="fill:var(--emfe-w-color-secondary, #FD2839);" points="378.303,28.285 350.018,0 189.151,160.867 28.285,0 0,28.285 160.867,189.151 0,350.018
1031
+ 28.285,378.302 189.151,217.436 350.018,378.302 378.303,350.018 217.436,189.151 "/>
1032
+ </svg>
1033
+ </span>
1034
+ </div>
1035
+ </div>
1036
+ {/if}
1037
+ {#if !searched || !recentSearches}
1038
+ {#if !mostPlayedScreen}
1039
+ <div class="FilterButtonWrapper" part="FilterButtonWrapper" on:click='{() => {openFiltersModal()}}'>
1040
+ <div class="FilterButton" part="FilterButton">{$_('casinoPage.filters')}</div>
1041
+ <div class="FilterIconContainer" part="FilterIconContainer">
1042
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 26 26"><defs><style>.a{fill:var(--emfe-w-color-white, #FFFFFF);}</style></defs><path class="a" d="M16.7,32.2a1.654,1.654,0,0,1-.636-.148,1.526,1.526,0,0,1-.867-1.393V20.578L5.433,10.588A1.543,1.543,0,0,1,5,9.491V7.742A1.512,1.512,0,0,1,6.5,6.2h23A1.512,1.512,0,0,1,31,7.742V9.491a1.543,1.543,0,0,1-.433,1.1L20.8,20.578v7.738a1.594,1.594,0,0,1-.52,1.156l-2.6,2.312A1.461,1.461,0,0,1,16.7,32.2ZM6.618,9.431l9.764,10.02a1.543,1.543,0,0,1,.433,1.1v9.813l2.34-2.075V20.519a1.543,1.543,0,0,1,.433-1.1L29.353,9.4V7.831H6.618Z" transform="translate(-5 -6.2)"/></svg>
1043
+ {#if numberOfFilters > 0}
1044
+ <div class="NumberOfFiltersContainer" part="NumberOfFiltersContainer">
1045
+ <span class="NumberOfFilters" part="NumberOfFilters">{numberOfFilters}</span>
1046
+ </div>
1047
+ {/if}
1048
+ </div>
1049
+ </div>
1050
+ {/if}
1051
+ {/if}
1052
+ </div>
1053
+ {/if}
1054
+ </div>
1055
+ <!-- end alternative search layout-->
1056
+ {/if}
1057
+
1058
+ {#if playrandomgame == 'true' && searchFocus == false}
1059
+ <casino-random-game {datasource} {endpoint} {lang} {gameevent} {randombuttonicon}>
1060
+ </casino-random-game>
1061
+ {/if}
1062
+
1063
+ {#if isLoading}
1064
+ <p class="SearchLoading" part="SearchLoading">{$_('casinoPage.loading')}</p>
1065
+ {:else}
1066
+ {#if searched}
1067
+ <casino-games-category-section
1068
+ endpoint={endpoint}
1069
+ datasource={datasource}
1070
+ lang={lang}
1071
+ currency={currency}
1072
+ session={session}
1073
+ userid={userid}
1074
+ use:sendSearchData={searchArray}
1075
+ categoryid="Search"
1076
+ favorites={favorites}
1077
+ categoryindex="0"
1078
+ class="CategoryContainer"
1079
+ {clientstyling}
1080
+ {clientstylingurl}
1081
+ {livecasino}
1082
+ {visiblegames}
1083
+ {gamepagemodalurl}
1084
+ {enablecasinowinners}
1085
+ {enableautoscroll}
1086
+ {tabsorder}
1087
+ {isrecentavailable}
1088
+ {istopavailable}
1089
+ />
1090
+ {:else}
1091
+ {#if lobbyScreen}
1092
+ {#each shownCategories as category, index}
1093
+ {#if index === 4}
1094
+ <br>
1095
+ <jackpot-banner
1096
+ visualstructure="typeSpread"
1097
+ lang="gr"
1098
+ title="Jackpot Cards"
1099
+ backgroundsrc="../mock_rsrc/background0.png"
1100
+ backgroundsrcmobile=""
1101
+ currency = {currency || 'RON'}
1102
+ gameid = "999"
1103
+ endpoint = "https://winmasters-ro-api.stage.norway.everymatrix.com/v1/casino/jackpots"
1104
+
1105
+ titlelogopath = "../mock_rsrc/jackpots_logo.svg"
1106
+
1107
+ caticon0="../../jackpot-banner/mock_rsrc/icon0.svg"
1108
+ caticon1="../mock_rsrc/icon1.svg"
1109
+ caticon2="../mock_rsrc/icon2.svg"
1110
+ caticon3="../mock_rsrc/icon3.svg"
1111
+ ></jackpot-banner>
1112
+ {:else if index === 6}
1113
+ <br>
1114
+ <jackpot-banner
1115
+ visualstructure="typeLeft"
1116
+ lang="en"
1117
+ title="Egypt Quest"
1118
+ backgroundsrc="../mock_rsrc/background_egypt.svg"
1119
+ backgroundsrcmobile="../mock_rsrc/background0.png"
1120
+ currency = {currency || 'RON'}
1121
+ gameid = "998"
1122
+ endpoint = "https://winmasters-ro-api.stage.norway.everymatrix.com/v1/casino/jackpots"
1123
+
1124
+ titlelogopath = "../mock_rsrc/egypt_logo.svg"
1125
+
1126
+ caticon0="../mock_rsrc/egypt_icon0.svg"
1127
+ caticon1="../mock_rsrc/egypt_icon0.svg"
1128
+ caticon2="../mock_rsrc/egypt_icon0.svg"
1129
+ caticon3="../mock_rsrc/egypt_icon0.svg"
1130
+ iconlabels="platinum, gold, silver, bronze"
1131
+ ></jackpot-banner>
1132
+ {/if}
1133
+ <casino-games-category-section
1134
+ session={session}
1135
+ userid={userid}
1136
+ endpoint={endpoint}
1137
+ datasource={datasource}
1138
+ lang={lang}
1139
+ currency={currency}
1140
+ use:sendCategoryData={category}
1141
+ categoryid={category}
1142
+ categoryindex={index}
1143
+ categorygames="9"
1144
+ favorites={favorites}
1145
+ class="CategoryContainer"
1146
+ style="background-color: {(index % 2 !== 0) ? categorybackground : 'transparent'}"
1147
+ {clientstyling}
1148
+ {clientstylingurl}
1149
+ {livecasino}
1150
+ {visiblegames}
1151
+ {gamepagemodalurl}
1152
+ {enablecasinowinners}
1153
+ />
1154
+ {/each}
1155
+ {:else if favoritesScreen}
1156
+ <casino-games-category-section
1157
+ session={session}
1158
+ userid={userid}
1159
+ endpoint={endpoint}
1160
+ datasource={datasource}
1161
+ lang={lang}
1162
+ currency={currency}
1163
+ favorites={favorites}
1164
+ use:getFavoredGames={`${endpoint}/player/${playerID}/favorites/`, sessionID, playerID}
1165
+ categoryid={"FAVORITES"}
1166
+ class="CategoryContainer"
1167
+ {clientstyling}
1168
+ {clientstylingurl}
1169
+ {livecasino}
1170
+ {visiblegames}
1171
+ {gamepagemodalurl}
1172
+ {enablecasinowinners}
1173
+ />
1174
+ {:else if mostPlayedScreen}
1175
+ {#if mostPlayedEmpty}
1176
+ <p class="SearchLoading" part="SearchLoading">{$_('casinoPage.noGamesPlayed')}</p>
1177
+ {:else}
1178
+ <casino-games-category-section
1179
+ session={session}
1180
+ userid={userid}
1181
+ endpoint={endpoint}
1182
+ datasource={datasource}
1183
+ lang={lang}
1184
+ currency={currency}
1185
+ favorites={favorites}
1186
+ categoryid="MOSTPLAYED"
1187
+ categoryindex="1"
1188
+ categorygames="9"
1189
+ class="CategoryContainer"
1190
+ {clientstyling}
1191
+ {clientstylingurl}
1192
+ {livecasino}
1193
+ {visiblegames}
1194
+ {gamepagemodalurl}
1195
+ {enablecasinowinners}
1196
+ />
1197
+ {/if}
1198
+ {:else}
1199
+ {#if !recentSearches}
1200
+ <casino-games-category-section
1201
+ userid={userid}
1202
+ endpoint={endpoint}
1203
+ datasource={datasource}
1204
+ favorites={favorites}
1205
+ lang={lang}
1206
+ currency={currency}
1207
+ session={session}
1208
+ categoryid={activeCategory}
1209
+ categorygames="9"
1210
+ class="CategoryContainer"
1211
+ {clientstyling}
1212
+ {clientstylingurl}
1213
+ {livecasino}
1214
+ {visiblegames}
1215
+ {gamepagemodalurl}
1216
+ {enablecasinowinners}
1217
+ />
1218
+ {/if}
1219
+ {/if}
1220
+ {/if}
1221
+ {/if}
1222
+ {#if isLoggedIn && haspanicbutton == "true"}
1223
+ <div class="PanicSection {(getDevice(userAgent) !== 'PC') ? 'PanicSectionMobile' : ''}" part="PanicSection {(getDevice(userAgent) !== 'PC') ? 'PanicSectionMobile' : ''}">
1224
+ <button class="PanicButton {(getDevice(userAgent) !== 'PC') ? 'PanicButtonMobile ' : ''}" class:PanicButtonAnimation={panicLoading} part="PanicButton {(getDevice(userAgent) !== 'PC') ? 'PanicButtonMobile' : ''}" bind:this={panicButton} >{$_('casinoPage.breakButton')}</button>
1225
+ </div>
1226
+ {/if}
1227
+ </section>
1228
+ {/if}
1229
+
1230
+ <style lang="scss">
1231
+
1232
+ :host {
1233
+ font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
1234
+ }
1235
+
1236
+ *, *::before, *::after {
1237
+ margin: 0;
1238
+ padding: 0;
1239
+ box-sizing: border-box;
1240
+ }
1241
+
1242
+ .CategoriesLobby {
1243
+ margin: 0 auto;
1244
+ }
1245
+
1246
+ .PanicSectionMobile {
1247
+ flex-direction: column;
1248
+ margin: 20px 0;
1249
+ }
1250
+
1251
+ .PanicSection {
1252
+ display: flex;
1253
+ justify-content: center;
1254
+ align-items: center;
1255
+ gap: 10px;
1256
+ margin-top: 20px;
1257
+ }
1258
+
1259
+ .PanicButton {
1260
+ border-radius: 5px;
1261
+ border: 1px solid var(--emfe-w-color-primary, #D0046C);
1262
+ background-color: var(--emfe-w-color-primary, #D0046C);
1263
+ width: 280px;
1264
+ height: 48px;
1265
+ line-height: 18px;
1266
+ color: var(--emfe-w-color-white, #FFFFFF);
1267
+ cursor: pointer;
1268
+ }
1269
+
1270
+ .PanicButtonAnimation {
1271
+ background: -webkit-linear-gradient(
1272
+ 135deg,
1273
+ rgba(20, 20, 20, 0) 55%, rgba(20, 20, 20, 0.3) 100%
1274
+ );
1275
+
1276
+ background: -moz-linear-gradient(
1277
+ 135deg,
1278
+ rgba(20, 20, 20, 0) 55%, rgba(20, 20, 20, 0.3) 100%
1279
+ );
1280
+
1281
+ background: -o-linear-gradient(
1282
+ 135deg,
1283
+ rgba(20, 20, 20, 0) 55%, rgba(20, 20, 20, 0.3) 100%
1284
+ );
1285
+
1286
+ background-color: var(--emfe-w-color-primary, #D0046C);
1287
+ width: 280px;
1288
+ color: #fff;
1289
+
1290
+ -webkit-animation: bar-animation 2s linear;
1291
+ }
1292
+
1293
+ .PanicButtonMobile {
1294
+ width: 280px;
1295
+ padding: 0 5px;
1296
+
1297
+ //Remove text selection for panic button on mobile
1298
+ -webkit-touch-callout: none; /* iOS Safari */
1299
+ -webkit-user-select: none; /* Safari */
1300
+ -moz-user-select: none; /* Old versions of Firefox */
1301
+ -ms-user-select: none; /* Internet Explorer/Edge */
1302
+ user-select: none;
1303
+ // End of removing selection properties
1304
+ }
1305
+
1306
+ @-webkit-keyframes bar-animation {
1307
+ 0% {
1308
+ background-position: 0;
1309
+ }
1310
+ 100% {
1311
+ background-position: 280px;
1312
+ }
1313
+ }
1314
+
1315
+
1316
+ [type="search"] {
1317
+ appearance: none;
1318
+ }
1319
+
1320
+ .SrOnly {
1321
+ position: absolute;
1322
+ width: 1px;
1323
+ height: 1px;
1324
+ padding: 0;
1325
+ margin: -1px;
1326
+ overflow: hidden;
1327
+ clip: rect(0, 0, 0, 0);
1328
+ white-space: nowrap;
1329
+ border-width: 0;
1330
+ }
1331
+
1332
+ .CategoryContainer {
1333
+ display: block;
1334
+
1335
+ @media screen and (max-width: 1300px) {
1336
+ padding: 0 2.4%
1337
+ }
1338
+ }
1339
+
1340
+ .SearchLoading {
1341
+ color: var(--emfe-w-color-white, #FFFFFF);
1342
+ font-size: 14px;
1343
+ margin-top: 16px;
1344
+ text-align: center;
1345
+ }
1346
+
1347
+ .SearchContainer {
1348
+ flex: 3;
1349
+ width: 100%;
1350
+ max-width: 600px;
1351
+ margin: auto 0 auto 30%;
1352
+ &.SearchTruncated {
1353
+ margin: auto 0 auto 30%;
1354
+ .SearchInput {
1355
+ tabindex: 999;
1356
+ padding: 20px 12px 20px 40px;
1357
+ }
1358
+ }
1359
+ .SearchWrapper {
1360
+ position: relative;
1361
+ display: inline-flex;
1362
+ color: rgba(199, 210, 254, 1);
1363
+
1364
+ .SearchIcon {
1365
+ position: absolute;
1366
+ display: flex;
1367
+ align-items: center;
1368
+ top: 0;
1369
+ bottom: 0;
1370
+ left: 1.2%;
1371
+ pointer-events: none;
1372
+
1373
+ svg {
1374
+ width: 26px;
1375
+ height: 26px;
1376
+ display: block;
1377
+ vertical-align: middle;
1378
+ fill: rgba(199, 210, 254, 1);
1379
+ }
1380
+ }
1381
+ .SearchInput {
1382
+ width: 520px;
1383
+ display: block;
1384
+ padding: 12px 12px 12px 40px;
1385
+ border-radius: 6px;
1386
+ border-color: transparent;
1387
+ font-size: 16px;
1388
+ background-color: rgba(156, 163, 175, 0.25);
1389
+ color: rgba(224, 231, 255, 1);
1390
+ &::-webkit-search-decoration,
1391
+ &::-webkit-search-cancel-button,
1392
+ &::-webkit-search-results-button,
1393
+ &::-webkit-search-results-decoration {
1394
+ -webkit-appearance:none;
1395
+ }
1396
+
1397
+ &::placeholder {
1398
+ color:rgba(255, 255, 255, 1);
1399
+ }
1400
+
1401
+ &:focus {
1402
+ background-color: rgba(255, 255, 255, 1);
1403
+ color: rgba(17, 24, 39, 1);
1404
+ outline: 2px solid transparent;
1405
+ outline-offset: 2px;
1406
+
1407
+ &::placeholder {
1408
+ color: rgba(156, 163, 175, 1);
1409
+ }
1410
+ }
1411
+ }
1412
+
1413
+ &:focus-within {
1414
+ color: rgba(156, 163, 175, 1);
1415
+
1416
+ .SearchIcon svg {
1417
+ fill: rgba(156, 163, 175, 1);
1418
+ }
1419
+ }
1420
+ }
1421
+ }
1422
+
1423
+ .FiltersButtonsContainer {
1424
+ display: inline-flex;
1425
+ flex-direction: row-reverse;
1426
+ flex: 1;
1427
+ grid-gap: 20px;
1428
+ flex-direction: row-reverse;
1429
+ }
1430
+ .FilterButtonWrapper, .ClearFilterButtonWrapper {
1431
+ display: inline-flex;
1432
+ padding: 10px;
1433
+ border: 1px solid var(--emfe-w-color-gray-300, #58586B);
1434
+ border-radius: 5px;
1435
+ text-transform: uppercase;
1436
+ color: var(--emfe-w-color-white, #FFFFFF);
1437
+ cursor: pointer;
1438
+ }
1439
+ .ClearFilterButtonWrapper {
1440
+ border: 1px solid var(--emfe-w-color-secondary, #FD2839);
1441
+ color: var(--emfe-w-color-secondary, #FD2839);
1442
+ }
1443
+ .FilterIconContainer, .ClearIcon {
1444
+ position: relative;
1445
+ padding-left: 5px;
1446
+ }
1447
+ .FilterIconContainer {
1448
+ top: 2px;
1449
+ }
1450
+ .ClearIcon {
1451
+ position: relative;
1452
+ top: 1px;
1453
+ svg {
1454
+ width: 14px;
1455
+ }
1456
+ }
1457
+ .FilterButtonWrapper, .ClearFilterButtonWrapper {
1458
+ display: inline-flex;
1459
+ justify-content: center;
1460
+ align-items: center;
1461
+ }
1462
+ .NumberOfFiltersContainer {
1463
+ display: block;
1464
+ line-height: 0px;
1465
+ border-radius: 50%;
1466
+ border: 2px solid var(--emfe-w-color-primary, #D0046C);
1467
+ background: var(--emfe-w-color-primary, #D0046C);
1468
+ color: var(--emfe-w-color-white, #FFFFFF);
1469
+ font-size: 12px;
1470
+ position: absolute;
1471
+ top: -5px;
1472
+ left: 18px;
1473
+ .NumberOfFilters {
1474
+ display: inline-block;
1475
+ padding-top: 50%;
1476
+ padding-bottom: 50%;
1477
+ margin-left: 3px;
1478
+ margin-right: 3px;
1479
+ }
1480
+ }
1481
+
1482
+ .CategoriesHeaderSection {
1483
+ width: 100%;
1484
+ display: inline-flex;
1485
+ flex-direction: row;
1486
+ margin-top: 30px;
1487
+ }
1488
+ .CategoriesHeaderMobileSection {
1489
+ position: fixed;
1490
+ bottom: 0;
1491
+ left: 0;
1492
+ flex-direction: row-reverse;
1493
+ z-index: 1;
1494
+ .ClearFilterButtonWrapper {
1495
+ display: none;
1496
+ }
1497
+ .SearchContainer {
1498
+ flex: 1;
1499
+ max-width: unset;
1500
+ margin: unset;
1501
+ background-color: rgba(208, 5, 108, 1);
1502
+ z-index: 1;
1503
+ .SearchWrapper {
1504
+ display: flex;
1505
+ color: var(--emfe-w-color-white, #FFFFFF);
1506
+ .SearchIcon {
1507
+ left: 2.4%;
1508
+ }
1509
+ .SearchInput {
1510
+ padding: 12px;
1511
+ border-radius: 0;
1512
+ background-color: rgba(208, 5, 108, 1);
1513
+ color: var(--emfe-w-color-white, #FFFFFF);
1514
+ text-align: center;
1515
+ opacity: 1;
1516
+ &::placeholder, &:-ms-input-placeholder, &::-ms-input-placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
1517
+ color: rgba(255, 255, 255, 1);
1518
+ opacity: 1; /* Firefox */
1519
+ }
1520
+ }
1521
+ path {
1522
+ fill: var(--emfe-w-color-white, #FFFFFF);
1523
+ }
1524
+ }
1525
+ }
1526
+ .FiltersButtonsContainer {
1527
+ flex: 1;
1528
+ .FilterButtonWrapper {
1529
+ position: relative;
1530
+ width: 100%;
1531
+ display: flex;
1532
+ flex-direction: row-reverse;
1533
+ border: 1px solid var(--emfe-w-color-white, #FFFFFF);
1534
+ border-radius: 0;
1535
+ background: var(--emfe-w-color-white, #FFFFFF);
1536
+ color: var(--emfe-w-color-primary, #D0046C);
1537
+ }
1538
+ .FilterIconContainer {
1539
+ position: absolute;
1540
+ left: 40px;
1541
+ top: revert;
1542
+ padding-left: 0;
1543
+ path {
1544
+ fill: var(--emfe-w-color-primary, #D0046C);
1545
+ }
1546
+ }
1547
+ }
1548
+ .NumberOfFiltersContainer {
1549
+ font-size: 8px;
1550
+ left: 15px;
1551
+ }
1552
+ }
1553
+
1554
+ // start alternative search design
1555
+ .CategoriesHeaderSectionAltDesign {
1556
+ &.CategoriesHeaderMobileSection {
1557
+ flex-direction: row;
1558
+ position: relative;
1559
+ margin-top: 30px;
1560
+ .SearchContainer {
1561
+ background-color: var(--emfe-w-color-contrast, #07072A);
1562
+
1563
+ padding: 0 2.4%;
1564
+ .SearchWrapper {
1565
+ justify-content: center;
1566
+ .SearchInput {
1567
+ width: 100%;
1568
+ border: 1px solid var(--emfe-w-color-gray-300, #58586B);
1569
+ border-radius: 6.4px;
1570
+ background-color: transparent;
1571
+ color: var(--emfe-w-color-white, #FFFFFF);
1572
+ padding: 12px 3.6%;
1573
+ &:active, &:focus {
1574
+ width: 100%;
1575
+ }
1576
+ }
1577
+ }
1578
+ }
1579
+ .FiltersButtonsContainer {
1580
+ position: absolute;
1581
+ top: 160px;
1582
+ font-size: 13px;
1583
+ gap: 6px;
1584
+
1585
+ @media screen and (max-width: 1300px) {
1586
+ right: 2.4%;
1587
+ }
1588
+
1589
+ .FilterIconContainer {
1590
+ display: none;
1591
+ }
1592
+ .FilterButtonWrapper {
1593
+ border-radius: 5px;
1594
+ border: 1px solid var(--emfe-w-color-white, #FFFFFF);
1595
+ background: transparent;
1596
+ color: var(--emfe-w-color-white, #FFFFFF);
1597
+ padding: 6px 16px;
1598
+ }
1599
+ .ClearFilterButtonWrapper {
1600
+ padding: 6px 16px;
1601
+ .ClearIcon {
1602
+ display: none;
1603
+ }
1604
+ }
1605
+ }
1606
+ &.CategoriesHeaderSearchActive {
1607
+ top: 0;
1608
+ }
1609
+ }
1610
+ .FiltersActive.ClearFilterButtonWrapper {
1611
+ display: inline-flex;
1612
+ }
1613
+ .ClearSearchButton {
1614
+ right: 2.4%;
1615
+ top: 11px;
1616
+ }
1617
+ .ClearSearchButtonMobile {
1618
+ right: 2.4%;
1619
+ top: 9px;
1620
+ }
1621
+ }
1622
+ // end alternative search design
1623
+ .ClearFilterMobileButtonWrapper {
1624
+ position: absolute;
1625
+ right: 5px;
1626
+ padding: 8px 18px;
1627
+ display: inline-flex;
1628
+ border: 1px solid var(--emfe-w-color-gray-300, #58586B);
1629
+ border-radius: 5px;
1630
+ border: 1px solid var(--emfe-w-color-secondary, #FD2839);
1631
+ text-transform: uppercase;
1632
+ color: var(--emfe-w-color-white, #FFFFFF);
1633
+ cursor: pointer;
1634
+ color: var(--emfe-w-color-secondary, #FD2839);
1635
+ font-size: 14px;
1636
+ .ClearIcon svg {
1637
+ width: 12px;
1638
+ }
1639
+ }
1640
+ .CategoriesHeaderSearchActive {
1641
+ position: fixed;
1642
+ bottom: unset;
1643
+ top: 70px;
1644
+ margin-top: 0;
1645
+ .SearchContainer {
1646
+ background-color:rgba(255, 255, 255, 1);
1647
+ .SearchWrapper {
1648
+ .SearchInput {
1649
+ background-color: rgba(255, 255, 255, 1);
1650
+ color: var(--emfe-w-color-black, #000000);
1651
+ }
1652
+ }
1653
+ }
1654
+ }
1655
+ .SearchStickTop {
1656
+ margin-top: 0;
1657
+ }
1658
+ @media (max-width: 768px) {
1659
+ .SearchContainer {
1660
+ margin: auto 3% auto 0%;
1661
+ }
1662
+ }
1663
+ // push content lower when on mobile and search is active
1664
+ .SearchBarPlaceholder {
1665
+ display: block;
1666
+ width: 100%;
1667
+ height: 46px;
1668
+ }
1669
+ // push content lower when on mobile and search is active
1670
+ .SearchBarPlaceholder {
1671
+ display: block;
1672
+ width: 100%;
1673
+ height: 46px;
1674
+ }
1675
+
1676
+ .ClearSearchButton, .ClearSearchButtonMobile {
1677
+ cursor: pointer;
1678
+ position: absolute;
1679
+ right: 14px;
1680
+ top: 11px;
1681
+ .CloseIconContainer {
1682
+ width: 25px;
1683
+ height: 25px;
1684
+ }
1685
+
1686
+ .CloseIconWrapper {
1687
+ height: 25px;
1688
+ width: 3px;
1689
+ margin-left: 12px;
1690
+ background-color:var(--emfe-w-color-white, #FFFFFF);
1691
+ transform: rotate(45deg);
1692
+ Z-index: 1;
1693
+ }
1694
+
1695
+ .CloseIcon {
1696
+ height: 25px;
1697
+ width: 3px;
1698
+ background-color:var(--emfe-w-color-white, #FFFFFF);
1699
+ transform: rotate(90deg);
1700
+ Z-index: 2;
1701
+ }
1702
+ }
1703
+ .SearchContainer {
1704
+ .CloseIconWrapper, .CloseIcon {
1705
+ background-color: var(--emfe-w-color-secondary, #FD2839);
1706
+ }
1707
+ }
1708
+ .ClearSearchButtonMobile {
1709
+ display: none;
1710
+ }
1711
+ .CategoriesHeaderSearchActive {
1712
+ .ClearSearchButtonMobile {
1713
+ display: block;
1714
+ .CloseIconWrapper, .CloseIcon {
1715
+ background-color: var(--emfe-w-color-secondary, #FD2839);
1716
+ }
1717
+ }
1718
+ }
1719
+
1720
+ </style>