hexo-theme-shokax 0.4.25 → 0.5.0-beta1

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.
Files changed (68) hide show
  1. package/README.md +19 -31
  2. package/UsageRestrictions.md +2 -2
  3. package/_config.yml +11 -25
  4. package/_images.yml +0 -7
  5. package/eslint.config.mjs +4 -5
  6. package/layout/_mixin/card.pug +1 -2
  7. package/layout/_mixin/comment.pug +0 -1
  8. package/layout/_mixin/segment.pug +1 -1
  9. package/layout/_partials/footer.pug +1 -4
  10. package/layout/_partials/head/head.pug +0 -8
  11. package/layout/_partials/head/pwa.pug +1 -1
  12. package/layout/_partials/header.pug +0 -1
  13. package/layout/_partials/layout.pug +4 -14
  14. package/layout/_partials/post/footer.pug +0 -2
  15. package/layout/_partials/post/post.pug +1 -2
  16. package/layout/_partials/post/reward.pug +1 -1
  17. package/layout/_partials/sidebar/overview.pug +0 -2
  18. package/layout/_partials/third-party/baidu-analytics.pug +1 -1
  19. package/layout/_partials/third-party/google-analytics.pug +1 -1
  20. package/layout/archive.pug +3 -0
  21. package/layout/category.pug +3 -0
  22. package/layout/index.pug +3 -0
  23. package/layout/page.pug +7 -0
  24. package/layout/post.pug +8 -0
  25. package/layout/tag.pug +3 -0
  26. package/package.json +9 -10
  27. package/scripts/filters/post.js +1 -1
  28. package/scripts/generaters/config.js +12 -7
  29. package/scripts/generaters/images.js +9 -8
  30. package/scripts/generaters/index.js +57 -44
  31. package/scripts/generaters/script.js +18 -33
  32. package/scripts/helpers/engine.js +2 -7
  33. package/scripts/plugin/index.js +32 -69
  34. package/scripts/tags/media.js +1 -1
  35. package/source/css/app.styl +0 -13
  36. package/source/css/page.styl +3 -0
  37. package/source/css/post.styl +5 -0
  38. package/source/css/scaffolding.styl +5 -0
  39. package/source/js/_app/components/comments.ts +2 -3
  40. package/source/js/_app/components/sidebar.ts +35 -35
  41. package/source/js/_app/components/tcomments.ts +0 -1
  42. package/source/js/_app/globals/globalVars.ts +0 -15
  43. package/source/js/_app/globals/handles.ts +9 -9
  44. package/source/js/_app/globals/themeColor.ts +5 -6
  45. package/source/js/_app/globals/thirdparty.ts +2 -2
  46. package/source/js/_app/globals/tools.ts +4 -6
  47. package/source/js/_app/library/anime.ts +30 -19
  48. package/source/js/_app/library/declare.d.ts +0 -5
  49. package/source/js/_app/library/proto.ts +0 -67
  50. package/source/js/_app/library/vue.ts +7 -7
  51. package/source/js/_app/page/common.ts +8 -10
  52. package/source/js/_app/page/fancybox.ts +6 -8
  53. package/source/js/_app/page/post.ts +42 -54
  54. package/source/js/_app/page/search.ts +1 -6
  55. package/source/js/_app/page/tab.ts +8 -9
  56. package/source/js/_app/pjax/domInit.ts +19 -14
  57. package/source/js/_app/pjax/refresh.ts +8 -36
  58. package/source/js/_app/pjax/siteInit.ts +13 -42
  59. package/source/js/_app/player.ts +14 -798
  60. package/toolbox/compiler.mjs +20 -48
  61. package/toolbox/dev-version.mjs +14 -0
  62. package/README_en.MD +0 -71
  63. package/scripts/plugin/lib/injects-point.js +0 -41
  64. package/scripts/plugin/lib/injects.js +0 -105
  65. package/source/js/_app/library/dom.ts +0 -28
  66. package/source/js/_app/library/loadFile.ts +0 -47
  67. package/source/js/_app/library/scriptPjax.ts +0 -56
  68. package/source/js/_app/library/storage.ts +0 -12
@@ -1,798 +1,14 @@
1
- import { CONFIG, originTitle } from './globals/globalVars'
2
- import { showtip } from './globals/tools'
3
- import { pageScroll } from './library/anime'
4
- import { $storage } from './library/storage'
5
- import { tabFormat } from './page/tab'
6
- import { createChild, getLeft, getWidth, setDisplay, setWidth } from './library/proto'
7
-
8
- let NOWPLAYING = null
9
-
10
- const isMobile = /mobile/i.test(window.navigator.userAgent)
11
- export const mediaPlayer = (t, config?) => {
12
- const buttons = {
13
- el: {},
14
- create () {
15
- if (!t.player.options.btns) { return }
16
- t.player.options.btns.forEach((item) => {
17
- if (buttons.el[item]) { return }
18
-
19
- buttons.el[item] = createChild(t, 'div', {
20
- className: item + ' btn',
21
- onclick (event) {
22
- t.player.fetch().then(() => {
23
- t.player.options.events[item](event)
24
- })
25
- }
26
- })
27
- })
28
- }
29
- }
30
- const controller = {
31
- el: null,
32
- btns: {
33
- mode: undefined,
34
- volume: undefined
35
- },
36
- step: 'next',
37
- create: () => {
38
- if (!t.player.options.controls) { return }
39
-
40
- const that = controller
41
- t.player.options.controls.forEach((item) => {
42
- if (that.btns[item]) { return }
43
-
44
- const opt = <HTMLElement> {
45
- onclick (event) {
46
- that.events[item] ? that.events[item](event) : t.player.options.events[item](event)
47
- }
48
- }
49
-
50
- switch (item) {
51
- case 'volume':
52
- opt.className = ' ' + (source.muted ? 'off' : 'on')
53
- opt.innerHTML = '<div class="bar"></div>'
54
- opt['on' + utils.nameMap.dragStart] = that.events.volume
55
- opt.onclick = null
56
- break
57
- case 'mode':
58
- opt.className = ' ' + t.player.options.mode
59
- break
60
- default:
61
- opt.className = ''
62
- break
63
- }
64
-
65
- opt.className = item + opt.className + ' btn'
66
-
67
- that.btns[item] = createChild(that.el, 'div', opt)
68
- })
69
-
70
- that.btns.volume.bar = that.btns.volume.querySelector('.bar')
71
- },
72
- events: {
73
- mode (e) {
74
- switch (t.player.options.mode) {
75
- case 'loop':
76
- t.player.options.mode = 'random'
77
- break
78
- case 'random':
79
- t.player.options.mode = 'order'
80
- break
81
- default:
82
- t.player.options.mode = 'loop'
83
- }
84
-
85
- controller.btns.mode.className = 'mode ' + t.player.options.mode + ' btn'
86
- $storage.set('_PlayerMode', t.player.options.mode)
87
- },
88
- volume (e) {
89
- e.preventDefault()
90
-
91
- const current = e.currentTarget
92
-
93
- let drag = false
94
-
95
- const thumbMove = (e) => {
96
- e.preventDefault()
97
- t.player.volume(controller.percent(e, current))
98
- drag = true
99
- }
100
-
101
- const thumbUp = (e) => {
102
- e.preventDefault()
103
- current.removeEventListener(utils.nameMap.dragEnd, thumbUp)
104
- current.removeEventListener(utils.nameMap.dragMove, thumbMove)
105
- if (drag) {
106
- t.player.muted()
107
- t.player.volume(controller.percent(e, current))
108
- } else {
109
- if (source.muted) {
110
- t.player.muted()
111
- t.player.volume(source.volume)
112
- } else {
113
- t.player.muted('muted')
114
- controller.update(0)
115
- }
116
- }
117
- }
118
-
119
- current.addEventListener(utils.nameMap.dragMove, thumbMove)
120
- current.addEventListener(utils.nameMap.dragEnd, thumbUp)
121
- },
122
- backward (e) {
123
- controller.step = 'prev'
124
- t.player.mode()
125
- },
126
- forward (e) {
127
- controller.step = 'next'
128
- t.player.mode()
129
- }
130
- },
131
- update (percent) {
132
- controller.btns.volume.className = 'volume ' + (!source.muted && percent > 0 ? 'on' : 'off') + ' btn'
133
- setWidth(controller.btns.volume.bar, Math.floor(percent * 100) + '%')
134
- },
135
- percent (e, el) {
136
- let percentage = ((e.clientX || e.changedTouches[0].clientX) - getLeft(el)) / getWidth(el)
137
- percentage = Math.max(percentage, 0)
138
- return Math.min(percentage, 1)
139
- }
140
- }
141
- const progress = {
142
- el: null,
143
- bar: null,
144
- create () {
145
- const current = playlist.current().el
146
-
147
- if (current) {
148
- if (progress.el) {
149
- progress.el.parentNode.removeClass('current')
150
- .removeEventListener(utils.nameMap.dragStart, progress.drag)
151
- progress.el.remove()
152
- }
153
-
154
- progress.el = createChild(current, 'div', {
155
- className: 'progress'
156
- });
157
-
158
- (progress.el as HTMLElement).setAttribute('data-dtime', utils.secondToTime(0))
159
-
160
- progress.bar = createChild(progress.el, 'div', {
161
- className: 'bar'
162
- })
163
-
164
- current.addClass('current')
165
-
166
- current.addEventListener(utils.nameMap.dragStart, progress.drag)
167
-
168
- playlist.scroll()
169
- }
170
- },
171
- update (percent) {
172
- setWidth(progress.bar, Math.floor(percent * 100) + '%');
173
- (progress.el as HTMLElement).setAttribute('data-ptime', utils.secondToTime(percent * source.duration))
174
- },
175
- seeking (type) {
176
- if (type) { progress.el.addClass('seeking') } else { progress.el.removeClass('seeking') }
177
- },
178
- percent (e, el) {
179
- let percentage = ((e.clientX || e.changedTouches[0].clientX) - getLeft(el)) / getWidth(el)
180
- percentage = Math.max(percentage, 0)
181
- return Math.min(percentage, 1)
182
- },
183
- drag (e) {
184
- e.preventDefault()
185
-
186
- const current = playlist.current().el
187
-
188
- const thumbMove = (e) => {
189
- e.preventDefault()
190
- const percentage = progress.percent(e, current)
191
- progress.update(percentage)
192
- lyrics.update(percentage * source.duration)
193
- }
194
-
195
- const thumbUp = (e) => {
196
- e.preventDefault()
197
- current.removeEventListener(utils.nameMap.dragEnd, thumbUp)
198
- current.removeEventListener(utils.nameMap.dragMove, thumbMove)
199
- const percentage = progress.percent(e, current)
200
- progress.update(percentage)
201
- t.player.seek(percentage * source.duration)
202
- source.disableTimeupdate = false
203
- progress.seeking(false)
204
- }
205
-
206
- source.disableTimeupdate = true
207
- progress.seeking(true)
208
- current.addEventListener(utils.nameMap.dragMove, thumbMove)
209
- current.addEventListener(utils.nameMap.dragEnd, thumbUp)
210
- }
211
- }
212
- const preview = {
213
- el: null,
214
- create () {
215
- const current = playlist.current()
216
-
217
- preview.el.innerHTML = '<div class="cover"><div class="disc"><img src="' + (current.cover) + '" class="blur" alt="music cover"/></div></div>' +
218
- '<div class="info"><h4 class="title">' + current.name + '</h4><span>' + current.artist + '</span>' +
219
- '<div class="lrc"></div></div>';
220
-
221
- (preview.el as HTMLElement).querySelector('.cover').addEventListener('click', t.player.options.events['play-pause'])
222
-
223
- lyrics.create((preview.el as HTMLElement).querySelector('.lrc'))
224
- }
225
- }
226
- let source
227
- const playlist = {
228
- el: null,
229
- data: [],
230
- index: -1,
231
- errnum: 0,
232
- add: (group, list) => {
233
- list.forEach((item) => {
234
- item.group = group
235
- item.name = item.name || item.title || 'Meida name'
236
- item.artist = item.artist || item.author || 'Anonymous'
237
- item.cover = item.cover || item.pic
238
- item.type = item.type || 'normal'
239
-
240
- playlist.data.push(item)
241
- })
242
- },
243
- clear () {
244
- playlist.data = []
245
- playlist.el.innerHTML = ''
246
-
247
- if (playlist.index !== -1) {
248
- playlist.index = -1
249
- t.player.fetch()
250
- }
251
- },
252
- create () {
253
- const el = playlist.el
254
-
255
- playlist.data.map((item, index) => {
256
- if (item.el) { return null }
257
-
258
- const id = 'list-' + t.player._id + '-' + item.group
259
- let tab = document.getElementById(id)
260
- if (!tab) {
261
- tab = createChild(el, 'div', {
262
- id,
263
- className: t.player.group ? 'tab' : '',
264
- innerHTML: '<ol></ol>'
265
- })
266
- if (t.player.group) {
267
- tab.setAttribute('data-title', t.player.options.rawList[item.group].title)
268
- tab.setAttribute('data-id', t.player._id)
269
- }
270
- }
271
-
272
- item.el = createChild(tab.querySelector('ol'), 'li', {
273
- title: item.name + ' - ' + item.artist,
274
- innerHTML: '<span class="info"><span>' + item.name + '</span><span>' + item.artist + '</span></span>',
275
- onclick (event) {
276
- const current = event.currentTarget
277
- if (playlist.index === index && progress.el) {
278
- if (source.paused) {
279
- t.player.play()
280
- } else {
281
- t.player.seek(source.duration * progress.percent(event, current))
282
- }
283
- return
284
- }
285
- t.player.switch(index)
286
- t.player.play()
287
- }
288
- })
289
-
290
- return item
291
- })
292
- if (__shokax_tabs__) {
293
- tabFormat()
294
- }
295
- },
296
- current () {
297
- return this.data[this.index]
298
- },
299
- scroll () {
300
- const item = this.current()
301
- let li = this.el.querySelector('li.active')
302
- li && li.removeClass('active')
303
- let tab = this.el.querySelector('.tab.active')
304
- tab && tab.removeClass('active')
305
- li = this.el.querySelectorAll('.nav li')[item.group]
306
- li && li.addClass('active')
307
- tab = this.el.querySelectorAll('.tab')[item.group]
308
- tab && tab.addClass('active')
309
-
310
- pageScroll(item.el, item.el.offsetTop)
311
-
312
- return this
313
- },
314
- title () {
315
- if (source.paused) { return }
316
-
317
- const current = this.current()
318
- document.title = 'Now Playing...' + current.name + ' - ' + current.artist + ' | ' + originTitle
319
- },
320
- error () {
321
- const current = this.current()
322
- current.el.removeClass('current').addClass('error')
323
- current.error = true
324
- this.errnum++
325
- }
326
- }
327
- const info = {
328
- el: null,
329
- create () {
330
- if (this.el) { return }
331
-
332
- this.el = createChild(t, 'div', {
333
- className: 'player-info',
334
- innerHTML: (t.player.options.type === 'audio' ? '<div class="preview"></div>' : '') + '<div class="controller"></div><div class="playlist"></div>'
335
- }, 'after')
336
-
337
- preview.el = this.el.querySelector('.preview')
338
- playlist.el = this.el.querySelector('.playlist')
339
- controller.el = this.el.querySelector('.controller')
340
- },
341
- hide () {
342
- const el = this.el
343
- el.addClass('hide')
344
- window.setTimeout(() => {
345
- el.removeClass('show hide')
346
- }, 300)
347
- }
348
- }
349
- const option = {
350
- type: 'audio',
351
- mode: 'random',
352
- btns: ['play-pause', 'music'],
353
- controls: ['mode', 'backward', 'play-pause', 'forward', 'volume'],
354
- events: {
355
- 'play-pause' (event) {
356
- if (source.paused) {
357
- t.player.play()
358
- } else {
359
- t.player.pause()
360
- }
361
- },
362
- music (event) {
363
- if (info.el.hasClass('show')) {
364
- info.hide()
365
- } else {
366
- info.el.addClass('show')
367
- playlist.scroll().title()
368
- }
369
- }
370
- }
371
- }
372
- const utils = {
373
- random (len) {
374
- return Math.floor((Math.random() * len))
375
- },
376
- parse (link) {
377
- let result = [];
378
- [
379
- ['music.163.com.*song.*id=(\\d+)', 'netease', 'song'],
380
- ['music.163.com.*album.*id=(\\d+)', 'netease', 'album'],
381
- ['music.163.com.*artist.*id=(\\d+)', 'netease', 'artist'],
382
- ['music.163.com.*playlist.*id=(\\d+)', 'netease', 'playlist'],
383
- ['music.163.com.*discover/toplist.*id=(\\d+)', 'netease', 'playlist'],
384
- ['y.qq.com.*song/(\\w+)(.html)?', 'tencent', 'song'],
385
- ['y.qq.com.*album/(\\w+)(.html)?', 'tencent', 'album'],
386
- ['y.qq.com.*singer/(\\w+)(.html)?', 'tencent', 'artist'],
387
- ['y.qq.com.*playsquare/(\\w+)(.html)?', 'tencent', 'playlist'],
388
- ['y.qq.com.*playlist/(\\w+)(.html)?', 'tencent', 'playlist'],
389
- ['xiami.com.*song/(\\w+)', 'xiami', 'song'],
390
- ['xiami.com.*album/(\\w+)', 'xiami', 'album'],
391
- ['xiami.com.*artist/(\\w+)', 'xiami', 'artist'],
392
- ['xiami.com.*collect/(\\w+)', 'xiami', 'playlist']
393
- ].forEach((rule) => {
394
- const patt = new RegExp(rule[0])
395
- const res = patt.exec(link)
396
- if (res !== null) {
397
- result = [rule[1], rule[2], res[1]]
398
- }
399
- })
400
- return result
401
- },
402
- fetch (source) {
403
- const list = []
404
-
405
- return new Promise((resolve, reject) => {
406
- source.forEach((raw) => {
407
- const meta = utils.parse(raw)
408
- if (meta[0]) {
409
- const skey = JSON.stringify(meta)
410
- const playlist = $storage.get(skey)
411
- if (playlist) {
412
- // list.push.apply(list, JSON.parse(playlist))
413
- list.push(...JSON.parse(playlist))
414
- resolve(list)
415
- } else {
416
- fetch(`${CONFIG.playerAPI}/meting/?server=` + meta[0] + '&type=' + meta[1] + '&id=' + meta[2] + '&r=' + Math.random())
417
- .then((response) => {
418
- return response.json()
419
- }).then((json) => {
420
- $storage.set(skey, JSON.stringify(json))
421
- // list.push.apply(list, json)
422
- list.push(...json)
423
- resolve(list)
424
- }).catch((ex) => {
425
- // (不)处理catch的异常
426
- })
427
- }
428
- } else {
429
- list.push(raw)
430
- resolve(list)
431
- }
432
- })
433
- })
434
- },
435
- secondToTime (second) {
436
- const add0 = (num) => {
437
- return isNaN(num) ? '00' : (num < 10 ? '0' + num : '' + num)
438
- }
439
- const hour = Math.floor(second / 3600)
440
- const min = Math.floor((second - hour * 3600) / 60)
441
- const sec = Math.floor(second - hour * 3600 - min * 60)
442
- return (hour > 0 ? [hour, min, sec] : [min, sec]).map(add0).join(':')
443
- },
444
- nameMap: {
445
- dragStart: isMobile ? 'touchstart' : 'mousedown',
446
- dragMove: isMobile ? 'touchmove' : 'mousemove',
447
- dragEnd: isMobile ? 'touchend' : 'mouseup'
448
- }
449
- }
450
- source = null
451
-
452
- t.player = {
453
- _id: utils.random(999999),
454
- group: true,
455
- // 加载播放列表
456
- load (newList) {
457
- let d = ''
458
-
459
- if (newList && newList.length > 0) {
460
- if (this.options.rawList !== newList) {
461
- this.options.rawList = newList
462
- playlist.clear()
463
- // 获取新列表
464
- this.fetch()
465
- }
466
- } else {
467
- // 没有列表时,隐藏按钮
468
- d = 'none'
469
- this.pause()
470
- }
471
- for (const el in buttons.el) {
472
- setDisplay(buttons.el[el], d)
473
- }
474
- return this
475
- },
476
- fetch () {
477
- return new Promise<boolean>((resolve, reject) => {
478
- if (playlist.data.length > 0) {
479
- resolve(false)
480
- } else {
481
- if (this.options.rawList) {
482
- const promises = []
483
-
484
- this.options.rawList.forEach((raw, index) => {
485
- promises.push(new Promise((resolve, reject) => {
486
- let group = index
487
- let source
488
- if (!raw.list) {
489
- group = 0
490
- this.group = false
491
- source = [raw]
492
- } else {
493
- this.group = true
494
- source = raw.list
495
- }
496
- utils.fetch(source).then((list) => {
497
- playlist.add(group, list)
498
- resolve(0)
499
- })
500
- }))
501
- })
502
-
503
- Promise.all(promises).then(() => {
504
- resolve(true)
505
- })
506
- }
507
- }
508
- }).then((c) => {
509
- if (c) {
510
- playlist.create()
511
- controller.create()
512
- this.mode()
513
- }
514
- })
515
- },
516
- // 根据模式切换当前曲目index
517
- mode () {
518
- const total = playlist.data.length
519
-
520
- if (!total || playlist.errnum === total) { return }
521
-
522
- const step = controller.step === 'next' ? 1 : -1
523
-
524
- const next = () => {
525
- let index = playlist.index + step
526
- if (index > total || index < 0) {
527
- index = controller.step === 'next' ? 0 : total - 1
528
- }
529
- playlist.index = index
530
- }
531
-
532
- const random = () => {
533
- const p = utils.random(total)
534
- if (playlist.index !== p) {
535
- playlist.index = p
536
- } else {
537
- next()
538
- }
539
- }
540
-
541
- switch (this.options.mode) {
542
- case 'random':
543
- random()
544
- break
545
- case 'order':
546
- next()
547
- break
548
- case 'loop':
549
- if (controller.step) { next() }
550
-
551
- if (playlist.index === -1) { random() }
552
- break
553
- }
554
-
555
- this.init()
556
- },
557
- // 直接设置当前曲目index
558
- switch (index) {
559
- if (typeof index === 'number' &&
560
- index !== playlist.index &&
561
- playlist.current() &&
562
- !playlist.current().error) {
563
- playlist.index = index
564
- this.init()
565
- }
566
- },
567
- // 更新source为当前曲目index
568
- init () {
569
- const item = playlist.current()
570
-
571
- if (!item || item.error) {
572
- this.mode()
573
- return
574
- }
575
-
576
- let playing = false
577
- if (!source.paused) {
578
- playing = true
579
- this.stop()
580
- }
581
-
582
- source.setAttribute('src', item.url)
583
- source.setAttribute('title', item.name + ' - ' + item.artist)
584
- this.volume($storage.get('_PlayerVolume') || '0.7')
585
- this.muted($storage.get('_PlayerMuted'))
586
-
587
- progress.create()
588
-
589
- if (this.options.type === 'audio') { preview.create() }
590
-
591
- if (playing === true) {
592
- this.play()
593
- }
594
- },
595
- play () {
596
- NOWPLAYING && NOWPLAYING.player.pause()
597
-
598
- if (playlist.current().error) {
599
- this.mode()
600
- return
601
- }
602
- source.play().then(() => {
603
- playlist.scroll()
604
- }).catch((e) => {
605
- // 不处理错误
606
- })
607
- },
608
- pause () {
609
- source.pause()
610
- document.title = originTitle
611
- },
612
- stop () {
613
- source.pause()
614
- source.currentTime = 0
615
- document.title = originTitle
616
- },
617
- seek (time) {
618
- time = Math.max(time, 0)
619
- time = Math.min(time, source.duration)
620
- source.currentTime = time
621
- progress.update(time / source.duration)
622
- },
623
- muted (status?) {
624
- if (status === 'muted') {
625
- source.muted = status
626
- $storage.set('_PlayerMuted', status)
627
- controller.update(0)
628
- } else {
629
- $storage.del('_PlayerMuted')
630
- source.muted = false
631
- controller.update(source.volume)
632
- }
633
- },
634
- volume (percentage) {
635
- if (!isNaN(percentage)) {
636
- controller.update(percentage)
637
- $storage.set('_PlayerVolume', percentage)
638
- source.volume = percentage
639
- }
640
- },
641
- mini () {
642
- info.hide()
643
- }
644
- }
645
-
646
- const lyrics = {
647
- el: null,
648
- data: null,
649
- index: 0,
650
- create (box) {
651
- const current = playlist.index
652
- // const that = this
653
- const raw = playlist.current().lrc
654
-
655
- const callback = (body) => {
656
- if (current !== playlist.index) { return }
657
-
658
- this.data = this.parse(body)
659
-
660
- let lrc = ''
661
- this.data.forEach((line, index) => {
662
- lrc += '<p' + (index === 0 ? ' class="current"' : '') + '>' + line[1] + '</p>'
663
- })
664
-
665
- this.el = createChild(box, 'div', {
666
- className: 'inner',
667
- innerHTML: lrc
668
- }, 'replace')
669
-
670
- this.index = 0
671
- }
672
-
673
- if (raw.startsWith('http')) { this.fetch(raw, callback) } else { callback(raw) }
674
- },
675
- update (currentTime) {
676
- if (!this.data) { return }
677
-
678
- if (this.index > this.data.length - 1 || currentTime < this.data[this.index][0] || (!this.data[this.index + 1] || currentTime >= this.data[this.index + 1][0])) {
679
- for (let i = 0; i < this.data.length; i++) {
680
- if (currentTime >= this.data[i][0] && (!this.data[i + 1] || currentTime < this.data[i + 1][0])) {
681
- this.index = i
682
- const y = -(this.index - 1)
683
- this.el.style.transform = 'translateY(' + y + 'rem)'
684
- // this.el.style.webkitTransform = 'translateY(' + y + 'rem)';
685
- this.el.getElementsByClassName('current')[0].removeClass('current')
686
- this.el.getElementsByTagName('p')[i].addClass('current')
687
- }
688
- }
689
- }
690
- },
691
- parse (lrc_s) {
692
- if (lrc_s) {
693
- lrc_s = lrc_s.replace(/([^\]^\n])\[/g, (match, p1) => {
694
- return p1 + '\n['
695
- })
696
- const lyric = lrc_s.split('\n')
697
- let lrc = []
698
- const lyricLen = lyric.length
699
- for (let i = 0; i < lyricLen; i++) {
700
- // match lrc time
701
- const lrcTimes = lyric[i].match(/\[(\d{2}):(\d{2})(\.(\d{2,3}))?]/g)
702
- // match lrc text
703
- const lrcText = lyric[i]
704
- .replace(/.*\[(\d{2}):(\d{2})(\.(\d{2,3}))?]/g, '')
705
- .replace(/<(\d{2}):(\d{2})(\.(\d{2,3}))?>/g, '')
706
- .trim()
707
-
708
- if (lrcTimes) {
709
- // handle multiple time tag
710
- const timeLen = lrcTimes.length
711
- for (let j = 0; j < timeLen; j++) {
712
- const oneTime = /\[(\d{2}):(\d{2})(\.(\d{2,3}))?]/.exec(lrcTimes[j])
713
- const min2sec = <number><unknown> oneTime[1] * 60
714
- const sec2sec = parseInt(oneTime[2])
715
- const msec2sec = oneTime[4] ? parseInt(oneTime[4]) / ((oneTime[4] + '').length === 2 ? 100 : 1000) : 0
716
- const lrcTime = min2sec + sec2sec + msec2sec
717
- lrc.push([lrcTime, lrcText])
718
- }
719
- }
720
- }
721
- // sort by time
722
- lrc = lrc.filter((item) => item[1])
723
- lrc.sort((a, b) => a[0] - b[0])
724
- return lrc
725
- } else {
726
- return []
727
- }
728
- },
729
- fetch (url, callback) {
730
- fetch(url)
731
- .then((response) => {
732
- return response.text()
733
- }).then((body) => {
734
- callback(body)
735
- }).catch((ex) => {
736
- // 不处理错误
737
- })
738
- }
739
- }
740
-
741
- const events = {
742
- onerror () {
743
- playlist.error()
744
- t.player.mode()
745
- },
746
- ondurationchange () {
747
- if (source.duration !== 1) {
748
- progress.el.setAttribute('data-dtime', utils.secondToTime(source.duration))
749
- }
750
- },
751
- onloadedmetadata () {
752
- t.player.seek(0)
753
- progress.el.setAttribute('data-dtime', utils.secondToTime(source.duration))
754
- },
755
- onplay () {
756
- t.parentNode.addClass('playing')
757
- showtip(this.getAttribute('title'))
758
- NOWPLAYING = t
759
- },
760
- onpause () {
761
- t.parentNode.removeClass('playing')
762
- NOWPLAYING = null
763
- },
764
- ontimeupdate () {
765
- if (!this.disableTimeupdate) {
766
- progress.update(this.currentTime / this.duration)
767
- lyrics.update(this.currentTime)
768
- }
769
- },
770
- onended (argument) {
771
- t.player.mode()
772
- t.player.play()
773
- }
774
- }
775
-
776
- const init = (config) => {
777
- if (t.player.created) { return }
778
-
779
- t.player.options = Object.assign(option, config)
780
- t.player.options.mode = $storage.get('_PlayerMode') || t.player.options.mode
781
-
782
- // 初始化button、controls以及click事件
783
- buttons.create()
784
-
785
- // 初始化audio or video
786
- source = createChild(t, t.player.options.type, events)
787
- // 初始化播放列表、预览、控件按钮等
788
- info.create()
789
-
790
- t.parentNode.addClass(t.player.options.type)
791
-
792
- t.player.created = true
793
- }
794
-
795
- init(config)
796
-
797
- return t
798
- }
1
+ import { CONFIG } from './globals/globalVars'
2
+ import 'nyx-player/style'
3
+
4
+ export const initAudioPlayer = async function () {
5
+ const urls = []
6
+ CONFIG.audio.forEach((item) => {
7
+ urls.push({
8
+ name: item.title,
9
+ url: item.list[0]
10
+ })
11
+ })
12
+ const { initPlayer } = await import('nyx-player')
13
+ initPlayer("#player","#showBtn", urls, "#playBtn")
14
+ }