@everymatrix/lottery-program-wof 1.20.8 → 1.20.10

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@everymatrix/lottery-program-wof",
3
- "version": "1.20.8",
3
+ "version": "1.20.10",
4
4
  "main": "dist/lottery-program-wof.js",
5
5
  "svelte": "src/index.ts",
6
6
  "scripts": {
@@ -39,5 +39,5 @@
39
39
  "publishConfig": {
40
40
  "access": "public"
41
41
  },
42
- "gitHead": "4a16a48b4b373f277887e6630034f139df224ee0"
42
+ "gitHead": "90ba6c4378f429df47a59fecc6bc15675ebcfbf9"
43
43
  }
package/src/api/api.ts CHANGED
@@ -218,6 +218,8 @@ export interface ILotteryProgramRecurrence {
218
218
  * @memberof ILotteryProgramRecurrence
219
219
  */
220
220
  activeTickets?: number;
221
+
222
+ remainingTimes?: number;
221
223
  }
222
224
  /**
223
225
  *
@@ -285,6 +287,9 @@ export interface LotteryProgram {
285
287
  * @memberof LotteryProgram
286
288
  */
287
289
  time?: Date;
290
+ metadata?: {
291
+ [key: string]: string
292
+ }
288
293
  }
289
294
  /**
290
295
  *
@@ -0,0 +1,80 @@
1
+ import type { WheelOfFortunePartition } from './api'
2
+
3
+ // @ts-ignore
4
+ import Thankyou1Svg from './images/Thankyou_1.svg'
5
+ // @ts-ignore
6
+ import Thankyou2Svg from './images/Thankyou_2.svg'
7
+ // @ts-ignore
8
+ import Thankyou3Svg from './images/Thankyou_3.svg'
9
+ // @ts-ignore
10
+ import Thankyou4Svg from './images/Thankyou_4.svg'
11
+ import type { Lang } from './types'
12
+ import type { LotteryProgramForPlayer } from './types.business'
13
+ import { imageLoaderSvg } from './util'
14
+
15
+ export interface Option {
16
+ image: SVGElement | string,
17
+ name: string,
18
+ prizeText: string,
19
+ prizeImage: string
20
+ }
21
+
22
+ const optionCompliment = {
23
+ image: Thankyou1Svg,
24
+ name: 'Thank you',
25
+ prizeText: '',
26
+ prizeImage: '',
27
+ }
28
+
29
+ const getSumProbability = (partitions) => {
30
+ let probabilityAll = 0
31
+ partitions.map(partition => {
32
+ probabilityAll += Number(partition.probability)
33
+ })
34
+ return probabilityAll
35
+ }
36
+
37
+ const getOptionsFromPartitions = (partitions: WheelOfFortunePartition[], lang: Lang): Option[] => {
38
+ const options = partitions.map(_partition => {
39
+ const option = {}
40
+ Object.keys(_partition).map((_key) => {
41
+ if(
42
+ typeof _partition[_key] === 'object' &&
43
+ (_partition[_key] as Object).hasOwnProperty('*')
44
+ ){
45
+ const targetKey = _key === 'image1' ? 'image' : _key
46
+ option[targetKey] = _partition[_key][lang] || _partition[_key]['*']
47
+ }
48
+ })
49
+
50
+ return option as Option
51
+ })
52
+
53
+ if(getSumProbability(partitions) < 1){
54
+ options.push(optionCompliment)
55
+ }
56
+
57
+ return options
58
+ }
59
+
60
+ const preloadImage = async (src: string) => {
61
+ if(!src) return {}
62
+
63
+ return {
64
+ image: await imageLoaderSvg(src) as SVGImageElement
65
+ }
66
+ }
67
+
68
+ export const getOptions = async (bonus: LotteryProgramForPlayer, lang: Lang) => {
69
+
70
+ const { partitions } = bonus.program.wheelOfFortune
71
+
72
+ const options: Option[] = await Promise.all(
73
+ getOptionsFromPartitions(partitions, lang).map(async o => ({
74
+ ...o,
75
+ ...(await preloadImage(o.image as string))
76
+ }))
77
+ )
78
+
79
+ return options
80
+ }
package/src/business.ts CHANGED
@@ -1,30 +1,15 @@
1
- import type { WheelOfFortunePartition } from './api';
2
1
  import { findDeg } from './calc';
3
- import { getStatePropsForSpin } from './css.state';
4
2
  import { _postMessage } from './message';
5
- import { Api, ApiConfigs, Lang, PointerMode } from './types';
6
- import type { LotteryProgramForPlayer } from './types.business';
3
+ import { Api, ApiConfigs, PointerMode } from './types';
4
+ import type { LotteryProgramForPlayer, ApiDrawResult, ApiLotteriesResult } from './types.business';
7
5
  import { CurrentInfo } from './types.business';
8
- import { delay, fetcher, imageLoaderSvg, setProps } from './util';
6
+ import { fetcher } from './util';
9
7
  import { _ } from './i18n';
10
8
 
11
- // @ts-ignore
12
- import Thankyou1Svg from './images/Thankyou_1.svg'
13
- // @ts-ignore
14
- import Thankyou2Svg from './images/Thankyou_2.svg'
15
- // @ts-ignore
16
- import Thankyou3Svg from './images/Thankyou_3.svg'
17
- // @ts-ignore
18
- import Thankyou4Svg from './images/Thankyou_4.svg'
9
+ export * from './business.partition'
10
+ import type { Option } from './business.partition'
19
11
 
20
- export interface Option {
21
- image: SVGElement | string,
22
- name: string,
23
- prizeText: string,
24
- prizeImage: string
25
- }
26
-
27
- const fetcherApi = async <T extends Api>(api: T, endpoint: string, config: ApiConfigs[T]) => {
12
+ const fetcherApi = async <T extends Api>(api: Api, endpoint: string, config: ApiConfigs[T]) => {
28
13
 
29
14
  const { session } = config
30
15
 
@@ -86,44 +71,6 @@ const fetcherApi = async <T extends Api>(api: T, endpoint: string, config: ApiCo
86
71
  return await fetcher(args)
87
72
  }
88
73
 
89
- export const getSumProbability = (partitions) => {
90
- let probabilityAll = 0
91
- partitions.map(partition => {
92
- probabilityAll += Number(partition.probability)
93
- })
94
- return probabilityAll
95
- }
96
-
97
- export const getOptionsFromPartitions = (partitions: WheelOfFortunePartition[], lang: Lang): Option[] => {
98
- let options = partitions.map((_partition, index) => {
99
- const partitionLang = {}
100
- Object.keys(_partition).map((_key) => {
101
- if(['name', 'image1', 'image2', 'image3', 'prizeText', 'prizeImage'].includes(_key)){
102
- partitionLang[_key] = _partition[_key][lang] || _partition[_key]['*']
103
- }
104
- })
105
-
106
- const option: Option = {
107
- image: partitionLang['image1'],
108
- name: partitionLang['name'],
109
- prizeText: partitionLang['prizeText'],
110
- prizeImage: partitionLang['prizeImage'],
111
- }
112
- return option
113
- })
114
-
115
- if(getSumProbability(partitions) < 1){
116
- options.push({
117
- image: Thankyou1Svg,
118
- name: 'Thank you',
119
- prizeText: '',
120
- prizeImage: '',
121
- })
122
- }
123
-
124
- return options
125
- }
126
-
127
74
  export const setMessage = (id: string, entry: string | object) => {
128
75
  const _postMessageScoped = (props) => _postMessage({ ...props, id })
129
76
  switch(typeof entry) {
@@ -136,28 +83,6 @@ export const setMessage = (id: string, entry: string | object) => {
136
83
  }
137
84
  }
138
85
 
139
- export const getOptions = async (bonus: LotteryProgramForPlayer, lang: Lang) => {
140
-
141
- const { partitions } = bonus.program.wheelOfFortune
142
-
143
- const preloadImage = async (src: string) => {
144
- if(!src) return {}
145
-
146
- return {
147
- image: await imageLoaderSvg(src) as SVGImageElement
148
- }
149
- }
150
-
151
- const options: Option[] = await Promise.all(
152
- getOptionsFromPartitions(partitions, lang).map(async o => ({
153
- ...o,
154
- ...(await preloadImage(o.image as string))
155
- }))
156
- )
157
-
158
- return options
159
- }
160
-
161
86
  export const getCurrentInfo = (
162
87
  lotteryProgramForPlayer: LotteryProgramForPlayer,
163
88
  key: CurrentInfo
@@ -186,7 +111,7 @@ export const api = {
186
111
  lotteries:
187
112
  async (endpoint: string, session: string) => {
188
113
 
189
- const data = await fetcherApi(Api.lotteries, endpoint, { session })
114
+ const data = await fetcherApi(Api.lotteries, endpoint, { session }) as ApiLotteriesResult
190
115
 
191
116
  const lotteryProgramForPlayers = data.items as LotteryProgramForPlayer[] || []
192
117
 
@@ -195,7 +120,7 @@ export const api = {
195
120
  draw:
196
121
  async (endpoint: string, session: string, id: string, guid, options: Option[]) => {
197
122
 
198
- let data = await fetcherApi(Api.draw, endpoint, { id, session, guid })
123
+ let data = await fetcherApi(Api.draw, endpoint, { id, session, guid }) as ApiDrawResult
199
124
 
200
125
  // data = getExceptionData(data)
201
126
 
@@ -203,26 +128,25 @@ export const api = {
203
128
 
204
129
  let message: any
205
130
 
131
+ const option = options[index]
132
+ const imageSrc = (option.image as SVGAElement)?.href?.baseVal
133
+
206
134
  if(!index){
207
135
  index = options.length - 1
208
136
  message = {
209
137
  mode: 'nogift',
210
138
  modeValue: {
211
- image: options[index].image?.href?.baseVal
139
+ image: imageSrc
212
140
  }
213
141
  }
214
142
  }else{
215
- const modeValue = {
216
- index,
217
- prizeText: options[index].prizeText,
218
- prizeImage: options[index].prizeImage,
219
- name: options[index].name,
220
- image: options[index].prizeImage || options[index].image?.href?.baseVal
221
- }
222
-
223
143
  message = {
224
144
  mode: 'gift',
225
- modeValue
145
+ modeValue: {
146
+ prize: option.name || 'prize',
147
+ prizeText: option.prizeText,
148
+ prizeSrc: option.prizeImage || imageSrc
149
+ }
226
150
  }
227
151
  }
228
152
 
@@ -238,38 +162,6 @@ export const api = {
238
162
  },
239
163
  }
240
164
 
241
- // export const getMessageByCurrent = (current) => {
242
-
243
- // const { maxImplicitTickets, usedImplicitTickets, activeTickets } = current
244
-
245
- // const conditionImplicitTickets = usedImplicitTickets < maxImplicitTickets
246
- // const conditionActiveTickets = activeTickets > 0
247
-
248
- // if(conditionImplicitTickets){
249
- // const implicitTickets = `${maxImplicitTickets - usedImplicitTickets}/${maxImplicitTickets}`
250
- // return `You have ${implicitTickets} Implicit Tickets`
251
- // }
252
-
253
- // if(conditionActiveTickets){
254
- // return `You used all Implicit Tickets in this period, but you have ${activeTickets} active Tickets`
255
- // }
256
-
257
- // return `You not have any more tickets, please check T&C to get a chance.`
258
- // }
259
-
260
- export const checkIfNowIsBetween = (current) => {
261
-
262
- const { startTime, endTime } = current
263
-
264
- const getTime = (timeString: string) => (new Date(timeString)).getTime()
265
- const nowTime = (new Date()).getTime()
266
-
267
- const condition =
268
- getTime(startTime) < nowTime && nowTime < getTime(endTime)
269
-
270
- return condition
271
- }
272
-
273
165
  export const getSpinContainerSelector = (pointerMode: PointerMode) => {
274
166
  switch(pointerMode){
275
167
  case PointerMode.Arrow: return 'g.PartitionsContainer'
@@ -284,29 +176,4 @@ export const findDegWithPointerMode = (index: number, length: number, pointerMod
284
176
  case PointerMode.Partition:
285
177
  return findDeg(index, length)
286
178
  }
287
- }
288
-
289
- export const spin = async (container: Element, deg: number, rotation: string, duration: string) => {
290
-
291
- const _duration = Number(duration)
292
- const _rotation = Number(rotation)
293
-
294
- const props = getStatePropsForSpin(deg, _rotation, _duration)
295
-
296
- setProps(container, props.before)
297
-
298
- await delay(_duration)
299
-
300
- setProps(container, props.after)
301
- }
302
-
303
- export const getSpinCondition = (lotteryProgramForPlayer: LotteryProgramForPlayer) => {
304
- const { current } = lotteryProgramForPlayer
305
- if(!current) return false;
306
-
307
- const condition =
308
- current.activeTickets === 0 &&
309
- current.usedImplicitTickets === current.maxImplicitTickets
310
-
311
- return condition
312
179
  }
@@ -51,8 +51,7 @@ export class Process {
51
51
  if(frequency < 4){
52
52
  this.drawer(guid, frequency + 1)
53
53
  }else{
54
- const messageError = 'There was a problem to grant the reward. Please contact support'
55
- this.handleHaltProcess(index, messageError)
54
+ this.handleHaltProcess(index, 'DrawFailed')
56
55
  }
57
56
  }
58
57
  }
@@ -42,6 +42,7 @@
42
42
 
43
43
  let bonus: LotteryProgramForPlayer
44
44
  let bonusNew: LotteryProgramForPlayer
45
+ let currentInfoKeys: CurrentInfo[]
45
46
 
46
47
  // lifecycles
47
48
  const init = async () => {
@@ -57,11 +58,15 @@
57
58
 
58
59
  onMountMessageLifeCycle({
59
60
  'wof-private-bonuses': (data) => {
60
- bonus = data.bonuses.find(l => l.program.id === id)
61
+ const bonusFound = data.bonuses.find(l => l.program.id === id)
62
+ if(bonusFound){
63
+ bonus = bonusFound
64
+ }
61
65
  },
62
66
  'wof-private-message-spin-after': (data) => {
63
67
  if(data.id !== id) return;
64
68
  bonus = bonusNew
69
+ _postMessage({type: 'wof-private-bonus', bonus: bonusNew, id })
65
70
  },
66
71
 
67
72
  'wof-private-message-spin-before': async (data) => {
@@ -75,6 +80,8 @@
75
80
  $: ratio = size / 375
76
81
  $: radius = 247 / 2 * ratio
77
82
 
83
+ // @ts-ignore
84
+ $: currentInfoKeys = currentinfo ? currentinfo.split(',') : [CurrentInfo.RemainingTimes]
78
85
  </script>
79
86
 
80
87
  <div class="LotteryItem" bind:this={rootContainer}>
@@ -94,7 +101,7 @@
94
101
 
95
102
  {#if bonus?.current}
96
103
  <div class="Current">
97
- {#each currentinfo ? currentinfo.split(',') : [CurrentInfo.RemainingTimes] as CurrentInfoKey}
104
+ {#each currentInfoKeys as CurrentInfoKey}
98
105
  <p class={CurrentInfoKey}>
99
106
  {$_(`wof.${CurrentInfoKey}`)}: {getCurrentInfo(bonus, CurrentInfoKey)}
100
107
  </p>
@@ -4,7 +4,7 @@
4
4
 
5
5
  // types
6
6
  import { PointerMode, Lang, ContentDirection } from './types';
7
- import { getOptions, getSpinCondition, getSpinContainerSelector, Option } from './business';
7
+ import { getOptions, getSpinContainerSelector, Option } from './business';
8
8
  import { api } from './business';
9
9
  import { onMountMessageLifeCycle, _postMessage } from './message';
10
10
  import type { LotteryProgramForPlayer } from './types.business';
@@ -55,6 +55,7 @@
55
55
 
56
56
  // states
57
57
  let spinable = true;
58
+ let isSpinning = false;
58
59
  let isShowPrizeArea = false;
59
60
  let messageShown: boolean = false;
60
61
  let shownFirstCheck = false
@@ -72,7 +73,7 @@
72
73
  $: options && updateCalcOptions()
73
74
  $: (contentdirection || !contentdirection) && updateCalcContentDirection()
74
75
 
75
- $: bonus && checkSpinable()
76
+ $: bonus && runFirstCheck()
76
77
 
77
78
  const updateCalcOptions = () => {
78
79
  calc.options = options
@@ -93,20 +94,27 @@
93
94
  }
94
95
  }
95
96
 
96
- const checkSpinable = () => {
97
+ const runFirstCheck = () => {
97
98
  if(shownFirstCheck) return;
98
99
  shownFirstCheck = true
99
-
100
- if(spinable){
100
+ updateSpinable()
101
+ }
101
102
 
102
- const isNoTimeToSpin = getSpinCondition(bonus)
103
+ const updateSpinable = () => {
104
+ const isSpinable = !!bonus.current && bonus.current.remainingTimes > 0
103
105
 
104
- if(isNoTimeToSpin){
106
+ if(isSpinable){
107
+ spinable = true
108
+ }else{
109
+ spinable = false;
110
+
111
+ if(bonus.next){
105
112
  process.setMessage({
106
- mode: 'spin-failed'
113
+ mode: 'show-next',
114
+ modeValue: bonus.next
107
115
  })
108
- }else if(!isNoTimeToSpin && !bonus.next){
109
- process.setMessage($_('wof.NoNext'))
116
+ }else{
117
+ process.setMessage('NoNext')
110
118
  }
111
119
  }
112
120
  }
@@ -121,21 +129,11 @@
121
129
 
122
130
  // events
123
131
  const eventSpin = async () => {
132
+ updateSpinable();
124
133
  if(!spinable) return;
134
+ if(isSpinning) return;
125
135
 
126
- if(!bonus.current?.remainingTimes){
127
- if(bonus.next){
128
- process.setMessage({
129
- mode: 'show-next',
130
- modeValue: bonus.next
131
- })
132
- }else{
133
- process.setMessage($_('wof.NoNext'))
134
- }
135
- return;
136
- }
137
-
138
- spinable = false
136
+ isSpinning = true
139
137
  isShowPrizeArea = false
140
138
 
141
139
  spinContainer = svg.querySelector(getSpinContainerSelector(theme.pointerMode))
@@ -147,10 +145,15 @@
147
145
  'wof-private-bonuses': (data) => {
148
146
  bonus = data.bonuses.find(_bonus => _bonus.program.id === id)
149
147
  },
148
+ 'wof-private-bonus': (data) => {
149
+ if(data.id !== id) return;
150
+ bonus = data.bonus
151
+ },
150
152
  'wof-private-message-close': (data) => {
151
153
  if(data.id !== id) return;
152
154
 
153
- spinable = true
155
+ isSpinning = false
156
+ setTimeout(() => updateSpinable(), 1)
154
157
  messageShown = false
155
158
  },
156
159
  })
@@ -274,7 +277,7 @@
274
277
 
275
278
  <g
276
279
  class="Center"
277
- class:disabled={!spinable}
280
+ class:disabled={isSpinning}
278
281
  on:click={() => eventSpin()}
279
282
  >
280
283
  {#each calc.getThemedCenterImages() as themedImage}
@@ -67,8 +67,7 @@
67
67
 
68
68
  $: startTime = modeValue?.startTime && getTimeString(modeValue?.startTime)
69
69
 
70
- $: prize = modeValue?.name || 'prize'
71
- $: prizeSrc = modeValue?.prizeImage || giftimagesrc || modeValue?.image || giftSvg
70
+ $: prizeSrc = modeValue?.prizeSrc || giftimagesrc || giftSvg
72
71
 
73
72
  </script>
74
73
 
@@ -87,11 +86,7 @@
87
86
  >
88
87
 
89
88
  {#if mode === 'normal' || mode === 'init-failed'}
90
- <p>{modeValue}</p>
91
- {/if}
92
-
93
- {#if mode === 'spin-failed'}
94
- <p>{$_('wof.SpinFailed')}</p>
89
+ <p>{$_(`wof.${modeValue}`)}</p>
95
90
  {/if}
96
91
 
97
92
  {#if mode === 'show-next'}
@@ -105,7 +100,7 @@
105
100
  {#if modeValue.prizeText}
106
101
  {modeValue.prizeText}
107
102
  {:else}
108
- {@html $_('wof.Congratulation', {values: { prize }})}
103
+ {@html $_('wof.Congratulation', {values: { prize: modeValue.prize }})}
109
104
  {/if}
110
105
  <p>
111
106
 
@@ -10,7 +10,8 @@ export const translations = {
10
10
  ImplicitTickets: `Implicit Tickets`,
11
11
  RemainingTimes: `Remaining Times`,
12
12
  ShowNext: `The Wheel will be available on <strong>{startTime}</strong>. please wait till it is open.`,
13
- SpinFaild: `We are sorry that you don't have any Wheels available, please <strong>check T&C</strong> here to get a chance!`,
13
+ SpinFailed: `We are sorry that you don't have any Wheels available, please <strong>check T&C</strong> here to get a chance!`,
14
+ DrawFailed: 'There was a problem to grant the reward. Please contact support',
14
15
  Congratulation: `Congratulations! You won a {prize}!`,
15
16
  OK: `OK`,
16
17
  Rewards: `Rewards`,
@@ -49,4 +50,4 @@ export const translations = {
49
50
 
50
51
  }
51
52
  }
52
- };
53
+ };
@@ -1,4 +1,8 @@
1
- import type { LotteryProgramILotteryProgramForPlayer } from "./api";
1
+ import type {
2
+ LotteryProgramDraw,
3
+ LotteryProgramILotteryProgramForPlayer,
4
+ LotteryProgramIQueryLotteryProgramForPlayerResult
5
+ } from "./api";
2
6
 
3
7
 
4
8
  export type LotteryProgramForPlayer = LotteryProgramILotteryProgramForPlayer
@@ -7,4 +11,10 @@ export enum CurrentInfo {
7
11
  ActiveTickets = 'ActiveTickets',
8
12
  ImplicitTickets = 'ImplicitTickets',
9
13
  RemainingTimes = 'RemainingTimes',
14
+ }
15
+
16
+ export type ApiLotteriesResult = LotteryProgramIQueryLotteryProgramForPlayerResult
17
+
18
+ export interface ApiDrawResult {
19
+ item?: LotteryProgramDraw;
10
20
  }
package/src/types.ts CHANGED
@@ -40,6 +40,7 @@ export interface ApiConfigs {
40
40
  [Api.draw]: {
41
41
  session?: string
42
42
  id: string
43
+ guid: string
43
44
  },
44
45
 
45
46
  }
package/src/css.state.ts DELETED
@@ -1,13 +0,0 @@
1
-
2
- export const getStatePropsForSpin = (deg: number, rotation: number, duration: number) => {
3
- return {
4
- before: {
5
- style: `transition-timing-function: ease-in-out; transition-duration: ${duration}s;`,
6
- transform: `rotate(${deg + 360 * rotation})`,
7
- },
8
- after: {
9
- style: '',
10
- transform: `rotate(${deg})`,
11
- }
12
- }
13
- }