@mixd-id/web-scaffold 0.1.230406214 → 0.1.230406216

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,7 +1,7 @@
1
1
  {
2
2
  "name": "@mixd-id/web-scaffold",
3
3
  "private": false,
4
- "version": "0.1.230406214",
4
+ "version": "0.1.230406216",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -1,12 +1,17 @@
1
1
  <template>
2
2
  <div :class="$style.comp" :style="computedStyle">
3
- <div id="player" :class="videoClass" class="relative" @click="loadVideo">
4
- <Image :src="thumbnailUrl" :class="videoClass" />
5
- <div class="absolute top-0 left-0 right-0 bottom-0 flex items-center justify-center">
6
- <div class="bg-primary-500 cursor-pointer hover:bg-primary-600 p-3 px-4 rounded-lg">
7
- <svg class="w-[16px] h-[16px] fill-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z"/></svg>
8
- </div>
9
- </div>
3
+ <div :class="videoClass" class="absolute top-0 left-0 right-0 bottom-0 z-10"
4
+ :style="{ opacity:ready ? 1 : 0 }">
5
+ <div id="player"></div>
6
+ </div>
7
+ <div :class="videoClass" class="relative flex items-center justify-center"
8
+ :style="thumbnailStyle">
9
+ <button class="w-[68px] h-[48px]" aria-label="Play" title="Play">
10
+ <svg height="100%" version="1.1" viewBox="0 0 68 48" width="100%">
11
+ <path class="ytp-large-play-button-bg" d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z" fill="#333"></path>
12
+ <path d="M 45,24 27,14 27,34" fill="#fff"></path>
13
+ </svg>
14
+ </button>
10
15
  </div>
11
16
  </div>
12
17
  </template>
@@ -15,34 +20,38 @@
15
20
 
16
21
  import { componentMixin } from '../mixin/component'
17
22
 
18
-
19
23
  export default{
20
24
 
21
- inject: [ 'alert' ],
22
-
23
25
  mixins: [ componentMixin ],
24
26
 
25
27
  props: {
26
28
 
27
- videoId: String
29
+ videoId: String,
30
+
31
+ delay: {
32
+ type: Number,
33
+ default: 0
34
+ },
28
35
 
29
36
  },
30
37
 
31
38
  computed: {
32
39
 
33
40
  videoUrl(){
34
- return `https://www.youtube.com/embed/${this.videoId}?autoplay=1`
41
+ return `https://www.youtube.com/embed/${this.videoId}`
35
42
  },
36
43
 
37
- thumbnailUrl(){
38
- return `https://img.youtube.com/vi/${this.videoId}/0.jpg`
44
+ thumbnailStyle(){
45
+ return {
46
+ 'background-image': `url('https://img.youtube.com/vi/${this.videoId}/0.jpg')`,
47
+ 'background-size': 'cover',
48
+ 'background-position': 'center center',
49
+ }
39
50
  },
40
51
 
41
52
  videoClass(){
42
53
  return [
43
54
  this.$style.video,
44
- /*this.width[0] ? `w-${this.width[0]}` : undefined,
45
- this.width[1] ? `md:w-${this.width[1]}` : undefined,*/
46
55
  ]
47
56
  .filter(_ => _)
48
57
  .join(' ')
@@ -50,6 +59,34 @@ export default{
50
59
 
51
60
  },
52
61
 
62
+ data(){
63
+ return {
64
+ ready: false,
65
+ player: null
66
+ }
67
+ },
68
+
69
+ mounted() {
70
+ window.onYouTubeIframeAPIReady = () => {
71
+ this.loadVideo()
72
+ }
73
+
74
+ if(parseInt(this.delay) > 0){
75
+ window.setTimeout(() => {
76
+ if(!this.ready){
77
+ this.loadVideo()
78
+ }
79
+ }, parseInt(this.delay))
80
+ }
81
+ else{
82
+ this.$observe.once(this.$el, () => {
83
+ if(!this.ready){
84
+ this.loadVideo()
85
+ }
86
+ })
87
+ }
88
+ },
89
+
53
90
  methods: {
54
91
 
55
92
  loadVideo(){
@@ -60,43 +97,37 @@ export default{
60
97
  document.head.appendChild(script)
61
98
  }
62
99
  else{
63
-
64
100
  if(!this.player){
65
101
  this.player = new YT.Player('player', {
102
+ height: '100%',
103
+ width: '100%',
66
104
  videoId: this.videoId,
67
105
  playerVars: {
68
106
  autoplay: 1,
69
- controls: 0,
70
- rel: 0,
107
+ controls: 1,
71
108
  },
72
109
  events: {
73
- onReady: () => console.log('onReady'),
74
- onStateChange: () => console.log('onStateChange'),
75
- onAutoplayBlocked: () => this.alert('onAutoplayBlocked'),
110
+ onReady: () => {
111
+ window.setTimeout(() => this.ready = true, 500)
112
+ }
76
113
  }
77
- });
114
+ })
78
115
  }
79
116
  else{
80
117
  this.player.loadVideoById(this.videoId)
81
118
  }
82
119
  }
120
+
83
121
  }
84
122
 
85
123
  },
86
124
 
87
- mounted() {
88
- this.id = this.uniqid()
89
- window.onYouTubeIframeAPIReady = () => {
125
+ watch: {
126
+
127
+ videoId(){
90
128
  this.loadVideo()
91
129
  }
92
- },
93
130
 
94
- data(){
95
- return {
96
- id: null,
97
- player: null,
98
- start: false
99
- }
100
131
  }
101
132
 
102
133
  }
@@ -106,7 +137,8 @@ export default{
106
137
  <style module>
107
138
 
108
139
  .comp{
109
- @apply flex flex-col;
140
+ @apply relative;
141
+ aspect-ratio: 16 / 9;
110
142
  }
111
143
 
112
144
  .video{
@@ -41,7 +41,7 @@
41
41
  </div>
42
42
 
43
43
  </div>
44
- <div :class="$style.comp" class="" v-else-if="state === 2">
44
+ <div :class="$style.comp" class="flex items-center justify-center" v-else-if="state === 2" :style="compStyle">
45
45
  <div class="flex flex-col items-center gap-4">
46
46
  <svg width="84" height="84" class="fill-green-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z"/></svg>
47
47
  <h2>{{ completedTitle }}</h2>
@@ -117,7 +117,15 @@ export default{
117
117
  },
118
118
  params: this.form
119
119
  })
120
- .then(_ => this.state = 2)
120
+ .then(_ => {
121
+ this.state = 2
122
+ const redirect = (this.onSubmit ?? []).find(_ => _.type === 'redirect')
123
+ if(redirect){
124
+ window.setTimeout(() => {
125
+ window.location = redirect.target
126
+ }, redirect.delay ?? 1)
127
+ }
128
+ })
121
129
  .catch(err => this.alert(err))
122
130
  .finally(_ => this.$refs.submitBtn ? this.$refs.submitBtn.resetState(2) : null)
123
131
  },
@@ -141,7 +149,13 @@ export default{
141
149
  this.fields.every(field => !field.required || this.form[field.type]) &&
142
150
  Object.values(this.form).join('').length > 0 &&
143
151
  !this.completed
144
- }
152
+ },
153
+
154
+ compStyle(){
155
+ return {
156
+ 'min-height': this.minHeight
157
+ }
158
+ }
145
159
 
146
160
  },
147
161
 
@@ -150,6 +164,7 @@ export default{
150
164
  form: {},
151
165
  completed: false,
152
166
  state: 1,
167
+ minHeight: undefined,
153
168
  }
154
169
  },
155
170
 
@@ -157,6 +172,10 @@ export default{
157
172
  if('ref' in this.$route.query){
158
173
  this.form['referralCode'] = this.$route.query.ref
159
174
  }
175
+
176
+ window.setTimeout(() => {
177
+ this.minHeight = this.$el.clientHeight + 'px'
178
+ }, 1000)
160
179
  }
161
180
 
162
181
  }
@@ -57,7 +57,7 @@
57
57
  <label class="text-text-400 leading-1">Send whatsapp to</label>
58
58
  <div class="flex flex-row gap-2">
59
59
  <Textbox class="flex-1" v-model="action.number" type="tel"/>
60
- <Button type="button" class="text-primary px-3"
60
+ <Button type="button" class="px-3"
61
61
  :state="!action.number ? -1 : 1"
62
62
  @click="delete action._edit;$emit('change')">OK</Button>
63
63
  </div>
@@ -88,6 +88,45 @@
88
88
  </button>
89
89
  </div>
90
90
  </div>
91
+
92
+ <div v-else-if="action.type === 'redirect'">
93
+ <div v-if="action._edit" class="flex flex-row items-start gap-2 p-3 bg-base-500 rounded-lg">
94
+ <div class="flex-1 flex flex-col gap-2">
95
+ <div>
96
+ <label class="text-text-400 leading-1">Redirect to</label>
97
+ <div class="flex flex-row gap-2">
98
+ <Textbox class="flex-1" v-model="action.target"/>
99
+ <Button type="button" class="px-3"
100
+ :state="!action.target ? -1 : 1"
101
+ @click="delete action._edit;$emit('change')">OK</Button>
102
+ </div>
103
+ </div>
104
+ <div>
105
+ <label class="text-text-400 leading-1">Delay</label>
106
+ <Dropdown class="flex-1 w-[100px]" v-model="action.delay">
107
+ <option value="0">No delay</option>
108
+ <option value="1000">1s</option>
109
+ <option value="2000">2s</option>
110
+ <option value="3000">3s</option>
111
+ <option value="4000">4s</option>
112
+ <option value="5000">5s</option>
113
+ </Dropdown>
114
+ </div>
115
+ </div>
116
+ </div>
117
+ <div v-else class="flex flex-row items-center gap-2 p-3 bg-base-500 rounded-lg">
118
+ <div class="flex-1 flex flex-row gap-2 items-center">
119
+ <svg width="14" height="14" class="fill-text" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM474.67,0H316a28,28,0,0,0-28,28V46.71A28,28,0,0,0,316.79,73.9L384,72,135.06,319.09l-.06.06a24,24,0,0,0,0,33.94l23.94,23.85.06.06a24,24,0,0,0,33.91-.09L440,128l-1.88,67.22V196a28,28,0,0,0,28,28H484a28,28,0,0,0,28-28V37.33h0A37.33,37.33,0,0,0,474.67,0Z"/></svg>
120
+ <div class="flex-1 line-clamp-1">{{ action.target }}</div>
121
+ </div>
122
+ <button type="button" @click="action._edit = true">
123
+ <svg width="13" height="13" class="fill-text-300 hover:fill-primary-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z"/></svg>
124
+ </button>
125
+ <button type="button" @click="confirm($t('Remove this action?'), '', () => { item.props.onSubmit.splice(index, 1); $emit('change') })">
126
+ <svg width="16" height="16" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"/></svg>
127
+ </button>
128
+ </div>
129
+ </div>
91
130
  </template>
92
131
  </ListItem>
93
132
  </div>
@@ -142,11 +181,13 @@
142
181
  </ContextMenu>
143
182
 
144
183
  <ContextMenu ref="actionOpt" position="bottom-right">
145
- <div class="flex flex-col gap-1 min-w-[120px]">
184
+ <div class="flex flex-col gap-1 p-1 min-w-[120px]">
146
185
  <button class="p-3 bg-base-500 text-left pl-8 hover:bg-text-50"
147
186
  @click="item.props.onSubmit.push({ type:'send-whatsapp', _edit:true })">Send Whatsapp</button>
148
187
  <button class="p-3 bg-base-500 text-left pl-8 hover:bg-text-50" v-if="item.props.fields.includes('referralCode')"
149
188
  @click="item.props.onSubmit.push({ type:'send-whatsapp-referral' });$emit('change')">Send Whatsapp to Referral</button>
189
+ <button class="p-3 bg-base-500 text-left pl-8 hover:bg-text-50"
190
+ @click="item.props.onSubmit.push({ type:'redirect', delay:'0', _edit:true })">Redirect</button>
150
191
  </div>
151
192
  </ContextMenu>
152
193
 
@@ -1627,7 +1627,7 @@ export default{
1627
1627
 
1628
1628
  { type:'Countdown', name:'Countdown', group:'Components', props:{}},
1629
1629
 
1630
- { type:'YoutubeVideo', name:'YoutubeVideo', group:'Components', props:{}},
1630
+ { type:'YoutubeVideo', name:'Youtube Video', group:'Components', props:{ name:"Youtube Video", delay:"0" }},
1631
1631
 
1632
1632
  { type:'Test', name:'Test', group:'Components', props:{}},
1633
1633
 
@@ -1,11 +1,28 @@
1
1
  <template>
2
2
  <div :class="$style.comp">
3
3
 
4
- <div>
5
- <label class="text-text-400">Video ID</label>
6
- <Textbox v-model="item.props.videoId"
7
- @keyup.enter="$emit('change')" />
8
- </div>
4
+ <div class="flex flex-col gap-6">
5
+
6
+ <div>
7
+ <label class="text-text-400">Video ID</label>
8
+ <Textbox v-model="item.props.videoId" class="mt-1"
9
+ @keyup.enter="$emit('change')" />
10
+ </div>
11
+
12
+ <div>
13
+ <label class="text-text-400">Load Delay</label>
14
+ <Dropdown v-model="item.props.delay" class="mt-1"
15
+ @keyup.enter="$emit('change')">
16
+ <option value="1000">1s</option>
17
+ <option value="2000">2s</option>
18
+ <option value="3000">3s</option>
19
+ <option value="4000">4s</option>
20
+ <option value="5000">5s</option>
21
+ <option value="0">On visible</option>
22
+ </Dropdown>
23
+ </div>
24
+
25
+ </div>
9
26
 
10
27
  <ComponentSetting :item="item"
11
28
  :view-type="viewType"
@@ -42,7 +59,7 @@ export default{
42
59
  <style module>
43
60
 
44
61
  .comp{
45
- @apply flex flex-col gap-4;
62
+ @apply flex flex-col gap-8;
46
63
  }
47
64
 
48
65
  </style>