croco-html 20.3.5 → 20.4.0

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.
@@ -2112,14 +2112,14 @@ class AudioPlayerTagViewComponent {
2112
2112
  }
2113
2113
  }
2114
2114
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AudioPlayerTagViewComponent, deps: [{ token: CrocoHtmlOptionsToken }, { token: CommonFileInfoQueryService }], target: i0.ɵɵFactoryTarget.Component }); }
2115
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: AudioPlayerTagViewComponent, isStandalone: true, selector: "croco-html-audio-player-tag-view", inputs: { data: "data" }, viewQueries: [{ propertyName: "audioPlayer", first: true, predicate: ["audioPlayer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"audio-view\">\n @if (hasAudioError) {\n <div class=\"error-block\">\n <mat-icon>error</mat-icon>\n <span>{{ errorMessage }}</span>\n </div>\n }\n\n @if (hasFileId() && !hasAudioError) {\n <div class=\"audio-player-container\">\n <audio\n #audioPlayer\n [src]=\"audioSrc\"\n (error)=\"onErrorHandler()\"\n (loadedmetadata)=\"onLoadedMetadata()\"\n (timeupdate)=\"onTimeUpdate()\"\n (ended)=\"onEnded()\"\n (canplay)=\"onCanPlay()\"\n preload=\"metadata\">\n </audio>\n\n @if (isLoading) {\n <div class=\"loading-indicator\">\n <div class=\"progress-bar\">\n <div class=\"progress-bar-fill\"></div>\n </div>\n <span>\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u0430\u0443\u0434\u0438\u043E...</span>\n </div>\n }\n\n <div class=\"file-info\">\n <mat-icon>audiotrack</mat-icon>\n <span class=\"file-name\">{{ title }}</span>\n </div>\n\n <div class=\"player-controls\">\n <div class=\"control-buttons\">\n <button (click)=\"restart()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>replay</mat-icon>\n </button>\n\n <button (click)=\"rewind()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>replay_10</mat-icon>\n </button>\n\n <button\n (click)=\"togglePlayPause()\"\n [disabled]=\"!hasFileId() || isLoading\"\n class=\"play-pause-btn\" mat-icon-button>\n <mat-icon>{{ isPlaying ? 'pause' : 'play_arrow' }}</mat-icon>\n </button>\n\n <button (click)=\"forward()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>forward_10</mat-icon>\n </button>\n </div>\n\n <div class=\"progress-section\">\n <span class=\"time-display\">{{ formatTime(currentTime) }}</span>\n\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n [value]=\"getProgress()\"\n (input)=\"onSeekChange($event)\"\n [disabled]=\"!hasFileId() || duration === 0\"\n class=\"progress-slider\">\n\n <span class=\"time-display\">{{ formatTime(duration) }}</span>\n </div>\n\n <div class=\"volume-controls\">\n <button (click)=\"toggleMute()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>{{ isMuted ? 'volume_off' : 'volume_up' }}</mat-icon>\n </button>\n\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n [value]=\"volume * 100\"\n (input)=\"onVolumeChange($event)\"\n [disabled]=\"!hasFileId()\"\n class=\"volume-slider\">\n </div>\n </div>\n </div>\n }\n\n <!-- \u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043E\u0431 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u0444\u0430\u0439\u043B\u0430 -->\n @if (!hasFileId()) {\n <div class=\"no-file-message\">\n <mat-icon>music_off</mat-icon>\n <h5>\u0410\u0443\u0434\u0438\u043E-\u0444\u0430\u0439\u043B \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D</h5>\n </div>\n }\n</div>\n", styles: [".audio-view{width:100%;max-width:500px;margin:0 auto}.error-block{display:flex;align-items:center;gap:8px;background-color:#ffebee;color:#c62828;padding:12px;border-radius:8px;border:1px solid #ffcdd2;margin-bottom:16px}.error-block mat-icon{color:#c62828}.audio-player-container{background:#fff;border-radius:12px;padding:20px;box-shadow:0 2px 8px #0000001a;margin-bottom:16px}.loading-indicator{display:flex;flex-direction:column;align-items:center;gap:8px;padding:16px;color:#666}.loading-indicator .progress-bar{width:200px;height:4px;background-color:#e0e0e0;border-radius:2px;overflow:hidden}.loading-indicator .progress-bar .progress-bar-fill{height:100%;background-color:#1976d2;animation:loading 1.5s ease-in-out infinite}@keyframes loading{0%{transform:translate(-100%)}50%{transform:translate(0)}to{transform:translate(100%)}}.file-info{display:flex;align-items:center;gap:8px;margin-bottom:16px;padding:12px;background:#f5f5f5;border-radius:8px}.file-info mat-icon{color:#1976d2}.file-info .file-name{font-weight:500;flex:1}.player-controls{display:flex;flex-direction:column;gap:16px}.control-buttons{display:flex;justify-content:center;align-items:center;gap:8px}.control-buttons .play-pause-btn{background-color:#1976d2;color:#fff;width:48px;height:48px}.control-buttons .play-pause-btn:hover{background-color:#1565c0}.control-buttons .play-pause-btn mat-icon{font-size:24px}.control-buttons mat-icon-button{width:40px;height:40px}.control-buttons mat-icon-button:disabled{color:#ccc}.progress-section{display:flex;align-items:center;gap:12px}.progress-section .time-display{font-family:Roboto Mono,monospace;font-size:14px;color:#666;min-width:40px;text-align:center}.progress-section .progress-slider{flex:1;height:6px;-webkit-appearance:none;appearance:none;background:#e0e0e0;outline:none;border-radius:3px}.progress-section .progress-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.progress-section .progress-slider::-moz-range-thumb{width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.progress-section .progress-slider:hover::-webkit-slider-thumb{background:#1565c0}.progress-section .progress-slider:hover::-moz-range-thumb{background:#1565c0}.volume-controls{display:flex;align-items:center;gap:8px;justify-content:center}.volume-controls .volume-slider{width:100px;height:6px;-webkit-appearance:none;appearance:none;background:#e0e0e0;outline:none;border-radius:3px}.volume-controls .volume-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.volume-controls .volume-slider::-moz-range-thumb{width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.volume-controls .volume-slider:hover::-webkit-slider-thumb{background:#1565c0}.volume-controls .volume-slider:hover::-moz-range-thumb{background:#1565c0}.no-file-message{text-align:center;padding:40px 20px;color:#666}.no-file-message mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:16px;color:#ccc}.no-file-message h5{margin:0;color:#999}@media screen and (max-width: 768px){.audio-player-container{padding:16px}.control-buttons{flex-wrap:wrap;gap:4px}.progress-section{flex-direction:column;gap:8px}.progress-section .progress-slider{width:100%}.volume-controls{justify-content:flex-start}.volume-controls .volume-slider{width:80px}}input[type=range].progress-slider:disabled,input[type=range].volume-slider:disabled{opacity:.5;cursor:not-allowed}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }] }); }
2115
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: AudioPlayerTagViewComponent, isStandalone: true, selector: "croco-html-audio-player-tag-view", inputs: { data: "data" }, viewQueries: [{ propertyName: "audioPlayer", first: true, predicate: ["audioPlayer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"audio-view\">\n @if (hasAudioError) {\n <div class=\"error-block\">\n <mat-icon>error</mat-icon>\n <span>{{ errorMessage }}</span>\n </div>\n }\n\n @if (hasFileId() && !hasAudioError) {\n <div class=\"audio-player-container\">\n <audio\n #audioPlayer\n [src]=\"audioSrc\"\n (error)=\"onErrorHandler()\"\n (loadedmetadata)=\"onLoadedMetadata()\"\n (timeupdate)=\"onTimeUpdate()\"\n (ended)=\"onEnded()\"\n (canplay)=\"onCanPlay()\"\n preload=\"metadata\">\n </audio>\n\n @if (isLoading) {\n <div class=\"loading-indicator\">\n <div class=\"progress-bar\">\n <div class=\"progress-bar-fill\"></div>\n </div>\n <span>\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u0430\u0443\u0434\u0438\u043E...</span>\n </div>\n }\n\n <div class=\"file-info\">\n <mat-icon>audiotrack</mat-icon>\n <span class=\"file-name\">{{ title }}</span>\n </div>\n\n <div class=\"player-controls\">\n <div class=\"control-buttons\">\n <button (click)=\"restart()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>replay</mat-icon>\n </button>\n\n <button (click)=\"rewind()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>replay_10</mat-icon>\n </button>\n\n <button\n (click)=\"togglePlayPause()\"\n [disabled]=\"!hasFileId() || isLoading\"\n class=\"play-pause-btn\" mat-icon-button>\n <mat-icon>{{ isPlaying ? 'pause' : 'play_arrow' }}</mat-icon>\n </button>\n\n <button (click)=\"forward()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>forward_10</mat-icon>\n </button>\n </div>\n\n <div class=\"progress-section\">\n <span class=\"time-display\">{{ formatTime(currentTime) }}</span>\n\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n [value]=\"getProgress()\"\n (input)=\"onSeekChange($event)\"\n [disabled]=\"!hasFileId() || duration === 0\"\n class=\"progress-slider\">\n\n <span class=\"time-display\">{{ formatTime(duration) }}</span>\n </div>\n\n <div class=\"volume-controls\">\n <button (click)=\"toggleMute()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>{{ isMuted ? 'volume_off' : 'volume_up' }}</mat-icon>\n </button>\n\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n [value]=\"volume * 100\"\n (input)=\"onVolumeChange($event)\"\n [disabled]=\"!hasFileId()\"\n class=\"volume-slider\">\n </div>\n </div>\n </div>\n }\n\n <!-- \u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043E\u0431 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u0444\u0430\u0439\u043B\u0430 -->\n @if (!hasFileId()) {\n <div class=\"no-file-message\">\n <mat-icon>music_off</mat-icon>\n <h5>\u0410\u0443\u0434\u0438\u043E-\u0444\u0430\u0439\u043B \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D</h5>\n </div>\n }\n</div>\n", styles: [".audio-view{width:100%;margin:0 auto}.error-block{display:flex;align-items:center;gap:8px;background-color:#ffebee;color:#c62828;padding:12px;border-radius:8px;border:1px solid #ffcdd2;margin-bottom:16px}.error-block mat-icon{color:#c62828}.audio-player-container{background:#fff;border-radius:12px;padding:20px;box-shadow:0 2px 8px #0000001a;margin-bottom:16px}.loading-indicator{display:flex;flex-direction:column;align-items:center;gap:8px;padding:16px;color:#666}.loading-indicator .progress-bar{width:200px;height:4px;background-color:#e0e0e0;border-radius:2px;overflow:hidden}.loading-indicator .progress-bar .progress-bar-fill{height:100%;background-color:#1976d2;animation:loading 1.5s ease-in-out infinite}@keyframes loading{0%{transform:translate(-100%)}50%{transform:translate(0)}to{transform:translate(100%)}}.file-info{display:flex;align-items:center;gap:8px;margin-bottom:16px;padding:12px;background:#f5f5f5;border-radius:8px}.file-info mat-icon{color:#1976d2}.file-info .file-name{font-weight:500;flex:1}.player-controls{display:flex;flex-direction:column;gap:16px}.control-buttons{display:flex;justify-content:center;align-items:center;gap:8px}.control-buttons .play-pause-btn{background-color:#1976d2;color:#fff;width:48px;height:48px}.control-buttons .play-pause-btn:hover{background-color:#1565c0}.control-buttons .play-pause-btn mat-icon{font-size:24px}.control-buttons mat-icon-button{width:40px;height:40px}.control-buttons mat-icon-button:disabled{color:#ccc}.progress-section{display:flex;align-items:center;gap:12px}.progress-section .time-display{font-family:Roboto Mono,monospace;font-size:14px;color:#666;min-width:40px;text-align:center}.progress-section .progress-slider{flex:1;height:6px;-webkit-appearance:none;appearance:none;background:#e0e0e0;outline:none;border-radius:3px}.progress-section .progress-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.progress-section .progress-slider::-moz-range-thumb{width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.progress-section .progress-slider:hover::-webkit-slider-thumb{background:#1565c0}.progress-section .progress-slider:hover::-moz-range-thumb{background:#1565c0}.volume-controls{display:flex;align-items:center;gap:8px;justify-content:center}.volume-controls .volume-slider{width:100px;height:6px;-webkit-appearance:none;appearance:none;background:#e0e0e0;outline:none;border-radius:3px}.volume-controls .volume-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.volume-controls .volume-slider::-moz-range-thumb{width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.volume-controls .volume-slider:hover::-webkit-slider-thumb{background:#1565c0}.volume-controls .volume-slider:hover::-moz-range-thumb{background:#1565c0}.no-file-message{text-align:center;padding:40px 20px;color:#666}.no-file-message mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:16px;color:#ccc}.no-file-message h5{margin:0;color:#999}@media screen and (max-width: 768px){.audio-player-container{padding:16px}.control-buttons{flex-wrap:wrap;gap:4px}.progress-section{flex-direction:column;gap:8px}.progress-section .progress-slider{width:100%}.volume-controls{justify-content:flex-start}.volume-controls .volume-slider{width:80px}}input[type=range].progress-slider:disabled,input[type=range].volume-slider:disabled{opacity:.5;cursor:not-allowed}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }] }); }
2116
2116
  }
2117
2117
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AudioPlayerTagViewComponent, decorators: [{
2118
2118
  type: Component,
2119
2119
  args: [{ selector: 'croco-html-audio-player-tag-view', standalone: true, imports: [
2120
2120
  MatIcon,
2121
2121
  MatIconButton
2122
- ], template: "<div class=\"audio-view\">\n @if (hasAudioError) {\n <div class=\"error-block\">\n <mat-icon>error</mat-icon>\n <span>{{ errorMessage }}</span>\n </div>\n }\n\n @if (hasFileId() && !hasAudioError) {\n <div class=\"audio-player-container\">\n <audio\n #audioPlayer\n [src]=\"audioSrc\"\n (error)=\"onErrorHandler()\"\n (loadedmetadata)=\"onLoadedMetadata()\"\n (timeupdate)=\"onTimeUpdate()\"\n (ended)=\"onEnded()\"\n (canplay)=\"onCanPlay()\"\n preload=\"metadata\">\n </audio>\n\n @if (isLoading) {\n <div class=\"loading-indicator\">\n <div class=\"progress-bar\">\n <div class=\"progress-bar-fill\"></div>\n </div>\n <span>\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u0430\u0443\u0434\u0438\u043E...</span>\n </div>\n }\n\n <div class=\"file-info\">\n <mat-icon>audiotrack</mat-icon>\n <span class=\"file-name\">{{ title }}</span>\n </div>\n\n <div class=\"player-controls\">\n <div class=\"control-buttons\">\n <button (click)=\"restart()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>replay</mat-icon>\n </button>\n\n <button (click)=\"rewind()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>replay_10</mat-icon>\n </button>\n\n <button\n (click)=\"togglePlayPause()\"\n [disabled]=\"!hasFileId() || isLoading\"\n class=\"play-pause-btn\" mat-icon-button>\n <mat-icon>{{ isPlaying ? 'pause' : 'play_arrow' }}</mat-icon>\n </button>\n\n <button (click)=\"forward()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>forward_10</mat-icon>\n </button>\n </div>\n\n <div class=\"progress-section\">\n <span class=\"time-display\">{{ formatTime(currentTime) }}</span>\n\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n [value]=\"getProgress()\"\n (input)=\"onSeekChange($event)\"\n [disabled]=\"!hasFileId() || duration === 0\"\n class=\"progress-slider\">\n\n <span class=\"time-display\">{{ formatTime(duration) }}</span>\n </div>\n\n <div class=\"volume-controls\">\n <button (click)=\"toggleMute()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>{{ isMuted ? 'volume_off' : 'volume_up' }}</mat-icon>\n </button>\n\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n [value]=\"volume * 100\"\n (input)=\"onVolumeChange($event)\"\n [disabled]=\"!hasFileId()\"\n class=\"volume-slider\">\n </div>\n </div>\n </div>\n }\n\n <!-- \u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043E\u0431 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u0444\u0430\u0439\u043B\u0430 -->\n @if (!hasFileId()) {\n <div class=\"no-file-message\">\n <mat-icon>music_off</mat-icon>\n <h5>\u0410\u0443\u0434\u0438\u043E-\u0444\u0430\u0439\u043B \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D</h5>\n </div>\n }\n</div>\n", styles: [".audio-view{width:100%;max-width:500px;margin:0 auto}.error-block{display:flex;align-items:center;gap:8px;background-color:#ffebee;color:#c62828;padding:12px;border-radius:8px;border:1px solid #ffcdd2;margin-bottom:16px}.error-block mat-icon{color:#c62828}.audio-player-container{background:#fff;border-radius:12px;padding:20px;box-shadow:0 2px 8px #0000001a;margin-bottom:16px}.loading-indicator{display:flex;flex-direction:column;align-items:center;gap:8px;padding:16px;color:#666}.loading-indicator .progress-bar{width:200px;height:4px;background-color:#e0e0e0;border-radius:2px;overflow:hidden}.loading-indicator .progress-bar .progress-bar-fill{height:100%;background-color:#1976d2;animation:loading 1.5s ease-in-out infinite}@keyframes loading{0%{transform:translate(-100%)}50%{transform:translate(0)}to{transform:translate(100%)}}.file-info{display:flex;align-items:center;gap:8px;margin-bottom:16px;padding:12px;background:#f5f5f5;border-radius:8px}.file-info mat-icon{color:#1976d2}.file-info .file-name{font-weight:500;flex:1}.player-controls{display:flex;flex-direction:column;gap:16px}.control-buttons{display:flex;justify-content:center;align-items:center;gap:8px}.control-buttons .play-pause-btn{background-color:#1976d2;color:#fff;width:48px;height:48px}.control-buttons .play-pause-btn:hover{background-color:#1565c0}.control-buttons .play-pause-btn mat-icon{font-size:24px}.control-buttons mat-icon-button{width:40px;height:40px}.control-buttons mat-icon-button:disabled{color:#ccc}.progress-section{display:flex;align-items:center;gap:12px}.progress-section .time-display{font-family:Roboto Mono,monospace;font-size:14px;color:#666;min-width:40px;text-align:center}.progress-section .progress-slider{flex:1;height:6px;-webkit-appearance:none;appearance:none;background:#e0e0e0;outline:none;border-radius:3px}.progress-section .progress-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.progress-section .progress-slider::-moz-range-thumb{width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.progress-section .progress-slider:hover::-webkit-slider-thumb{background:#1565c0}.progress-section .progress-slider:hover::-moz-range-thumb{background:#1565c0}.volume-controls{display:flex;align-items:center;gap:8px;justify-content:center}.volume-controls .volume-slider{width:100px;height:6px;-webkit-appearance:none;appearance:none;background:#e0e0e0;outline:none;border-radius:3px}.volume-controls .volume-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.volume-controls .volume-slider::-moz-range-thumb{width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.volume-controls .volume-slider:hover::-webkit-slider-thumb{background:#1565c0}.volume-controls .volume-slider:hover::-moz-range-thumb{background:#1565c0}.no-file-message{text-align:center;padding:40px 20px;color:#666}.no-file-message mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:16px;color:#ccc}.no-file-message h5{margin:0;color:#999}@media screen and (max-width: 768px){.audio-player-container{padding:16px}.control-buttons{flex-wrap:wrap;gap:4px}.progress-section{flex-direction:column;gap:8px}.progress-section .progress-slider{width:100%}.volume-controls{justify-content:flex-start}.volume-controls .volume-slider{width:80px}}input[type=range].progress-slider:disabled,input[type=range].volume-slider:disabled{opacity:.5;cursor:not-allowed}\n"] }]
2122
+ ], template: "<div class=\"audio-view\">\n @if (hasAudioError) {\n <div class=\"error-block\">\n <mat-icon>error</mat-icon>\n <span>{{ errorMessage }}</span>\n </div>\n }\n\n @if (hasFileId() && !hasAudioError) {\n <div class=\"audio-player-container\">\n <audio\n #audioPlayer\n [src]=\"audioSrc\"\n (error)=\"onErrorHandler()\"\n (loadedmetadata)=\"onLoadedMetadata()\"\n (timeupdate)=\"onTimeUpdate()\"\n (ended)=\"onEnded()\"\n (canplay)=\"onCanPlay()\"\n preload=\"metadata\">\n </audio>\n\n @if (isLoading) {\n <div class=\"loading-indicator\">\n <div class=\"progress-bar\">\n <div class=\"progress-bar-fill\"></div>\n </div>\n <span>\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u0430\u0443\u0434\u0438\u043E...</span>\n </div>\n }\n\n <div class=\"file-info\">\n <mat-icon>audiotrack</mat-icon>\n <span class=\"file-name\">{{ title }}</span>\n </div>\n\n <div class=\"player-controls\">\n <div class=\"control-buttons\">\n <button (click)=\"restart()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>replay</mat-icon>\n </button>\n\n <button (click)=\"rewind()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>replay_10</mat-icon>\n </button>\n\n <button\n (click)=\"togglePlayPause()\"\n [disabled]=\"!hasFileId() || isLoading\"\n class=\"play-pause-btn\" mat-icon-button>\n <mat-icon>{{ isPlaying ? 'pause' : 'play_arrow' }}</mat-icon>\n </button>\n\n <button (click)=\"forward()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>forward_10</mat-icon>\n </button>\n </div>\n\n <div class=\"progress-section\">\n <span class=\"time-display\">{{ formatTime(currentTime) }}</span>\n\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n [value]=\"getProgress()\"\n (input)=\"onSeekChange($event)\"\n [disabled]=\"!hasFileId() || duration === 0\"\n class=\"progress-slider\">\n\n <span class=\"time-display\">{{ formatTime(duration) }}</span>\n </div>\n\n <div class=\"volume-controls\">\n <button (click)=\"toggleMute()\" [disabled]=\"!hasFileId()\" mat-icon-button>\n <mat-icon>{{ isMuted ? 'volume_off' : 'volume_up' }}</mat-icon>\n </button>\n\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n [value]=\"volume * 100\"\n (input)=\"onVolumeChange($event)\"\n [disabled]=\"!hasFileId()\"\n class=\"volume-slider\">\n </div>\n </div>\n </div>\n }\n\n <!-- \u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043E\u0431 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u0444\u0430\u0439\u043B\u0430 -->\n @if (!hasFileId()) {\n <div class=\"no-file-message\">\n <mat-icon>music_off</mat-icon>\n <h5>\u0410\u0443\u0434\u0438\u043E-\u0444\u0430\u0439\u043B \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D</h5>\n </div>\n }\n</div>\n", styles: [".audio-view{width:100%;margin:0 auto}.error-block{display:flex;align-items:center;gap:8px;background-color:#ffebee;color:#c62828;padding:12px;border-radius:8px;border:1px solid #ffcdd2;margin-bottom:16px}.error-block mat-icon{color:#c62828}.audio-player-container{background:#fff;border-radius:12px;padding:20px;box-shadow:0 2px 8px #0000001a;margin-bottom:16px}.loading-indicator{display:flex;flex-direction:column;align-items:center;gap:8px;padding:16px;color:#666}.loading-indicator .progress-bar{width:200px;height:4px;background-color:#e0e0e0;border-radius:2px;overflow:hidden}.loading-indicator .progress-bar .progress-bar-fill{height:100%;background-color:#1976d2;animation:loading 1.5s ease-in-out infinite}@keyframes loading{0%{transform:translate(-100%)}50%{transform:translate(0)}to{transform:translate(100%)}}.file-info{display:flex;align-items:center;gap:8px;margin-bottom:16px;padding:12px;background:#f5f5f5;border-radius:8px}.file-info mat-icon{color:#1976d2}.file-info .file-name{font-weight:500;flex:1}.player-controls{display:flex;flex-direction:column;gap:16px}.control-buttons{display:flex;justify-content:center;align-items:center;gap:8px}.control-buttons .play-pause-btn{background-color:#1976d2;color:#fff;width:48px;height:48px}.control-buttons .play-pause-btn:hover{background-color:#1565c0}.control-buttons .play-pause-btn mat-icon{font-size:24px}.control-buttons mat-icon-button{width:40px;height:40px}.control-buttons mat-icon-button:disabled{color:#ccc}.progress-section{display:flex;align-items:center;gap:12px}.progress-section .time-display{font-family:Roboto Mono,monospace;font-size:14px;color:#666;min-width:40px;text-align:center}.progress-section .progress-slider{flex:1;height:6px;-webkit-appearance:none;appearance:none;background:#e0e0e0;outline:none;border-radius:3px}.progress-section .progress-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.progress-section .progress-slider::-moz-range-thumb{width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.progress-section .progress-slider:hover::-webkit-slider-thumb{background:#1565c0}.progress-section .progress-slider:hover::-moz-range-thumb{background:#1565c0}.volume-controls{display:flex;align-items:center;gap:8px;justify-content:center}.volume-controls .volume-slider{width:100px;height:6px;-webkit-appearance:none;appearance:none;background:#e0e0e0;outline:none;border-radius:3px}.volume-controls .volume-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.volume-controls .volume-slider::-moz-range-thumb{width:20px;height:20px;background:#1976d2;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0003}.volume-controls .volume-slider:hover::-webkit-slider-thumb{background:#1565c0}.volume-controls .volume-slider:hover::-moz-range-thumb{background:#1565c0}.no-file-message{text-align:center;padding:40px 20px;color:#666}.no-file-message mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:16px;color:#ccc}.no-file-message h5{margin:0;color:#999}@media screen and (max-width: 768px){.audio-player-container{padding:16px}.control-buttons{flex-wrap:wrap;gap:4px}.progress-section{flex-direction:column;gap:8px}.progress-section .progress-slider{width:100%}.volume-controls{justify-content:flex-start}.volume-controls .volume-slider{width:80px}}input[type=range].progress-slider:disabled,input[type=range].volume-slider:disabled{opacity:.5;cursor:not-allowed}\n"] }]
2123
2123
  }], ctorParameters: () => [{ type: undefined, decorators: [{
2124
2124
  type: Inject,
2125
2125
  args: [CrocoHtmlOptionsToken]
@@ -2847,24 +2847,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
2847
2847
  */
2848
2848
  class HtmlPageDataController {
2849
2849
  constructor() {
2850
- this.data = null;
2850
+ this._data = new Map();
2851
2851
  }
2852
2852
  /**
2853
2853
  * Получить данные.
2854
2854
  * @returns
2855
2855
  */
2856
- get() {
2857
- if (!this.data) {
2856
+ get(name) {
2857
+ if (!this._data.has(name)) {
2858
2858
  return null;
2859
2859
  }
2860
- return this.data;
2860
+ return this._data.get(name);
2861
2861
  }
2862
2862
  /**
2863
2863
  * Установить данные.
2864
2864
  * @param data
2865
2865
  */
2866
- set(data) {
2867
- this.data = data;
2866
+ set(name, data) {
2867
+ this._data.set(name, data);
2868
2868
  }
2869
2869
  }
2870
2870