@eternalheart/angular-file-preview 1.6.5 → 1.6.6

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 (58) hide show
  1. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-UobTf36G.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-RPRQhVCg.mjs} +39 -32
  2. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-RPRQhVCg.mjs.map +1 -0
  3. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-pG0Ko5mI-DthQJg-X.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-3-0UYUJy-CD5hv6Xd.mjs} +27 -8
  4. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-3-0UYUJy-CD5hv6Xd.mjs.map +1 -0
  5. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-D35x1nwM-CugEEXjg.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-5zqP72gq-lAwuxCQV.mjs} +2 -2
  6. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-D35x1nwM-CugEEXjg.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-5zqP72gq-lAwuxCQV.mjs.map} +1 -1
  7. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CDjKPqyW-CmX5sdkL.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-71x_jK0V-BwzFr9L0.mjs} +2 -2
  8. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CDjKPqyW-CmX5sdkL.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-71x_jK0V-BwzFr9L0.mjs.map} +1 -1
  9. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-Bv3JRXKn-B4Wewc-4.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-7KavuB8u-CFBWzMGm.mjs} +2 -2
  10. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-Bv3JRXKn-B4Wewc-4.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-7KavuB8u-CFBWzMGm.mjs.map} +1 -1
  11. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-DsNNZ59Q-C8MaSME6.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-B-TVstXS-Dh1KMX_8.mjs} +2 -2
  12. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-DsNNZ59Q-C8MaSME6.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-B-TVstXS-Dh1KMX_8.mjs.map} +1 -1
  13. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-6dZS_Cfs-B1itLV5R.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-B4L1kfY--BHy3x_oj.mjs} +2 -2
  14. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-6dZS_Cfs-B1itLV5R.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-B4L1kfY--BHy3x_oj.mjs.map} +1 -1
  15. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-D9jJNzeM-mWX59Aj2.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-B56pscOG-ClsvukS5.mjs} +4 -5
  16. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-B56pscOG-ClsvukS5.mjs.map +1 -0
  17. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-DbmuvdvN-C29uLyt2.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BNU3NWQp-C5U5krn9.mjs} +2 -2
  18. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-DbmuvdvN-C29uLyt2.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BNU3NWQp-C5U5krn9.mjs.map} +1 -1
  19. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-B1ANUCTy-BRs7TMLn.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BbRwLog8-B9Sw6HEr.mjs} +2 -2
  20. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-B1ANUCTy-BRs7TMLn.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BbRwLog8-B9Sw6HEr.mjs.map} +1 -1
  21. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BGqTRZbm-CAOLRw20.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BeL4xzpS-eYswtncp.mjs} +2 -2
  22. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BGqTRZbm-CAOLRw20.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BeL4xzpS-eYswtncp.mjs.map} +1 -1
  23. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-C518mdUd-B5SCzrzU.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BeTNUne--CwUzGLn3.mjs} +2 -2
  24. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-C518mdUd-B5SCzrzU.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BeTNUne--CwUzGLn3.mjs.map} +1 -1
  25. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-DufW2Fuc-CTosCut6.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-C3uCX4wD-CoZ795pn.mjs} +3 -3
  26. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-DufW2Fuc-CTosCut6.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-C3uCX4wD-CoZ795pn.mjs.map} +1 -1
  27. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-C0McUoqT-DJ35bhIz.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CBbnvps8-ClkiJKQ9.mjs} +2 -2
  28. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-C0McUoqT-DJ35bhIz.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CBbnvps8-ClkiJKQ9.mjs.map} +1 -1
  29. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-Cb1RLXeO-Bj9gjS1Z.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CMeATokn-iD-SSbnK.mjs} +2 -2
  30. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-Cb1RLXeO-Bj9gjS1Z.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CMeATokn-iD-SSbnK.mjs.map} +1 -1
  31. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CHi9tOe0-NOeQYAnM.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CZQnGY6g-DexFUJLU.mjs} +2 -2
  32. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CHi9tOe0-NOeQYAnM.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CZQnGY6g-DexFUJLU.mjs.map} +1 -1
  33. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-TSTa_Q7E-DBhkL6pV.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-Cjjsjooa-24Qg-LjD.mjs} +2 -2
  34. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-TSTa_Q7E-DBhkL6pV.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-Cjjsjooa-24Qg-LjD.mjs.map} +1 -1
  35. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CSCTj7ft-BfqruUyY.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CpiK7yUb-T48dTv66.mjs} +3 -3
  36. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CSCTj7ft-BfqruUyY.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CpiK7yUb-T48dTv66.mjs.map} +1 -1
  37. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index--7d8Hgi0-D-sg24Qs.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CyO8N29I-CMesNfcT.mjs} +2 -2
  38. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index--7d8Hgi0-D-sg24Qs.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CyO8N29I-CMesNfcT.mjs.map} +1 -1
  39. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-Cw90Kdyg-BzrW_cyx.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-D6UfVKL_-CAqlAQIN.mjs} +2 -2
  40. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-Cw90Kdyg-BzrW_cyx.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-D6UfVKL_-CAqlAQIN.mjs.map} +1 -1
  41. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-DWe1kVtU-CJlU6sOy.mjs +597 -0
  42. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-DWe1kVtU-CJlU6sOy.mjs.map +1 -0
  43. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BEaqpRV8-BidVIVlO.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-QydIBtJH-Dw052TRv.mjs} +2 -2
  44. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-BEaqpRV8-BidVIVlO.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-QydIBtJH-Dw052TRv.mjs.map} +1 -1
  45. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-shiki-highlight-CL9cG481-BKfwdOpN.mjs → eternalheart-angular-file-preview-eternalheart-angular-file-preview-shiki-highlight-CE3FZF7D-BjdXRpvN.mjs} +2 -2
  46. package/lib/fesm2022/{eternalheart-angular-file-preview-eternalheart-angular-file-preview-shiki-highlight-CL9cG481-BKfwdOpN.mjs.map → eternalheart-angular-file-preview-eternalheart-angular-file-preview-shiki-highlight-CE3FZF7D-BjdXRpvN.mjs.map} +1 -1
  47. package/lib/fesm2022/eternalheart-angular-file-preview.mjs +1 -1
  48. package/lib/index.css +340 -60
  49. package/lib/index.d.ts +1 -1
  50. package/lib/renderers/Audio/index.d.ts +1 -18
  51. package/lib/renderers/Cad/index.d.ts +1 -0
  52. package/lib/version.d.ts +1 -0
  53. package/package.json +2 -1
  54. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-UobTf36G.mjs.map +0 -1
  55. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CQwhffym-DAGw4Xy_.mjs +0 -823
  56. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-CQwhffym-DAGw4Xy_.mjs.map +0 -1
  57. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-D9jJNzeM-mWX59Aj2.mjs.map +0 -1
  58. package/lib/fesm2022/eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-pG0Ko5mI-DthQJg-X.mjs.map +0 -1
@@ -0,0 +1,597 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, inject, DestroyRef, signal, viewChild, computed, effect, untracked, afterNextRender, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import * as i1 from 'lucide-angular';
4
+ import { AudioLines, Play, Pause, SkipBack, SkipForward, Repeat, VolumeX, Volume1, Volume2, LucideAngularModule } from 'lucide-angular';
5
+ import { L as LocaleService, g as getFallbackTranslator, r as r0 } from './eternalheart-angular-file-preview-eternalheart-angular-file-preview-RPRQhVCg.mjs';
6
+ import { R as RendererError } from './eternalheart-angular-file-preview-eternalheart-angular-file-preview-RendererError-DtNihCIX-DtNihCIX.mjs';
7
+ import { T as ToolbarEventEmitter } from './eternalheart-angular-file-preview-eternalheart-angular-file-preview-base.types-D5x7QPey-D5x7QPey.mjs';
8
+
9
+ function createAudioPlayer() {
10
+ const isPlaying = signal(false);
11
+ const isLoading = signal(true);
12
+ const currentTime = signal(0);
13
+ const duration = signal(0);
14
+ const volume = signal(1);
15
+ const isMuted = signal(false);
16
+ const isLoop = signal(false);
17
+ const error = signal(null);
18
+ let audio = null;
19
+ let unbind = null;
20
+ const bind = (el) => {
21
+ unbind?.();
22
+ unbind = null;
23
+ audio = el;
24
+ if (!el)
25
+ return;
26
+ isLoading.set(true);
27
+ error.set(null);
28
+ const onTimeUpdate = () => {
29
+ if (!isNaN(el.currentTime))
30
+ currentTime.set(el.currentTime);
31
+ };
32
+ const onDurationChange = () => {
33
+ if (!isNaN(el.duration) && isFinite(el.duration))
34
+ duration.set(el.duration);
35
+ };
36
+ const onCanPlay = () => {
37
+ isLoading.set(false);
38
+ onDurationChange();
39
+ };
40
+ const onWaiting = () => isLoading.set(true);
41
+ const onPlaying = () => {
42
+ isLoading.set(false);
43
+ isPlaying.set(true);
44
+ };
45
+ const onPlay = () => isPlaying.set(true);
46
+ const onPause = () => isPlaying.set(false);
47
+ const onEnded = () => isPlaying.set(false);
48
+ const onError = () => {
49
+ error.set('audio.load_failed');
50
+ isLoading.set(false);
51
+ };
52
+ el.addEventListener('timeupdate', onTimeUpdate);
53
+ el.addEventListener('loadedmetadata', onDurationChange);
54
+ el.addEventListener('durationchange', onDurationChange);
55
+ el.addEventListener('canplay', onCanPlay);
56
+ el.addEventListener('waiting', onWaiting);
57
+ el.addEventListener('playing', onPlaying);
58
+ el.addEventListener('play', onPlay);
59
+ el.addEventListener('pause', onPause);
60
+ el.addEventListener('ended', onEnded);
61
+ el.addEventListener('error', onError);
62
+ if (el.readyState >= 3) {
63
+ isLoading.set(false);
64
+ onDurationChange();
65
+ }
66
+ unbind = () => {
67
+ el.removeEventListener('timeupdate', onTimeUpdate);
68
+ el.removeEventListener('loadedmetadata', onDurationChange);
69
+ el.removeEventListener('durationchange', onDurationChange);
70
+ el.removeEventListener('canplay', onCanPlay);
71
+ el.removeEventListener('waiting', onWaiting);
72
+ el.removeEventListener('playing', onPlaying);
73
+ el.removeEventListener('play', onPlay);
74
+ el.removeEventListener('pause', onPause);
75
+ el.removeEventListener('ended', onEnded);
76
+ el.removeEventListener('error', onError);
77
+ };
78
+ };
79
+ const togglePlay = () => {
80
+ if (!audio)
81
+ return;
82
+ if (audio.paused)
83
+ void audio.play();
84
+ else
85
+ audio.pause();
86
+ };
87
+ const seek = (time) => {
88
+ if (!audio)
89
+ return;
90
+ audio.currentTime = time;
91
+ currentTime.set(time);
92
+ };
93
+ const skip = (seconds) => {
94
+ if (!audio)
95
+ return;
96
+ audio.currentTime = Math.max(0, Math.min(audio.currentTime + seconds, audio.duration || Infinity));
97
+ currentTime.set(audio.currentTime);
98
+ };
99
+ const setVolume = (v) => {
100
+ volume.set(v);
101
+ if (audio)
102
+ audio.volume = v;
103
+ if (v > 0 && isMuted()) {
104
+ isMuted.set(false);
105
+ if (audio)
106
+ audio.muted = false;
107
+ }
108
+ };
109
+ const toggleMute = () => {
110
+ const next = !isMuted();
111
+ isMuted.set(next);
112
+ if (audio)
113
+ audio.muted = next;
114
+ };
115
+ const toggleLoop = () => {
116
+ const next = !isLoop();
117
+ isLoop.set(next);
118
+ if (audio)
119
+ audio.loop = next;
120
+ };
121
+ const formattedCurrent = () => r0(currentTime());
122
+ const formattedDuration = () => r0(duration());
123
+ const destroy = () => {
124
+ unbind?.();
125
+ unbind = null;
126
+ audio = null;
127
+ };
128
+ return {
129
+ isPlaying,
130
+ isLoading,
131
+ currentTime,
132
+ duration,
133
+ volume,
134
+ isMuted,
135
+ isLoop,
136
+ error,
137
+ bind,
138
+ togglePlay,
139
+ seek,
140
+ skip,
141
+ setVolume,
142
+ toggleMute,
143
+ toggleLoop,
144
+ formattedCurrent,
145
+ formattedDuration,
146
+ destroy,
147
+ };
148
+ }
149
+
150
+ class AudioRenderer {
151
+ constructor() {
152
+ this.url = input.required();
153
+ this.fileName = input.required();
154
+ this.emitter = new ToolbarEventEmitter();
155
+ this.locale = inject(LocaleService, { optional: true });
156
+ this.destroyRef = inject(DestroyRef);
157
+ this.t = this.locale?.t() ?? getFallbackTranslator();
158
+ this.formatTime = r0;
159
+ this.Math = Math;
160
+ this.audioLinesIcon = AudioLines;
161
+ this.playIcon = Play;
162
+ this.pauseIcon = Pause;
163
+ this.skipBackIcon = SkipBack;
164
+ this.skipForwardIcon = SkipForward;
165
+ this.repeatIcon = Repeat;
166
+ this.player = createAudioPlayer();
167
+ this.isPlaying = this.player.isPlaying;
168
+ this.isLoop = this.player.isLoop;
169
+ this.currentTime = this.player.currentTime;
170
+ this.duration = this.player.duration;
171
+ this.volume = this.player.volume;
172
+ this.isMuted = this.player.isMuted;
173
+ this.error = this.player.error;
174
+ this.togglePlay = this.player.togglePlay;
175
+ this.toggleMute = this.player.toggleMute;
176
+ this.toggleLoop = this.player.toggleLoop;
177
+ this.showVolume = signal(false);
178
+ this.isDragging = signal(false);
179
+ this.dragTime = signal(0);
180
+ this.volumeRef = viewChild('volumeRef');
181
+ this.audioEl = viewChild('audioRef');
182
+ this.volumeHideTimer = null;
183
+ this.bindRaf = 0;
184
+ this.displayTime = computed(() => this.isDragging() ? this.dragTime() : this.currentTime());
185
+ this.progress = computed(() => this.duration() > 0 ? this.displayTime() / this.duration() : 0);
186
+ this.volumeIcon = computed(() => {
187
+ if (this.isMuted() || this.volume() === 0)
188
+ return VolumeX;
189
+ if (this.volume() < 0.5)
190
+ return Volume1;
191
+ return Volume2;
192
+ });
193
+ this.getToolbarGroups = () => [];
194
+ this.onToolbarChange = (listener) => this.emitter.subscribe(listener);
195
+ this.handleClickOutside = (e) => {
196
+ const el = this.volumeRef()?.nativeElement;
197
+ if (el && !el.contains(e.target)) {
198
+ this.showVolume.set(false);
199
+ }
200
+ };
201
+ effect(() => {
202
+ this.url();
203
+ const el = this.audioEl()?.nativeElement ?? null;
204
+ untracked(() => {
205
+ cancelAnimationFrame(this.bindRaf);
206
+ this.bindRaf = requestAnimationFrame(() => {
207
+ this.player.bind(el);
208
+ });
209
+ });
210
+ });
211
+ afterNextRender(() => {
212
+ document.addEventListener('mousedown', this.handleClickOutside);
213
+ });
214
+ this.destroyRef.onDestroy(() => {
215
+ document.removeEventListener('mousedown', this.handleClickOutside);
216
+ if (this.volumeHideTimer !== null)
217
+ clearTimeout(this.volumeHideTimer);
218
+ cancelAnimationFrame(this.bindRaf);
219
+ this.player.destroy();
220
+ });
221
+ }
222
+ skip(seconds) {
223
+ const dur = this.duration();
224
+ const next = Math.max(0, Math.min(this.currentTime() + seconds, dur || Infinity));
225
+ this.player.seek(next);
226
+ }
227
+ onProgressPointerDown() {
228
+ this.dragTime.set(this.currentTime());
229
+ this.isDragging.set(true);
230
+ }
231
+ onProgressInput(e) {
232
+ const value = parseFloat(e.target.value);
233
+ if (this.isDragging()) {
234
+ this.dragTime.set(value);
235
+ }
236
+ else {
237
+ this.player.seek(value);
238
+ }
239
+ }
240
+ onProgressPointerUp(e) {
241
+ const value = parseFloat(e.target.value);
242
+ this.player.seek(value);
243
+ this.isDragging.set(false);
244
+ }
245
+ onVolumeInput(e) {
246
+ this.player.setVolume(parseFloat(e.target.value));
247
+ }
248
+ handleVolumeEnter() {
249
+ if (this.volumeHideTimer !== null)
250
+ clearTimeout(this.volumeHideTimer);
251
+ this.showVolume.set(true);
252
+ }
253
+ handleVolumeLeave() {
254
+ this.volumeHideTimer = window.setTimeout(() => {
255
+ this.showVolume.set(false);
256
+ }, 300);
257
+ }
258
+ progressFillStyle() {
259
+ return `width:${this.progress() * 100}%;background:var(--fp-player-progress);transition:${this.isDragging() ? 'none' : 'width 0.1s linear'}`;
260
+ }
261
+ playBtnStyle() {
262
+ return 'background:var(--fp-player-progress);color:var(--fp-fg-inverse)';
263
+ }
264
+ volumeFillStyle() {
265
+ const h = (this.isMuted() ? 0 : this.volume()) * 100;
266
+ return `width:3px;height:${h}%;background:var(--fp-player-progress);transition:height 0.1s linear`;
267
+ }
268
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: AudioRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
269
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: AudioRenderer, isStandalone: true, selector: "afp-audio-renderer", inputs: { url: { classPropertyName: "url", publicName: "url", isSignal: true, isRequired: true, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "afp-block afp-w-full afp-h-full" }, viewQueries: [{ propertyName: "volumeRef", first: true, predicate: ["volumeRef"], descendants: true, isSignal: true }, { propertyName: "audioEl", first: true, predicate: ["audioRef"], descendants: true, isSignal: true }], ngImport: i0, template: `
270
+ @if (error(); as err) {
271
+ <afp-renderer-error [message]="t(err)" />
272
+ } @else {
273
+ <div class="afp-flex afp-items-center afp-justify-center afp-w-full afp-h-full afp-p-4 afp-select-none afp-overflow-auto">
274
+ <div class="afp-w-full afp-max-w-xl afp-flex-shrink-0 afp-rounded-lg afp-border afp-border-line-weak afp-bg-surface-1 afp-p-4">
275
+ <div class="afp-flex afp-items-center afp-gap-3 afp-mb-4">
276
+ <div
277
+ aria-hidden="true"
278
+ class="afp-audio-mark afp-w-10 afp-h-10 afp-flex afp-items-center afp-justify-center afp-rounded-md afp-flex-shrink-0"
279
+ [class.afp-audio-mark-playing]="isPlaying()"
280
+ >
281
+ <i-lucide [img]="audioLinesIcon" class="afp-w-5 afp-h-5" />
282
+ </div>
283
+ <div class="afp-min-w-0 afp-flex-1 afp-truncate afp-text-sm afp-font-medium afp-text-fg-primary">
284
+ {{ fileName() }}
285
+ </div>
286
+ </div>
287
+
288
+ <div class="afp-flex afp-items-center afp-gap-3 afp-mb-4">
289
+ <span class="afp-w-9 afp-flex-shrink-0 afp-text-right afp-text-[11px] afp-text-fg-tertiary afp-tabular-nums">
290
+ {{ formatTime(displayTime()) }}
291
+ </span>
292
+ <div class="afp-relative afp-h-4 afp-flex afp-flex-1 afp-items-center">
293
+ <div class="afp-absolute afp-left-[6px] afp-right-[6px] afp-h-[3px] afp-rounded-full afp-bg-surface-3">
294
+ <div
295
+ class="afp-h-full afp-rounded-full afp-pointer-events-none"
296
+ [attr.style]="progressFillStyle()"
297
+ ></div>
298
+ </div>
299
+ <input
300
+ type="range"
301
+ min="0"
302
+ [max]="duration() > 0 ? duration() : currentTime() || 100"
303
+ step="any"
304
+ [value]="displayTime()"
305
+ [disabled]="duration() <= 0"
306
+ [attr.aria-label]="t('audio.aria.progress')"
307
+ class="audio-slider afp-absolute afp-w-full"
308
+ (pointerdown)="onProgressPointerDown()"
309
+ (input)="onProgressInput($event)"
310
+ (pointerup)="onProgressPointerUp($event)"
311
+ (pointercancel)="isDragging.set(false)"
312
+ />
313
+ </div>
314
+ <span class="afp-w-9 afp-flex-shrink-0 afp-text-[11px] afp-text-fg-tertiary afp-tabular-nums">
315
+ {{ duration() > 0 ? formatTime(duration()) : '--:--' }}
316
+ </span>
317
+ </div>
318
+
319
+ <div class="afp-flex afp-items-center afp-gap-1">
320
+ <button
321
+ type="button"
322
+ class="afp-audio-control afp-w-10 afp-h-10 afp-rounded-md afp-flex afp-items-center afp-justify-center afp-flex-shrink-0"
323
+ [attr.style]="playBtnStyle()"
324
+ [attr.title]="isPlaying() ? t('audio.aria.pause') : t('audio.aria.play')"
325
+ [attr.aria-label]="isPlaying() ? t('audio.aria.pause') : t('audio.aria.play')"
326
+ (click)="togglePlay()"
327
+ >
328
+ @if (isPlaying()) {
329
+ <i-lucide [img]="pauseIcon" class="afp-w-5 afp-h-5" />
330
+ } @else {
331
+ <i-lucide [img]="playIcon" class="afp-w-5 afp-h-5 afp-ml-0.5" />
332
+ }
333
+ </button>
334
+
335
+ <button
336
+ type="button"
337
+ class="afp-audio-control afp-w-9 afp-h-9 afp-rounded-md afp-flex afp-items-center afp-justify-center afp-transition-colors afp-text-fg-secondary hover:afp-bg-surface-3 afp-flex-shrink-0"
338
+ [attr.title]="t('audio.aria.backward_10')"
339
+ [attr.aria-label]="t('audio.aria.backward_10')"
340
+ (click)="skip(-10)"
341
+ >
342
+ <i-lucide [img]="skipBackIcon" class="afp-w-[18px] afp-h-[18px]" />
343
+ </button>
344
+
345
+ <button
346
+ type="button"
347
+ class="afp-audio-control afp-w-9 afp-h-9 afp-rounded-md afp-flex afp-items-center afp-justify-center afp-transition-colors afp-text-fg-secondary hover:afp-bg-surface-3 afp-flex-shrink-0"
348
+ [attr.title]="t('audio.aria.forward_10')"
349
+ [attr.aria-label]="t('audio.aria.forward_10')"
350
+ (click)="skip(10)"
351
+ >
352
+ <i-lucide [img]="skipForwardIcon" class="afp-w-[18px] afp-h-[18px]" />
353
+ </button>
354
+
355
+ <div class="afp-w-px afp-h-5 afp-mx-1 afp-bg-divide"></div>
356
+
357
+ <button
358
+ type="button"
359
+ class="afp-audio-control afp-w-9 afp-h-9 afp-rounded-md afp-flex afp-items-center afp-justify-center afp-transition-colors afp-flex-shrink-0"
360
+ [class.afp-bg-surface-3]="isLoop()"
361
+ [class.afp-text-fg-primary]="isLoop()"
362
+ [class.afp-text-fg-tertiary]="!isLoop()"
363
+ [attr.title]="isLoop() ? t('audio.aria.loop_off') : t('audio.aria.loop_on')"
364
+ [attr.aria-label]="isLoop() ? t('audio.aria.loop_off') : t('audio.aria.loop_on')"
365
+ (click)="toggleLoop()"
366
+ >
367
+ <i-lucide [img]="repeatIcon" class="afp-w-4 afp-h-4" />
368
+ </button>
369
+
370
+ <div class="afp-flex-1"></div>
371
+
372
+ <div
373
+ #volumeRef
374
+ class="afp-relative"
375
+ (mouseenter)="handleVolumeEnter()"
376
+ (mouseleave)="handleVolumeLeave()"
377
+ >
378
+ <button
379
+ type="button"
380
+ class="afp-audio-control afp-w-9 afp-h-9 afp-rounded-md afp-flex afp-items-center afp-justify-center afp-transition-colors afp-flex-shrink-0"
381
+ [class.afp-bg-surface-3]="showVolume()"
382
+ [class.afp-text-fg-primary]="showVolume()"
383
+ [class.afp-text-fg-secondary]="!showVolume()"
384
+ [attr.title]="isMuted() ? t('audio.aria.unmute') : t('audio.aria.mute')"
385
+ [attr.aria-label]="isMuted() ? t('audio.aria.unmute') : t('audio.aria.mute')"
386
+ (click)="toggleMute()"
387
+ >
388
+ <i-lucide [img]="volumeIcon()" class="afp-w-4 afp-h-4" />
389
+ </button>
390
+
391
+ @if (showVolume()) {
392
+ <div
393
+ class="afp-absolute afp-right-0 afp-bottom-full afp-mb-2 afp-w-[54px] afp-rounded-md afp-p-3 afp-border afp-bg-surface-toolbar afp-border-line afp-volume-popup"
394
+ (mouseenter)="handleVolumeEnter()"
395
+ (mouseleave)="handleVolumeLeave()"
396
+ >
397
+ <div class="afp-flex afp-flex-col afp-items-center afp-gap-2" style="height: 100px">
398
+ <div class="afp-relative afp-flex afp-items-center afp-justify-center" style="width: 24px; height: 80px">
399
+ <div class="afp-absolute afp-rounded-full afp-bg-surface-2" style="width: 3px; height: 100%"></div>
400
+ <div
401
+ class="afp-absolute afp-bottom-0 afp-rounded-full afp-pointer-events-none"
402
+ [attr.style]="volumeFillStyle()"
403
+ ></div>
404
+ <input
405
+ type="range"
406
+ min="0"
407
+ max="1"
408
+ step="0.01"
409
+ [value]="isMuted() ? 0 : volume()"
410
+ [attr.aria-label]="t('audio.aria.volume')"
411
+ class="volume-slider-vertical afp-absolute"
412
+ style="width: 80px; height: 24px; transform: rotate(-90deg); transform-origin: center center"
413
+ (input)="onVolumeInput($event)"
414
+ />
415
+ </div>
416
+ <span class="afp-text-[10px] afp-tabular-nums afp-text-fg-tertiary">
417
+ {{ Math.round((isMuted() ? 0 : volume()) * 100) }}
418
+ </span>
419
+ </div>
420
+ </div>
421
+ }
422
+ </div>
423
+ </div>
424
+ </div>
425
+
426
+ <audio #audioRef [src]="url()" class="afp-hidden"></audio>
427
+ </div>
428
+ }
429
+ `, isInline: true, styles: [".afp-volume-popup{animation:afp-fade-in .2s ease}@keyframes afp-fade-in{0%{opacity:0}to{opacity:1}}\n"], dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "component", type: RendererError, selector: "afp-renderer-error", inputs: ["message", "detail", "showIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
430
+ }
431
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: AudioRenderer, decorators: [{
432
+ type: Component,
433
+ args: [{ selector: 'afp-audio-renderer', standalone: true, imports: [LucideAngularModule, RendererError], changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'afp-block afp-w-full afp-h-full' }, template: `
434
+ @if (error(); as err) {
435
+ <afp-renderer-error [message]="t(err)" />
436
+ } @else {
437
+ <div class="afp-flex afp-items-center afp-justify-center afp-w-full afp-h-full afp-p-4 afp-select-none afp-overflow-auto">
438
+ <div class="afp-w-full afp-max-w-xl afp-flex-shrink-0 afp-rounded-lg afp-border afp-border-line-weak afp-bg-surface-1 afp-p-4">
439
+ <div class="afp-flex afp-items-center afp-gap-3 afp-mb-4">
440
+ <div
441
+ aria-hidden="true"
442
+ class="afp-audio-mark afp-w-10 afp-h-10 afp-flex afp-items-center afp-justify-center afp-rounded-md afp-flex-shrink-0"
443
+ [class.afp-audio-mark-playing]="isPlaying()"
444
+ >
445
+ <i-lucide [img]="audioLinesIcon" class="afp-w-5 afp-h-5" />
446
+ </div>
447
+ <div class="afp-min-w-0 afp-flex-1 afp-truncate afp-text-sm afp-font-medium afp-text-fg-primary">
448
+ {{ fileName() }}
449
+ </div>
450
+ </div>
451
+
452
+ <div class="afp-flex afp-items-center afp-gap-3 afp-mb-4">
453
+ <span class="afp-w-9 afp-flex-shrink-0 afp-text-right afp-text-[11px] afp-text-fg-tertiary afp-tabular-nums">
454
+ {{ formatTime(displayTime()) }}
455
+ </span>
456
+ <div class="afp-relative afp-h-4 afp-flex afp-flex-1 afp-items-center">
457
+ <div class="afp-absolute afp-left-[6px] afp-right-[6px] afp-h-[3px] afp-rounded-full afp-bg-surface-3">
458
+ <div
459
+ class="afp-h-full afp-rounded-full afp-pointer-events-none"
460
+ [attr.style]="progressFillStyle()"
461
+ ></div>
462
+ </div>
463
+ <input
464
+ type="range"
465
+ min="0"
466
+ [max]="duration() > 0 ? duration() : currentTime() || 100"
467
+ step="any"
468
+ [value]="displayTime()"
469
+ [disabled]="duration() <= 0"
470
+ [attr.aria-label]="t('audio.aria.progress')"
471
+ class="audio-slider afp-absolute afp-w-full"
472
+ (pointerdown)="onProgressPointerDown()"
473
+ (input)="onProgressInput($event)"
474
+ (pointerup)="onProgressPointerUp($event)"
475
+ (pointercancel)="isDragging.set(false)"
476
+ />
477
+ </div>
478
+ <span class="afp-w-9 afp-flex-shrink-0 afp-text-[11px] afp-text-fg-tertiary afp-tabular-nums">
479
+ {{ duration() > 0 ? formatTime(duration()) : '--:--' }}
480
+ </span>
481
+ </div>
482
+
483
+ <div class="afp-flex afp-items-center afp-gap-1">
484
+ <button
485
+ type="button"
486
+ class="afp-audio-control afp-w-10 afp-h-10 afp-rounded-md afp-flex afp-items-center afp-justify-center afp-flex-shrink-0"
487
+ [attr.style]="playBtnStyle()"
488
+ [attr.title]="isPlaying() ? t('audio.aria.pause') : t('audio.aria.play')"
489
+ [attr.aria-label]="isPlaying() ? t('audio.aria.pause') : t('audio.aria.play')"
490
+ (click)="togglePlay()"
491
+ >
492
+ @if (isPlaying()) {
493
+ <i-lucide [img]="pauseIcon" class="afp-w-5 afp-h-5" />
494
+ } @else {
495
+ <i-lucide [img]="playIcon" class="afp-w-5 afp-h-5 afp-ml-0.5" />
496
+ }
497
+ </button>
498
+
499
+ <button
500
+ type="button"
501
+ class="afp-audio-control afp-w-9 afp-h-9 afp-rounded-md afp-flex afp-items-center afp-justify-center afp-transition-colors afp-text-fg-secondary hover:afp-bg-surface-3 afp-flex-shrink-0"
502
+ [attr.title]="t('audio.aria.backward_10')"
503
+ [attr.aria-label]="t('audio.aria.backward_10')"
504
+ (click)="skip(-10)"
505
+ >
506
+ <i-lucide [img]="skipBackIcon" class="afp-w-[18px] afp-h-[18px]" />
507
+ </button>
508
+
509
+ <button
510
+ type="button"
511
+ class="afp-audio-control afp-w-9 afp-h-9 afp-rounded-md afp-flex afp-items-center afp-justify-center afp-transition-colors afp-text-fg-secondary hover:afp-bg-surface-3 afp-flex-shrink-0"
512
+ [attr.title]="t('audio.aria.forward_10')"
513
+ [attr.aria-label]="t('audio.aria.forward_10')"
514
+ (click)="skip(10)"
515
+ >
516
+ <i-lucide [img]="skipForwardIcon" class="afp-w-[18px] afp-h-[18px]" />
517
+ </button>
518
+
519
+ <div class="afp-w-px afp-h-5 afp-mx-1 afp-bg-divide"></div>
520
+
521
+ <button
522
+ type="button"
523
+ class="afp-audio-control afp-w-9 afp-h-9 afp-rounded-md afp-flex afp-items-center afp-justify-center afp-transition-colors afp-flex-shrink-0"
524
+ [class.afp-bg-surface-3]="isLoop()"
525
+ [class.afp-text-fg-primary]="isLoop()"
526
+ [class.afp-text-fg-tertiary]="!isLoop()"
527
+ [attr.title]="isLoop() ? t('audio.aria.loop_off') : t('audio.aria.loop_on')"
528
+ [attr.aria-label]="isLoop() ? t('audio.aria.loop_off') : t('audio.aria.loop_on')"
529
+ (click)="toggleLoop()"
530
+ >
531
+ <i-lucide [img]="repeatIcon" class="afp-w-4 afp-h-4" />
532
+ </button>
533
+
534
+ <div class="afp-flex-1"></div>
535
+
536
+ <div
537
+ #volumeRef
538
+ class="afp-relative"
539
+ (mouseenter)="handleVolumeEnter()"
540
+ (mouseleave)="handleVolumeLeave()"
541
+ >
542
+ <button
543
+ type="button"
544
+ class="afp-audio-control afp-w-9 afp-h-9 afp-rounded-md afp-flex afp-items-center afp-justify-center afp-transition-colors afp-flex-shrink-0"
545
+ [class.afp-bg-surface-3]="showVolume()"
546
+ [class.afp-text-fg-primary]="showVolume()"
547
+ [class.afp-text-fg-secondary]="!showVolume()"
548
+ [attr.title]="isMuted() ? t('audio.aria.unmute') : t('audio.aria.mute')"
549
+ [attr.aria-label]="isMuted() ? t('audio.aria.unmute') : t('audio.aria.mute')"
550
+ (click)="toggleMute()"
551
+ >
552
+ <i-lucide [img]="volumeIcon()" class="afp-w-4 afp-h-4" />
553
+ </button>
554
+
555
+ @if (showVolume()) {
556
+ <div
557
+ class="afp-absolute afp-right-0 afp-bottom-full afp-mb-2 afp-w-[54px] afp-rounded-md afp-p-3 afp-border afp-bg-surface-toolbar afp-border-line afp-volume-popup"
558
+ (mouseenter)="handleVolumeEnter()"
559
+ (mouseleave)="handleVolumeLeave()"
560
+ >
561
+ <div class="afp-flex afp-flex-col afp-items-center afp-gap-2" style="height: 100px">
562
+ <div class="afp-relative afp-flex afp-items-center afp-justify-center" style="width: 24px; height: 80px">
563
+ <div class="afp-absolute afp-rounded-full afp-bg-surface-2" style="width: 3px; height: 100%"></div>
564
+ <div
565
+ class="afp-absolute afp-bottom-0 afp-rounded-full afp-pointer-events-none"
566
+ [attr.style]="volumeFillStyle()"
567
+ ></div>
568
+ <input
569
+ type="range"
570
+ min="0"
571
+ max="1"
572
+ step="0.01"
573
+ [value]="isMuted() ? 0 : volume()"
574
+ [attr.aria-label]="t('audio.aria.volume')"
575
+ class="volume-slider-vertical afp-absolute"
576
+ style="width: 80px; height: 24px; transform: rotate(-90deg); transform-origin: center center"
577
+ (input)="onVolumeInput($event)"
578
+ />
579
+ </div>
580
+ <span class="afp-text-[10px] afp-tabular-nums afp-text-fg-tertiary">
581
+ {{ Math.round((isMuted() ? 0 : volume()) * 100) }}
582
+ </span>
583
+ </div>
584
+ </div>
585
+ }
586
+ </div>
587
+ </div>
588
+ </div>
589
+
590
+ <audio #audioRef [src]="url()" class="afp-hidden"></audio>
591
+ </div>
592
+ }
593
+ `, styles: [".afp-volume-popup{animation:afp-fade-in .2s ease}@keyframes afp-fade-in{0%{opacity:0}to{opacity:1}}\n"] }]
594
+ }], ctorParameters: () => [] });
595
+
596
+ export { AudioRenderer };
597
+ //# sourceMappingURL=eternalheart-angular-file-preview-eternalheart-angular-file-preview-index-DWe1kVtU-CJlU6sOy.mjs.map